diff --git a/.storybook/main.ts b/.storybook/main.ts index 429d8ad4..6addc407 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,32 +1,32 @@ -import { type StorybookConfig } from '@storybook/nextjs' -import { merge } from 'merge-anything' +import { type StorybookConfig } from "@storybook/nextjs"; +import { merge } from "merge-anything"; -import { dirname, join } from 'path' +import { dirname, join } from "path"; const config: StorybookConfig = { - stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], + stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], staticDirs: [ { - from: '../public', - to: '/', + from: "../public", + to: "/", }, ], addons: [ - getAbsolutePath('@storybook/addon-a11y'), - getAbsolutePath('@storybook/addon-links'), - getAbsolutePath('@storybook/addon-essentials'), - getAbsolutePath('@storybook/addon-interactions'), + getAbsolutePath("@storybook/addon-a11y"), + getAbsolutePath("@storybook/addon-links"), + getAbsolutePath("@storybook/addon-essentials"), + getAbsolutePath("@storybook/addon-interactions"), ], framework: { - name: '@storybook/nextjs', + name: "@storybook/nextjs", options: {}, }, docs: { - autodocs: 'tag', + autodocs: "tag", }, typescript: { check: true, - reactDocgen: 'react-docgen-typescript', //'react-docgen-typescript', + reactDocgen: "react-docgen-typescript", //'react-docgen-typescript', reactDocgenTypescriptOptions: { shouldExtractLiteralValuesFromEnum: true, shouldExtractValuesFromUnion: true, @@ -42,14 +42,14 @@ const config: StorybookConfig = { // 'next-i18next': 'react-i18next', }, }, - } - const mergedConfig = merge(config, configAdditions) - return mergedConfig + }; + const mergedConfig = merge(config, configAdditions); + return mergedConfig; }, -} +}; -export default config +export default config; function getAbsolutePath(value: string): string { - return dirname(require.resolve(join(value, 'package.json'))) + return dirname(require.resolve(join(value, "package.json"))); } diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index e01ec016..14d43838 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,16 +1,16 @@ -import { Global, MantineProvider } from '@mantine/core' -import { type MantineProviderProps } from '@mantine/core' -import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport' -import { type StoryFn } from '@storybook/react' -import { type ReactNode } from 'react' -import { I18nextProvider } from 'react-i18next' +import { Global, MantineProvider } from "@mantine/core"; +import { type MantineProviderProps } from "@mantine/core"; +import { INITIAL_VIEWPORTS } from "@storybook/addon-viewport"; +import { type StoryFn } from "@storybook/react"; +import { type ReactNode } from "react"; +import { I18nextProvider } from "react-i18next"; -import { i18n, i18nLocales } from './i18next' -import { storybookFont } from '../src/styles' -import { theme } from '../src/styles/theme' +import { i18n, i18nLocales } from "./i18next"; +import { storybookFont } from "../src/styles"; +import { theme } from "../src/styles/theme"; export const parameters = { - layout: 'centered', + layout: "centered", controls: { matchers: { color: /(background|color)$/i, @@ -18,17 +18,17 @@ export const parameters = { }, }, i18n, - locale: 'en', + locale: "en", locales: i18nLocales, viewport: { viewports: INITIAL_VIEWPORTS, }, -} -const mantineProviderProps: Omit = { +}; +const mantineProviderProps: Omit = { withCSSVariables: false, withGlobalStyles: true, withNormalizeCSS: false, -} +}; const ThemeWrapper = ({ children }: DecoratorProps) => { return ( @@ -38,8 +38,8 @@ const ThemeWrapper = ({ children }: DecoratorProps) => { {children} {/* */} - ) -} + ); +}; export const decorators = [ (Story: StoryFn) => ( @@ -47,8 +47,8 @@ export const decorators = [ ), -] +]; type DecoratorProps = { - children: ReactNode -} + children: ReactNode; +}; diff --git a/prisma/dataMigrationRunner.ts b/prisma/dataMigrationRunner.ts index 17572a98..10f72349 100644 --- a/prisma/dataMigrationRunner.ts +++ b/prisma/dataMigrationRunner.ts @@ -8,9 +8,9 @@ import { type ListrTaskWrapper, PRESET_TIMER, PRESET_TIMESTAMP, -} from 'listr2' +} from "listr2"; -import * as jobList from './data-migrations' +import * as jobList from "./data-migrations"; /** * Job Runner @@ -22,18 +22,18 @@ const rendererOptions = { outputBar: 10, persistentOutput: true, timer: PRESET_TIMER, -} satisfies ListrJob['rendererOptions'] +} satisfies ListrJob["rendererOptions"]; const injectOptions = (job: ListrJob): ListrJob => ({ ...job, rendererOptions, -}) +}); const jobs = new Listr( Object.values(jobList).map((job) => injectOptions(job)), { rendererOptions: { - formatOutput: 'wrap', + formatOutput: "wrap", timer: PRESET_TIMER, suffixSkips: true, }, @@ -42,17 +42,21 @@ const jobs = new Listr( timestamp: PRESET_TIMESTAMP, }, exitOnError: false, - } -) + }, +); -jobs.run() +jobs.run(); export type Context = { - error?: boolean -} -export type PassedTask = ListrTaskWrapper -export type ListrJob = ListrTaskObj + error?: boolean; +}; +export type PassedTask = ListrTaskWrapper< + Context, + ListrDefaultRenderer, + ListrDefaultRenderer +>; +export type ListrJob = ListrTaskObj; export type ListrTask = ( ctx: Context, - task: PassedTask -) => void | Promise> | Listr + task: PassedTask, +) => void | Promise> | Listr; diff --git a/src/server/api/routers/stories.ts b/src/server/api/routers/stories.ts index ed5a5abf..91d784e1 100644 --- a/src/server/api/routers/stories.ts +++ b/src/server/api/routers/stories.ts @@ -1,33 +1,33 @@ -import { z } from 'zod' +import { z } from "zod"; -import { SurveySchema } from '~/pages/survey' -import { crowdin } from '~/server/crowdin' +import { SurveySchema } from "~/pages/survey"; +import { crowdin } from "~/server/crowdin"; -import { createTRPCRouter, publicProcedure } from '../trpc' +import { createTRPCRouter, publicProcedure } from "../trpc"; export const storyRouter = createTRPCRouter({ getStoryBySlug: publicProcedure .input( z.object({ publicSlug: z.string(), - }) + }), ) .query(async ({ ctx, input }) => { const story = await ctx.prisma.story.findUniqueOrThrow({ where: { publicSlug: input.publicSlug }, include: { categories: { include: { category: true } } }, - }) - return story + }); + return story; }), getStoryById: publicProcedure .input( z.object({ id: z.string(), - locale: z.enum(['en', 'es']), - }) + locale: z.enum(["en", "es"]), + }), ) .query(async ({ ctx, input }) => { - const isEN = input.locale === 'en' + const isEN = input.locale === "en"; if (isEN) { const story = await ctx.prisma.story.findUniqueOrThrow({ where: { id: input.id, published: true }, @@ -51,8 +51,9 @@ export const storyRouter = createTRPCRouter({ }, pronouns: { select: { pronoun: { select: { pronounsEN: true } } } }, }, - }) - const { categories, pronouns, response1EN, response2EN, ...rest } = story + }); + const { categories, pronouns, response1EN, response2EN, ...rest } = + story; const formatted = { ...rest, response1: response1EN, @@ -69,8 +70,8 @@ export const storyRouter = createTRPCRouter({ pronouns: pronouns.map(({ pronoun }) => ({ pronoun: pronoun.pronounsEN, })), - } - return formatted + }; + return formatted; } const story = await ctx.prisma.story.findUniqueOrThrow({ where: { id: input.id, published: true }, @@ -94,8 +95,8 @@ export const storyRouter = createTRPCRouter({ }, pronouns: { select: { pronoun: { select: { pronounsES: true } } } }, }, - }) - const { categories, pronouns, response1ES, response2ES, ...rest } = story + }); + const { categories, pronouns, response1ES, response2ES, ...rest } = story; const formatted = { ...rest, response1: response1ES, @@ -112,8 +113,8 @@ export const storyRouter = createTRPCRouter({ pronouns: pronouns.map(({ pronoun }) => ({ pronoun: pronoun.pronounsES, })), - } - return formatted + }; + return formatted; }), // unpublishStory: protectedProcedure.input(z.object({ id: z.string() })).mutation(async ({ ctx, input }) => { // const { id } = input @@ -124,9 +125,9 @@ export const storyRouter = createTRPCRouter({ // }) // }), getCategories: publicProcedure - .input(z.object({ locale: z.enum(['en', 'es']) })) + .input(z.object({ locale: z.enum(["en", "es"]) })) .query(async ({ ctx, input }) => { - if (input.locale === 'en') { + if (input.locale === "en") { const categories = await ctx.prisma.storyCategory.findMany({ select: { categoryEN: true, @@ -135,14 +136,16 @@ export const storyRouter = createTRPCRouter({ imageAltEN: true, tag: true, }, - orderBy: { order: 'asc' }, - }) - const formatted = categories.map(({ categoryEN, imageAltEN, ...rest }) => ({ - ...rest, - category: categoryEN, - imageAlt: imageAltEN, - })) - return formatted + orderBy: { order: "asc" }, + }); + const formatted = categories.map( + ({ categoryEN, imageAltEN, ...rest }) => ({ + ...rest, + category: categoryEN, + imageAlt: imageAltEN, + }), + ); + return formatted; } const categories = await ctx.prisma.storyCategory.findMany({ @@ -153,25 +156,27 @@ export const storyRouter = createTRPCRouter({ imageAltES: true, tag: true, }, - orderBy: { order: 'asc' }, - }) - const formatted = categories.map(({ categoryES, imageAltES, ...rest }) => ({ - ...rest, - category: categoryES, - imageAlt: imageAltES, - })) - return formatted + orderBy: { order: "asc" }, + }); + const formatted = categories.map( + ({ categoryES, imageAltES, ...rest }) => ({ + ...rest, + category: categoryES, + imageAlt: imageAltES, + }), + ); + return formatted; }), getByCategory: publicProcedure .input( z.object({ tag: z.string(), take: z.number().optional(), - locale: z.enum(['en', 'es']), - }) + locale: z.enum(["en", "es"]), + }), ) .query(async ({ ctx, input }) => { - if (input.locale === 'en') { + if (input.locale === "en") { const stories = await ctx.prisma.story.findMany({ where: { published: true, @@ -190,23 +195,25 @@ export const storyRouter = createTRPCRouter({ response2EN: true, }, ...(input.take ? { take: input.take } : {}), - orderBy: { createdAt: 'desc' }, - }) - const formatted = stories.map(({ categories, pronouns, response1EN, response2EN, ...rest }) => ({ - ...rest, - response1: response1EN, - response2: response2EN, - categories: categories.map(({ category }) => ({ - category: { - id: category.id, - category: category.categoryEN, - }, - })), - pronouns: pronouns.map(({ pronoun }) => ({ - pronoun: pronoun.pronounsEN, - })), - })) - return formatted + orderBy: { createdAt: "desc" }, + }); + const formatted = stories.map( + ({ categories, pronouns, response1EN, response2EN, ...rest }) => ({ + ...rest, + response1: response1EN, + response2: response2EN, + categories: categories.map(({ category }) => ({ + category: { + id: category.id, + category: category.categoryEN, + }, + })), + pronouns: pronouns.map(({ pronoun }) => ({ + pronoun: pronoun.pronounsEN, + })), + }), + ); + return formatted; } const stories = await ctx.prisma.story.findMany({ where: { @@ -226,93 +233,100 @@ export const storyRouter = createTRPCRouter({ response2ES: true, }, ...(input.take ? { take: input.take } : {}), - orderBy: { createdAt: 'desc' }, - }) - const formatted = stories.map(({ categories, pronouns, response1ES, response2ES, ...rest }) => ({ - ...rest, - response1: response1ES, - response2: response2ES, - categories: categories.map(({ category }) => ({ - category: { - id: category.id, - category: category.categoryES, - }, - })), - pronouns: pronouns.map(({ pronoun }) => ({ - pronoun: pronoun.pronounsES, - })), - })) - return formatted + orderBy: { createdAt: "desc" }, + }); + const formatted = stories.map( + ({ categories, pronouns, response1ES, response2ES, ...rest }) => ({ + ...rest, + response1: response1ES, + response2: response2ES, + categories: categories.map(({ category }) => ({ + category: { + id: category.id, + category: category.categoryES, + }, + })), + pronouns: pronouns.map(({ pronoun }) => ({ + pronoun: pronoun.pronounsES, + })), + }), + ); + return formatted; }), - submit: publicProcedure.input(SurveySchema()).mutation(async ({ ctx, input }) => { - const submission = await ctx.prisma.storySubmission.create({ - data: { - responses: input, - userId: 'noUserId', - }, - select: { - id: true, - }, - }) - const storyRecord = await ctx.prisma.story.create({ - data: { - name: input.q4, - response1EN: input.q8, - response2EN: input.q9, - categories: { - create: input.q5.map((tag) => ({ category: { connect: { tag } } })), - }, - pronouns: { - create: input.q7.map((tag) => ({ pronoun: { connect: { tag } } })), + submit: publicProcedure + .input(SurveySchema()) + .mutation(async ({ ctx, input }) => { + const submission = await ctx.prisma.storySubmission.create({ + data: { + responses: input, + userId: "noUserId", }, - published: false, - }, - }) - - const crowdinAdditions: CrowdinBatchAdd[] = [] - if (storyRecord.response1EN) { - crowdinAdditions.push({ - op: 'add', - path: '/-', - value: { - text: storyRecord.response1EN, - identifier: `${storyRecord.id}.response1`, - fileId: 2653, - context: `Submitter's Name: "${input.q4}" | Pronouns: "${input.q7.join('/')}"`, + select: { + id: true, }, - }) - } - if (storyRecord.response2EN) { - crowdinAdditions.push({ - op: 'add', - path: '/-', - value: { - text: storyRecord.response2EN, - identifier: `${storyRecord.id}.response2`, - fileId: 2653, - context: `Submitter's Name: "${input.q4}" | Pronouns: "${input.q7.join('/')}"`, + }); + const storyRecord = await ctx.prisma.story.create({ + data: { + name: input.q4, + response1EN: input.q8, + response2EN: input.q9, + categories: { + create: input.q5.map((tag) => ({ category: { connect: { tag } } })), + }, + pronouns: { + create: input.q7.map((tag) => ({ pronoun: { connect: { tag } } })), + }, + published: false, }, - }) - } + }); - if (crowdinAdditions.length) { - try { - await crowdin.sourceStringsApi.stringBatchOperations(14, crowdinAdditions) - } catch (e) { - console.error(e) + const crowdinAdditions: CrowdinBatchAdd[] = []; + if (storyRecord.response1EN) { + crowdinAdditions.push({ + op: "add", + path: "/-", + value: { + text: storyRecord.response1EN, + identifier: `${storyRecord.id}.response1`, + fileId: 2653, + context: `Submitter's Name: "${input.q4}" | Pronouns: "${input.q7.join("/")}"`, + }, + }); } - } - return submission - }), -}) + if (storyRecord.response2EN) { + crowdinAdditions.push({ + op: "add", + path: "/-", + value: { + text: storyRecord.response2EN, + identifier: `${storyRecord.id}.response2`, + fileId: 2653, + context: `Submitter's Name: "${input.q4}" | Pronouns: "${input.q7.join("/")}"`, + }, + }); + } + + if (crowdinAdditions.length) { + try { + await crowdin.sourceStringsApi.stringBatchOperations( + 14, + crowdinAdditions, + ); + } catch (e) { + console.error(e); + } + } + return submission; + }), +}); type CrowdinBatchAdd = { - op: 'add' - path: string + op: "add"; + path: string; value: { - text: string - identifier: string - fileId: number - context?: string - } -} + text: string; + identifier: string; + fileId: number; + context?: string; + }; +};