From a2eec1bd3da4bf01a73c7ae5f9a50bacf9a352c1 Mon Sep 17 00:00:00 2001 From: Corbin Crutchley Date: Tue, 15 Apr 2025 08:17:31 -0700 Subject: [PATCH] chore: apply Prettier --- apps/backend/scripts/generate-openapi-spec.ts | 14 +- apps/backend/src/aws-lambda.ts | 2 +- apps/backend/src/constants/open-api.ts | 10 +- apps/backend/src/node.ts | 13 +- ...son__[person_id]__hobbies.post.describe.ts | 10 +- ...erson__[person_id]__hobbies.post.schema.ts | 8 +- .../post/person__[person_id]__hobbies.post.ts | 31 +++-- .../person__[person_id]__hobbies.app.ts | 7 +- apps/backend/src/shared.ts | 7 +- apps/backend/tsconfig.json | 4 +- apps/frontend/eslint.config.js | 24 ++-- apps/frontend/src/App.tsx | 12 +- .../frontend/src/hooks/useNetworkingParams.ts | 18 +-- apps/frontend/src/main.tsx | 13 +- apps/frontend/src/services/people.ts | 87 +++++++------ .../frontend/src/services/schemas/people.d.ts | 122 +++++++++--------- apps/frontend/src/types/hobby.ts | 4 +- apps/frontend/src/types/tests.d.ts | 2 +- .../src/utils/testing-utils/people-mocks.ts | 31 ++--- .../utils/testing-utils/render-container.tsx | 14 +- .../src/utils/testing-utils/server.ts | 2 +- .../frontend/src/utils/testing-utils/setup.ts | 9 +- .../frontend/src/views/people/people.logic.ts | 36 +++--- .../frontend/src/views/people/people.spec.tsx | 49 ++++--- apps/frontend/src/views/people/people.ui.tsx | 24 ++-- .../frontend/src/views/people/people.view.tsx | 10 +- apps/frontend/vite.config.ts | 14 +- 27 files changed, 293 insertions(+), 284 deletions(-) diff --git a/apps/backend/scripts/generate-openapi-spec.ts b/apps/backend/scripts/generate-openapi-spec.ts index 41b1476..357a276 100644 --- a/apps/backend/scripts/generate-openapi-spec.ts +++ b/apps/backend/scripts/generate-openapi-spec.ts @@ -1,10 +1,10 @@ -import {resolve} from "node:path"; -import {writeFile} from "node:fs/promises"; -import {app} from "../src/shared.ts"; -import {generateSpecs} from "hono-openapi"; -import {openAPIOptions} from "../src/constants/open-api.ts"; +import { resolve } from 'node:path' +import { writeFile } from 'node:fs/promises' +import { app } from '../src/shared.ts' +import { generateSpecs } from 'hono-openapi' +import { openAPIOptions } from '../src/constants/open-api.ts' -const outPath = resolve(import.meta.dirname, "../out/openapi.json"); +const outPath = resolve(import.meta.dirname, '../out/openapi.json') -const specs = await generateSpecs(app, openAPIOptions); +const specs = await generateSpecs(app, openAPIOptions) await writeFile(outPath, JSON.stringify(specs, null, 2), 'utf-8') diff --git a/apps/backend/src/aws-lambda.ts b/apps/backend/src/aws-lambda.ts index 3dd6efc..a54f6ec 100644 --- a/apps/backend/src/aws-lambda.ts +++ b/apps/backend/src/aws-lambda.ts @@ -1,4 +1,4 @@ import { handle } from 'hono/aws-lambda' -import {app} from "./shared.ts"; +import { app } from './shared.ts' export const handler = handle(app) diff --git a/apps/backend/src/constants/open-api.ts b/apps/backend/src/constants/open-api.ts index 36a12db..85c45a2 100644 --- a/apps/backend/src/constants/open-api.ts +++ b/apps/backend/src/constants/open-api.ts @@ -1,14 +1,12 @@ -import type {OpenApiSpecsOptions} from "hono-openapi"; +import type { OpenApiSpecsOptions } from 'hono-openapi' export const openAPIOptions = { documentation: { info: { title: 'Hono API', - version: '1.0.0', - description: 'Greeting API', + version: '1.0.0', + description: 'Greeting API', }, - servers: [ - { url: 'http://localhost:3000', description: 'Local Server' }, - ], + servers: [{ url: 'http://localhost:3000', description: 'Local Server' }], }, } satisfies OpenApiSpecsOptions diff --git a/apps/backend/src/node.ts b/apps/backend/src/node.ts index d9db051..42fe70b 100644 --- a/apps/backend/src/node.ts +++ b/apps/backend/src/node.ts @@ -1,19 +1,16 @@ import { serve } from '@hono/node-server' -import {app} from "./shared.ts"; +import { app } from './shared.ts' import { openAPISpecs } from 'hono-openapi' import { apiReference } from '@scalar/hono-api-reference' -import {openAPIOptions} from "./constants/open-api.ts"; +import { openAPIOptions } from './constants/open-api.ts' -app.get( - '/openapi', - openAPISpecs(app, openAPIOptions) -) +app.get('/openapi', openAPISpecs(app, openAPIOptions)) app.get( '/docs', apiReference({ theme: 'saturn', spec: { url: '/openapi' }, - }) + }), ) -serve(app); +serve(app) diff --git a/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.describe.ts b/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.describe.ts index d644933..81c0189 100644 --- a/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.describe.ts +++ b/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.describe.ts @@ -1,14 +1,14 @@ -import {describeRoute} from "hono-openapi"; -import {resolver} from "hono-openapi/valibot"; -import {responseSchema} from "./person__[person_id]__hobbies.post.schema.ts"; +import { describeRoute } from 'hono-openapi' +import { resolver } from 'hono-openapi/valibot' +import { responseSchema } from './person__[person_id]__hobbies.post.schema.ts' export const personHobbiesPostDescribe = describeRoute({ - description: 'Return what\'s said to the user', + description: "Return what's said to the user", responses: { 200: { description: 'Successful response', content: { - 'application/json': {schema: resolver(responseSchema)}, + 'application/json': { schema: resolver(responseSchema) }, }, }, }, diff --git a/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.schema.ts b/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.schema.ts index 942d056..cd2db87 100644 --- a/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.schema.ts +++ b/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.schema.ts @@ -1,9 +1,9 @@ -import * as v from "valibot"; +import * as v from 'valibot' // TODO: Move this to a `packages/types` shared package so that FE and BE can use alike const HobbySchema = v.object({ name: v.string(), - id: v.string() + id: v.string(), }) export const bodySchema = v.object({ @@ -11,9 +11,9 @@ export const bodySchema = v.object({ }) export const paramSchema = v.object({ - "person_id": v.string(), + person_id: v.string(), }) -export const responseSchema = v.object({hobbies: v.array(HobbySchema)}) +export const responseSchema = v.object({ hobbies: v.array(HobbySchema) }) export type ResponseSchemaType = v.InferOutput diff --git a/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.ts b/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.ts index 03aa941..0a32bd0 100644 --- a/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.ts +++ b/apps/backend/src/routes/person__[person_id]__hobbies/methods/post/person__[person_id]__hobbies.post.ts @@ -1,17 +1,22 @@ import { Hono } from 'hono' import { validator } from 'hono-openapi/valibot' -import { bodySchema, paramSchema, type ResponseSchemaType } from './person__[person_id]__hobbies.post.schema.ts' +import { + bodySchema, + paramSchema, + type ResponseSchemaType, +} from './person__[person_id]__hobbies.post.schema.ts' import { personHobbiesPostDescribe } from './person__[person_id]__hobbies.post.describe.ts' -export const personHobbiesPost = new Hono() - .post('/', - personHobbiesPostDescribe, - validator('param', paramSchema), - validator('json', bodySchema), - (c) => { - const body = c.req.valid('json') - const _params = c.req.valid('param') - return c.json({ - hobbies: body.new_hobbies - } satisfies ResponseSchemaType) - }) +export const personHobbiesPost = new Hono().post( + '/', + personHobbiesPostDescribe, + validator('param', paramSchema), + validator('json', bodySchema), + (c) => { + const body = c.req.valid('json') + const _params = c.req.valid('param') + return c.json({ + hobbies: body.new_hobbies, + } satisfies ResponseSchemaType) + }, +) diff --git a/apps/backend/src/routes/person__[person_id]__hobbies/person__[person_id]__hobbies.app.ts b/apps/backend/src/routes/person__[person_id]__hobbies/person__[person_id]__hobbies.app.ts index ca3255a..a89007d 100644 --- a/apps/backend/src/routes/person__[person_id]__hobbies/person__[person_id]__hobbies.app.ts +++ b/apps/backend/src/routes/person__[person_id]__hobbies/person__[person_id]__hobbies.app.ts @@ -1,5 +1,4 @@ -import {Hono} from "hono"; -import { personHobbiesPost } from './methods/post/person__[person_id]__hobbies.post.ts' +import { Hono } from 'hono' +import { personHobbiesPost } from './methods/post/person__[person_id]__hobbies.post.ts' -export const personHobbiesApp = new Hono() - .route('/', personHobbiesPost) +export const personHobbiesApp = new Hono().route('/', personHobbiesPost) diff --git a/apps/backend/src/shared.ts b/apps/backend/src/shared.ts index 285fd33..6b8b5d9 100644 --- a/apps/backend/src/shared.ts +++ b/apps/backend/src/shared.ts @@ -1,7 +1,6 @@ -import {Hono} from 'hono' +import { Hono } from 'hono' import { personHobbiesApp } from './routes/person__[person_id]__hobbies/person__[person_id]__hobbies.app.ts' -const app = new Hono() - .route("/:person_id/hobbies", personHobbiesApp) +const app = new Hono().route('/:person_id/hobbies', personHobbiesApp) -export {app} +export { app } diff --git a/apps/backend/tsconfig.json b/apps/backend/tsconfig.json index b0e4241..ef0e489 100644 --- a/apps/backend/tsconfig.json +++ b/apps/backend/tsconfig.json @@ -7,9 +7,7 @@ "skipLibCheck": true, "allowImportingTsExtensions": true, "erasableSyntaxOnly": true, - "types": [ - "node" - ], + "types": ["node"], "jsx": "react-jsx", "jsxImportSource": "hono/jsx" } diff --git a/apps/frontend/eslint.config.js b/apps/frontend/eslint.config.js index 79a552e..092408a 100644 --- a/apps/frontend/eslint.config.js +++ b/apps/frontend/eslint.config.js @@ -1,28 +1,28 @@ -import js from "@eslint/js"; -import globals from "globals"; -import reactHooks from "eslint-plugin-react-hooks"; -import reactRefresh from "eslint-plugin-react-refresh"; -import tseslint from "typescript-eslint"; +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' export default tseslint.config( - { ignores: ["dist"] }, + { ignores: ['dist'] }, { extends: [js.configs.recommended, ...tseslint.configs.recommended], - files: ["**/*.{ts,tsx}"], + files: ['**/*.{ts,tsx}'], languageOptions: { ecmaVersion: 2020, globals: globals.browser, }, plugins: { - "react-hooks": reactHooks, - "react-refresh": reactRefresh, + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, }, rules: { ...reactHooks.configs.recommended.rules, - "react-refresh/only-export-components": [ - "warn", + 'react-refresh/only-export-components': [ + 'warn', { allowConstantExport: true }, ], }, }, -); +) diff --git a/apps/frontend/src/App.tsx b/apps/frontend/src/App.tsx index 351f119..ab0be38 100644 --- a/apps/frontend/src/App.tsx +++ b/apps/frontend/src/App.tsx @@ -1,8 +1,12 @@ -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { PeopleView } from "./views/people/people.view"; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { PeopleView } from './views/people/people.view' -const queryClient = new QueryClient(); +const queryClient = new QueryClient() export function App() { - return ; + return ( + + + + ) } diff --git a/apps/frontend/src/hooks/useNetworkingParams.ts b/apps/frontend/src/hooks/useNetworkingParams.ts index b0d3d1e..4d44ac1 100644 --- a/apps/frontend/src/hooks/useNetworkingParams.ts +++ b/apps/frontend/src/hooks/useNetworkingParams.ts @@ -1,17 +1,17 @@ -import { useMemo } from "react"; +import { useMemo } from 'react' export const getBaseUrl = (_env: ImportMetaEnv) => { // You can return different base URLs depending on your environmental vars - return `https://example.com`; -}; + return `https://example.com` +} export const useNetworkingParams = () => { - const env = import.meta.env; + const env = import.meta.env const baseUrl = useMemo(() => { - if (!env) return ""; - return getBaseUrl(env); - }, [env]); + if (!env) return '' + return getBaseUrl(env) + }, [env]) - return { baseUrl } as const; -}; + return { baseUrl } as const +} diff --git a/apps/frontend/src/main.tsx b/apps/frontend/src/main.tsx index b2a0945..35f28f1 100644 --- a/apps/frontend/src/main.tsx +++ b/apps/frontend/src/main.tsx @@ -1,19 +1,18 @@ -import { StrictMode } from "react"; -import { createRoot } from "react-dom/client"; -import { App } from "./App.tsx"; - +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import { App } from './App.tsx' async function enableMocking() { // You can add a check here for `dev` mode to conditionally enable this - + const { worker } = await import('./utils/testing-utils/server') return worker.start() } enableMocking().then(() => { - createRoot(document.getElementById("root")!).render( + createRoot(document.getElementById('root')!).render( , - ); + ) }) diff --git a/apps/frontend/src/services/people.ts b/apps/frontend/src/services/people.ts index 928d55b..4050c73 100644 --- a/apps/frontend/src/services/people.ts +++ b/apps/frontend/src/services/people.ts @@ -1,39 +1,48 @@ -import createClient from "openapi-fetch"; -import { paths } from "./schemas/people"; +import createClient from 'openapi-fetch' +import { paths } from './schemas/people' -type GetPathReqBody = - Required extends {requestBody: infer TRequestBody} ? - TRequestBody extends {content: infer TContent} ? - TContent extends { 'application/json': infer TJson } ? TJson : never : never : never; +type GetPathReqBody< + TKey extends keyof paths, + TMethod extends keyof paths[TKey], +> = + Required extends { requestBody: infer TRequestBody } + ? TRequestBody extends { content: infer TContent } + ? TContent extends { 'application/json': infer TJson } + ? TJson + : never + : never + : never +type GetPathReqParams< + TKey extends keyof paths, + TMethod extends keyof paths[TKey], +> = + Required extends { parameters: infer TParameters } + ? TParameters extends { path: infer TPath } + ? TPath + : never + : never -type GetPathReqParams = - Required extends {parameters: infer TParameters} ? - TParameters extends {path: infer TPath} ? - TPath : never : never; - -type GetReqProps = - GetPathReqBody & GetPathReqParams +type GetReqProps< + TKey extends keyof paths, + TMethod extends keyof paths[TKey], +> = GetPathReqBody & GetPathReqParams interface BaseNetworkProp { - baseUrl: string; - signal?: AbortSignal; - body?: any; + baseUrl: string + signal?: AbortSignal + body?: any } -const client = createClient(); +const client = createClient() -function getBaseFetchOptions({ - baseUrl, - body, - signal, -}: BaseNetworkProp) { +function getBaseFetchOptions({ baseUrl, body, signal }: BaseNetworkProp) { return { baseUrl, body: JSON.stringify(body), headers: { - Accept: "application/json", - "Content-Type": "application/json", + Accept: 'application/json', + 'Content-Type': 'application/json', }, signal: AbortSignal.any([ // Add timeout to fetch @@ -41,7 +50,7 @@ function getBaseFetchOptions({ // Manual cancelation ...(signal ? [signal] : []), ]), - }; + } } export async function createPersonHobbies({ @@ -50,24 +59,22 @@ export async function createPersonHobbies({ person_id, new_hobbies, ...props -}: BaseNetworkProp & GetReqProps<"/{person_id}/hobbies", 'post'>) { - const { data, error } = await client.POST( - "/{person_id}/hobbies", - { - params: { - path: { - person_id - } +}: BaseNetworkProp & GetReqProps<'/{person_id}/hobbies', 'post'>) { + const { data, error } = await client.POST('/{person_id}/hobbies', { + params: { + path: { + person_id, }, - ...getBaseFetchOptions({baseUrl, signal, body: new_hobbies}), - ...props, - }); + }, + ...getBaseFetchOptions({ baseUrl, signal, body: new_hobbies }), + ...props, + }) - if (error) throw error; - if (!data) throw "No data returned from API" + if (error) throw error + if (!data) throw 'No data returned from API' // Here, we can map our API responses to whatever data would make most sense to return from the server - const { hobbies } = data; + const { hobbies } = data - return hobbies; + return hobbies } diff --git a/apps/frontend/src/services/schemas/people.d.ts b/apps/frontend/src/services/schemas/people.d.ts index 8e64d47..13460e4 100644 --- a/apps/frontend/src/services/schemas/people.d.ts +++ b/apps/frontend/src/services/schemas/people.d.ts @@ -4,69 +4,69 @@ */ export interface paths { - "/{person_id}/hobbies": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Return what's said to the user */ - post: operations["postByPerson_idHobbies"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; + '/{person_id}/hobbies': { + parameters: { + query?: never + header?: never + path?: never + cookie?: never + } + get?: never + put?: never + /** @description Return what's said to the user */ + post: operations['postByPerson_idHobbies'] + delete?: never + options?: never + head?: never + patch?: never + trace?: never + } } -export type webhooks = Record; +export type webhooks = Record export interface components { - schemas: never; - responses: never; - parameters: never; - requestBodies: never; - headers: never; - pathItems: never; + schemas: never + responses: never + parameters: never + requestBodies: never + headers: never + pathItems: never } -export type $defs = Record; +export type $defs = Record export interface operations { - postByPerson_idHobbies: { - parameters: { - query?: never; - header?: never; - path: { - person_id: string; - }; - cookie?: never; - }; - requestBody?: { - content: { - "application/json": { - new_hobbies: { - name: string; - id: string; - }[]; - }; - }; - }; - responses: { - /** @description Successful response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - hobbies: { - name: string; - id: string; - }[]; - }; - }; - }; - }; - }; + postByPerson_idHobbies: { + parameters: { + query?: never + header?: never + path: { + person_id: string + } + cookie?: never + } + requestBody?: { + content: { + 'application/json': { + new_hobbies: { + name: string + id: string + }[] + } + } + } + responses: { + /** @description Successful response */ + 200: { + headers: { + [name: string]: unknown + } + content: { + 'application/json': { + hobbies: { + name: string + id: string + }[] + } + } + } + } + } } diff --git a/apps/frontend/src/types/hobby.ts b/apps/frontend/src/types/hobby.ts index 0e0770c..da468da 100644 --- a/apps/frontend/src/types/hobby.ts +++ b/apps/frontend/src/types/hobby.ts @@ -1,4 +1,4 @@ export interface Hobby { - id: string; - name: string; + id: string + name: string } diff --git a/apps/frontend/src/types/tests.d.ts b/apps/frontend/src/types/tests.d.ts index ce9166c..d90ced5 100644 --- a/apps/frontend/src/types/tests.d.ts +++ b/apps/frontend/src/types/tests.d.ts @@ -1 +1 @@ -/// \ No newline at end of file +/// diff --git a/apps/frontend/src/utils/testing-utils/people-mocks.ts b/apps/frontend/src/utils/testing-utils/people-mocks.ts index 7fe48fc..7e6a33a 100644 --- a/apps/frontend/src/utils/testing-utils/people-mocks.ts +++ b/apps/frontend/src/utils/testing-utils/people-mocks.ts @@ -2,25 +2,22 @@ import { paths } from '../../services/schemas/people' import { createOpenApiHttp } from 'openapi-msw' // Should be replaced with an env var of some kind -const baseUrl = "https://example.com"; +const baseUrl = 'https://example.com' export const http = createOpenApiHttp({ - baseUrl -}); + baseUrl, +}) // The default mocks that can be replaced on a test-by-test basis export const peopleHandlers = [ - http.post( - "/{person_id}/hobbies", - async ({response}) => { - return response(200).json({ - hobbies: [ - { - id: "1", - name: "Tennis", - }, - ], - }) - }, - ), -]; + http.post('/{person_id}/hobbies', async ({ response }) => { + return response(200).json({ + hobbies: [ + { + id: '1', + name: 'Tennis', + }, + ], + }) + }), +] diff --git a/apps/frontend/src/utils/testing-utils/render-container.tsx b/apps/frontend/src/utils/testing-utils/render-container.tsx index 3a8a47e..9ad136c 100644 --- a/apps/frontend/src/utils/testing-utils/render-container.tsx +++ b/apps/frontend/src/utils/testing-utils/render-container.tsx @@ -1,9 +1,11 @@ -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { render } from "@testing-library/react"; -import { PropsWithChildren } from "react"; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { render } from '@testing-library/react' +import { PropsWithChildren } from 'react' -const queryClient = new QueryClient(); +const queryClient = new QueryClient() export function renderContainer(children: PropsWithChildren['children']) { - return render({children}) -} \ No newline at end of file + return render( + {children}, + ) +} diff --git a/apps/frontend/src/utils/testing-utils/server.ts b/apps/frontend/src/utils/testing-utils/server.ts index 9299ef3..54595b7 100644 --- a/apps/frontend/src/utils/testing-utils/server.ts +++ b/apps/frontend/src/utils/testing-utils/server.ts @@ -1,5 +1,5 @@ import { setupWorker } from 'msw/browser' -import { peopleHandlers } from "./people-mocks"; +import { peopleHandlers } from './people-mocks' /** * This only works like this if you're using Vitest browser mode. diff --git a/apps/frontend/src/utils/testing-utils/setup.ts b/apps/frontend/src/utils/testing-utils/setup.ts index 8596fdf..66e5fe1 100644 --- a/apps/frontend/src/utils/testing-utils/setup.ts +++ b/apps/frontend/src/utils/testing-utils/setup.ts @@ -1,7 +1,6 @@ -import { afterEach, beforeAll } from "vitest"; -import { worker } from "./server"; +import { afterEach, beforeAll } from 'vitest' +import { worker } from './server' +beforeAll(() => worker.start()) -beforeAll(() => worker.start()); - -afterEach(() => worker.resetHandlers()); +afterEach(() => worker.resetHandlers()) diff --git a/apps/frontend/src/views/people/people.logic.ts b/apps/frontend/src/views/people/people.logic.ts index 3fae3e0..8db31af 100644 --- a/apps/frontend/src/views/people/people.logic.ts +++ b/apps/frontend/src/views/people/people.logic.ts @@ -1,17 +1,17 @@ -import { useMutation } from "@tanstack/react-query"; -import { useNetworkingParams } from "../../hooks/useNetworkingParams"; +import { useMutation } from '@tanstack/react-query' +import { useNetworkingParams } from '../../hooks/useNetworkingParams' import { createPersonHobbies as _createPersonHobbies, HobbyCreatePayload, -} from "../../services/people"; -import { useEffect, useRef, useState } from "react"; +} from '../../services/people' +import { useEffect, useRef, useState } from 'react' interface UsePeopleLogicProps { - person_id: string; + person_id: string } export function usePeopleLogic({ person_id }: UsePeopleLogicProps) { - const networkingProps = useNetworkingParams(); + const networkingProps = useNetworkingParams() const { data: personHobbies, @@ -19,30 +19,30 @@ export function usePeopleLogic({ person_id }: UsePeopleLogicProps) { error: personHobbiesError, isPending: isPersonHobbiesPending, } = useMutation({ - mutationKey: ["people", person_id, "hobbies"], - mutationFn: (data: Omit) => { + mutationKey: ['people', person_id, 'hobbies'], + mutationFn: (data: Omit) => { return _createPersonHobbies({ ...networkingProps, ...data, person_id, - }); + }) }, - }); + }) - const hobbyCountRef = useRef(0); + const hobbyCountRef = useRef(0) - const [hobbyInputVal, setHobbyInputVal] = useState(""); + const [hobbyInputVal, setHobbyInputVal] = useState('') const addHobby = () => { - const newHobby = { name: hobbyInputVal, id: "" + ++hobbyCountRef.current }; + const newHobby = { name: hobbyInputVal, id: '' + ++hobbyCountRef.current } createPersonHobbies({ new_hobbies: [newHobby], - }); - }; + }) + } useEffect(() => { - if (!personHobbiesError) return; - console.error(personHobbiesError); + if (!personHobbiesError) return + console.error(personHobbiesError) }, [personHobbiesError]) return { @@ -53,5 +53,5 @@ export function usePeopleLogic({ person_id }: UsePeopleLogicProps) { hobbyInputVal, setHobbyInputVal, addHobby, - }; + } } diff --git a/apps/frontend/src/views/people/people.spec.tsx b/apps/frontend/src/views/people/people.spec.tsx index 47fc01e..e4dad4d 100644 --- a/apps/frontend/src/views/people/people.spec.tsx +++ b/apps/frontend/src/views/people/people.spec.tsx @@ -1,31 +1,38 @@ -import { describe, expect, it } from "vitest"; -import { renderContainer } from "../../utils/testing-utils/render-container"; -import { PeopleView } from "./people.view"; -import { screen, waitFor } from "@testing-library/react"; +import { describe, expect, it } from 'vitest' +import { renderContainer } from '../../utils/testing-utils/render-container' +import { PeopleView } from './people.view' +import { screen, waitFor } from '@testing-library/react' import { worker } from '../../utils/testing-utils/server' -import { userEvent } from "@vitest/browser/context"; +import { userEvent } from '@vitest/browser/context' import { http } from '../../utils/testing-utils/people-mocks.ts' -const user = userEvent.setup(); +const user = userEvent.setup() -describe("PeopleView", () => { - it("Should allow the user to add a hobby to their person", async () => { - worker.use(http.post("/{person_id}/hobbies", ({response}) => - response(200).json({ - hobbies: [{ - id: "0", - name: "Go to the gym" - }] - }))) +describe('PeopleView', () => { + it('Should allow the user to add a hobby to their person', async () => { + worker.use( + http.post('/{person_id}/hobbies', ({ response }) => + response(200).json({ + hobbies: [ + { + id: '0', + name: 'Go to the gym', + }, + ], + }), + ), + ) - renderContainer() + renderContainer() - expect(screen.getByText("There are no hobbies")).toBeInTheDocument(); + expect(screen.getByText('There are no hobbies')).toBeInTheDocument() - await user.type(screen.getByLabelText("New hobby name"), "Do something fun"); + await user.type(screen.getByLabelText('New hobby name'), 'Do something fun') - await user.click(screen.getByText("Add hobby")); + await user.click(screen.getByText('Add hobby')) - await waitFor(() => expect(screen.getByText("Go to the gym")).toBeInTheDocument()) - }) + await waitFor(() => + expect(screen.getByText('Go to the gym')).toBeInTheDocument(), + ) + }) }) diff --git a/apps/frontend/src/views/people/people.ui.tsx b/apps/frontend/src/views/people/people.ui.tsx index 56cbc31..2995f96 100644 --- a/apps/frontend/src/views/people/people.ui.tsx +++ b/apps/frontend/src/views/people/people.ui.tsx @@ -1,13 +1,13 @@ -import { createPersonHobbiesResType } from "../../services/people"; +import { createPersonHobbiesResType } from '../../services/people' interface PeopleUIProps { - personId: string; - personHobbies: createPersonHobbiesResType["hobbies"] | undefined; - addHobby: () => void; - personHobbiesError: Error | null; - isPersonHobbiesPending: boolean; - hobbyInputVal: string; - setHobbyInputVal: (val: string) => void; + personId: string + personHobbies: createPersonHobbiesResType['hobbies'] | undefined + addHobby: () => void + personHobbiesError: Error | null + isPersonHobbiesPending: boolean + hobbyInputVal: string + setHobbyInputVal: (val: string) => void } export function PeopleUI({ @@ -26,8 +26,8 @@ export function PeopleUI({
{ - e.preventDefault(); - addHobby(); + e.preventDefault() + addHobby() }} >

Add new hobby

@@ -40,7 +40,7 @@ export function PeopleUI({
- {isPersonHobbiesPending ? "Adding hobby..." : null} + {isPersonHobbiesPending ? 'Adding hobby...' : null} {personHobbiesError ?

There was an error adding the hobby

: null}

Hobbies

@@ -49,5 +49,5 @@ export function PeopleUI({ {personHobbies?.map((hobby) =>
  • {hobby.name}
  • )} - ); + ) } diff --git a/apps/frontend/src/views/people/people.view.tsx b/apps/frontend/src/views/people/people.view.tsx index 280375d..2a7492b 100644 --- a/apps/frontend/src/views/people/people.view.tsx +++ b/apps/frontend/src/views/people/people.view.tsx @@ -1,9 +1,9 @@ -import { usePeopleLogic } from "./people.logic"; -import { PeopleUI } from "./people.ui"; +import { usePeopleLogic } from './people.logic' +import { PeopleUI } from './people.ui' export function PeopleView() { // This would usually be derived from a router of some kind - const person_id = "123"; + const person_id = '123' const { personHobbies, @@ -14,7 +14,7 @@ export function PeopleView() { setHobbyInputVal, } = usePeopleLogic({ person_id, - }); + }) return ( - ); + ) } diff --git a/apps/frontend/vite.config.ts b/apps/frontend/vite.config.ts index 612337d..116f349 100644 --- a/apps/frontend/vite.config.ts +++ b/apps/frontend/vite.config.ts @@ -1,16 +1,14 @@ -import { defineConfig } from "vitest/config"; -import react from "@vitejs/plugin-react"; +import { defineConfig } from 'vitest/config' +import react from '@vitejs/plugin-react' // https://vite.dev/config/ export default defineConfig({ plugins: [react()], test: { - setupFiles: ["./src/utils/testing-utils/setup.ts"], + setupFiles: ['./src/utils/testing-utils/setup.ts'], browser: { enabled: true, - instances: [ - { browser: 'chromium' }, - ], + instances: [{ browser: 'chromium' }], }, - } -}); + }, +}) -- 2.51.2