diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 691d8e4f4..8e608153e 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,7 +1,7 @@ /** @type {import("eslint").Linter.Config} */ module.exports = { root: true, - parser: "@typescript-eslint/parser", + extends: ["eslint-config-custom"], parserOptions: { tsconfigRootDir: __dirname, project: [ @@ -10,9 +10,4 @@ module.exports = { "./packages/*/tsconfig.json", ], }, - plugins: ["@typescript-eslint"], - extends: ["plugin:@typescript-eslint/recommended"], - rules: { - "no-console": "warn" - } }; diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 245182dad..cad1aa60e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: run: pnpm install - name: Generate prisma client - run: pnpm db-generate + run: pnpm db-generate:no-engine - name: Inject Doppler env vars uses: dopplerhq/secrets-fetch-action@v1.2.0 @@ -43,4 +43,4 @@ jobs: inject-env-vars: true - name: Run tests - run: pnpm turbo test --cache-dir=".turbo" + run: pnpm turbo test --cache-dir=".turbo" -- --maxWorkers=33% diff --git a/.vscode/settings.json b/.vscode/settings.json index f17db0427..daa6fc1fd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,8 +19,10 @@ "autodocs", "autoprefixer", "autosize", + "backmerge", "backticked", "beitzah", + "bethclark", "bugsnag", "categorisation", "Categorised", @@ -28,6 +30,7 @@ "cloudinary", "clsx", "codegen", + "COLOR", "compat", "contrib", "cuid", @@ -40,6 +43,7 @@ "Docgen", "dockerized", "dopplerhq", + "dotenv", "EASS", "EHRC", "estree", @@ -106,6 +110,7 @@ "ponyfill", "popover", "portabletext", + "postcss", "posthog", "postpack", "posttest", @@ -117,6 +122,7 @@ "psql", "pusherapp", "ratelimit", + "refs", "Regen", "remeda", "Rerank", @@ -128,6 +134,7 @@ "sslmode", "SUBJ", "superjson", + "svgs", "tailwindcss", "tanstack", "testid", @@ -143,6 +150,8 @@ "turborepo", "uidotdev", "unjudged", + "unsets", + "unshallow", "unsummarised", "untruncate", "untruncated", @@ -154,6 +163,7 @@ "valign", "vars", "vectorstores", + "vercel", "WCAG", "webvtt", "zadd", @@ -193,5 +203,6 @@ "yaml.schemas": { "file:///c%3A/Users/Simon/.vscode/extensions/atlassian.atlascode-2.8.6/resources/schemas/pipelines-schema.json": "bitbucket-pipelines.yml", "https://www.artillery.io/schema.json": [] - } + }, + "typescript.preferences.preferTypeOnlyAutoImports": true } diff --git a/apps/nextjs/.eslintrc.cjs b/apps/nextjs/.eslintrc.cjs index cc5073297..d815e14a5 100644 --- a/apps/nextjs/.eslintrc.cjs +++ b/apps/nextjs/.eslintrc.cjs @@ -16,4 +16,7 @@ module.exports = { }, ], }, + parserOptions: { + project: __dirname + "/tsconfig.json", + }, }; diff --git a/apps/nextjs/.storybook/main.ts b/apps/nextjs/.storybook/main.ts index 53b58e031..0b2d01b6e 100644 --- a/apps/nextjs/.storybook/main.ts +++ b/apps/nextjs/.storybook/main.ts @@ -2,6 +2,8 @@ import type { StorybookConfig } from "@storybook/nextjs"; import { join, dirname, resolve } from "path"; import webpack from "webpack"; +process.env.NEXT_PUBLIC_DEBUG = process.env.DEBUG; + /** * This function is used to resolve the absolute path of a package. * It is needed in projects that use Yarn PnP or are set up within a monorepo. diff --git a/apps/nextjs/.storybook/preview.tsx b/apps/nextjs/.storybook/preview.tsx index 3a13c4d01..887d667e3 100644 --- a/apps/nextjs/.storybook/preview.tsx +++ b/apps/nextjs/.storybook/preview.tsx @@ -8,7 +8,6 @@ import "@fontsource/lexend/800.css"; import "@fontsource/lexend/900.css"; import { OakThemeProvider, oakDefaultTheme } from "@oaknational/oak-components"; import type { Preview, Decorator } from "@storybook/react"; -import { GeistMono } from "geist/font/mono"; // ModerationProvider is coming in the main Chat.tsx refactor //import { ModerationProvider } from "../src/components/AppComponents/Chat/Chat/ModerationProvider"; diff --git a/apps/nextjs/jest.setup.js b/apps/nextjs/jest.setup.js index 61958adc9..f6a95f743 100644 --- a/apps/nextjs/jest.setup.js +++ b/apps/nextjs/jest.setup.js @@ -1,5 +1,7 @@ require("@testing-library/jest-dom"); +process.env.NEXT_PUBLIC_DEBUG = process.env.DEBUG; + // Mock Next.js Image component jest.mock("next/image", () => ({ __esModule: true, diff --git a/apps/nextjs/next.config.js b/apps/nextjs/next.config.js index 3d7103f35..4cc207922 100644 --- a/apps/nextjs/next.config.js +++ b/apps/nextjs/next.config.js @@ -5,7 +5,6 @@ const { RELEASE_STAGE_TESTING, } = require("./scripts/build_config_helpers.js"); const path = require("path"); -const Sentry = require("@sentry/nextjs"); const { PHASE_PRODUCTION_BUILD, PHASE_TEST } = require("next/constants"); @@ -89,6 +88,7 @@ const getConfig = async (phase) => { env: { NEXT_PUBLIC_APP_VERSION: appVersion, NEXT_PUBLIC_RELEASE_STAGE: releaseStage, + NEXT_PUBLIC_DEBUG: process.env.DEBUG, }, productionBrowserSourceMaps: true, @@ -155,41 +155,37 @@ const getConfig = async (phase) => { module.exports = getConfig; -if (!process.env.TURBOPACK) { - module.exports = withSentryConfig(module.exports, { - // For all available options, see: - // https://github.com/getsentry/sentry-webpack-plugin#options +module.exports = withSentryConfig(module.exports, { + // For all available options, see: + // https://github.com/getsentry/sentry-webpack-plugin#options - org: process.env.SENTRY_ORG, - project: process.env.SENTRY_PROJECT, + org: process.env.SENTRY_ORG, + project: process.env.SENTRY_PROJECT, - // Only print logs for uploading source maps in CI - silent: !process.env.CI, + // Only print logs for uploading source maps in CI + silent: !process.env.CI, - // For all available options, see: - // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/ + // For all available options, see: + // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/ - // Upload a larger set of source maps for prettier stack traces (increases build time) - widenClientFileUpload: true, + // Upload a larger set of source maps for prettier stack traces (increases build time) + widenClientFileUpload: true, - // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. - // This can increase your server load as well as your hosting bill. - // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client- - // side errors will fail. - tunnelRoute: "/monitoring", + // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. + // This can increase your server load as well as your hosting bill. + // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client- + // side errors will fail. + tunnelRoute: "/monitoring", - // Hides source maps from generated client bundles - hideSourceMaps: true, + // Hides source maps from generated client bundles + hideSourceMaps: true, - // Automatically tree-shake Sentry logger statements to reduce bundle size - disableLogger: true, + // Automatically tree-shake Sentry logger statements to reduce bundle size + disableLogger: true, - // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.) - // See the following for more information: - // https://docs.sentry.io/product/crons/ - // https://vercel.com/docs/cron-jobs - automaticVercelMonitors: true, - }); -} - -module.exports.onRequestError = Sentry.captureRequestError; + // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.) + // See the following for more information: + // https://docs.sentry.io/product/crons/ + // https://vercel.com/docs/cron-jobs + automaticVercelMonitors: true, +}); diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json index 7ae770a2d..fd0e25a4f 100644 --- a/apps/nextjs/package.json +++ b/apps/nextjs/package.json @@ -7,10 +7,8 @@ "build:dev": "pnpm with-env next build", "check": "tsc --noEmit", "clean": "rm -rf .next .turbo node_modules", - "dev": "FORCE_COLOR=1 concurrently \"pnpm dev-server\" \"node scripts/local-dev.mjs\"", - "dev-turbo": "FORCE_COLOR=1 concurrently \"pnpm dev-server-turbo\" \"node scripts/local-dev.mjs\"", - "dev-server-turbo": "FORCE_COLOR=1 pnpm with-env node scripts/increase-listeners.js next dev --port 2525 --turbo | pino-pretty -C", - "dev-server": "FORCE_COLOR=1 pnpm with-env node scripts/increase-listeners.js next dev --port 2525 | pino-pretty -C", + "dev": "FORCE_COLOR=1 SENTRY_SUPPRESS_TURBOPACK_WARNING=1 pnpm with-env node scripts/increase-listeners.js next dev --port 2525 --turbo | pino-pretty -C", + "dev:sentry": "FORCE_COLOR=1 pnpm with-env node scripts/increase-listeners.js next dev --port 2525 | pino-pretty -C", "dev-trace-deprecation": "NODE_OPTIONS=\"--trace-deprecation\" next dev --port 2525 | pino-pretty -C", "lint": "next lint", "lint-fix": "next lint --fix", @@ -56,7 +54,7 @@ "@radix-ui/react-tooltip": "^1.0.7", "@radix-ui/themes": "^1.0.0", "@sanity/client": "^6.21.3", - "@sentry/nextjs": "^8.19.0", + "@sentry/nextjs": "^8.35.0", "@storybook/testing-react": "^2.0.1", "@tanstack/react-query": "^4.16.1", "@testing-library/jest-dom": "^6.4.8", @@ -151,7 +149,7 @@ "concurrently": "^8.2.2", "dotenv-cli": "^6.0.0", "eslint": "^8.56.0", - "eslint-config-next": "14.0.4", + "eslint-config-next": "15.0.1", "eslint-plugin-storybook": "^0.8.0", "graphql": "^16.9.0", "jest": "^29.7.0", diff --git a/apps/nextjs/scripts/aila-cli.ts b/apps/nextjs/scripts/aila-cli.ts index 23c7f3dca..12e328731 100644 --- a/apps/nextjs/scripts/aila-cli.ts +++ b/apps/nextjs/scripts/aila-cli.ts @@ -1,4 +1,4 @@ -import { Aila } from "@oakai/aila"; +import { Aila } from "@oakai/aila/src/core/Aila"; import { AilaPlugin } from "@oakai/aila/src/core/plugins"; const cliPlugin: AilaPlugin = { diff --git a/apps/nextjs/scripts/local-dev.mjs b/apps/nextjs/scripts/preload-chat-routes.mjs similarity index 100% rename from apps/nextjs/scripts/local-dev.mjs rename to apps/nextjs/scripts/preload-chat-routes.mjs diff --git a/apps/nextjs/src/ai-apps/common/getSessionOutput.ts b/apps/nextjs/src/ai-apps/common/getSessionOutput.ts index 6b4f8d1e8..bcbebb9f8 100644 --- a/apps/nextjs/src/ai-apps/common/getSessionOutput.ts +++ b/apps/nextjs/src/ai-apps/common/getSessionOutput.ts @@ -1,4 +1,4 @@ -import { Apps } from "@oakai/core"; +import { Apps } from "@oakai/core/src/models/apps"; import { prisma } from "@oakai/db"; import { outputSchema } from "ai-apps/generations/types"; diff --git a/apps/nextjs/src/ai-apps/common/parseLocalStorageData.ts b/apps/nextjs/src/ai-apps/common/parseLocalStorageData.ts index 5bd6ce109..63a57753f 100644 --- a/apps/nextjs/src/ai-apps/common/parseLocalStorageData.ts +++ b/apps/nextjs/src/ai-apps/common/parseLocalStorageData.ts @@ -1,6 +1,6 @@ import { aiLogger } from "@oakai/logger"; import * as Sentry from "@sentry/nextjs"; -import { z } from "zod"; +import type { z } from "zod"; const log = aiLogger("ui"); diff --git a/apps/nextjs/src/ai-apps/common/state/create-parts.ts b/apps/nextjs/src/ai-apps/common/state/create-parts.ts index ada374416..ce6f27dd5 100644 --- a/apps/nextjs/src/ai-apps/common/state/create-parts.ts +++ b/apps/nextjs/src/ai-apps/common/state/create-parts.ts @@ -1,9 +1,9 @@ -import { +import type { GenerationPart, GenerationPartAIGenerated, - GenerationPartType, GenerationPartUserTweaked, } from "@oakai/core/src/types"; +import { GenerationPartType } from "@oakai/core/src/types"; export function createAIGeneratedPart( value: Value, diff --git a/apps/nextjs/src/ai-apps/common/state/helpers.ts b/apps/nextjs/src/ai-apps/common/state/helpers.ts index 33cea956f..d62726193 100644 --- a/apps/nextjs/src/ai-apps/common/state/helpers.ts +++ b/apps/nextjs/src/ai-apps/common/state/helpers.ts @@ -1,4 +1,4 @@ -import { GenerationPart } from "@oakai/core/src/types"; +import type { GenerationPart } from "@oakai/core/src/types"; /** * Apply the `updater` function to the item diff --git a/apps/nextjs/src/ai-apps/lesson-planner/state/actions.ts b/apps/nextjs/src/ai-apps/lesson-planner/state/actions.ts index d237bb22e..16ef00a41 100644 --- a/apps/nextjs/src/ai-apps/lesson-planner/state/actions.ts +++ b/apps/nextjs/src/ai-apps/lesson-planner/state/actions.ts @@ -1,13 +1,13 @@ -import { RateLimitInfo } from "@oakai/api/src/types"; -import { KeyStageName, SubjectName } from "@oakai/core"; -import { +import type { RateLimitInfo } from "@oakai/api/src/types"; +import type { KeyStageName, SubjectName } from "@oakai/core"; +import type { QuizAppQuestion, QuizAppStateQuestion, } from "ai-apps/quiz-designer/state/types"; -import { DeepPartial } from "@/utils/types/DeepPartial"; +import type { DeepPartial } from "@/utils/types/DeepPartial"; -import { +import type { LPKeyLearningPoint, LPKeyword, LPMisconception, diff --git a/apps/nextjs/src/ai-apps/quiz-designer/convertToCSV.ts b/apps/nextjs/src/ai-apps/quiz-designer/convertToCSV.ts index f4e45054e..6dec1fc91 100644 --- a/apps/nextjs/src/ai-apps/quiz-designer/convertToCSV.ts +++ b/apps/nextjs/src/ai-apps/quiz-designer/convertToCSV.ts @@ -1,4 +1,4 @@ -import { ExportableQuizAppState } from "@oakai/exports/src/schema/input.schema"; +import type { ExportableQuizAppState } from "@oakai/exports/src/schema/input.schema"; export function convertQuizToCSV(data: ExportableQuizAppState) { // Define the headers for your CSV diff --git a/apps/nextjs/src/ai-apps/quiz-designer/convertToGIFTFormat.ts b/apps/nextjs/src/ai-apps/quiz-designer/convertToGIFTFormat.ts index 900419109..f7eb577e9 100644 --- a/apps/nextjs/src/ai-apps/quiz-designer/convertToGIFTFormat.ts +++ b/apps/nextjs/src/ai-apps/quiz-designer/convertToGIFTFormat.ts @@ -1,4 +1,4 @@ -import { +import type { ExportableQuizAppState, ExportableQuizQuestion, } from "@oakai/exports/src/schema/input.schema"; @@ -29,7 +29,7 @@ export function convertToGIFTFormat( } } - giftString += `\n}\n`; + giftString += "\n}\n"; } return giftString; diff --git a/apps/nextjs/src/ai-apps/quiz-designer/export-helpers.ts b/apps/nextjs/src/ai-apps/quiz-designer/export-helpers.ts index 44ecd6ce9..e4a90e80b 100644 --- a/apps/nextjs/src/ai-apps/quiz-designer/export-helpers.ts +++ b/apps/nextjs/src/ai-apps/quiz-designer/export-helpers.ts @@ -1,4 +1,4 @@ -import { +import type { ExportableQuizAppState, ExportableQuizQuestion, } from "@oakai/exports/src/schema/input.schema"; @@ -6,7 +6,7 @@ import { getGenerationPartValue } from "ai-apps/common/state/helpers"; import { sortAlphabetically } from "@/utils/alphabetiseArray"; -import { +import type { QuizAppQuestion, QuizAppState, QuizAppStateQuestion, diff --git a/apps/nextjs/src/ai-apps/quiz-designer/extraQuizPromptInfo.ts b/apps/nextjs/src/ai-apps/quiz-designer/extraQuizPromptInfo.ts index 22b579306..d90b7a39b 100644 --- a/apps/nextjs/src/ai-apps/quiz-designer/extraQuizPromptInfo.ts +++ b/apps/nextjs/src/ai-apps/quiz-designer/extraQuizPromptInfo.ts @@ -1,4 +1,4 @@ -import { QuizAppState, QuizAppStateQuestion } from "./state/types"; +import type { QuizAppState, QuizAppStateQuestion } from "./state/types"; type OtherQuestionForPromptPropos = { state: QuizAppState; diff --git a/apps/nextjs/src/ai-apps/quiz-designer/quizRequestGeneration.ts b/apps/nextjs/src/ai-apps/quiz-designer/quizRequestGeneration.ts index a270b3942..5efddcb15 100644 --- a/apps/nextjs/src/ai-apps/quiz-designer/quizRequestGeneration.ts +++ b/apps/nextjs/src/ai-apps/quiz-designer/quizRequestGeneration.ts @@ -1,9 +1,9 @@ -import { GenerationPart } from "@oakai/core/src/types"; +import type { GenerationPart } from "@oakai/core/src/types"; import { getAgesFromKeyStage } from "@/utils/getAgesFromKeyStage"; import { extraQuizPromptInfo } from "./extraQuizPromptInfo"; -import { QuizAppState, QuizAppStateQuestion } from "./state/types"; +import type { QuizAppState, QuizAppStateQuestion } from "./state/types"; type RequestionGenerationInputs = { lastGenerationId: string | null; diff --git a/apps/nextjs/src/ai-apps/quiz-designer/state/actions.ts b/apps/nextjs/src/ai-apps/quiz-designer/state/actions.ts index a5a55c020..9641f803e 100644 --- a/apps/nextjs/src/ai-apps/quiz-designer/state/actions.ts +++ b/apps/nextjs/src/ai-apps/quiz-designer/state/actions.ts @@ -1,8 +1,8 @@ -import { RateLimitInfo } from "@oakai/api/src/types"; -import { KeyStageName, SubjectName } from "@oakai/core"; -import { PotentialQuestionsType } from "hooks/useSuggestedQuestions"; +import type { RateLimitInfo } from "@oakai/api/src/types"; +import type { KeyStageName, SubjectName } from "@oakai/core"; +import type { PotentialQuestionsType } from "hooks/useSuggestedQuestions"; -import { QuizAppState, QuizQuestionType } from "./types"; +import type { QuizAppState, QuizQuestionType } from "./types"; /** * Our action types are declared as a const enum with string values diff --git a/apps/nextjs/src/ai-apps/quiz-designer/state/reducer.ts b/apps/nextjs/src/ai-apps/quiz-designer/state/reducer.ts index 0b2719325..82ca64f85 100644 --- a/apps/nextjs/src/ai-apps/quiz-designer/state/reducer.ts +++ b/apps/nextjs/src/ai-apps/quiz-designer/state/reducer.ts @@ -5,15 +5,12 @@ import { createTweakPart, } from "ai-apps/common/state/create-parts"; import { removeAtIndex, updateAtIndex } from "ai-apps/common/state/helpers"; -import { PotentialQuestionsType } from "hooks/useSuggestedQuestions"; +import type { PotentialQuestionsType } from "hooks/useSuggestedQuestions"; -import { QuizAppAction, QuizAppActions } from "./actions"; -import { - QuizAppState, - QuizAppStateQuestion, - QuizAppStatus, - QuizQuestionType, -} from "./types"; +import type { QuizAppAction } from "./actions"; +import { QuizAppActions } from "./actions"; +import type { QuizAppState, QuizAppStateQuestion } from "./types"; +import { QuizAppStatus, QuizQuestionType } from "./types"; export function quizAppReducer( state: QuizAppState, diff --git a/apps/nextjs/src/app/actions.ts b/apps/nextjs/src/app/actions.ts index d515d3330..7cc3bb9b5 100644 --- a/apps/nextjs/src/app/actions.ts +++ b/apps/nextjs/src/app/actions.ts @@ -1,7 +1,9 @@ "use server"; -import { AilaPersistedChat, chatSchema } from "@oakai/aila/src/protocol/schema"; -import { Prisma, prisma } from "@oakai/db"; +import type { AilaPersistedChat } from "@oakai/aila/src/protocol/schema"; +import { chatSchema } from "@oakai/aila/src/protocol/schema"; +import type { Prisma } from "@oakai/db"; +import { prisma } from "@oakai/db"; import * as Sentry from "@sentry/nextjs"; function parseChatAndReportError({ @@ -14,7 +16,7 @@ function parseChatAndReportError({ userId: string; }): AilaPersistedChat | undefined { if (typeof sessionOutput !== "object") { - throw new Error(`sessionOutput is not an object`); + throw new Error("sessionOutput is not an object"); } const parseResult = chatSchema.safeParse({ ...sessionOutput, @@ -23,7 +25,7 @@ function parseChatAndReportError({ }); if (!parseResult.success) { - const error = new Error(`Failed to parse chat`); + const error = new Error("Failed to parse chat"); Sentry.captureException(error, { extra: { id, diff --git a/apps/nextjs/src/app/admin/aila/[chatId]/view.tsx b/apps/nextjs/src/app/admin/aila/[chatId]/view.tsx index 8b223ea2e..fa67b0510 100644 --- a/apps/nextjs/src/app/admin/aila/[chatId]/view.tsx +++ b/apps/nextjs/src/app/admin/aila/[chatId]/view.tsx @@ -1,8 +1,8 @@ import { useState } from "react"; -import { type AilaPersistedChat } from "@oakai/aila/src/protocol/schema"; +import type { AilaPersistedChat } from "@oakai/aila/src/protocol/schema"; import { getSafetyResult } from "@oakai/core/src/utils/ailaModeration/helpers"; -import { type Moderation } from "@oakai/db"; +import type { Moderation } from "@oakai/db"; import { OakAccordion, OakPrimaryButton } from "@oaknational/oak-components"; import { trpc } from "@/utils/trpc"; diff --git a/apps/nextjs/src/app/aila/[id]/download/DownloadView.tsx b/apps/nextjs/src/app/aila/[id]/download/DownloadView.tsx index 30c02929f..a6fde2f92 100644 --- a/apps/nextjs/src/app/aila/[id]/download/DownloadView.tsx +++ b/apps/nextjs/src/app/aila/[id]/download/DownloadView.tsx @@ -1,6 +1,6 @@ "use client"; -import { AilaPersistedChat } from "@oakai/aila/src/protocol/schema"; +import type { AilaPersistedChat } from "@oakai/aila/src/protocol/schema"; import { Box, Flex, Grid } from "@radix-ui/themes"; import Layout from "@/components/AppComponents/Layout"; diff --git a/apps/nextjs/src/app/aila/[id]/download/page.tsx b/apps/nextjs/src/app/aila/[id]/download/page.tsx index 4c1c13193..819e50957 100644 --- a/apps/nextjs/src/app/aila/[id]/download/page.tsx +++ b/apps/nextjs/src/app/aila/[id]/download/page.tsx @@ -1,5 +1,5 @@ import { auth } from "@clerk/nextjs/server"; -import { type Metadata } from "next"; +import type { Metadata } from "next"; import { notFound, redirect } from "next/navigation"; import { getChatById } from "@/app/actions"; diff --git a/apps/nextjs/src/app/aila/[id]/download/useDownloadView.ts b/apps/nextjs/src/app/aila/[id]/download/useDownloadView.ts index cd0eef6ad..ab80452e2 100644 --- a/apps/nextjs/src/app/aila/[id]/download/useDownloadView.ts +++ b/apps/nextjs/src/app/aila/[id]/download/useDownloadView.ts @@ -1,8 +1,8 @@ import { getLastAssistantMessage } from "@oakai/aila/src/helpers/chat/getLastAssistantMessage"; -import { AilaPersistedChat } from "@oakai/aila/src/protocol/schema"; +import type { AilaPersistedChat } from "@oakai/aila/src/protocol/schema"; import { useProgressForDownloads } from "@/components/AppComponents/Chat/Chat/hooks/useProgressForDownloads"; -import { ExportsHookProps } from "@/components/ExportsDialogs/exports.types"; +import type { ExportsHookProps } from "@/components/ExportsDialogs/exports.types"; import { useExportAdditionalMaterials } from "@/components/ExportsDialogs/useExportAdditionalMaterials"; import { useExportAllLessonAssets } from "@/components/ExportsDialogs/useExportAllLessonAssets"; import { useExportLessonPlanDoc } from "@/components/ExportsDialogs/useExportLessonPlanDoc"; diff --git a/apps/nextjs/src/app/aila/[id]/layout.tsx b/apps/nextjs/src/app/aila/[id]/layout.tsx index a31f4fe7f..89534d9e0 100644 --- a/apps/nextjs/src/app/aila/[id]/layout.tsx +++ b/apps/nextjs/src/app/aila/[id]/layout.tsx @@ -2,9 +2,7 @@ interface ChatLayoutProps { children: React.ReactNode; } -export default async function ChatLayout({ - children, -}: Readonly) { +export default function ChatLayout({ children }: Readonly) { return (
diff --git a/apps/nextjs/src/app/aila/[id]/share/index.tsx b/apps/nextjs/src/app/aila/[id]/share/index.tsx index 833238906..e199c6023 100644 --- a/apps/nextjs/src/app/aila/[id]/share/index.tsx +++ b/apps/nextjs/src/app/aila/[id]/share/index.tsx @@ -2,8 +2,8 @@ import { useEffect, useState } from "react"; -import { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; -import { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; +import type { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; +import type { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; import { OakSmallPrimaryButton } from "@oaknational/oak-components"; import Link from "next/link"; diff --git a/apps/nextjs/src/app/aila/[id]/share/page.tsx b/apps/nextjs/src/app/aila/[id]/share/page.tsx index be64ec031..fe63e137b 100644 --- a/apps/nextjs/src/app/aila/[id]/share/page.tsx +++ b/apps/nextjs/src/app/aila/[id]/share/page.tsx @@ -1,9 +1,10 @@ -import { User, clerkClient } from "@clerk/nextjs/server"; +import type { User } from "@clerk/nextjs/server"; +import { clerkClient } from "@clerk/nextjs/server"; import { getSessionModerations } from "@oakai/aila/src/features/moderation/getSessionModerations"; -import { demoUsers } from "@oakai/core"; +import { demoUsers } from "@oakai/core/src/models/demoUsers"; import { isToxic } from "@oakai/core/src/utils/ailaModeration/helpers"; -import { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; -import { type Metadata } from "next"; +import type { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; +import type { Metadata } from "next"; import { notFound } from "next/navigation"; import { getSharedChatById } from "@/app/actions"; diff --git a/apps/nextjs/src/app/aila/help/index.tsx b/apps/nextjs/src/app/aila/help/index.tsx index a58146343..649a9431d 100644 --- a/apps/nextjs/src/app/aila/help/index.tsx +++ b/apps/nextjs/src/app/aila/help/index.tsx @@ -99,7 +99,7 @@ const Help = () => {
Back to Aila diff --git a/apps/nextjs/src/app/aila/help/page.tsx b/apps/nextjs/src/app/aila/help/page.tsx index d6598506f..a49d678c5 100644 --- a/apps/nextjs/src/app/aila/help/page.tsx +++ b/apps/nextjs/src/app/aila/help/page.tsx @@ -1,5 +1,5 @@ import Help from "."; -export default async function HelpPage() { +export default function HelpPage() { return ; } diff --git a/apps/nextjs/src/app/aila/page.tsx b/apps/nextjs/src/app/aila/page.tsx index e5d4e01a5..4d8e8e054 100644 --- a/apps/nextjs/src/app/aila/page.tsx +++ b/apps/nextjs/src/app/aila/page.tsx @@ -5,11 +5,11 @@ import { redirect } from "next/navigation"; import { ChatStart } from "@/components/AppComponents/Chat/chat-start"; import Layout from "@/components/AppComponents/Layout"; -export default async function IndexPage() { +export default function IndexPage() { const clerkAuthentication = auth(); const { userId }: { userId: string | null } = clerkAuthentication; if (!userId) { - redirect(`/sign-in?next=/aila`); + redirect("/sign-in?next=/aila"); } return ( diff --git a/apps/nextjs/src/app/api/aila-download-all/route.ts b/apps/nextjs/src/app/api/aila-download-all/route.ts index 169dc444b..7df412f2e 100644 --- a/apps/nextjs/src/app/api/aila-download-all/route.ts +++ b/apps/nextjs/src/app/api/aila-download-all/route.ts @@ -1,5 +1,6 @@ import { auth } from "@clerk/nextjs/server"; -import { LessonExportType, prisma } from "@oakai/db"; +import type { LessonExportType } from "@oakai/db"; +import { prisma } from "@oakai/db"; import { downloadDriveFile } from "@oakai/exports"; import * as Sentry from "@sentry/node"; import { kv } from "@vercel/kv"; diff --git a/apps/nextjs/src/app/api/aila-download/route.ts b/apps/nextjs/src/app/api/aila-download/route.ts index ada790560..52d4cf5b3 100644 --- a/apps/nextjs/src/app/api/aila-download/route.ts +++ b/apps/nextjs/src/app/api/aila-download/route.ts @@ -1,5 +1,6 @@ import { auth } from "@clerk/nextjs/server"; -import { LessonExportType, prisma } from "@oakai/db"; +import type { LessonExportType } from "@oakai/db"; +import { prisma } from "@oakai/db"; import { downloadDriveFile } from "@oakai/exports"; import * as Sentry from "@sentry/node"; diff --git a/apps/nextjs/src/app/api/chat/chatHandler.ts b/apps/nextjs/src/app/api/chat/chatHandler.ts index 3283a993d..7ab8bf78c 100644 --- a/apps/nextjs/src/app/api/chat/chatHandler.ts +++ b/apps/nextjs/src/app/api/chat/chatHandler.ts @@ -1,25 +1,31 @@ -import { Aila } from "@oakai/aila"; +import type { Aila } from "@oakai/aila/src/core/Aila"; +import type { AilaServices } from "@oakai/aila/src/core/AilaServices"; +import type { Message } from "@oakai/aila/src/core/chat"; +import type { AilaInitializationOptions } from "@oakai/aila/src/core/types"; import type { - AilaInitializationOptions, AilaOptions, AilaPublicChatOptions, - Message, -} from "@oakai/aila"; -import { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; +} from "@oakai/aila/src/core/types"; +import { AilaAmericanisms } from "@oakai/aila/src/features/americanisms/AilaAmericanisms"; import { - TracingSpan, - withTelemetry, -} from "@oakai/core/src/tracing/serverTracing"; -import { PrismaClientWithAccelerate, prisma as globalPrisma } from "@oakai/db"; + DatadogAnalyticsAdapter, + PosthogAnalyticsAdapter, +} from "@oakai/aila/src/features/analytics"; +import { AilaRag } from "@oakai/aila/src/features/rag/AilaRag"; +import type { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; +import type { TracingSpan } from "@oakai/core/src/tracing/serverTracing"; +import { withTelemetry } from "@oakai/core/src/tracing/serverTracing"; +import type { PrismaClientWithAccelerate } from "@oakai/db"; +import { prisma as globalPrisma } from "@oakai/db/client"; import { aiLogger } from "@oakai/logger"; // #TODO StreamingTextResponse is deprecated. If we choose to adopt the "ai" package // more fully, we should refactor to support its approach to streaming // but this could be a significant change given we have our record-separator approach import { StreamingTextResponse } from "ai"; -import { NextRequest } from "next/server"; +import type { NextRequest } from "next/server"; import invariant from "tiny-invariant"; -import { Config } from "./config"; +import type { Config } from "./config"; import { handleChatException } from "./errorHandling"; import { getFixtureLLMService, @@ -176,6 +182,12 @@ export async function handleChatPostRequest( services: { chatLlmService: llmService, moderationAiClient, + ragService: (aila: AilaServices) => new AilaRag({ aila }), + americanismsService: () => new AilaAmericanisms(), + analyticsAdapters: (aila: AilaServices) => [ + new PosthogAnalyticsAdapter(aila), + new DatadogAnalyticsAdapter(aila), + ], }, lessonPlan: lessonPlan ?? {}, }; diff --git a/apps/nextjs/src/app/api/chat/config.ts b/apps/nextjs/src/app/api/chat/config.ts index 5c9b91f3f..c3ba5b90d 100644 --- a/apps/nextjs/src/app/api/chat/config.ts +++ b/apps/nextjs/src/app/api/chat/config.ts @@ -1,9 +1,10 @@ -import { Aila, AilaInitializationOptions } from "@oakai/aila"; +import { Aila } from "@oakai/aila/src/core/Aila"; +import type { AilaInitializationOptions } from "@oakai/aila/src/core/types"; import { prisma as globalPrisma, type PrismaClientWithAccelerate, } from "@oakai/db"; -import { nanoid } from "ai"; +import { nanoid } from "nanoid"; import { createWebActionsPlugin } from "./webActionsPlugin"; diff --git a/apps/nextjs/src/app/api/chat/errorHandling.test.ts b/apps/nextjs/src/app/api/chat/errorHandling.test.ts index 573c8550c..33f618225 100644 --- a/apps/nextjs/src/app/api/chat/errorHandling.test.ts +++ b/apps/nextjs/src/app/api/chat/errorHandling.test.ts @@ -1,9 +1,10 @@ -import { AilaAuthenticationError, AilaThreatDetectionError } from "@oakai/aila"; +import { AilaAuthenticationError } from "@oakai/aila/src/core/AilaError"; +import { AilaThreatDetectionError } from "@oakai/aila/src/features/threatDetection/types"; import * as moderationErrorHandling from "@oakai/aila/src/utils/moderation/moderationErrorHandling"; -import { UserBannedError } from "@oakai/core/src/models/safetyViolations"; -import { TracingSpan } from "@oakai/core/src/tracing/serverTracing"; +import { UserBannedError } from "@oakai/core/src/models/userBannedError"; +import type { TracingSpan } from "@oakai/core/src/tracing/serverTracing"; import { RateLimitExceededError } from "@oakai/core/src/utils/rateLimiting/userBasedRateLimiter"; -import { PrismaClientWithAccelerate } from "@oakai/db"; +import type { PrismaClientWithAccelerate } from "@oakai/db"; import invariant from "tiny-invariant"; import { @@ -37,7 +38,7 @@ describe("handleChatException", () => { expect(response.status).toBe(200); - invariant(response.body instanceof ReadableStream); + invariant(response.body); const message = extractStreamMessage(await consumeStream(response.body)); expect(message).toEqual({ @@ -123,4 +124,4 @@ describe("handleChatException", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/apps/nextjs/src/app/api/chat/errorHandling.ts b/apps/nextjs/src/app/api/chat/errorHandling.ts index be22e99d6..d6ca10169 100644 --- a/apps/nextjs/src/app/api/chat/errorHandling.ts +++ b/apps/nextjs/src/app/api/chat/errorHandling.ts @@ -1,13 +1,14 @@ -import { AilaAuthenticationError, AilaThreatDetectionError } from "@oakai/aila"; -import { +import { AilaAuthenticationError } from "@oakai/aila/src/core/AilaError"; +import { AilaThreatDetectionError } from "@oakai/aila/src/features/threatDetection"; +import type { ActionDocument, ErrorDocument, } from "@oakai/aila/src/protocol/jsonPatchProtocol"; import { handleHeliconeError } from "@oakai/aila/src/utils/moderation/moderationErrorHandling"; -import { UserBannedError } from "@oakai/core/src/models/safetyViolations"; -import { TracingSpan } from "@oakai/core/src/tracing/serverTracing"; +import { UserBannedError } from "@oakai/core/src/models/userBannedError"; +import type { TracingSpan } from "@oakai/core/src/tracing/serverTracing"; import { RateLimitExceededError } from "@oakai/core/src/utils/rateLimiting/userBasedRateLimiter"; -import { PrismaClientWithAccelerate } from "@oakai/db"; +import type { PrismaClientWithAccelerate } from "@oakai/db"; import { streamingJSON } from "./protocol"; diff --git a/apps/nextjs/src/app/api/chat/fixtures/FixtureRecordLLMService.ts b/apps/nextjs/src/app/api/chat/fixtures/FixtureRecordLLMService.ts index d4d9f5b8e..fa68531f1 100644 --- a/apps/nextjs/src/app/api/chat/fixtures/FixtureRecordLLMService.ts +++ b/apps/nextjs/src/app/api/chat/fixtures/FixtureRecordLLMService.ts @@ -1,9 +1,9 @@ -import { Message } from "@oakai/aila"; -import { LLMService } from "@oakai/aila/src/core/llm/LLMService"; +import type { Message } from "@oakai/aila"; +import type { LLMService } from "@oakai/aila/src/core/llm/LLMService"; import { OpenAIService } from "@oakai/aila/src/core/llm/OpenAIService"; import { aiLogger } from "@oakai/logger"; import fs from "fs/promises"; -import { ZodSchema } from "zod"; +import type { ZodSchema } from "zod"; const log = aiLogger("fixtures"); diff --git a/apps/nextjs/src/app/api/chat/fixtures/FixtureRecordOpenAiClient.ts b/apps/nextjs/src/app/api/chat/fixtures/FixtureRecordOpenAiClient.ts index b7b0e0b31..cb0d5d686 100644 --- a/apps/nextjs/src/app/api/chat/fixtures/FixtureRecordOpenAiClient.ts +++ b/apps/nextjs/src/app/api/chat/fixtures/FixtureRecordOpenAiClient.ts @@ -1,9 +1,9 @@ -import { OpenAILike } from "@oakai/aila/src/features/moderation/moderators/OpenAiModerator"; +import type { OpenAILike } from "@oakai/aila/src/features/moderation/moderators/OpenAiModerator"; import { createOpenAIClient } from "@oakai/core/src/llm/openai"; import { aiLogger } from "@oakai/logger"; import fs from "fs/promises"; -import OpenAI from "openai"; -import { ChatCompletionCreateParamsNonStreaming } from "openai/resources"; +import type OpenAI from "openai"; +import type { ChatCompletionCreateParamsNonStreaming } from "openai/resources"; const log = aiLogger("fixtures"); diff --git a/apps/nextjs/src/app/api/chat/fixtures/FixtureReplayOpenAiClient.ts b/apps/nextjs/src/app/api/chat/fixtures/FixtureReplayOpenAiClient.ts index 895a9ea33..bd7248313 100644 --- a/apps/nextjs/src/app/api/chat/fixtures/FixtureReplayOpenAiClient.ts +++ b/apps/nextjs/src/app/api/chat/fixtures/FixtureReplayOpenAiClient.ts @@ -1,7 +1,7 @@ -import { OpenAILike } from "@oakai/aila/src/features/moderation/moderators/OpenAiModerator"; +import type { OpenAILike } from "@oakai/aila/src/features/moderation/moderators/OpenAiModerator"; import { aiLogger } from "@oakai/logger"; import fs from "fs/promises"; -import OpenAI from "openai"; +import type OpenAI from "openai"; const log = aiLogger("fixtures"); diff --git a/apps/nextjs/src/app/api/chat/protocol.ts b/apps/nextjs/src/app/api/chat/protocol.ts index 322d43d6a..fc4fb0cb5 100644 --- a/apps/nextjs/src/app/api/chat/protocol.ts +++ b/apps/nextjs/src/app/api/chat/protocol.ts @@ -1,4 +1,4 @@ -import { +import type { ActionDocument, ErrorDocument, } from "@oakai/aila/src/protocol/jsonPatchProtocol"; diff --git a/apps/nextjs/src/app/api/chat/route.test.ts b/apps/nextjs/src/app/api/chat/route.test.ts index 7adfde59b..1d976909c 100644 --- a/apps/nextjs/src/app/api/chat/route.test.ts +++ b/apps/nextjs/src/app/api/chat/route.test.ts @@ -1,12 +1,13 @@ -import { Aila, AilaInitializationOptions } from "@oakai/aila"; +import { Aila } from "@oakai/aila/src/core/Aila"; import { MockLLMService } from "@oakai/aila/src/core/llm/MockLLMService"; +import type { AilaInitializationOptions } from "@oakai/aila/src/core/types"; import { MockCategoriser } from "@oakai/aila/src/features/categorisation/categorisers/MockCategoriser"; import { mockTracer } from "@oakai/core/src/tracing/mockTracer"; import { NextRequest } from "next/server"; import { expectTracingSpan } from "../../../utils/testHelpers/tracing"; import { handleChatPostRequest } from "./chatHandler"; -import { Config } from "./config"; +import type { Config } from "./config"; const chatId = "test-chat-id"; const userId = "test-user-id"; diff --git a/apps/nextjs/src/app/api/chat/route.ts b/apps/nextjs/src/app/api/chat/route.ts index 365edd577..5e68ed27d 100644 --- a/apps/nextjs/src/app/api/chat/route.ts +++ b/apps/nextjs/src/app/api/chat/route.ts @@ -1,9 +1,10 @@ -import { NextRequest } from "next/server"; +import type { NextRequest } from "next/server"; import { withSentry } from "@/lib/sentry/withSentry"; import { handleChatPostRequest } from "./chatHandler"; -import { Config, defaultConfig } from "./config"; +import type { Config } from "./config"; +import { defaultConfig } from "./config"; async function postHandler(req: NextRequest): Promise { const config: Config = defaultConfig; @@ -11,7 +12,7 @@ async function postHandler(req: NextRequest): Promise { } async function getHandler(): Promise { - return new Response("Server is ready", { status: 200 }); + return Promise.resolve(new Response("Server is ready", { status: 200 })); } export const POST = withSentry(postHandler); diff --git a/apps/nextjs/src/app/api/chat/user.test.ts b/apps/nextjs/src/app/api/chat/user.test.ts index 4c9c3cedf..9e693e036 100644 --- a/apps/nextjs/src/app/api/chat/user.test.ts +++ b/apps/nextjs/src/app/api/chat/user.test.ts @@ -1,10 +1,10 @@ -import { inngest } from "@oakai/core"; import { posthogAiBetaServerClient } from "@oakai/core/src/analytics/posthogAiBetaServerClient"; +import { inngest } from "@oakai/core/src/inngest"; import { RateLimitExceededError } from "@oakai/core/src/utils/rateLimiting/userBasedRateLimiter"; import { reportRateLimitError } from "./user"; -jest.mock("@oakai/core/src/client", () => ({ +jest.mock("@oakai/core/src/inngest", () => ({ inngest: { createFunction: jest.fn(), send: jest.fn(), @@ -62,7 +62,6 @@ describe("chat route user functions", () => { const chatId = "testChatId"; await reportRateLimitError(error, userId, chatId); - expect(inngest.send).toHaveBeenCalledTimes(1); expect(inngest.send).toHaveBeenCalledWith({ name: "app/slack.notifyRateLimit", diff --git a/apps/nextjs/src/app/api/chat/user.ts b/apps/nextjs/src/app/api/chat/user.ts index dfa8bd629..3ebf504b5 100644 --- a/apps/nextjs/src/app/api/chat/user.ts +++ b/apps/nextjs/src/app/api/chat/user.ts @@ -1,8 +1,9 @@ import { auth, clerkClient } from "@clerk/nextjs/server"; -import { AilaAuthenticationError } from "@oakai/aila"; -import { demoUsers, inngest } from "@oakai/core"; +import { AilaAuthenticationError } from "@oakai/aila/src/core/AilaError"; +import { demoUsers } from "@oakai/core"; import { posthogAiBetaServerClient } from "@oakai/core/src/analytics/posthogAiBetaServerClient"; -import { UserBannedError } from "@oakai/core/src/models/safetyViolations"; +import { inngest } from "@oakai/core/src/inngest"; +import { UserBannedError } from "@oakai/core/src/models/userBannedError"; import { withTelemetry } from "@oakai/core/src/tracing/serverTracing"; import { rateLimits } from "@oakai/core/src/utils/rateLimiting/rateLimit"; import { RateLimitExceededError } from "@oakai/core/src/utils/rateLimiting/userBasedRateLimiter"; diff --git a/apps/nextjs/src/app/api/chat/webActionsPlugin.test.ts b/apps/nextjs/src/app/api/chat/webActionsPlugin.test.ts index 289b5a6a3..906b4d83a 100644 --- a/apps/nextjs/src/app/api/chat/webActionsPlugin.test.ts +++ b/apps/nextjs/src/app/api/chat/webActionsPlugin.test.ts @@ -1,14 +1,17 @@ -import { AilaThreatDetectionError } from "@oakai/aila"; -import { AilaPluginContext } from "@oakai/aila/src/core/plugins"; -import { inngest } from "@oakai/core"; -import { UserBannedError } from "@oakai/core/src/models/safetyViolations"; -import { PrismaClientWithAccelerate } from "@oakai/db"; -import { Moderation } from "@prisma/client"; +import type { AilaPluginContext } from "@oakai/aila/src/core/plugins"; +import { AilaThreatDetectionError } from "@oakai/aila/src/features/threatDetection/types"; +import { inngest } from "@oakai/core/src/inngest"; +import { UserBannedError } from "@oakai/core/src/models/userBannedError"; +import type { PrismaClientWithAccelerate } from "@oakai/db"; +import type { Moderation } from "@prisma/client"; import { createWebActionsPlugin } from "./webActionsPlugin"; -jest.mock("@oakai/core", () => ({ +jest.mock("@oakai/core/src/inngest", () => ({ + __esModule: true, + inngest: { + createFunction: jest.fn(), send: jest.fn(), }, })); diff --git a/apps/nextjs/src/app/api/chat/webActionsPlugin.ts b/apps/nextjs/src/app/api/chat/webActionsPlugin.ts index 2d24a3aa2..46daa425b 100644 --- a/apps/nextjs/src/app/api/chat/webActionsPlugin.ts +++ b/apps/nextjs/src/app/api/chat/webActionsPlugin.ts @@ -1,12 +1,10 @@ -import { AilaThreatDetectionError } from "@oakai/aila"; -import { AilaPlugin } from "@oakai/aila/src/core/plugins"; +import type { AilaPlugin } from "@oakai/aila/src/core/plugins"; +import { AilaThreatDetectionError } from "@oakai/aila/src/features/threatDetection"; import { handleHeliconeError } from "@oakai/aila/src/utils/moderation/moderationErrorHandling"; -import { - SafetyViolations as defaultSafetyViolations, - inngest, -} from "@oakai/core"; -import { UserBannedError } from "@oakai/core/src/models/safetyViolations"; -import { PrismaClientWithAccelerate } from "@oakai/db"; +import { SafetyViolations as defaultSafetyViolations } from "@oakai/core"; +import { inngest } from "@oakai/core/src/inngest"; +import { UserBannedError } from "@oakai/core/src/models/userBannedError"; +import type { PrismaClientWithAccelerate } from "@oakai/db"; import { aiLogger } from "@oakai/logger"; import { waitUntil } from "@vercel/functions"; @@ -35,11 +33,11 @@ export const createWebActionsPlugin: PluginCreator = ( prisma, SafetyViolations, ); - enqueue(heliconeErrorMessage); + await enqueue(heliconeErrorMessage); } if (error instanceof Error) { - enqueue({ + await enqueue({ type: "error", message: error.message, value: `Sorry, an error occurred: ${error.message}`, @@ -82,7 +80,7 @@ export const createWebActionsPlugin: PluginCreator = ( } catch (error) { if (error instanceof UserBannedError) { log.info("User is banned, queueing account lock message"); - enqueue({ + await enqueue({ type: "action", action: "SHOW_ACCOUNT_LOCKED", }); diff --git a/apps/nextjs/src/app/api/qd-download/route.ts b/apps/nextjs/src/app/api/qd-download/route.ts index bae256c49..49e30af9e 100644 --- a/apps/nextjs/src/app/api/qd-download/route.ts +++ b/apps/nextjs/src/app/api/qd-download/route.ts @@ -1,5 +1,6 @@ import { auth } from "@clerk/nextjs/server"; -import { LessonExportType, prisma } from "@oakai/db"; +import type { LessonExportType } from "@oakai/db"; +import { prisma } from "@oakai/db/client"; import { downloadDriveFile } from "@oakai/exports"; import * as Sentry from "@sentry/node"; @@ -128,7 +129,7 @@ async function getHandler(req: Request) { }); } - saveDownloadEvent({ + await saveDownloadEvent({ exportId: qdExport.id, downloadedBy: userId, ext, diff --git a/apps/nextjs/src/app/api/sanitizeFilename.test.ts b/apps/nextjs/src/app/api/sanitizeFilename.test.ts index ac8b3d888..e0af33511 100644 --- a/apps/nextjs/src/app/api/sanitizeFilename.test.ts +++ b/apps/nextjs/src/app/api/sanitizeFilename.test.ts @@ -3,9 +3,9 @@ import { sanitizeFilename } from "./sanitizeFilename"; describe("sanitizeFilename", () => { test("should remove special characters", () => { const lessonTitle = - "The econonomy: Boom or Bust? You decide! Let's start, shall we?"; + "The economy: Boom or Bust? You decide! Let's start, shall we?"; expect(sanitizeFilename(lessonTitle)).toBe( - "The econonomy Boom or Bust You decide Lets start shall we", + "The economy Boom or Bust You decide Lets start shall we", ); }); }); diff --git a/apps/nextjs/src/app/api/trpc/chat/[trpc]/route.ts b/apps/nextjs/src/app/api/trpc/chat/[trpc]/route.ts index d38a54bf4..27e3f609d 100644 --- a/apps/nextjs/src/app/api/trpc/chat/[trpc]/route.ts +++ b/apps/nextjs/src/app/api/trpc/chat/[trpc]/route.ts @@ -3,7 +3,7 @@ import { chatAppRouter } from "@oakai/api/src/router/chat"; import { aiLogger } from "@oakai/logger"; import * as Sentry from "@sentry/nextjs"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; -import { NextRequest, NextResponse } from "next/server"; +import type { NextRequest, NextResponse } from "next/server"; import { withSentry } from "@/lib/sentry/withSentry"; diff --git a/apps/nextjs/src/app/api/trpc/main/[trpc]/route.ts b/apps/nextjs/src/app/api/trpc/main/[trpc]/route.ts index 41b409442..97cbf0c94 100644 --- a/apps/nextjs/src/app/api/trpc/main/[trpc]/route.ts +++ b/apps/nextjs/src/app/api/trpc/main/[trpc]/route.ts @@ -3,7 +3,7 @@ import { oakAppRouter } from "@oakai/api/src/router"; import { aiLogger } from "@oakai/logger"; import * as Sentry from "@sentry/nextjs"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; -import { NextRequest, NextResponse } from "next/server"; +import type { NextRequest, NextResponse } from "next/server"; import { withSentry } from "@/lib/sentry/withSentry"; diff --git a/apps/nextjs/src/app/api/trpc/test-support/[trpc]/route.ts b/apps/nextjs/src/app/api/trpc/test-support/[trpc]/route.ts index 9d1b4bfa1..15d0ccf6a 100644 --- a/apps/nextjs/src/app/api/trpc/test-support/[trpc]/route.ts +++ b/apps/nextjs/src/app/api/trpc/test-support/[trpc]/route.ts @@ -4,7 +4,7 @@ import { router } from "@oakai/api/src/trpc"; import { aiLogger } from "@oakai/logger"; import * as Sentry from "@sentry/nextjs"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; -import { NextRequest, NextResponse } from "next/server"; +import type { NextRequest, NextResponse } from "next/server"; import { withSentry } from "@/lib/sentry/withSentry"; diff --git a/apps/nextjs/src/app/faqs/page.tsx b/apps/nextjs/src/app/faqs/page.tsx index 43148a4c4..4a7701661 100644 --- a/apps/nextjs/src/app/faqs/page.tsx +++ b/apps/nextjs/src/app/faqs/page.tsx @@ -1,6 +1,6 @@ import FAQPage from "."; -const FAQ = async () => { +const FAQ = () => { return ; }; diff --git a/apps/nextjs/src/app/generations/page.tsx b/apps/nextjs/src/app/generations/page.tsx index 4d70f247d..718eb0df7 100644 --- a/apps/nextjs/src/app/generations/page.tsx +++ b/apps/nextjs/src/app/generations/page.tsx @@ -1,3 +1,3 @@ -export default async function GenerationsPage() { +export default function GenerationsPage() { return null; } diff --git a/apps/nextjs/src/app/home-page.tsx b/apps/nextjs/src/app/home-page.tsx index e3c6cbbc6..1179832f0 100644 --- a/apps/nextjs/src/app/home-page.tsx +++ b/apps/nextjs/src/app/home-page.tsx @@ -2,18 +2,18 @@ import { useUser } from "@clerk/nextjs"; import MuxPlayer from "@mux/mux-player-react"; +import type { OakColorToken } from "@oaknational/oak-components"; import { OakBox, OakFlex, OakHeading, OakLink, OakP, - OakColorToken, oakColorTokens, OakPrimaryButton, } from "@oaknational/oak-components"; -import { HomePageQueryResult } from "cms/types/aiHomePageType"; -import { Metadata } from "next"; +import type { HomePageQueryResult } from "cms/types/aiHomePageType"; +import type { Metadata } from "next"; import Image from "next/image"; import Link from "next/link"; import styled from "styled-components"; diff --git a/apps/nextjs/src/app/layout.tsx b/apps/nextjs/src/app/layout.tsx index 5c476fa6d..70fb045da 100644 --- a/apps/nextjs/src/app/layout.tsx +++ b/apps/nextjs/src/app/layout.tsx @@ -44,7 +44,7 @@ export const metadata = { metadataBase: new URL(vercel_url), title: { default: "Oak AI Experiments", - template: `%s - AI Lesson Planner`, + template: "%s - AI Lesson Planner", }, description: "Oak AI experiments offers some experimental generative AI tools designed for and freely available to teachers. We are actively looking for your feedback to refine and optimise these tools, making them more effective and time-saving.", diff --git a/apps/nextjs/src/app/legal/[slug]/legal.tsx b/apps/nextjs/src/app/legal/[slug]/legal.tsx index baff0b6aa..34ee39173 100644 --- a/apps/nextjs/src/app/legal/[slug]/legal.tsx +++ b/apps/nextjs/src/app/legal/[slug]/legal.tsx @@ -2,7 +2,7 @@ import { OakBox } from "@oaknational/oak-components"; import { PortableText } from "@portabletext/react"; -import { PolicyDocument } from "cms/types/policyDocument"; +import type { PolicyDocument } from "cms/types/policyDocument"; import Layout from "@/components/Layout"; import { portableTextComponents } from "@/components/PortableText/portableTextComponents"; diff --git a/apps/nextjs/src/app/legal/account-locked/page.tsx b/apps/nextjs/src/app/legal/account-locked/page.tsx index 5cb497153..d1f64fc61 100644 --- a/apps/nextjs/src/app/legal/account-locked/page.tsx +++ b/apps/nextjs/src/app/legal/account-locked/page.tsx @@ -1,5 +1,5 @@ import AccountLocked from "./account-locked"; -export default async function SuspendedPage() { +export default function SuspendedPage() { return ; } diff --git a/apps/nextjs/src/app/lesson-planner/page.tsx b/apps/nextjs/src/app/lesson-planner/page.tsx index 089e4c78c..d6cadf0fe 100644 --- a/apps/nextjs/src/app/lesson-planner/page.tsx +++ b/apps/nextjs/src/app/lesson-planner/page.tsx @@ -1,5 +1,5 @@ import LessonPlannerPage from "."; -export default async function LessonPlanner() { +export default function LessonPlanner() { return ; } diff --git a/apps/nextjs/src/app/lesson-planner/preview/[slug]/page.tsx b/apps/nextjs/src/app/lesson-planner/preview/[slug]/page.tsx index f626780f6..4de40351c 100644 --- a/apps/nextjs/src/app/lesson-planner/preview/[slug]/page.tsx +++ b/apps/nextjs/src/app/lesson-planner/preview/[slug]/page.tsx @@ -1,5 +1,5 @@ -import { Apps } from "@oakai/core"; -import { prisma } from "@oakai/db"; +import { Apps } from "@oakai/core/src/models/apps"; +import { prisma } from "@oakai/db/client"; import { aiLogger } from "@oakai/logger"; import { LessonPlanPreview } from "./preview"; diff --git a/apps/nextjs/src/app/lesson-planner/preview/page.tsx b/apps/nextjs/src/app/lesson-planner/preview/page.tsx index 466483d34..24a1db312 100644 --- a/apps/nextjs/src/app/lesson-planner/preview/page.tsx +++ b/apps/nextjs/src/app/lesson-planner/preview/page.tsx @@ -1,5 +1,5 @@ import PreviewRedirect from "./preview-redirect"; -export default async function PreviewRedirectPage() { +export default function PreviewRedirectPage() { return ; } diff --git a/apps/nextjs/src/app/manifest.ts b/apps/nextjs/src/app/manifest.ts index 90755d770..17d91bd8d 100644 --- a/apps/nextjs/src/app/manifest.ts +++ b/apps/nextjs/src/app/manifest.ts @@ -1,45 +1,46 @@ -import type { MetadataRoute } from 'next' - +import type { MetadataRoute } from "next"; + export default function manifest(): MetadataRoute.Manifest { return { name: "Aila: Oak's AI Lesson Assistant", - short_name: 'Aila', - description: 'An AI lesson assistant chatbot for UK teachers to create lessons personalised for their classes, with the aim of reducing teacher workload.', - start_url: '/', - display: 'minimal-ui', - background_color: '#BEF2BD', - theme_color: '#BEF2BD', + short_name: "Aila", + description: + "An AI lesson assistant chatbot for UK teachers to create lessons personalised for their classes, with the aim of reducing teacher workload.", + start_url: "/", + display: "minimal-ui", + background_color: "#BEF2BD", + theme_color: "#BEF2BD", icons: [ { - "src": "/favicon/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" + src: "/favicon/android-chrome-192x192.png", + sizes: "192x192", + type: "image/png", }, { - "src": "/favicon/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" + src: "/favicon/android-chrome-512x512.png", + sizes: "512x512", + type: "image/png", }, { - "src": "/favicon/apple-touch-icon.png", - "sizes": "180x180", - "type": "image/png" + src: "/favicon/apple-touch-icon.png", + sizes: "180x180", + type: "image/png", }, { - "src": "/favicon/favicon-16x16.png", - "sizes": "16x16", - "type": "image/png" + src: "/favicon/favicon-16x16.png", + sizes: "16x16", + type: "image/png", }, { - "src": "/favicon/favicon-32x32.png", - "sizes": "32x32", - "type": "image/png" + src: "/favicon/favicon-32x32.png", + sizes: "32x32", + type: "image/png", }, { - "src": "/favicon/favicon.ico", - "sizes": "48x48 16x16 32x32", - "type": "image/x-icon" - } - ] - } -} \ No newline at end of file + src: "/favicon/favicon.ico", + sizes: "48x48 16x16 32x32", + type: "image/x-icon", + }, + ], + }; +} diff --git a/apps/nextjs/src/app/prompts/prompts.tsx b/apps/nextjs/src/app/prompts/prompts.tsx index b20f03aa1..b66557ff4 100644 --- a/apps/nextjs/src/app/prompts/prompts.tsx +++ b/apps/nextjs/src/app/prompts/prompts.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useMemo } from "react"; -import { SerializedAppWithPrompt } from "@oakai/core/src/models/serializers"; +import type { SerializedAppWithPrompt } from "@oakai/core/src/models/serializers"; import { OakBox, OakHeading, diff --git a/apps/nextjs/src/app/quiz-designer/page.tsx b/apps/nextjs/src/app/quiz-designer/page.tsx index 33f6d834e..42876ecdc 100644 --- a/apps/nextjs/src/app/quiz-designer/page.tsx +++ b/apps/nextjs/src/app/quiz-designer/page.tsx @@ -1,5 +1,5 @@ import QuizDesignerPage from "./quiz-designer-page"; -export default async function QuizDesigner() { +export default function QuizDesigner() { return ; } diff --git a/apps/nextjs/src/app/quiz-designer/preview/page.tsx b/apps/nextjs/src/app/quiz-designer/preview/page.tsx index 466483d34..24a1db312 100644 --- a/apps/nextjs/src/app/quiz-designer/preview/page.tsx +++ b/apps/nextjs/src/app/quiz-designer/preview/page.tsx @@ -1,5 +1,5 @@ import PreviewRedirect from "./preview-redirect"; -export default async function PreviewRedirectPage() { +export default function PreviewRedirectPage() { return ; } diff --git a/apps/nextjs/src/app/quiz-designer/quiz-designer-page.tsx b/apps/nextjs/src/app/quiz-designer/quiz-designer-page.tsx index 466f8671d..06b02df09 100644 --- a/apps/nextjs/src/app/quiz-designer/quiz-designer-page.tsx +++ b/apps/nextjs/src/app/quiz-designer/quiz-designer-page.tsx @@ -5,7 +5,8 @@ import { memo, useCallback, useEffect, useReducer, useState } from "react"; import { useUser } from "@clerk/nextjs"; import { aiLogger } from "@oakai/logger"; import { quizAppReducer } from "ai-apps/quiz-designer/state/reducer"; -import { QuizAppState, QuizAppStatus } from "ai-apps/quiz-designer/state/types"; +import type { QuizAppState } from "ai-apps/quiz-designer/state/types"; +import { QuizAppStatus } from "ai-apps/quiz-designer/state/types"; import { useQuizSession } from "hooks/useQuizSession"; import { useRouter } from "next/navigation"; import { equals } from "remeda"; diff --git a/apps/nextjs/src/app/test-support/clerk/page.tsx b/apps/nextjs/src/app/test-support/clerk/page.tsx index 6a01d80c2..d2d56463f 100644 --- a/apps/nextjs/src/app/test-support/clerk/page.tsx +++ b/apps/nextjs/src/app/test-support/clerk/page.tsx @@ -5,7 +5,7 @@ import { notFound } from "next/navigation"; * This is a minimal page that gives it access to a clerk instance */ -export default async function TestSupportSignIn() { +export default function TestSupportSignIn() { if ( process.env.NODE_ENV !== "development" && process.env.VERCEL_ENV !== "preview" diff --git a/apps/nextjs/src/app/user/[[...index]]/page.tsx b/apps/nextjs/src/app/user/[[...index]]/page.tsx index 804f85b9d..340bc036c 100644 --- a/apps/nextjs/src/app/user/[[...index]]/page.tsx +++ b/apps/nextjs/src/app/user/[[...index]]/page.tsx @@ -1,4 +1,4 @@ -import { UserProfile } from '@clerk/nextjs' +import { UserProfile } from "@clerk/nextjs"; export default function Page() { return ( diff --git a/apps/nextjs/src/cms/data/fetchAiHomepage.ts b/apps/nextjs/src/cms/data/fetchAiHomepage.ts index 955419f7b..39622c269 100644 --- a/apps/nextjs/src/cms/data/fetchAiHomepage.ts +++ b/apps/nextjs/src/cms/data/fetchAiHomepage.ts @@ -1,6 +1,6 @@ import { homePageQuery } from "cms/queries/homePageQuery"; import { sanityClient } from "cms/sanityClient"; -import { HomePageQueryResult } from "cms/types/aiHomePageType"; +import type { HomePageQueryResult } from "cms/types/aiHomePageType"; export async function fetchAiHomepage(): Promise { const query = homePageQuery; diff --git a/apps/nextjs/src/cms/data/fetchPolicyDocument.ts b/apps/nextjs/src/cms/data/fetchPolicyDocument.ts index 4abe871e6..e2e6d23e4 100644 --- a/apps/nextjs/src/cms/data/fetchPolicyDocument.ts +++ b/apps/nextjs/src/cms/data/fetchPolicyDocument.ts @@ -1,5 +1,5 @@ import { sanityClient } from "cms/sanityClient"; -import { PolicyDocument } from "cms/types/policyDocument"; +import type { PolicyDocument } from "cms/types/policyDocument"; export async function fetchPolicyDocument({ slug, diff --git a/apps/nextjs/src/components/AppComponents/Chat/Chat/ChatModerationDisplay.stories.tsx b/apps/nextjs/src/components/AppComponents/Chat/Chat/ChatModerationDisplay.stories.tsx index dcea3d3d2..84aa6955e 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/Chat/ChatModerationDisplay.stories.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/Chat/ChatModerationDisplay.stories.tsx @@ -1,4 +1,4 @@ -import { type PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; +import type { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; import type { Meta, StoryObj } from "@storybook/react"; import { ChatModerationDisplay } from "./ChatModerationDisplay"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/Chat/ChatModerationDisplay.tsx b/apps/nextjs/src/components/AppComponents/Chat/Chat/ChatModerationDisplay.tsx index 82f53e05f..fbf72ab34 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/Chat/ChatModerationDisplay.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/Chat/ChatModerationDisplay.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { type PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; +import type { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; import { Flex } from "@radix-ui/themes"; import ToxicModerationView from "../toxic-moderation-view"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/Chat/hooks/useAilaStreamingStatus.ts b/apps/nextjs/src/components/AppComponents/Chat/Chat/hooks/useAilaStreamingStatus.ts index 429271400..3ea9adca2 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/Chat/hooks/useAilaStreamingStatus.ts +++ b/apps/nextjs/src/components/AppComponents/Chat/Chat/hooks/useAilaStreamingStatus.ts @@ -1,7 +1,7 @@ import { useMemo, useEffect } from "react"; import { aiLogger } from "@oakai/logger"; -import { Message } from "ai"; +import type { Message } from "ai"; const log = aiLogger("chat"); @@ -20,8 +20,8 @@ export const useAilaStreamingStatus = ({ messages: Message[]; }): AilaStreamingStatus => { const ailaStreamingStatus = useMemo(() => { - const moderationStart = `MODERATION_START`; - const chatStart = `CHAT_START`; + const moderationStart = "MODERATION_START"; + const chatStart = "CHAT_START"; if (messages.length === 0) return "Idle"; const lastMessage = messages[messages.length - 1]; @@ -33,8 +33,8 @@ export const useAilaStreamingStatus = ({ } else if (content.includes(moderationStart)) { return "Moderating"; } else if ( - content.includes(`"type":"prompt"`) || - content.includes(`\\"type\\":\\"prompt\\"`) + content.includes('"type":"prompt"') || + content.includes('\\"type\\":\\"prompt\\"') ) { return "StreamingChatResponse"; } else if (content.includes(chatStart)) { diff --git a/apps/nextjs/src/components/AppComponents/Chat/Chat/hooks/useProgressForDownloads.ts b/apps/nextjs/src/components/AppComponents/Chat/Chat/hooks/useProgressForDownloads.ts index 3ae82ffe5..a3503b2c0 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/Chat/hooks/useProgressForDownloads.ts +++ b/apps/nextjs/src/components/AppComponents/Chat/Chat/hooks/useProgressForDownloads.ts @@ -1,8 +1,8 @@ import { useMemo } from "react"; -import { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; +import type { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; import { lessonPlanSectionsSchema } from "@oakai/exports/src/schema/input.schema"; -import { ZodIssue } from "zod"; +import type { ZodIssue } from "zod"; /** * For a given list of Zod issues and lessonPlan fields, checks that none of diff --git a/apps/nextjs/src/components/AppComponents/Chat/Chat/utils/index.ts b/apps/nextjs/src/components/AppComponents/Chat/Chat/utils/index.ts index 1f4cac571..48df113c6 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/Chat/utils/index.ts +++ b/apps/nextjs/src/components/AppComponents/Chat/Chat/utils/index.ts @@ -1,12 +1,12 @@ -import { type LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; +import type { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; import { aiLogger } from "@oakai/logger"; -import { type Message } from "ai/react"; +import type { Message } from "ai/react"; const log = aiLogger("chat"); export function findMessageIdFromContent({ content }: { content: string }) { return content - .split(`␞`) + .split("␞") .map((s) => { try { return JSON.parse(s.trim()); @@ -21,12 +21,12 @@ export function findMessageIdFromContent({ content }: { content: string }) { export function findLatestServerSideState(workingMessages: Message[]) { log.info("Finding latest server-side state", { workingMessages }); const lastMessage = workingMessages[workingMessages.length - 1]; - if (!lastMessage?.content.includes(`"type":"state"`)) { + if (!lastMessage?.content.includes('"type":"state"')) { log.info("No server state found"); return; } const state: LooseLessonPlan = lastMessage.content - .split(`␞`) + .split("␞") .map((s) => { try { return JSON.parse(s.trim()); diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-left-hand-side.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-left-hand-side.tsx index c7737763b..b36ff5a7f 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-left-hand-side.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-left-hand-side.tsx @@ -1,9 +1,9 @@ import React from "react"; import { Flex } from "@radix-ui/themes"; -import { Message } from "ai"; +import type { Message } from "ai"; -import { DemoContextProps } from "@/components/ContextProviders/Demo"; +import type { DemoContextProps } from "@/components/ContextProviders/Demo"; import ChatLhsHeader from "./chat-lhs-header"; import { ChatList } from "./chat-list"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-lessonPlanDisplay.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-lessonPlanDisplay.tsx index 632ba018f..81a8637c0 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-lessonPlanDisplay.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-lessonPlanDisplay.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "react"; -import { BasedOnOptional } from "@oakai/aila/src/protocol/schema"; +import type { BasedOnOptional } from "@oakai/aila/src/protocol/schema"; import { Flex, Text } from "@radix-ui/themes"; import { cva } from "class-variance-authority"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-lessonPlanMapToMarkDown.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-lessonPlanMapToMarkDown.tsx index ee8656e89..f9b405ee0 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-lessonPlanMapToMarkDown.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-lessonPlanMapToMarkDown.tsx @@ -1,6 +1,6 @@ import { useRef } from "react"; -import { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; +import type { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; import { sectionToMarkdown } from "@oakai/aila/src/protocol/sectionToMarkdown"; import { lessonSectionTitlesAndMiniDescriptions } from "data/lessonSectionTitlesAndMiniDescriptions"; @@ -64,7 +64,7 @@ export default LessonPlanMapToMarkDown; const ChatSection = ({ sectionRefs, objectKey, value }) => { const sectionRef = useRef(null); - if (!!sectionRefs) sectionRefs[objectKey] = sectionRef; + if (sectionRefs) sectionRefs[objectKey] = sectionRef; return (
diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-lhs-header.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-lhs-header.tsx index f8b69e2f7..f01676dec 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-lhs-header.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-lhs-header.tsx @@ -20,16 +20,14 @@ const ChatLhsHeader = ({ }: Readonly) => { const router = useRouter(); const chat = useLessonChat(); - return ( <>
- {process.env.NEXT_PUBLIC_ENVIRONMENT !== "prd" && ( -
- {chat.ailaStreamingStatus} + {process.env.NEXT_PUBLIC_ENVIRONMENT !== "production" && ( +
+
+ {chat.ailaStreamingStatus} +
)}
-
+
diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-list.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-list.tsx index c6794c2ff..5a6aaff8b 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-list.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-list.tsx @@ -1,27 +1,21 @@ "use client"; -import { - Dispatch, - SetStateAction, - useCallback, - useEffect, - useRef, - useState, -} from "react"; +import type { Dispatch, SetStateAction } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; -import { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; +import type { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; import { OakBox, OakFlex, OakIcon, OakSpan } from "@oaknational/oak-components"; -import { Message } from "ai"; +import type { Message } from "ai"; import Link from "next/link"; import { ChatMessage } from "@/components/AppComponents/Chat/chat-message"; import { useLessonChat } from "@/components/ContextProviders/ChatProvider"; -import { DemoContextProps } from "@/components/ContextProviders/Demo"; +import type { DemoContextProps } from "@/components/ContextProviders/Demo"; import { useDialog } from "../DialogContext"; -import { AilaStreamingStatus } from "./Chat/hooks/useAilaStreamingStatus"; +import type { AilaStreamingStatus } from "./Chat/hooks/useAilaStreamingStatus"; import { useProgressForDownloads } from "./Chat/hooks/useProgressForDownloads"; -import { DialogTypes } from "./Chat/types"; +import type { DialogTypes } from "./Chat/types"; export interface ChatListProps { isDemoLocked: boolean; @@ -38,7 +32,8 @@ function DemoLimitMessage({ id }: Readonly<{ id: string }>) { message={{ id: "demo-limit", role: "assistant", - content: `{"type": "error", "message": "**Your lesson is complete**\\nYou can no longer edit this lesson. [Create new lesson.](/aila)"}`, + content: + '{"type": "error", "message": "**Your lesson is complete**\\nYou can no longer edit this lesson. [Create new lesson.](/aila)"}', }} persistedModerations={[]} separator={} diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-message/index.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-message/index.tsx index dec946012..184bc6707 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-message/index.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-message/index.tsx @@ -1,8 +1,9 @@ // Inspired by Chatbot-UI and modified to fit the needs of this project // @see https://github.com/mckaywrigley/chatbot-ui/blob/main/components/Chat/ChatMessage.tsx -import { ReactNode, useState } from "react"; +import type { ReactNode } from "react"; +import { useState } from "react"; -import { +import type { ActionDocument, BadDocument, CommentDocument, @@ -14,20 +15,20 @@ import { StateDocument, TextDocument, UnknownDocument, - parseMessageParts, } from "@oakai/aila/src/protocol/jsonPatchProtocol"; +import { parseMessageParts } from "@oakai/aila/src/protocol/jsonPatchProtocol"; import { isSafe } from "@oakai/core/src/utils/ailaModeration/helpers"; -import { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; +import type { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; import { aiLogger } from "@oakai/logger"; -import { Message } from "ai"; +import type { Message } from "ai"; import { MemoizedReactMarkdownWithStyles } from "@/components/AppComponents/Chat/markdown"; import { useChatModeration } from "@/components/ContextProviders/ChatModerationContext"; import { Icon } from "@/components/Icon"; import { cn } from "@/lib/utils"; -import { ModerationModalHelpers } from "../../FeedbackForms/ModerationFeedbackModal"; -import { AilaStreamingStatus } from "../Chat/hooks/useAilaStreamingStatus"; +import type { ModerationModalHelpers } from "../../FeedbackForms/ModerationFeedbackModal"; +import type { AilaStreamingStatus } from "../Chat/hooks/useAilaStreamingStatus"; import { isModeration } from "./protocol"; const log = aiLogger("chat"); diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-message/protocol.ts b/apps/nextjs/src/components/AppComponents/Chat/chat-message/protocol.ts index dfcf5bfa0..5ed65611b 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-message/protocol.ts +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-message/protocol.ts @@ -1,4 +1,4 @@ -import { +import type { ActionDocument, MessagePartDocument, ModerationDocument, diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-quick-buttons.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-quick-buttons.tsx index 3b8a35b52..3226fc83d 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-quick-buttons.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-quick-buttons.tsx @@ -8,7 +8,7 @@ import { useLessonPlanTracking } from "@/lib/analytics/lessonPlanTrackingContext import useAnalytics from "@/lib/analytics/useAnalytics"; import { useDialog } from "../DialogContext"; -import { AilaStreamingStatus } from "./Chat/hooks/useAilaStreamingStatus"; +import type { AilaStreamingStatus } from "./Chat/hooks/useAilaStreamingStatus"; import ChatButton from "./ui/chat-button"; import { IconRefresh, IconStop } from "./ui/icons"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-right-hand-side-lesson.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-right-hand-side-lesson.tsx index bd0d63026..7f3b515e1 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-right-hand-side-lesson.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-right-hand-side-lesson.tsx @@ -1,12 +1,12 @@ import React, { useRef, useState } from "react"; -import { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; +import type { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; import { OakIcon, OakSmallSecondaryButton } from "@oaknational/oak-components"; -import { Message } from "ai"; +import type { Message } from "ai"; import Link from "next/link"; import AiIcon from "../../AiIcon"; -import { DemoContextProps } from "../../ContextProviders/Demo"; +import type { DemoContextProps } from "../../ContextProviders/Demo"; import { useDialog } from "../DialogContext"; import LessonPlanDisplay from "./chat-lessonPlanDisplay"; import ExportButtons from "./export-buttons"; @@ -61,7 +61,7 @@ const ChatRightHandSideLesson = ({ const endOfDocRef = useRef(null); return (
{ closeMobileLessonPullOut(); }} - className={`${demo.isDemoUser ? `mt-25` : ``} flex items-center justify-center gap-3 `} + className={`${demo.isDemoUser ? "mt-25" : ""} flex items-center justify-center gap-3 `} > diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-share-dialog.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-share-dialog.tsx index bd47903b4..f6ab67705 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-share-dialog.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-share-dialog.tsx @@ -4,7 +4,7 @@ import * as React from "react"; import { toast } from "react-hot-toast"; import { aiLogger } from "@oakai/logger"; -import { type DialogProps } from "@radix-ui/react-dialog"; +import type { DialogProps } from "@radix-ui/react-dialog"; import { Button } from "@/components/AppComponents/Chat/ui/button"; import { @@ -17,7 +17,7 @@ import { } from "@/components/AppComponents/Chat/ui/dialog"; import { IconSpinner } from "@/components/AppComponents/Chat/ui/icons"; import { useCopyToClipboard } from "@/lib/hooks/use-copy-to-clipboard"; -import { SideBarChatItem } from "@/lib/types"; +import type { SideBarChatItem } from "@/lib/types"; import { trpc } from "@/utils/trpc"; import { constructSharePath } from "./Chat/utils"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-start.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-start.tsx index 40ed7c88a..cbb91a319 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-start.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-start.tsx @@ -17,14 +17,15 @@ import { trpc } from "@/utils/trpc"; import { useDialog } from "../DialogContext"; import ChatPanelDisclaimer from "./chat-panel-disclaimer"; import { ChatStartForm } from "./chat-start-form"; -import EmptyScreenAccordion from "./empty-screen-accordian"; +import EmptyScreenAccordion from "./empty-screen-accordion"; const log = aiLogger("chat"); const exampleMessages = [ { heading: "History • Key stage 3 • The end of Roman Britain ", - message: `Create a lesson plan about The End of Roman Britain for Key Stage 3 History`, + message: + "Create a lesson plan about The End of Roman Britain for Key Stage 3 History", }, ]; diff --git a/apps/nextjs/src/components/AppComponents/Chat/drop-down-section/flag-button.tsx b/apps/nextjs/src/components/AppComponents/Chat/drop-down-section/flag-button.tsx index 523bd0ffd..48a17ecd5 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/drop-down-section/flag-button.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/drop-down-section/flag-button.tsx @@ -9,7 +9,8 @@ import { useLessonChat } from "@/components/ContextProviders/ChatProvider"; import { trpc } from "@/utils/trpc"; import ActionButton from "./action-button"; -import { DropDownFormWrapper, FeedbackOption } from "./drop-down-form-wrapper"; +import type { FeedbackOption } from "./drop-down-form-wrapper"; +import { DropDownFormWrapper } from "./drop-down-form-wrapper"; import { SmallRadioButton } from "./small-radio-button"; const flagOptions = [ diff --git a/apps/nextjs/src/components/AppComponents/Chat/drop-down-section/modify-button.tsx b/apps/nextjs/src/components/AppComponents/Chat/drop-down-section/modify-button.tsx index 0b6b4890d..ee4a17e30 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/drop-down-section/modify-button.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/drop-down-section/modify-button.tsx @@ -10,7 +10,8 @@ import { useLessonChat } from "@/components/ContextProviders/ChatProvider"; import { trpc } from "@/utils/trpc"; import ActionButton from "./action-button"; -import { DropDownFormWrapper, FeedbackOption } from "./drop-down-form-wrapper"; +import type { FeedbackOption } from "./drop-down-form-wrapper"; +import { DropDownFormWrapper } from "./drop-down-form-wrapper"; import { SmallRadioButton } from "./small-radio-button"; const log = aiLogger("chat"); diff --git a/apps/nextjs/src/components/AppComponents/Chat/empty-screen-accordian.tsx b/apps/nextjs/src/components/AppComponents/Chat/empty-screen-accordion.tsx similarity index 98% rename from apps/nextjs/src/components/AppComponents/Chat/empty-screen-accordian.tsx rename to apps/nextjs/src/components/AppComponents/Chat/empty-screen-accordion.tsx index 1aee07a50..4a4efa09f 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/empty-screen-accordian.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/empty-screen-accordion.tsx @@ -157,11 +157,12 @@ const AccordionItem = React.forwardRef( AccordionItem.displayName = "AccordionItem"; const AccordionTrigger = React.forwardRef< - HTMLDivElement, + HTMLButtonElement, AccordionTriggerProps ->(({ children, ...props }) => ( +>(({ children, ...props }, forwardedRef) => ( diff --git a/apps/nextjs/src/components/AppComponents/Chat/export-buttons/LessonPlanProgressDropdown.stories.tsx b/apps/nextjs/src/components/AppComponents/Chat/export-buttons/LessonPlanProgressDropdown.stories.tsx index cbac20242..f32699fa2 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/export-buttons/LessonPlanProgressDropdown.stories.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/export-buttons/LessonPlanProgressDropdown.stories.tsx @@ -1,4 +1,4 @@ -import { +import type { Cycle, Keyword, Misconception, diff --git a/apps/nextjs/src/components/AppComponents/Chat/export-buttons/LessonPlanProgressDropdown.tsx b/apps/nextjs/src/components/AppComponents/Chat/export-buttons/LessonPlanProgressDropdown.tsx index 72b1aa62a..98f414d2e 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/export-buttons/LessonPlanProgressDropdown.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/export-buttons/LessonPlanProgressDropdown.tsx @@ -1,6 +1,6 @@ import React, { useState } from "react"; -import { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; +import type { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; import { Flex } from "@radix-ui/themes"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/guidance-required.stories.tsx b/apps/nextjs/src/components/AppComponents/Chat/guidance-required.stories.tsx index a85f96a87..8d7b547d3 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/guidance-required.stories.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/guidance-required.stories.tsx @@ -1,4 +1,4 @@ -import { type PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; +import type { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; import type { Meta, StoryObj } from "@storybook/react"; import { GuidanceRequired } from "./guidance-required"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/guidance-required.tsx b/apps/nextjs/src/components/AppComponents/Chat/guidance-required.tsx index 1ef467d58..14cecca3b 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/guidance-required.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/guidance-required.tsx @@ -2,7 +2,7 @@ import { isSafe, moderationSlugToDescription, } from "@oakai/core/src/utils/ailaModeration/helpers"; -import { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; +import type { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; import { Icon } from "@/components/Icon"; import { cn } from "@/lib/utils"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx b/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx index bdc9dc5d6..1fe02df05 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx @@ -1,5 +1,7 @@ -import React, { FC, memo } from "react"; -import ReactMarkdown, { Options } from "react-markdown"; +import type { FC } from "react"; +import React, { memo } from "react"; +import type { Options } from "react-markdown"; +import ReactMarkdown from "react-markdown"; import * as Tooltip from "@radix-ui/react-tooltip"; import { Box, Flex } from "@radix-ui/themes"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/prompt-form.tsx b/apps/nextjs/src/components/AppComponents/Chat/prompt-form.tsx index 16b8de455..04e600d87 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/prompt-form.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/prompt-form.tsx @@ -1,5 +1,6 @@ import { useCallback, useEffect, useRef } from "react"; -import { UseChatHelpers } from "ai/react"; + +import type { UseChatHelpers } from "ai/react"; import { Tooltip, @@ -11,7 +12,7 @@ import { useLessonPlanTracking } from "@/lib/analytics/lessonPlanTrackingContext import { useEnterSubmit } from "@/lib/hooks/use-enter-submit"; import { useSidebar } from "@/lib/hooks/use-sidebar"; -import { AilaStreamingStatus } from "./Chat/hooks/useAilaStreamingStatus"; +import type { AilaStreamingStatus } from "./Chat/hooks/useAilaStreamingStatus"; export interface PromptFormProps extends Pick { diff --git a/apps/nextjs/src/components/AppComponents/Chat/sidebar-actions.tsx b/apps/nextjs/src/components/AppComponents/Chat/sidebar-actions.tsx index af053e9a1..90d157eaa 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/sidebar-actions.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/sidebar-actions.tsx @@ -27,7 +27,7 @@ import { TooltipContent, TooltipTrigger, } from "@/components/AppComponents/Chat/ui/tooltip"; -import { SideBarChatItem } from "@/lib/types"; +import type { SideBarChatItem } from "@/lib/types"; import { trpc } from "@/utils/trpc"; type SidebarActionsProps = Readonly<{ diff --git a/apps/nextjs/src/components/AppComponents/Chat/sidebar-item.tsx b/apps/nextjs/src/components/AppComponents/Chat/sidebar-item.tsx index 65926df69..71dec1e16 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/sidebar-item.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/sidebar-item.tsx @@ -14,7 +14,7 @@ import { TooltipContent, TooltipTrigger, } from "@/components/AppComponents/Chat/ui/tooltip"; -import { SideBarChatItem } from "@/lib/types"; +import type { SideBarChatItem } from "@/lib/types"; import { cn } from "@/lib/utils"; import { constructChatPath } from "./Chat/utils"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/sidebar-items.tsx b/apps/nextjs/src/components/AppComponents/Chat/sidebar-items.tsx index d396f6d6c..ff3503223 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/sidebar-items.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/sidebar-items.tsx @@ -3,7 +3,7 @@ import { AnimatePresence, motion } from "framer-motion"; import { SidebarItem } from "@/components/AppComponents/Chat/sidebar-item"; -import { SideBarChatItem } from "@/lib/types"; +import type { SideBarChatItem } from "@/lib/types"; interface SidebarItemsProps { chats: SideBarChatItem[]; diff --git a/apps/nextjs/src/components/AppComponents/Chat/sidebar-list.tsx b/apps/nextjs/src/components/AppComponents/Chat/sidebar-list.tsx index 9f5faea5f..d68c6860a 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/sidebar-list.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/sidebar-list.tsx @@ -4,7 +4,7 @@ import { ClearHistory } from "@/components/AppComponents/Chat/clear-history"; import { SidebarItems } from "@/components/AppComponents/Chat/sidebar-items"; import { trpc } from "@/utils/trpc"; -export async function SidebarList() { +export function SidebarList() { const chatsRequest = trpc.chat.appSessions.getSidebarChats.useQuery(); const chats = chatsRequest.data; diff --git a/apps/nextjs/src/components/AppComponents/Chat/toxic-moderation-view.tsx b/apps/nextjs/src/components/AppComponents/Chat/toxic-moderation-view.tsx index 2341659e9..853024644 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/toxic-moderation-view.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/toxic-moderation-view.tsx @@ -1,6 +1,6 @@ import Textarea from "react-textarea-autosize"; -import { type PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; +import type { PersistedModerationBase } from "@oakai/core/src/utils/ailaModeration/moderationSchema"; import { useModerationFeedbackSurvey } from "hooks/surveys/useModerationFeedbackSurvey"; import { useRouter } from "next/navigation"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/ui/button.tsx b/apps/nextjs/src/components/AppComponents/Chat/ui/button.tsx index ccc1923a2..8f4e0aa35 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/ui/button.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/ui/button.tsx @@ -1,57 +1,58 @@ -import * as React from 'react' -import { Slot } from '@radix-ui/react-slot' -import { cva, type VariantProps } from 'class-variance-authority' +import * as React from "react"; -import { cn } from '@/lib/utils' +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/lib/utils"; const buttonVariants = cva( - 'inline-flex items-center justify-center rounded-md text-sm font-medium shadow ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', + "inline-flex items-center justify-center rounded-md text-sm font-medium shadow ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", { variants: { variant: { default: - 'bg-primary text-primary-foreground shadow-md hover:bg-primary/90', + "bg-primary text-primary-foreground shadow-md hover:bg-primary/90", destructive: - 'bg-destructive text-destructive-foreground hover:bg-destructive/90', + "bg-destructive text-destructive-foreground hover:bg-destructive/90", outline: - 'border border-input hover:bg-accent hover:text-accent-foreground', + "border border-input hover:bg-accent hover:text-accent-foreground", secondary: - 'bg-secondary text-secondary-foreground hover:bg-secondary/80', - ghost: 'shadow-none hover:bg-accent hover:text-accent-foreground', - link: 'text-primary underline-offset-4 shadow-none hover:underline' + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "shadow-none hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 shadow-none hover:underline", }, size: { - default: 'h-18 px-10 py-7', - sm: 'h-18 rounded-md px-9', - lg: 'h-22 rounded-md px-18', - icon: 'h-18 w-18 p-0' - } + default: "h-18 px-10 py-7", + sm: "h-18 rounded-md px-9", + lg: "h-22 rounded-md px-18", + icon: "h-18 w-18 p-0", + }, }, defaultVariants: { - variant: 'default', - size: 'default' - } - } -) + variant: "default", + size: "default", + }, + }, +); export interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { - asChild?: boolean + asChild?: boolean; } const Button = React.forwardRef( ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : 'button' + const Comp = asChild ? Slot : "button"; return ( - ) - } -) -Button.displayName = 'Button' + ); + }, +); +Button.displayName = "Button"; -export { Button, buttonVariants } +export { Button, buttonVariants }; diff --git a/apps/nextjs/src/components/AppComponents/Chat/ui/chat-button.tsx b/apps/nextjs/src/components/AppComponents/Chat/ui/chat-button.tsx index 1c482e484..379b1d74a 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/ui/chat-button.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/ui/chat-button.tsx @@ -1,6 +1,7 @@ import { cva } from "class-variance-authority"; -import ButtonCore, { ButtonVariant } from "@/components/ButtonCore"; +import type { ButtonVariant } from "@/components/ButtonCore"; +import ButtonCore from "@/components/ButtonCore"; import type { IconName } from "@/components/Icon"; interface ButtonProps { diff --git a/apps/nextjs/src/components/AppComponents/Chat/ui/codeblock.tsx b/apps/nextjs/src/components/AppComponents/Chat/ui/codeblock.tsx index f9daf291d..1633f7d0c 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/ui/codeblock.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/ui/codeblock.tsx @@ -1,6 +1,7 @@ "use client"; -import { FC, memo } from "react"; +import type { FC } from "react"; +import { memo } from "react"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism"; diff --git a/apps/nextjs/src/components/AppComponents/Chat/ui/tooltip.tsx b/apps/nextjs/src/components/AppComponents/Chat/ui/tooltip.tsx index 2ba086a4c..baa2503dc 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/ui/tooltip.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/ui/tooltip.tsx @@ -1,15 +1,16 @@ -'use client' +"use client"; -import * as React from 'react' -import * as TooltipPrimitive from '@radix-ui/react-tooltip' +import * as React from "react"; -import { cn } from '@/lib/utils' +import * as TooltipPrimitive from "@radix-ui/react-tooltip"; -const TooltipProvider = TooltipPrimitive.Provider +import { cn } from "@/lib/utils"; -const Tooltip = TooltipPrimitive.Root +const TooltipProvider = TooltipPrimitive.Provider; -const TooltipTrigger = TooltipPrimitive.Trigger +const Tooltip = TooltipPrimitive.Root; + +const TooltipTrigger = TooltipPrimitive.Trigger; const TooltipContent = React.forwardRef< React.ElementRef, @@ -19,12 +20,12 @@ const TooltipContent = React.forwardRef< ref={ref} sideOffset={sideOffset} className={cn( - 'z-50 overflow-hidden rounded-md border bg-popover px-9 py-5.5 text-xs font-medium text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-5 data-[side=left]:slide-in-from-right-5 data-[side=right]:slide-in-from-left-5 data-[side=top]:slide-in-from-bottom-5', - className + "py-5.5 z-50 overflow-hidden rounded-md border bg-popover px-9 text-xs font-medium text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-5 data-[side=left]:slide-in-from-right-5 data-[side=right]:slide-in-from-left-5 data-[side=top]:slide-in-from-bottom-5", + className, )} {...props} /> -)) -TooltipContent.displayName = TooltipPrimitive.Content.displayName +)); +TooltipContent.displayName = TooltipPrimitive.Content.displayName; -export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } +export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }; diff --git a/apps/nextjs/src/components/AppComponents/ComparativeJudgement/JudgementContent.tsx b/apps/nextjs/src/components/AppComponents/ComparativeJudgement/JudgementContent.tsx index 3fd2f2427..f2c750455 100644 --- a/apps/nextjs/src/components/AppComponents/ComparativeJudgement/JudgementContent.tsx +++ b/apps/nextjs/src/components/AppComponents/ComparativeJudgement/JudgementContent.tsx @@ -1,9 +1,10 @@ -import { Dispatch, SetStateAction, useMemo } from "react"; +import type { Dispatch, SetStateAction } from "react"; +import { useMemo } from "react"; import { Box, Grid, Text } from "@radix-ui/themes"; import { cva } from "class-variance-authority"; -import { Option } from "../../../ai-apps/comparative-judgement/state/types"; +import type { Option } from "../../../ai-apps/comparative-judgement/state/types"; import JudgementHeading from "./JudgementHeading"; import QuestionButton from "./QuestionButton"; import ReasonForChoosing from "./ReasonForChoosing"; diff --git a/apps/nextjs/src/components/AppComponents/ComparativeJudgement/KeyStageAndSubjectPicker.tsx b/apps/nextjs/src/components/AppComponents/ComparativeJudgement/KeyStageAndSubjectPicker.tsx index 93224cdea..b5a039e53 100644 --- a/apps/nextjs/src/components/AppComponents/ComparativeJudgement/KeyStageAndSubjectPicker.tsx +++ b/apps/nextjs/src/components/AppComponents/ComparativeJudgement/KeyStageAndSubjectPicker.tsx @@ -1,10 +1,10 @@ import { useEffect, useMemo } from "react"; -import { +import type { KeyStageName, SubjectName, - subjectsAndKeyStages, } from "@oakai/core/src/data/subjectsAndKeyStages"; +import { subjectsAndKeyStages } from "@oakai/core/src/data/subjectsAndKeyStages"; import { Flex } from "@radix-ui/themes"; import Input from "@/components/Input"; @@ -80,7 +80,7 @@ const KeyStageAndSubjectPicker = ({ type="dropdown" label="Subject" name="subject" - options={allowedSubjects as string[]} + options={allowedSubjects} onChange={(e) => setSelectedSubject(e.target.value as SubjectName)} value={selectedSubject} /> diff --git a/apps/nextjs/src/components/AppComponents/ComparativeJudgement/PreviewContent.tsx b/apps/nextjs/src/components/AppComponents/ComparativeJudgement/PreviewContent.tsx index f0f961a18..c742826b3 100644 --- a/apps/nextjs/src/components/AppComponents/ComparativeJudgement/PreviewContent.tsx +++ b/apps/nextjs/src/components/AppComponents/ComparativeJudgement/PreviewContent.tsx @@ -1,8 +1,5 @@ import { Box, Flex, Text } from "@radix-ui/themes"; -import { - AnswerAndDistractor, - OptionWithPrompt, -} from "ai-apps/comparative-judgement/state/types"; +import type { OptionWithPrompt } from "ai-apps/comparative-judgement/state/types"; import { sortAlphabetically } from "@/utils/alphabetiseArray"; @@ -16,8 +13,7 @@ type PreviewContentProps = { const PreviewContent = ({ option, question }: PreviewContentProps) => { if (!option?.answerAndDistractor) return null; - const answersAndDistractors = - option?.answerAndDistractor as AnswerAndDistractor; + const answersAndDistractors = option?.answerAndDistractor; const { answers, distractors } = answersAndDistractors; const answerAndDistractorArray = [...answers, ...distractors]; @@ -39,7 +35,7 @@ const PreviewContent = ({ option, question }: PreviewContentProps) => { - {option.isOakQuestion ? "Created by a Human" : `Created by Oak AI`} + {option.isOakQuestion ? "Created by a Human" : "Created by Oak AI"} {!option.isOakQuestion && ( )} {isLoading && ( -
+
{children}
diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/DownloadGiftButton.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/DownloadGiftButton.tsx index 9d078dc29..732da1b79 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/DownloadGiftButton.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/DownloadGiftButton.tsx @@ -1,4 +1,4 @@ -import { ExportableQuizAppState } from "@oakai/exports/src/schema/input.schema"; +import type { ExportableQuizAppState } from "@oakai/exports/src/schema/input.schema"; import { convertToGIFTFormat } from "ai-apps/quiz-designer/convertToGIFTFormat"; import useAnalytics from "@/lib/analytics/useAnalytics"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/ErrorBox.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/ErrorBox.tsx index 9014511f0..3b3c7869c 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/ErrorBox.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/ErrorBox.tsx @@ -1,4 +1,5 @@ -import { Box, Responsive } from "@radix-ui/themes"; +import type { Responsive } from "@radix-ui/themes"; +import { Box } from "@radix-ui/themes"; type ErrorBoxProps = { message: string | JSX.Element; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/ExportMenu.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/ExportMenu.tsx index 4e8c1fe7c..35a626543 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/ExportMenu.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/ExportMenu.tsx @@ -3,7 +3,7 @@ import { useMemo } from "react"; import { Box, Flex, Heading, Text } from "@radix-ui/themes"; import { convertQuizToCSV } from "ai-apps/quiz-designer/convertToCSV"; import { makeExportable } from "ai-apps/quiz-designer/export-helpers"; -import { QuizAppState } from "ai-apps/quiz-designer/state/types"; +import type { QuizAppState } from "ai-apps/quiz-designer/state/types"; import useShareContent from "hooks/useShareContent"; import Button from "@/components/Button"; @@ -13,7 +13,7 @@ import LoadingWheel from "@/components/LoadingWheel"; import useAnalytics from "@/lib/analytics/useAnalytics"; import ChatButton from "../Chat/ui/chat-button"; -import ShareButtonGroup from "../common/ShareButttonGroup"; +import ShareButtonGroup from "../common/ShareButtonGroup"; import DownloadGiftButton from "./DownloadGiftButton"; interface ExportMenuProps { diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/GenerateAllButton.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/GenerateAllButton.tsx index 646f56d4a..a5cea6259 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/GenerateAllButton.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/GenerateAllButton.tsx @@ -1,6 +1,6 @@ import { Box, Flex } from "@radix-ui/themes"; -import { IconName } from "../../Icon"; +import type { IconName } from "../../Icon"; import ChatButton from "../Chat/ui/chat-button"; import Generating from "../common/Generating"; import PromptExplainerButton from "../common/PromptExplainerButton"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/Hero.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/Hero.tsx index b18bb246b..22661d048 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/Hero.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/Hero.tsx @@ -1,12 +1,12 @@ -import { Dispatch, useCallback } from "react"; +import type { Dispatch } from "react"; +import { useCallback } from "react"; -import { KeyStageName, SubjectName } from "@oakai/core"; +import type { KeyStageName, SubjectName } from "@oakai/core"; import { Box, Flex, Heading, Text } from "@radix-ui/themes"; -import { - QuizAppAction, - QuizAppActions, -} from "ai-apps/quiz-designer/state/actions"; -import { QuizAppState, QuizAppStatus } from "ai-apps/quiz-designer/state/types"; +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import { QuizAppActions } from "ai-apps/quiz-designer/state/actions"; +import type { QuizAppState } from "ai-apps/quiz-designer/state/types"; +import { QuizAppStatus } from "ai-apps/quiz-designer/state/types"; import Image from "next/image"; import jigsaw from "@/assets/svg/illustration/jigsaw.svg"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizContent.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizContent.tsx index 4c0fba348..23a5ef2bc 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizContent.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizContent.tsx @@ -1,8 +1,10 @@ -import { Dispatch, useRef } from "react"; +import type { Dispatch } from "react"; +import { useRef } from "react"; import { Box, Container } from "@radix-ui/themes"; -import { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; -import { QuizAppState, QuizAppStatus } from "ai-apps/quiz-designer/state/types"; +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import type { QuizAppState } from "ai-apps/quiz-designer/state/types"; +import { QuizAppStatus } from "ai-apps/quiz-designer/state/types"; import useShareContent from "hooks/useShareContent"; import useSuggestedQuestions from "hooks/useSuggestedQuestions"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizDesignerPageContent.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizDesignerPageContent.tsx index 56f090582..8b920cee7 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizDesignerPageContent.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizDesignerPageContent.tsx @@ -1,4 +1,5 @@ -import { Dispatch, useRef } from "react"; +import type { Dispatch } from "react"; +import { useRef } from "react"; import { Box, Container } from "@radix-ui/themes"; import useSuggestedQuestions from "hooks/useSuggestedQuestions"; @@ -10,11 +11,9 @@ import ControllerRow from "@/components/AppComponents/QuizDesigner/QuizQuestionR import RateLimitNotification from "@/components/AppComponents/common/RateLimitNotification"; import Layout from "@/components/Layout"; -import { QuizAppAction } from "../../../ai-apps/quiz-designer/state/actions"; -import { - QuizAppState, - QuizAppStatus, -} from "../../../ai-apps/quiz-designer/state/types"; +import type { QuizAppAction } from "../../../ai-apps/quiz-designer/state/actions"; +import type { QuizAppState } from "../../../ai-apps/quiz-designer/state/types"; +import { QuizAppStatus } from "../../../ai-apps/quiz-designer/state/types"; import SuggestedQuestions from "./SuggestedQuestions"; type Props = { diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Answer.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Answer.tsx index b1db590bd..0447dd562 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Answer.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Answer.tsx @@ -1,13 +1,12 @@ import { useCallback } from "react"; -import { GenerationPart, GenerationPartType } from "@oakai/core/src/types"; +import type { GenerationPart } from "@oakai/core/src/types"; +import { GenerationPartType } from "@oakai/core/src/types"; import browserLogger from "@oakai/logger/browser"; import { Flex } from "@radix-ui/themes"; -import { - QuizAppAction, - QuizAppActions, -} from "ai-apps/quiz-designer/state/actions"; -import { +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import { QuizAppActions } from "ai-apps/quiz-designer/state/actions"; +import type { QuizAppAnswer, QuizAppState, QuizAppStateQuestion, diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Answers.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Answers.tsx index b70c96cff..cd739f83d 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Answers.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Answers.tsx @@ -1,8 +1,9 @@ -import { Dispatch, useState } from "react"; +import type { Dispatch } from "react"; +import { useState } from "react"; import { Box, Flex } from "@radix-ui/themes"; -import { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; -import { +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import type { QuizAppState, QuizAppStateQuestion, } from "ai-apps/quiz-designer/state/types"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/ControllerRow.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/ControllerRow.tsx index 12adff9e6..49fa1d7f7 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/ControllerRow.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/ControllerRow.tsx @@ -1,15 +1,14 @@ -import { Dispatch, useState } from "react"; +import type { Dispatch } from "react"; +import { useState } from "react"; import { Flex, Heading } from "@radix-ui/themes"; -import { - QuizAppAction, - QuizAppActions, -} from "ai-apps/quiz-designer/state/actions"; +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import { QuizAppActions } from "ai-apps/quiz-designer/state/actions"; import useAnalytics from "@/lib/analytics/useAnalytics"; import ChatButton from "../../Chat/ui/chat-button"; -import ShareButtonGroup from "../../common/ShareButttonGroup"; +import ShareButtonGroup from "../../common/ShareButtonGroup"; type ControllerProps = { hasQuestions: boolean; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Distractor.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Distractor.tsx index 38d070217..9fc978685 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Distractor.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Distractor.tsx @@ -1,13 +1,13 @@ -import { Dispatch, useCallback, useState } from "react"; +import type { Dispatch } from "react"; +import { useCallback, useState } from "react"; -import { GenerationPart, GenerationPartType } from "@oakai/core/src/types"; +import type { GenerationPart } from "@oakai/core/src/types"; +import { GenerationPartType } from "@oakai/core/src/types"; import browserLogger from "@oakai/logger/browser"; import { Flex } from "@radix-ui/themes"; -import { - QuizAppAction, - QuizAppActions, -} from "ai-apps/quiz-designer/state/actions"; -import { +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import { QuizAppActions } from "ai-apps/quiz-designer/state/actions"; +import type { QuizAppDistractor, QuizAppState, QuizAppStateQuestion, diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Distractors.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Distractors.tsx index dc75c74b4..7c7ec3774 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Distractors.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Distractors.tsx @@ -1,8 +1,8 @@ -import { Dispatch } from "react"; +import type { Dispatch } from "react"; import { Box, Flex } from "@radix-ui/themes"; -import { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; -import { +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import type { QuizAppState, QuizAppStateQuestion, } from "ai-apps/quiz-designer/state/types"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Question.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Question.tsx index d5b6f2498..13b0272ef 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Question.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/Question.tsx @@ -1,17 +1,16 @@ -import { Dispatch, useCallback } from "react"; +import type { Dispatch } from "react"; +import { useCallback } from "react"; import { Box, Flex } from "@radix-ui/themes"; import { quizRequestGeneration } from "ai-apps/quiz-designer/quizRequestGeneration"; -import { - QuizAppAction, - QuizAppActions, -} from "ai-apps/quiz-designer/state/actions"; -import { +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import { QuizAppActions } from "ai-apps/quiz-designer/state/actions"; +import type { QuizAppState, QuizAppStateQuestion, } from "ai-apps/quiz-designer/state/types"; +import type { GenerationWithResponse } from "hooks/useGeneration"; import { - GenerationWithResponse, UseGenerationStatus, isGenerationHookLoading, } from "hooks/useGeneration"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/RegenButtonGroup.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/RegenButtonGroup.tsx index 89b05da04..420fede29 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/RegenButtonGroup.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/RegenButtonGroup.tsx @@ -1,8 +1,6 @@ import { Flex } from "@radix-ui/themes"; -import { - UseGenerationStatus, - isGenerationHookLoading, -} from "hooks/useGeneration"; +import type { UseGenerationStatus } from "hooks/useGeneration"; +import { isGenerationHookLoading } from "hooks/useGeneration"; import { trpc } from "@/utils/trpc"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/index.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/index.tsx index 3f2912fda..fbe90ec90 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/index.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizQuestionRow/index.tsx @@ -1,11 +1,9 @@ -import { Dispatch } from "react"; +import type { Dispatch } from "react"; import { Box, Flex, Heading, Text } from "@radix-ui/themes"; -import { - QuizAppAction, - QuizAppActions, -} from "ai-apps/quiz-designer/state/actions"; -import { +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import { QuizAppActions } from "ai-apps/quiz-designer/state/actions"; +import type { QuizAppState, QuizAppStateQuestion, } from "ai-apps/quiz-designer/state/types"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizRestoreDialog.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizRestoreDialog.tsx index cdbad249d..f61bfc39e 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizRestoreDialog.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/QuizRestoreDialog.tsx @@ -1,11 +1,10 @@ -import { Dispatch, useCallback } from "react"; +import type { Dispatch } from "react"; +import { useCallback } from "react"; import * as Sentry from "@sentry/nextjs"; -import { - QuizAppAction, - QuizAppActions, -} from "ai-apps/quiz-designer/state/actions"; -import { QuizAppState } from "ai-apps/quiz-designer/state/types"; +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import { QuizAppActions } from "ai-apps/quiz-designer/state/actions"; +import type { QuizAppState } from "ai-apps/quiz-designer/state/types"; import { trpc } from "@/utils/trpc"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/Choose.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/Choose.tsx index f317d172e..81d91e568 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/Choose.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/Choose.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "react"; -import { +import type { KeyStageName, SubjectName, } from "@oakai/core/src/data/subjectsAndKeyStages"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/Confirmed.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/Confirmed.tsx index ec2e0321d..690797399 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/Confirmed.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/Confirmed.tsx @@ -1,4 +1,4 @@ -import { KeyStageName, SubjectName } from "@oakai/core"; +import type { KeyStageName, SubjectName } from "@oakai/core"; import { Flex, Heading, Text } from "@radix-ui/themes"; type ConfirmedProps = { diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/index.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/index.tsx index 3e95c1b16..fd34ee4ec 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/index.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/SubjectKeyStageSection/index.tsx @@ -1,4 +1,4 @@ -import { +import type { KeyStageName, SubjectName, } from "@oakai/core/src/data/subjectsAndKeyStages"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/SuggestedQuestionCard.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/SuggestedQuestionCard.tsx index 9fdd2f725..5c907490a 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/SuggestedQuestionCard.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/SuggestedQuestionCard.tsx @@ -1,11 +1,10 @@ -import { Dispatch, useState } from "react"; +import type { Dispatch } from "react"; +import { useState } from "react"; import { Flex, Text } from "@radix-ui/themes"; -import { - QuizAppAction, - QuizAppActions, -} from "ai-apps/quiz-designer/state/actions"; -import { PotentialQuestionsType } from "hooks/useSuggestedQuestions"; +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import { QuizAppActions } from "ai-apps/quiz-designer/state/actions"; +import type { PotentialQuestionsType } from "hooks/useSuggestedQuestions"; import { Icon } from "@/components/Icon"; diff --git a/apps/nextjs/src/components/AppComponents/QuizDesigner/SuggestedQuestions.tsx b/apps/nextjs/src/components/AppComponents/QuizDesigner/SuggestedQuestions.tsx index 2145a3097..c1113bd8e 100644 --- a/apps/nextjs/src/components/AppComponents/QuizDesigner/SuggestedQuestions.tsx +++ b/apps/nextjs/src/components/AppComponents/QuizDesigner/SuggestedQuestions.tsx @@ -1,9 +1,9 @@ -import { Dispatch } from "react"; +import type { Dispatch } from "react"; import { Box, Flex, Grid, Text } from "@radix-ui/themes"; -import { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; -import { UseGenerationError } from "hooks/useGeneration"; -import { PotentialQuestionsType } from "hooks/useSuggestedQuestions"; +import type { QuizAppAction } from "ai-apps/quiz-designer/state/actions"; +import type { UseGenerationError } from "hooks/useGeneration"; +import type { PotentialQuestionsType } from "hooks/useSuggestedQuestions"; import LoadingWheel from "@/components/LoadingWheel"; diff --git a/apps/nextjs/src/components/AppComponents/common/RateLimitNotification.tsx b/apps/nextjs/src/components/AppComponents/common/RateLimitNotification.tsx index ea0b8d5e8..7e8e376cc 100644 --- a/apps/nextjs/src/components/AppComponents/common/RateLimitNotification.tsx +++ b/apps/nextjs/src/components/AppComponents/common/RateLimitNotification.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from "react"; import { useUser } from "@clerk/nextjs"; -import { RateLimitInfo } from "@oakai/api/src/types"; +import type { RateLimitInfo } from "@oakai/api/src/types"; import { Box, Flex, Text } from "@radix-ui/themes"; import { cva } from "class-variance-authority"; diff --git a/apps/nextjs/src/components/AppComponents/common/ShareButttonGroup.tsx b/apps/nextjs/src/components/AppComponents/common/ShareButtonGroup.tsx similarity index 100% rename from apps/nextjs/src/components/AppComponents/common/ShareButttonGroup.tsx rename to apps/nextjs/src/components/AppComponents/common/ShareButtonGroup.tsx diff --git a/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationFeedbackDialog.tsx b/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationFeedbackDialog.tsx index 58d886f53..444eb2d5b 100644 --- a/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationFeedbackDialog.tsx +++ b/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationFeedbackDialog.tsx @@ -1,7 +1,7 @@ import { useState } from "react"; import { useUser } from "@clerk/nextjs"; -import { GenerationPart } from "@oakai/core/src/types"; +import type { GenerationPart } from "@oakai/core/src/types"; import { structuredLogger as logger } from "@oakai/logger"; import * as Dialog from "@radix-ui/react-dialog"; diff --git a/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationInputAndText.tsx b/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationInputAndText.tsx index 9f7902b31..23e2b08be 100644 --- a/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationInputAndText.tsx +++ b/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationInputAndText.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "react"; -import { +import type { GenerationPart, GenerationPartPlaceholder, } from "@oakai/core/src/types"; @@ -59,7 +59,7 @@ function GenerationInputAndText({ className={ userIsEditing ? "hidden" - : `flex text-lg ${isLoading && `line-through opacity-60 `}` + : `flex text-lg ${isLoading && "line-through opacity-60 "}` } > {children} diff --git a/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationWrapper.tsx b/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationWrapper.tsx index 7ba0fe6cc..d837683f7 100644 --- a/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationWrapper.tsx +++ b/apps/nextjs/src/components/AppComponents/common/SingleGeneration/GenerationWrapper.tsx @@ -1,6 +1,6 @@ import { useCallback, useState } from "react"; -import { GenerationPart } from "@oakai/core/src/types"; +import type { GenerationPart } from "@oakai/core/src/types"; import { Box } from "@radix-ui/themes"; import GenerationFeedbackDialog, { diff --git a/apps/nextjs/src/components/AppComponents/common/SuggestedLessons.tsx b/apps/nextjs/src/components/AppComponents/common/SuggestedLessons.tsx index c91f50e15..5fba0caaf 100644 --- a/apps/nextjs/src/components/AppComponents/common/SuggestedLessons.tsx +++ b/apps/nextjs/src/components/AppComponents/common/SuggestedLessons.tsx @@ -1,6 +1,6 @@ import { Flex, Grid, Heading } from "@radix-ui/themes"; -import { LessonPlannerAppState } from "ai-apps/lesson-planner/state/types"; -import { QuizAppState } from "ai-apps/quiz-designer/state/types"; +import type { LessonPlannerAppState } from "ai-apps/lesson-planner/state/types"; +import type { QuizAppState } from "ai-apps/quiz-designer/state/types"; import Link from "next/link"; import { Icon } from "@/components/Icon"; diff --git a/apps/nextjs/src/components/AppComponents/download/DownloadAllButton.tsx b/apps/nextjs/src/components/AppComponents/download/DownloadAllButton.tsx index 50aa10624..4e75ffbe2 100644 --- a/apps/nextjs/src/components/AppComponents/download/DownloadAllButton.tsx +++ b/apps/nextjs/src/components/AppComponents/download/DownloadAllButton.tsx @@ -1,6 +1,6 @@ import { useState } from "react"; -import { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; +import type { LooseLessonPlan } from "@oakai/aila/src/protocol/schema"; import { aiLogger } from "@oakai/logger"; import { Box } from "@radix-ui/themes"; import * as Sentry from "@sentry/nextjs"; @@ -21,7 +21,7 @@ import SlidesIcon from "../../SVGParts/SlidesIcon"; const log = aiLogger("chat"); -const allexportLinksObject = z.object({ +const allExportLinksObject = z.object({ lessonSlides: z.string(), lessonPlan: z.string(), worksheet: z.string(), @@ -114,7 +114,7 @@ export const DownloadAllButton = ({ try { const lessonTitle = lesson.title; if (!lessonTitle) return; - const parsedData = allexportLinksObject.parse(data); + const parsedData = allExportLinksObject.parse(data); mutateAsync({ lessonTitle, slidesLink: parsedData.lessonSlides, @@ -188,8 +188,8 @@ export const DownloadAllButton = ({
Email me - {isSuccess && `- email sent`}{" "} - {isError && `- There was an error sending the email!`} + {isSuccess && "- email sent"}{" "} + {isError && "- There was an error sending the email!"} Google account needed for this option @@ -202,7 +202,7 @@ export const DownloadAllButton = ({ return ( <>