From b69aab5205b7bb738853386e7a437c0028e64089 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Sun, 30 Aug 2026 09:26:11 +0700 Subject: [PATCH] chore: drop unused assets, primitives and dead functions The Next.js starter left five SVGs in public/ that nothing references. Eight shadcn primitives were vendored in but rendered nowhere: avatar, form, popover, progress, separator, sheet, table and tooltip. Removing them frees five Radix packages plus react-hook-form, its resolvers and zod, none of which the app had wired up. getAccumulatedScoreMessage was imported by GameClient and never called. getRandomCityLocationFromBbox had no caller at all, so it goes with its tests rather than leaving coverage pointed at unreachable code. The docs claimed a form and validation stack the project never used, and listed components that are no longer vendored. --- docs/project-structure.md | 11 +-- docs/tech-stack.md | 8 +- public/file.svg | 1 - public/globe.svg | 1 - public/next.svg | 1 - public/vercel.svg | 1 - public/window.svg | 1 - src/app/components/GameClient.js | 3 +- src/components/ui/avatar.jsx | 47 ---------- src/components/ui/form.jsx | 144 ------------------------------- src/components/ui/popover.jsx | 47 ---------- src/components/ui/progress.jsx | 29 ------- src/components/ui/separator.jsx | 27 ------ src/components/ui/sheet.jsx | 140 ------------------------------ src/components/ui/table.jsx | 123 -------------------------- src/components/ui/tooltip.jsx | 55 ------------ src/lib/game.js | 20 ----- 17 files changed, 8 insertions(+), 651 deletions(-) delete mode 100644 public/file.svg delete mode 100644 public/globe.svg delete mode 100644 public/next.svg delete mode 100644 public/vercel.svg delete mode 100644 public/window.svg delete mode 100644 src/components/ui/avatar.jsx delete mode 100644 src/components/ui/form.jsx delete mode 100644 src/components/ui/popover.jsx delete mode 100644 src/components/ui/progress.jsx delete mode 100644 src/components/ui/separator.jsx delete mode 100644 src/components/ui/sheet.jsx delete mode 100644 src/components/ui/table.jsx delete mode 100644 src/components/ui/tooltip.jsx diff --git a/docs/project-structure.md b/docs/project-structure.md index e13eb28..cc89566 100644 --- a/docs/project-structure.md +++ b/docs/project-structure.md @@ -42,23 +42,18 @@ Next.js 15 App Router structure: ### Reusable Components (`src/components/`) #### shadcn/ui Components (`src/components/ui/`) +Only the primitives the app actually renders are vendored in. Add others with +the shadcn CLI when a screen needs them, rather than keeping unused ones around. + - `alert.jsx` - Alert notifications -- `avatar.jsx` - User avatars - `badge.jsx` - Badge components - `button.jsx` - Button variants - `card.jsx` - Card layouts - `dialog.jsx` - Modal dialogs -- `form.jsx` - Form components - `input.jsx` - Input fields - `label.jsx` - Form labels -- `popover.jsx` - Popover components -- `progress.jsx` - Progress indicators -- `separator.jsx` - Visual separators -- `sheet.jsx` - Side sheets - `skeleton.jsx` - Loading skeletons -- `table.jsx` - Data tables - `tabs.jsx` - Tab navigation -- `tooltip.jsx` - Tooltips ### Utility Libraries (`src/lib/`) - `utils.js` - Utility functions including `cn()` for class name merging diff --git a/docs/tech-stack.md b/docs/tech-stack.md index e260ba0..370844c 100644 --- a/docs/tech-stack.md +++ b/docs/tech-stack.md @@ -35,10 +35,10 @@ - **class-variance-authority**: Component variant management - **tailwind-merge + clsx**: Dynamic class name handling -## Form Handling & Validation -- **react-hook-form**: Form state management -- **@hookform/resolvers**: Form validation resolvers -- **zod**: Schema validation +## Testing +- **Vitest**: Test runner for the logic in `src/lib/` +- **In-memory Upstash fake**: Default backing store, no service required +- **SRH + Redis (Docker)**: Optional lane running the same tests against real Redis ## Development & Analytics - **ESLint**: Code linting with Next.js configuration diff --git a/public/file.svg b/public/file.svg deleted file mode 100644 index 004145c..0000000 --- a/public/file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/globe.svg b/public/globe.svg deleted file mode 100644 index 567f17b..0000000 --- a/public/globe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index 7705396..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/window.svg b/public/window.svg deleted file mode 100644 index b2b2a44..0000000 --- a/public/window.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/app/components/GameClient.js b/src/app/components/GameClient.js index f0d3a80..5ae8c95 100644 --- a/src/app/components/GameClient.js +++ b/src/app/components/GameClient.js @@ -21,8 +21,7 @@ import { cityNames, formatDistance, getUsername, - getResultMessage, - getAccumulatedScoreMessage + getResultMessage } from '../../lib/game'; export default function GameClient() { diff --git a/src/components/ui/avatar.jsx b/src/components/ui/avatar.jsx deleted file mode 100644 index 417ebdf..0000000 --- a/src/components/ui/avatar.jsx +++ /dev/null @@ -1,47 +0,0 @@ -"use client" - -import * as React from "react" -import * as AvatarPrimitive from "@radix-ui/react-avatar" - -import { cn } from "@/lib/utils" - -function Avatar({ - className, - ...props -}) { - return ( - - ); -} - -function AvatarImage({ - className, - ...props -}) { - return ( - - ); -} - -function AvatarFallback({ - className, - ...props -}) { - return ( - - ); -} - -export { Avatar, AvatarImage, AvatarFallback } diff --git a/src/components/ui/form.jsx b/src/components/ui/form.jsx deleted file mode 100644 index 728ea87..0000000 --- a/src/components/ui/form.jsx +++ /dev/null @@ -1,144 +0,0 @@ -"use client"; -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { Controller, FormProvider, useFormContext, useFormState } from "react-hook-form"; - -import { cn } from "@/lib/utils" -import { Label } from "@/components/ui/label" - -const Form = FormProvider - -const FormFieldContext = React.createContext({}) - -const FormField = ( - { - ...props - } -) => { - return ( - - - - ); -} - -const useFormField = () => { - const fieldContext = React.useContext(FormFieldContext) - const itemContext = React.useContext(FormItemContext) - const { getFieldState } = useFormContext() - const formState = useFormState({ name: fieldContext.name }) - const fieldState = getFieldState(fieldContext.name, formState) - - if (!fieldContext) { - throw new Error("useFormField should be used within ") - } - - const { id } = itemContext - - return { - id, - name: fieldContext.name, - formItemId: `${id}-form-item`, - formDescriptionId: `${id}-form-item-description`, - formMessageId: `${id}-form-item-message`, - ...fieldState, - } -} - -const FormItemContext = React.createContext({}) - -function FormItem({ - className, - ...props -}) { - const id = React.useId() - - return ( - -
- - ); -} - -function FormLabel({ - className, - ...props -}) { - const { error, formItemId } = useFormField() - - return ( -