diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6bb53e46..de06c7ba 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -60,4 +60,4 @@ repos: types_or: [javascript, jsx, ts, tsx] language: system pass_filenames: false - entry: bash -c 'cd website && npm install && npm run lint' + entry: bash -c 'cd website && npm ci && npm run lint' diff --git a/backend/alembic/versions/2022_12_28_1824-ef0b52902560_added_lang_column_for_iso_639_1_codes.py b/backend/alembic/versions/2022_12_28_1824-ef0b52902560_added_lang_column_for_iso_639_1_codes.py new file mode 100644 index 00000000..cb6ae5da --- /dev/null +++ b/backend/alembic/versions/2022_12_28_1824-ef0b52902560_added_lang_column_for_iso_639_1_codes.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +"""Added lang column for ISO-639-1 codes + +Revision ID: ef0b52902560 +Revises: 3358eb6834e6 +Create Date: 2022-12-28 18:24:21.393973 + +""" +import sqlalchemy as sa +import sqlmodel +from alembic import op + +# revision identifiers, used by Alembic. +revision = "ef0b52902560" +down_revision = "3358eb6834e6" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + "post", sa.Column("lang", sqlmodel.sql.sqltypes.AutoString(length=200), nullable=False, default="en-US") + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("post", "lang") + # ### end Alembic commands ### diff --git a/backend/alembic/versions/2022_12_29_2103-464ec4667aae_add_collective_flag_to_task.py b/backend/alembic/versions/2022_12_29_2103-464ec4667aae_add_collective_flag_to_task.py new file mode 100644 index 00000000..cbed707c --- /dev/null +++ b/backend/alembic/versions/2022_12_29_2103-464ec4667aae_add_collective_flag_to_task.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +"""add collective flag to task + +Revision ID: 464ec4667aae +Revises: d24b37426857 +Create Date: 2022-12-29 21:03:06.841962 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = "464ec4667aae" +down_revision = "d24b37426857" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + "work_package", sa.Column("collective", sa.Boolean(), server_default=sa.text("false"), nullable=False) + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("work_package", "collective") + # ### end Alembic commands ### diff --git a/backend/oasst_backend/api/v1/tasks.py b/backend/oasst_backend/api/v1/tasks.py index 94a0be4a..1318ba41 100644 --- a/backend/oasst_backend/api/v1/tasks.py +++ b/backend/oasst_backend/api/v1/tasks.py @@ -139,7 +139,7 @@ def request_task( try: pr = PromptRepository(db, api_client, request.user) task, thread_id, parent_post_id = generate_task(request, pr) - pr.store_task(task, thread_id, parent_post_id) + pr.store_task(task, thread_id, parent_post_id, request.collective) except OasstError: raise @@ -252,3 +252,15 @@ def post_interaction( except Exception: logger.exception("Interaction request failed.") raise OasstError("Interaction request failed.", OasstErrorCode.TASK_INTERACTION_REQUEST_FAILED) + + +@router.post("/close") +def close_collective_task( + close_task_request: protocol_schema.TaskClose, + db: Session = Depends(deps.get_db), + api_key: APIKey = Depends(deps.get_api_key), +): + api_client = deps.api_auth(api_key, db) + pr = PromptRepository(db, api_client, user=None) + pr.close_task(close_task_request.post_id) + return protocol_schema.TaskDone() diff --git a/backend/oasst_backend/exceptions.py b/backend/oasst_backend/exceptions.py index c1a7bd2e..1c30e453 100644 --- a/backend/oasst_backend/exceptions.py +++ b/backend/oasst_backend/exceptions.py @@ -41,6 +41,7 @@ class OasstErrorCode(IntEnum): WORK_PACKAGE_ALREADY_UPDATED = 2103 WORK_PACKAGE_NOT_ACK = 2104 WORK_PACKAGE_ALREADY_DONE = 2105 + WORK_PACKAGE_NOT_COLLECTIVE = 2106 class OasstError(Exception): diff --git a/backend/oasst_backend/models/post.py b/backend/oasst_backend/models/post.py index ffa52240..51fa067e 100644 --- a/backend/oasst_backend/models/post.py +++ b/backend/oasst_backend/models/post.py @@ -31,5 +31,6 @@ class Post(SQLModel, table=True): ) payload_type: str = Field(nullable=False, max_length=200) payload: PayloadContainer = Field(sa_column=sa.Column(payload_column_type(PayloadContainer), nullable=True)) + lang: str = Field(nullable=False, max_length=200, default="en-US") depth: int = Field(sa_column=sa.Column(sa.Integer, default=0, server_default=sa.text("0"), nullable=False)) children_count: int = Field(sa_column=sa.Column(sa.Integer, default=0, server_default=sa.text("0"), nullable=False)) diff --git a/backend/oasst_backend/models/work_package.py b/backend/oasst_backend/models/work_package.py index a89ed646..7e568cf7 100644 --- a/backend/oasst_backend/models/work_package.py +++ b/backend/oasst_backend/models/work_package.py @@ -32,6 +32,7 @@ class WorkPackage(SQLModel, table=True): frontend_ref_post_id: Optional[str] = None thread_id: Optional[UUID] = None parent_post_id: Optional[UUID] = None + collective: bool = Field(sa_column=sa.Column(sa.Boolean, nullable=False, server_default=false())) @property def expired(self) -> bool: diff --git a/backend/oasst_backend/prompt_repository.py b/backend/oasst_backend/prompt_repository.py index 95e7867e..13c6cd23 100644 --- a/backend/oasst_backend/prompt_repository.py +++ b/backend/oasst_backend/prompt_repository.py @@ -160,8 +160,9 @@ class PromptRepository: payload=db_payload.PostPayload(text=text), depth=depth, ) - wp.done = True - self.db.add(wp) + if not wp.collective: + wp.done = True + self.db.add(wp) self.db.commit() self.journal.log_text_reply(work_package=wp, post_id=new_post_id, role=role, length=len(text)) return user_post @@ -186,6 +187,10 @@ class PromptRepository: # store reaction to post reaction_payload = db_payload.RatingReactionPayload(rating=rating.rating) reaction = self.insert_reaction(post.id, reaction_payload) + if not work_package.collective: + work_package.done = True + self.db.add(work_package) + self.journal.log_rating(work_package, post_id=post.id, rating=rating.rating) logger.info(f"Ranking {rating.rating} stored for work_package {work_package.id}.") return reaction @@ -193,8 +198,9 @@ class PromptRepository: def store_ranking(self, ranking: protocol_schema.PostRanking) -> PostReaction: # fetch work_package work_package = self.fetch_workpackage_by_postid(ranking.post_id) - work_package.done = True - self.db.add(work_package) + if not work_package.collective: + work_package.done = True + self.db.add(work_package) work_payload: db_payload.RankConversationRepliesPayload | db_payload.RankInitialPromptsPayload = ( work_package.payload.payload @@ -250,6 +256,7 @@ class PromptRepository: task: protocol_schema.Task, thread_id: UUID = None, parent_post_id: UUID = None, + collective: bool = False, ) -> WorkPackage: payload: db_payload.TaskPayload match type(task): @@ -287,10 +294,7 @@ class PromptRepository: raise OasstError(f"Invalid task type: {type(task)=}", OasstErrorCode.INVALID_TASK_TYPE) wp = self.insert_work_package( - payload=payload, - id=task.id, - thread_id=thread_id, - parent_post_id=parent_post_id, + payload=payload, id=task.id, thread_id=thread_id, parent_post_id=parent_post_id, collective=collective ) assert wp.id == task.id return wp @@ -301,6 +305,7 @@ class PromptRepository: id: UUID = None, thread_id: UUID = None, parent_post_id: UUID = None, + collective: bool = False, ) -> WorkPackage: c = PayloadContainer(payload=payload) wp = WorkPackage( @@ -311,6 +316,7 @@ class PromptRepository: api_client_id=self.api_client.id, thread_id=thread_id, parent_post_id=parent_post_id, + collective=collective, ) self.db.add(wp) self.db.commit() @@ -397,7 +403,7 @@ class PromptRepository: distinct_threads = distinct_threads.filter(Post.role == require_role) distinct_threads = distinct_threads.subquery() - random_thread = self.db.query(distinct_threads).order_by(func.random()).limit(1).subquery() + random_thread = self.db.query(distinct_threads).order_by(func.random()).limit(1) thread_posts = self.db.query(Post).filter(Post.thread_id.in_(random_thread)).all() return thread_posts @@ -443,7 +449,7 @@ class PromptRepository: if post_role: parent = parent.filter(Post.role == post_role) - parent = parent.order_by(func.random()).limit(1).subquery() + parent = parent.order_by(func.random()).limit(1) replies = self.db.query(Post).filter(Post.parent_id.in_(parent)).order_by(func.random()).limit(max_size).all() if not replies: raise OasstError("No replies found", OasstErrorCode.NO_REPLIES_FOUND) @@ -465,3 +471,20 @@ class PromptRepository: def fetch_post(self, post_id: UUID) -> Optional[Post]: return self.db.query(Post).filter(Post.id == post_id).one() + + def close_task(self, post_id: str, allow_personal_tasks: bool = False): + self.validate_post_id(post_id) + wp = self.fetch_workpackage_by_postid(post_id) + + if not wp: + raise OasstError("Work package not found", OasstErrorCode.WORK_PACKAGE_NOT_FOUND) + if wp.expired: + raise OasstError("Work package expired", OasstErrorCode.WORK_PACKAGE_EXPIRED) + if not allow_personal_tasks and not wp.collective: + raise OasstError("This is not a collective task", OasstErrorCode.WORK_PACKAGE_NOT_COLLECTIVE) + if wp.done: + raise OasstError("Allready closed", OasstErrorCode.WORK_PACKAGE_ALREADY_DONE) + + wp.done = True + self.db.add(wp) + self.db.commit() diff --git a/discord-bot/api_client.py b/discord-bot/api_client.py index 1de6bb17..0c88258e 100644 --- a/discord-bot/api_client.py +++ b/discord-bot/api_client.py @@ -52,14 +52,19 @@ class ApiClient: return self.task_models_map[task_type].parse_obj(data) def fetch_task( - self, task_type: protocol_schema.TaskRequestType, user: Optional[protocol_schema.User] = None + self, + task_type: protocol_schema.TaskRequestType, + user: Optional[protocol_schema.User] = None, + collective: bool = False, ) -> protocol_schema.Task: - req = protocol_schema.TaskRequest(type=task_type, user=user) + req = protocol_schema.TaskRequest(type=task_type, user=user, collective=collective) data = self.post("/api/v1/tasks/", req.dict()) return self._parse_task(data) - def fetch_random_task(self, user: Optional[protocol_schema.User] = None) -> protocol_schema.Task: - return self.fetch_task(protocol_schema.TaskRequestType.random, user) + def fetch_random_task( + self, user: Optional[protocol_schema.User] = None, collective: bool = False + ) -> protocol_schema.Task: + return self.fetch_task(protocol_schema.TaskRequestType.random, user, collective=collective) def ack_task(self, task_id: str, post_id: str) -> None: req = protocol_schema.TaskAck(post_id=post_id) diff --git a/oasst-shared/oasst_shared/schemas/protocol.py b/oasst-shared/oasst_shared/schemas/protocol.py index 17ee23f0..19b1921d 100644 --- a/oasst-shared/oasst_shared/schemas/protocol.py +++ b/oasst-shared/oasst_shared/schemas/protocol.py @@ -43,6 +43,7 @@ class TaskRequest(BaseModel): type: TaskRequestType = TaskRequestType.random user: Optional[User] = None + collective: bool = False class TaskAck(BaseModel): @@ -57,6 +58,12 @@ class TaskNAck(BaseModel): reason: str +class TaskClose(BaseModel): + """The frontend asks to mark task as done""" + + post_id: str + + class Task(BaseModel): """A task is a unit of work that the backend gives to the frontend.""" diff --git a/website/.eslintrc.json b/website/.eslintrc.json index bffb357a..95127c06 100644 --- a/website/.eslintrc.json +++ b/website/.eslintrc.json @@ -1,3 +1,11 @@ { - "extends": "next/core-web-vitals" + "root": true, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "next/core-web-vitals" + ], + "rules": { + "sort-imports": "warn" + } } diff --git a/website/jsconfig.json b/website/jsconfig.json deleted file mode 100644 index 2c8ee2bb..00000000 --- a/website/jsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": ".", - "paths": { - "@/*": ["src/*"] - } - } -} diff --git a/website/package-lock.json b/website/package-lock.json index 0fdaf529..c912164e 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -51,6 +51,7 @@ "@storybook/testing-library": "^0.0.13", "@types/node": "18.11.17", "@types/react": "18.0.26", + "@typescript-eslint/eslint-plugin": "^5.47.1", "babel-loader": "^8.3.0", "eslint-plugin-storybook": "^0.6.8", "prettier": "2.8.1", @@ -3767,12 +3768,43 @@ "version": "13.1.0", "license": "MIT" }, - "node_modules/@next/swc-darwin-x64": { + "node_modules/@next/swc-android-arm-eabi": { "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.0.6.tgz", + "integrity": "sha512-FGFSj3v2Bluw8fD/X+1eXIEB0PhoJE0zfutsAauRhmNpjjZshLDgoXMWm1jTRL/04K/o9gwwO2+A8+sPVCH1uw==", "cpu": [ - "x64" + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-android-arm64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-13.0.6.tgz", + "integrity": "sha512-7MgbtU7kimxuovVsd7jSJWMkIHBDBUsNLmmlkrBRHTvgzx5nDBXogP0hzZm7EImdOPwVMPpUHRQMBP9mbsiJYQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.0.6.tgz", + "integrity": "sha512-AUVEpVTxbP/fxdFsjVI9d5a0CFn6NVV7A/RXOb0Y+pXKIIZ1V5rFjPwpYfIfyOo2lrqgehMNQcyMRoTrhq04xg==", + "cpu": [ + "arm64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -3781,6 +3813,156 @@ "node": ">= 10" } }, + "node_modules/@next/swc-darwin-x64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.0.6.tgz", + "integrity": "sha512-SasCDJlshglsPnbzhWaIF6VEGkQy2NECcAOxPwaPr0cwbbt4aUlZ7QmskNzgolr5eAjFS/xTr7CEeKJtZpAAtQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-freebsd-x64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.0.6.tgz", + "integrity": "sha512-6Lbxd9gAdXneTkwHyYW/qtX1Tdw7ND9UbiGsGz/SP43ZInNWnW6q0au4hEVPZ9bOWWRKzcVoeTBdoMpQk9Hx9w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm-gnueabihf": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.0.6.tgz", + "integrity": "sha512-wNdi5A519e1P+ozEuYOhWPzzE6m1y7mkO6NFwn6watUwO0X9nZs7fT9THmnekvmFQpaZ6U+xf2MQ9poQoCh6jQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.0.6.tgz", + "integrity": "sha512-e8KTRnleQY1KLk5PwGV5hrmvKksCc74QRpHl5ffWnEEAtL2FE0ave5aIkXqErsPdXkiKuA/owp3LjQrP+/AH7Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.0.6.tgz", + "integrity": "sha512-/7RF03C3mhjYpHN+pqOolgME3guiHU5T3TsejuyteqyEyzdEyLHod+jcYH6ft7UZ71a6TdOewvmbLOtzHW2O8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.0.6.tgz", + "integrity": "sha512-kxyEXnYHpOEkFnmrlwB1QlzJtjC6sAJytKcceIyFUHbCaD3W/Qb5tnclcnHKTaFccizZRePXvV25Ok/eUSpKTw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.0.6.tgz", + "integrity": "sha512-N0c6gubS3WW1oYYgo02xzZnNatfVQP/CiJq2ax+DJ55ePV62IACbRCU99TZNXXg+Kos6vNW4k+/qgvkvpGDeyA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.0.6.tgz", + "integrity": "sha512-QjeMB2EBqBFPb/ac0CYr7GytbhUkrG4EwFWbcE0vsRp4H8grt25kYpFQckL4Jak3SUrp7vKfDwZ/SwO7QdO8vw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.0.6.tgz", + "integrity": "sha512-EQzXtdqRTcmhT/tCq81rIwE36Y3fNHPInaCuJzM/kftdXfa0F+64y7FAoMO13npX8EG1+SamXgp/emSusKrCXg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.0.6.tgz", + "integrity": "sha512-pSkqZ//UP/f2sS9T7IvHLfEWDPTX0vRyXJnAUNisKvO3eF3e1xdhDX7dix/X3Z3lnN4UjSwOzclAI87JFbOwmQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "license": "MIT", @@ -7924,6 +8106,86 @@ "dev": true, "license": "MIT" }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.1.tgz", + "integrity": "sha512-r4RZ2Jl9kcQN7K/dcOT+J7NAimbiis4sSM9spvWimsBvDegMhKLA5vri2jG19PmIPbDjPeWzfUPQ2hjEzA4Nmg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/type-utils": "5.47.1", + "@typescript-eslint/utils": "5.47.1", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", + "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.47.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "5.46.1", "license": "BSD-2-Clause", @@ -7964,6 +8226,90 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.1.tgz", + "integrity": "sha512-/UKOeo8ee80A7/GJA427oIrBi/Gd4osk/3auBUg4Rn9EahFpevVV1mUK8hjyQD5lHPqX397x6CwOk5WGh1E/1w==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.47.1", + "@typescript-eslint/utils": "5.47.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", + "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.47.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "5.46.1", "license": "MIT", @@ -9302,16 +9648,6 @@ "node": ">=8" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -12642,13 +12978,6 @@ "node": ">=12" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, "node_modules/fill-range": { "version": "7.0.1", "license": "MIT", @@ -13184,17 +13513,6 @@ "version": "1.0.0", "license": "ISC" }, - "node_modules/fsevents": { - "version": "2.3.2", - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.1", "license": "MIT" @@ -15971,13 +16289,6 @@ "version": "2.1.2", "license": "MIT" }, - "node_modules/nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "dev": true, - "optional": true - }, "node_modules/nanoid": { "version": "3.3.4", "license": "MIT", @@ -16018,6 +16329,12 @@ "version": "1.4.0", "license": "MIT" }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node_modules/negotiator": { "version": "0.6.3", "dev": true, @@ -21480,25 +21797,6 @@ "node": ">=0.10.0" } }, - "node_modules/watchpack-chokidar2/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, "node_modules/watchpack-chokidar2/node_modules/glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -24716,8 +25014,82 @@ "@next/font": { "version": "13.1.0" }, + "@next/swc-android-arm-eabi": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.0.6.tgz", + "integrity": "sha512-FGFSj3v2Bluw8fD/X+1eXIEB0PhoJE0zfutsAauRhmNpjjZshLDgoXMWm1jTRL/04K/o9gwwO2+A8+sPVCH1uw==", + "optional": true + }, + "@next/swc-android-arm64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-13.0.6.tgz", + "integrity": "sha512-7MgbtU7kimxuovVsd7jSJWMkIHBDBUsNLmmlkrBRHTvgzx5nDBXogP0hzZm7EImdOPwVMPpUHRQMBP9mbsiJYQ==", + "optional": true + }, + "@next/swc-darwin-arm64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.0.6.tgz", + "integrity": "sha512-AUVEpVTxbP/fxdFsjVI9d5a0CFn6NVV7A/RXOb0Y+pXKIIZ1V5rFjPwpYfIfyOo2lrqgehMNQcyMRoTrhq04xg==", + "optional": true + }, "@next/swc-darwin-x64": { "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.0.6.tgz", + "integrity": "sha512-SasCDJlshglsPnbzhWaIF6VEGkQy2NECcAOxPwaPr0cwbbt4aUlZ7QmskNzgolr5eAjFS/xTr7CEeKJtZpAAtQ==", + "optional": true + }, + "@next/swc-freebsd-x64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.0.6.tgz", + "integrity": "sha512-6Lbxd9gAdXneTkwHyYW/qtX1Tdw7ND9UbiGsGz/SP43ZInNWnW6q0au4hEVPZ9bOWWRKzcVoeTBdoMpQk9Hx9w==", + "optional": true + }, + "@next/swc-linux-arm-gnueabihf": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.0.6.tgz", + "integrity": "sha512-wNdi5A519e1P+ozEuYOhWPzzE6m1y7mkO6NFwn6watUwO0X9nZs7fT9THmnekvmFQpaZ6U+xf2MQ9poQoCh6jQ==", + "optional": true + }, + "@next/swc-linux-arm64-gnu": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.0.6.tgz", + "integrity": "sha512-e8KTRnleQY1KLk5PwGV5hrmvKksCc74QRpHl5ffWnEEAtL2FE0ave5aIkXqErsPdXkiKuA/owp3LjQrP+/AH7Q==", + "optional": true + }, + "@next/swc-linux-arm64-musl": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.0.6.tgz", + "integrity": "sha512-/7RF03C3mhjYpHN+pqOolgME3guiHU5T3TsejuyteqyEyzdEyLHod+jcYH6ft7UZ71a6TdOewvmbLOtzHW2O8A==", + "optional": true + }, + "@next/swc-linux-x64-gnu": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.0.6.tgz", + "integrity": "sha512-kxyEXnYHpOEkFnmrlwB1QlzJtjC6sAJytKcceIyFUHbCaD3W/Qb5tnclcnHKTaFccizZRePXvV25Ok/eUSpKTw==", + "optional": true + }, + "@next/swc-linux-x64-musl": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.0.6.tgz", + "integrity": "sha512-N0c6gubS3WW1oYYgo02xzZnNatfVQP/CiJq2ax+DJ55ePV62IACbRCU99TZNXXg+Kos6vNW4k+/qgvkvpGDeyA==", + "optional": true + }, + "@next/swc-win32-arm64-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.0.6.tgz", + "integrity": "sha512-QjeMB2EBqBFPb/ac0CYr7GytbhUkrG4EwFWbcE0vsRp4H8grt25kYpFQckL4Jak3SUrp7vKfDwZ/SwO7QdO8vw==", + "optional": true + }, + "@next/swc-win32-ia32-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.0.6.tgz", + "integrity": "sha512-EQzXtdqRTcmhT/tCq81rIwE36Y3fNHPInaCuJzM/kftdXfa0F+64y7FAoMO13npX8EG1+SamXgp/emSusKrCXg==", + "optional": true + }, + "@next/swc-win32-x64-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.0.6.tgz", + "integrity": "sha512-pSkqZ//UP/f2sS9T7IvHLfEWDPTX0vRyXJnAUNisKvO3eF3e1xdhDX7dix/X3Z3lnN4UjSwOzclAI87JFbOwmQ==", "optional": true }, "@nodelib/fs.scandir": { @@ -27489,6 +27861,51 @@ "version": "21.0.0", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.1.tgz", + "integrity": "sha512-r4RZ2Jl9kcQN7K/dcOT+J7NAimbiis4sSM9spvWimsBvDegMhKLA5vri2jG19PmIPbDjPeWzfUPQ2hjEzA4Nmg==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/type-utils": "5.47.1", + "@typescript-eslint/utils": "5.47.1", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", + "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1" + } + }, + "@typescript-eslint/types": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.47.1", + "eslint-visitor-keys": "^3.3.0" + } + } + } + }, "@typescript-eslint/parser": { "version": "5.46.1", "requires": { @@ -27505,6 +27922,51 @@ "@typescript-eslint/visitor-keys": "5.46.1" } }, + "@typescript-eslint/type-utils": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.1.tgz", + "integrity": "sha512-/UKOeo8ee80A7/GJA427oIrBi/Gd4osk/3auBUg4Rn9EahFpevVV1mUK8hjyQD5lHPqX397x6CwOk5WGh1E/1w==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.47.1", + "@typescript-eslint/utils": "5.47.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", + "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.47.1", + "eslint-visitor-keys": "^3.3.0" + } + } + } + }, "@typescript-eslint/types": { "version": "5.46.1" }, @@ -28388,16 +28850,6 @@ "binary-extensions": { "version": "2.2.0" }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -30704,13 +31156,6 @@ } } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, "fill-range": { "version": "7.0.1", "requires": { @@ -31099,10 +31544,6 @@ "fs.realpath": { "version": "1.0.0" }, - "fsevents": { - "version": "2.3.2", - "optional": true - }, "function-bind": { "version": "1.1.1" }, @@ -32870,13 +33311,6 @@ "ms": { "version": "2.1.2" }, - "nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "dev": true, - "optional": true - }, "nanoid": { "version": "3.3.4" }, @@ -32905,6 +33339,12 @@ "natural-compare": { "version": "1.4.0" }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "negotiator": { "version": "0.6.3", "dev": true @@ -36520,17 +36960,6 @@ } } }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", diff --git a/website/package.json b/website/package.json index 41cf1078..b75354a5 100644 --- a/website/package.json +++ b/website/package.json @@ -57,6 +57,7 @@ "@types/react": "18.0.26", "babel-loader": "^8.3.0", "eslint-plugin-storybook": "^0.6.8", + "@typescript-eslint/eslint-plugin": "^5.47.1", "prettier": "2.8.1", "prisma": "^4.7.1", "typescript": "4.9.4" diff --git a/website/src/components/CircleBackground.tsx b/website/src/components/CircleBackground.tsx index b5873c33..5851d4ab 100644 --- a/website/src/components/CircleBackground.tsx +++ b/website/src/components/CircleBackground.tsx @@ -1,7 +1,7 @@ import { useId } from "react"; export function CircleBackground({ color, width = 558, height = 558, ...props }) { - let id = useId(); + const id = useId(); return (
- Join Us - FAQs + Join Us + FAQs
diff --git a/website/src/components/Header/NavLinks.tsx b/website/src/components/Header/NavLinks.tsx index c6e4959a..955d92f8 100644 --- a/website/src/components/Header/NavLinks.tsx +++ b/website/src/components/Header/NavLinks.tsx @@ -3,13 +3,13 @@ import Link from "next/link"; import { AnimatePresence, motion } from "framer-motion"; export function NavLinks(): JSX.Element { - let [hoveredIndex, setHoveredIndex] = useState(null); + const [hoveredIndex, setHoveredIndex] = useState(null); return ( <> {[ - ["Join Us", "#join-us"], - ["FAQ", "#faq"], + ["Join Us", "/#join-us"], + ["FAQ", "/#faq"], ].map(([label, href], index) => ( = NextPage & { +export type NextPageWithLayout

= NextPage & { getLayout?: (page: React.ReactElement) => React.ReactNode; }; diff --git a/website/src/components/Sortable/Sortable.tsx b/website/src/components/Sortable/Sortable.tsx new file mode 100644 index 00000000..3f805726 --- /dev/null +++ b/website/src/components/Sortable/Sortable.tsx @@ -0,0 +1,48 @@ +import { ReactNode, useEffect, useState } from "react"; +import { SortableItem } from "./SortableItem"; + +export interface SortableProps { + items: ReactNode[]; + onChange: (newSortedIndices: number[]) => void; +} + +export const Sortable = ({ items, onChange }) => { + const [sortOrder, setSortOrder] = useState([]); + + const update = (newRanking: number[]) => { + setSortOrder(newRanking); + onChange(newRanking); + }; + + useEffect(() => { + const indices = Array.from({ length: items.length }).map((_, i) => i); + setSortOrder(indices); + onChange(indices); + }, [items, onChange]); + + return ( +

+ ); +}; diff --git a/website/src/components/Sortable/SortableItem.tsx b/website/src/components/Sortable/SortableItem.tsx new file mode 100644 index 00000000..057e9674 --- /dev/null +++ b/website/src/components/Sortable/SortableItem.tsx @@ -0,0 +1,44 @@ +import { ArrowUpIcon, ArrowDownIcon } from "@heroicons/react/20/solid"; +import { Button } from "src/components/Button"; +import clsx from "clsx"; + +export interface SortableItemProps { + canIncrement: boolean; + canDecrement: boolean; + onIncrement: () => void; + onDecrement: () => void; + children: React.ReactNode; +} + +export const SortableItem = ({ canIncrement, canDecrement, onIncrement, onDecrement, children }: SortableItemProps) => { + return ( +
  • + + + + {children} + + + + +
  • + ); +}; + +interface ArrowButtonProps { + active: boolean; + onClick: () => void; + children: React.ReactNode; +} + +const ArrowButton = ({ children, active, onClick }: ArrowButtonProps) => { + return ( + + ); +}; diff --git a/website/src/components/TaskInfo/TaskInfo.tsx b/website/src/components/TaskInfo/TaskInfo.tsx new file mode 100644 index 00000000..629d5c1a --- /dev/null +++ b/website/src/components/TaskInfo/TaskInfo.tsx @@ -0,0 +1,10 @@ +export const TaskInfo = ({ id, output }: { id: string; output: any }) => { + return ( +
    + Prompt + {id} + Output + {output} +
    + ); +}; diff --git a/website/src/components/TaskSelection/TaskSelection.tsx b/website/src/components/TaskSelection/TaskSelection.tsx index 6077408f..eaf1f41e 100644 --- a/website/src/components/TaskSelection/TaskSelection.tsx +++ b/website/src/components/TaskSelection/TaskSelection.tsx @@ -34,6 +34,12 @@ export const TaskSelection = () => { title="Rank Initial Prompts" link="/evaluate/rank_initial_prompts" /> + ); diff --git a/website/src/lib/prismadb.ts b/website/src/lib/prismadb.ts index 32fb23d0..85f25fcb 100644 --- a/website/src/lib/prismadb.ts +++ b/website/src/lib/prismadb.ts @@ -1,10 +1,10 @@ import { PrismaClient } from "@prisma/client"; - declare global { - var prisma; + // eslint-disable-next-line no-var + var prisma: PrismaClient | undefined; } -const client = globalThis.prisma || new PrismaClient(); +const client = new PrismaClient(); if (process.env.NODE_ENV !== "production") { globalThis.prisma = client; } diff --git a/website/src/pages/_app.tsx b/website/src/pages/_app.tsx index f602457f..119f337b 100644 --- a/website/src/pages/_app.tsx +++ b/website/src/pages/_app.tsx @@ -4,7 +4,7 @@ import { Inter } from "@next/font/google"; import { extendTheme } from "@chakra-ui/react"; import type { AppProps } from "next/app"; -import { getDefaultLayout, NextPageWithLayout } from "src/components/Layout"; +import { NextPageWithLayout, getDefaultLayout } from "src/components/Layout"; import "../styles/globals.css"; import "focus-visible"; diff --git a/website/src/pages/create/assistant_reply.tsx b/website/src/pages/create/assistant_reply.tsx index a7f058f8..92938f35 100644 --- a/website/src/pages/create/assistant_reply.tsx +++ b/website/src/pages/create/assistant_reply.tsx @@ -5,10 +5,12 @@ import useSWRImmutable from "swr/immutable"; import fetcher from "src/lib/fetcher"; import poster from "src/lib/poster"; + +import { Button } from "src/components/Button"; import { Messages } from "src/components/Messages"; import { TwoColumns } from "src/components/TwoColumns"; -import { Button } from "src/components/Button"; import { LoadingScreen } from "src/components/Loading/LoadingScreen"; +import { TaskInfo } from "src/components/TaskInfo/TaskInfo"; const AssistantReply = () => { const [tasks, setTasks] = useState([]); @@ -61,13 +63,7 @@ const AssistantReply = () => {
    -
    - Prompt - {tasks[0].id} - Output - Submit your answer -
    - +
    diff --git a/website/src/pages/create/user_reply.tsx b/website/src/pages/create/user_reply.tsx index 18427c71..a9c4a079 100644 --- a/website/src/pages/create/user_reply.tsx +++ b/website/src/pages/create/user_reply.tsx @@ -5,10 +5,12 @@ import useSWRImmutable from "swr/immutable"; import fetcher from "src/lib/fetcher"; import poster from "src/lib/poster"; -import { Messages } from "src/components/Messages"; -import { TwoColumns } from "src/components/TwoColumns"; + import { Button } from "src/components/Button"; -import { LoadingScreen } from "@/components/Loading/LoadingScreen"; +import { LoadingScreen } from "src/components/Loading/LoadingScreen"; +import { Messages } from "src/components/Messages"; +import { TaskInfo } from "src/components/TaskInfo/TaskInfo"; +import { TwoColumns } from "src/components/TwoColumns"; const UserReply = () => { const [tasks, setTasks] = useState([]); @@ -62,12 +64,7 @@ const UserReply = () => {
    -
    - Prompt - {tasks[0].id} - Output - Submit your answer -
    +
    diff --git a/website/src/pages/evaluate/rank_initial_prompts.tsx b/website/src/pages/evaluate/rank_initial_prompts.tsx index 1c7ac361..645ddd9c 100644 --- a/website/src/pages/evaluate/rank_initial_prompts.tsx +++ b/website/src/pages/evaluate/rank_initial_prompts.tsx @@ -1,5 +1,3 @@ -import { ArrowUpIcon, ArrowDownIcon } from "@heroicons/react/20/solid"; -import clsx from "clsx"; import Head from "next/head"; import { useState } from "react"; import useSWRImmutable from "swr/immutable"; @@ -9,7 +7,9 @@ import fetcher from "src/lib/fetcher"; import poster from "src/lib/poster"; import { Button } from "src/components/Button"; -import { LoadingScreen } from "@/components/Loading/LoadingScreen"; +import { LoadingScreen } from "src/components/Loading/LoadingScreen"; +import { Sortable } from "src/components/Sortable/Sortable"; +import { TaskInfo } from "src/components/TaskInfo/TaskInfo"; const RankInitialPrompts = () => { const [tasks, setTasks] = useState([]); @@ -22,9 +22,6 @@ const RankInitialPrompts = () => { const { isLoading } = useSWRImmutable("/api/new_task/rank_initial_prompts", fetcher, { onSuccess: (data) => { setTasks([data]); - - const indices = Array.from({ length: data.task.prompts.length }).map((_, i) => i); - setRanking(indices); }, }); @@ -53,12 +50,6 @@ const RankInitialPrompts = () => { return
    No tasks found...
    ; } - const prompts = tasks[0].task.prompts as string[]; - const items = ranking.map((i) => ({ - text: prompts[i], - originalIndex: i, - })); - return ( <> @@ -71,38 +62,11 @@ const RankInitialPrompts = () => {

    Given the following prompts, sort them from best to worst, best being first, worst being last.

    -
      - {items.map(({ text, originalIndex }, i) => ( - 0} - onIncrement={() => { - const newRanking = ranking.slice(); - const newIdx = i - 1; - [newRanking[i], newRanking[newIdx]] = [newRanking[newIdx], newRanking[i]]; - setRanking(newRanking); - }} - canDecrement={i < items.length - 1} - onDecrement={() => { - const newRanking = ranking.slice(); - const newIdx = i + 1; - [newRanking[i], newRanking[newIdx]] = [newRanking[newIdx], newRanking[i]]; - setRanking(newRanking); - }} - > - {text} - - ))} -
    +
    -
    -
    - Prompt - {tasks[0].id} - Output - Submit your answer -
    +
    +
    @@ -121,30 +85,3 @@ const RankInitialPrompts = () => { }; export default RankInitialPrompts; - -const SortableItem = ({ canIncrement, canDecrement, onIncrement, onDecrement, children, ...props }) => { - return ( -
  • - - - - {children} - - - - -
  • - ); -}; - -const ArrowButton = ({ children, active, onClick }) => { - return ( - - ); -}; diff --git a/website/src/pages/evaluate/rank_user_replies.tsx b/website/src/pages/evaluate/rank_user_replies.tsx new file mode 100644 index 00000000..74b2ac8a --- /dev/null +++ b/website/src/pages/evaluate/rank_user_replies.tsx @@ -0,0 +1,88 @@ +import Head from "next/head"; +import { useState } from "react"; +import useSWRImmutable from "swr/immutable"; +import useSWRMutation from "swr/mutation"; + +import fetcher from "src/lib/fetcher"; +import poster from "src/lib/poster"; + +import { Button } from "src/components/Button"; +import { LoadingScreen } from "src/components/Loading/LoadingScreen"; +import { Sortable } from "src/components/Sortable/Sortable"; +import { TaskInfo } from "src/components/TaskInfo/TaskInfo"; + +const RankUserReplies = () => { + const [tasks, setTasks] = useState([]); + /** + * This array will contain the ranked indices of the replies + * The best reply will have index 0, and the worst is the last. + */ + const [ranking, setRanking] = useState([]); + + const { isLoading } = useSWRImmutable("/api/new_task/rank_user_replies", fetcher, { + onSuccess: (data) => { + setTasks([data]); + }, + }); + + const { trigger, isMutating } = useSWRMutation("/api/update_task", poster, { + onSuccess: async (data) => { + const newTask = await data.json(); + setTasks((oldTasks) => [...oldTasks, newTask]); + }, + }); + + const submitResponse = (task) => { + trigger({ + id: task.id, + update_type: "post_ranking", + content: { + ranking, + }, + }); + }; + + if (isLoading) { + return ; + } + + if (tasks.length == 0) { + return
    Loading...
    ; + } + const replies = tasks[0].task.replies as string[]; + + return ( + <> + + Rank User Replies + + +
    +
    +
    Instructions
    +

    + Given the following replies, sort them from best to worst, best being first, worst being last. +

    + +
    + +
    + + +
    + + +
    +
    +
    + + ); +}; + +export default RankUserReplies; diff --git a/website/src/pages/evaluate/rate_summary.tsx b/website/src/pages/evaluate/rate_summary.tsx index 6ff74c37..8ffe2a9d 100644 --- a/website/src/pages/evaluate/rate_summary.tsx +++ b/website/src/pages/evaluate/rate_summary.tsx @@ -9,9 +9,10 @@ import RatingRadioGroup from "src/components/RatingRadioGroup"; import fetcher from "src/lib/fetcher"; import poster from "src/lib/poster"; -import { TwoColumns } from "src/components/TwoColumns"; import { Button } from "src/components/Button"; -import { LoadingScreen } from "@/components/Loading/LoadingScreen"; +import { LoadingScreen } from "src/components/Loading/LoadingScreen"; +import { TwoColumns } from "src/components/TwoColumns"; +import { TaskInfo } from "src/components/TaskInfo/TaskInfo"; const RateSummary = () => { // Use an array of tasks that record the sequence of steps until a task is @@ -91,12 +92,7 @@ const RateSummary = () => {
    -
    - Prompt - {tasks[0].id} - Output - Submit your answer -
    +
    diff --git a/website/src/pages/leaderboard/score-leaderboard.tsx b/website/src/pages/leaderboard/score-leaderboard.tsx index da449b1a..495c1c35 100644 --- a/website/src/pages/leaderboard/score-leaderboard.tsx +++ b/website/src/pages/leaderboard/score-leaderboard.tsx @@ -1,7 +1,5 @@ import RankItem from "src/components/RankItem"; -import { BarsArrowUpIcon, BarsArrowDownIcon } from "@heroicons/react/24/solid"; -import Image from "next/image"; -import { HiBarsArrowUp, HiBarsArrowDown } from "react-icons/hi2"; +import { HiBarsArrowDown } from "react-icons/hi2"; const LeaderBoard = () => { const PlaceHolderProps = { username: "test_user", score: 10 }; diff --git a/website/tsconfig.json b/website/tsconfig.json index 8a5ec4fe..4f09afda 100644 --- a/website/tsconfig.json +++ b/website/tsconfig.json @@ -14,10 +14,7 @@ "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", - "baseUrl": ".", - "paths": { - "@/*": ["src/*"] - } + "baseUrl": "." }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules"]