From 0bea7bc3f455aa508170c29e7ebd3af147a91ce7 Mon Sep 17 00:00:00 2001 From: BeauTroll <-> Date: Mon, 19 Jan 2026 13:35:20 +0100 Subject: [PATCH] added biome --- .env.example | 9 + biome.json | 34 ++ components.json | 22 + docs/stories/1.1.story.md | 24 +- package.json | 9 + pnpm-lock.yaml | 545 ++++++++++++++++-- pnpm-workspace.yaml | 4 + .../20260119121104_init/migration.sql | 187 ++++++ prisma/migrations/migration_lock.toml | 3 + prisma/schema.prisma | 141 ++--- src/app/globals.css | 129 +++-- src/components/ui/button.tsx | 62 ++ src/components/ui/card.tsx | 92 +++ src/components/ui/input.tsx | 21 + src/components/ui/table.tsx | 114 ++++ src/lib/server/db.ts | 18 + src/lib/utils.ts | 6 + 17 files changed, 1226 insertions(+), 194 deletions(-) create mode 100644 .env.example create mode 100644 biome.json create mode 100644 components.json create mode 100644 pnpm-workspace.yaml create mode 100644 prisma/migrations/20260119121104_init/migration.sql create mode 100644 prisma/migrations/migration_lock.toml create mode 100644 src/components/ui/button.tsx create mode 100644 src/components/ui/card.tsx create mode 100644 src/components/ui/input.tsx create mode 100644 src/components/ui/table.tsx create mode 100644 src/lib/utils.ts diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..54a60b9 --- /dev/null +++ b/.env.example @@ -0,0 +1,9 @@ +# Database +DATABASE_URL="postgresql://postgres:postgres@localhost:5432/dofus_manager?schema=public" + +# App +APP_URL="http://localhost:3000" +NODE_ENV="development" + +# Session +SESSION_SECRET="change-me-to-a-random-string-min-32-chars" diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..750946b --- /dev/null +++ b/biome.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.3.11/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false + }, + "formatter": { + "enabled": true, + "indentStyle": "tab" + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + } + }, + "assist": { + "enabled": true, + "actions": { + "source": { + "organizeImports": "on" + } + } + } +} diff --git a/components.json b/components.json new file mode 100644 index 0000000..05d77cf --- /dev/null +++ b/components.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/app/globals.css", + "baseColor": "stone", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "registries": {} +} diff --git a/docs/stories/1.1.story.md b/docs/stories/1.1.story.md index a1656c1..974e261 100644 --- a/docs/stories/1.1.story.md +++ b/docs/stories/1.1.story.md @@ -39,24 +39,24 @@ Draft - [x] Configure PostgreSQL 16-alpine with healthcheck - [x] Test database connectivity -- [ ] Task 3: Configure Prisma ORM (AC: 3) +- [x] Task 3: Configure Prisma ORM (AC: 3) - [x] Install Prisma dependencies (`prisma`, `@prisma/client`) - [x] Initialize Prisma with `pnpm prisma init` - [x] Configure `prisma/schema.prisma` with PostgreSQL provider - - [ ] Create `src/lib/server/db.ts` for Prisma client singleton - - [ ] Create `.env.example` with DATABASE_URL template - - [ ] Verify Prisma connects to database + - [x] Create `src/lib/server/db.ts` for Prisma client singleton + - [x] Create `.env.example` with DATABASE_URL template + - [x] Verify Prisma connects to database -- [ ] Task 4: Install and configure shadcn/ui (AC: 4) - - [ ] Install Tailwind CSS 4.x - - [ ] Initialize shadcn/ui with `pnpm dlx shadcn@latest init` - - [ ] Configure `components.json` for path aliases - - [ ] Install base components: Button, Input, Card, Table - - [ ] Create `src/lib/utils.ts` with `cn` utility function - - [ ] Install Lucide React for icons +- [x] Task 4: Install and configure shadcn/ui (AC: 4) + - [x] Install Tailwind CSS 4.x + - [x] Initialize shadcn/ui with `pnpm dlx shadcn@latest init` + - [x] Configure `components.json` for path aliases + - [x] Install base components: Button, Input, Card, Table + - [x] Create `src/lib/utils.ts` with `cn` utility function + - [x] Install Lucide React for icons - [ ] Task 5: Configure linting and formatting (AC: 5) - - [ ] Install Biome (as specified in tech stack, not ESLint+Prettier) + - [x] Install Biome (as specified in tech stack, not ESLint+Prettier) - [ ] Create `biome.json` with recommended rules - [ ] Add lint and format scripts to `package.json` - [ ] Verify linting works on project files diff --git a/package.json b/package.json index 9fa34d0..922906b 100644 --- a/package.json +++ b/package.json @@ -10,19 +10,26 @@ }, "dependencies": { "@prisma/client": "^7.2.0", + "@radix-ui/react-slot": "^1.2.4", + "@tailwindcss/vite": "^4.1.18", "@tanstack/react-devtools": "^0.7.0", "@tanstack/react-router": "^1.132.0", "@tanstack/react-router-devtools": "^1.132.0", "@tanstack/react-router-ssr-query": "^1.131.7", "@tanstack/react-start": "^1.132.0", "@tanstack/router-plugin": "^1.132.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "lucide-react": "^0.561.0", "nitro": "npm:nitro-nightly@latest", "react": "^19.2.0", "react-dom": "^19.2.0", + "tailwind-merge": "^3.4.0", + "tailwindcss": "^4.1.18", "vite-tsconfig-paths": "^6.0.2" }, "devDependencies": { + "@biomejs/biome": "2.3.11", "@tanstack/devtools-vite": "^0.3.11", "@testing-library/dom": "^10.4.0", "@testing-library/react": "^16.2.0", @@ -30,8 +37,10 @@ "@types/react": "^19.2.0", "@types/react-dom": "^19.2.0", "@vitejs/plugin-react": "^5.0.4", + "dotenv": "^17.2.3", "jsdom": "^27.0.0", "prisma": "^7.2.0", + "tw-animate-css": "^1.4.0", "typescript": "^5.7.2", "vite": "^7.1.7", "vitest": "^3.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6b7e9e..3744f62 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,12 @@ importers: '@prisma/client': specifier: ^7.2.0 version: 7.2.0(prisma@7.2.0(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3) + '@radix-ui/react-slot': + specifier: ^1.2.4 + version: 1.2.4(@types/react@19.2.8)(react@19.2.3) + '@tailwindcss/vite': + specifier: ^4.1.18 + version: 4.1.18(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) '@tanstack/react-devtools': specifier: ^0.7.0 version: 0.7.11(@types/react-dom@19.2.3(@types/react@19.2.8))(@types/react@19.2.8)(csstype@3.2.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(solid-js@1.9.10) @@ -25,29 +31,44 @@ importers: version: 1.151.6(@tanstack/query-core@5.90.19)(@tanstack/react-query@5.90.19(react@19.2.3))(@tanstack/react-router@1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@tanstack/router-core@1.151.6)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start': specifier: ^1.132.0 - version: 1.153.0(crossws@0.4.1(srvx@0.10.0))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)) + version: 1.153.0(crossws@0.4.1(srvx@0.10.0))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) '@tanstack/router-plugin': specifier: ^1.132.0 - version: 1.151.6(@tanstack/react-router@1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)) + version: 1.151.6(@tanstack/react-router@1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 lucide-react: specifier: ^0.561.0 version: 0.561.0(react@19.2.3) nitro: specifier: npm:nitro-nightly@latest - version: nitro-nightly@3.0.1-20260115-135431-98fc91c5(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.4)(mysql2@3.15.3)(rollup@4.55.1)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)) + version: nitro-nightly@3.0.1-20260115-135431-98fc91c5(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.4)(mysql2@3.15.3)(rollup@4.55.1)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) react: specifier: ^19.2.0 version: 19.2.3 react-dom: specifier: ^19.2.0 version: 19.2.3(react@19.2.3) + tailwind-merge: + specifier: ^3.4.0 + version: 3.4.0 + tailwindcss: + specifier: ^4.1.18 + version: 4.1.18 vite-tsconfig-paths: specifier: ^6.0.2 - version: 6.0.4(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)) + version: 6.0.4(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) devDependencies: + '@biomejs/biome': + specifier: 2.3.11 + version: 2.3.11 '@tanstack/devtools-vite': specifier: ^0.3.11 - version: 0.3.12(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)) + version: 0.3.12(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) '@testing-library/dom': specifier: ^10.4.0 version: 10.4.1 @@ -65,22 +86,28 @@ importers: version: 19.2.3(@types/react@19.2.8) '@vitejs/plugin-react': specifier: ^5.0.4 - version: 5.1.2(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)) + version: 5.1.2(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) + dotenv: + specifier: ^17.2.3 + version: 17.2.3 jsdom: specifier: ^27.0.0 version: 27.4.0 prisma: specifier: ^7.2.0 version: 7.2.0(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + tw-animate-css: + specifier: ^1.4.0 + version: 1.4.0 typescript: specifier: ^5.7.2 version: 5.9.3 vite: specifier: ^7.1.7 - version: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) + version: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/node@22.19.7)(jiti@2.6.1)(jsdom@27.4.0)(tsx@4.21.0) + version: 3.2.4(@types/node@22.19.7)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(tsx@4.21.0) web-vitals: specifier: ^5.1.0 version: 5.1.0 @@ -202,6 +229,59 @@ packages: resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} engines: {node: '>=6.9.0'} + '@biomejs/biome@2.3.11': + resolution: {integrity: sha512-/zt+6qazBWguPG6+eWmiELqO+9jRsMZ/DBU3lfuU2ngtIQYzymocHhKiZRyrbra4aCOoyTg/BmY+6WH5mv9xmQ==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.3.11': + resolution: {integrity: sha512-/uXXkBcPKVQY7rc9Ys2CrlirBJYbpESEDme7RKiBD6MmqR2w3j0+ZZXRIL2xiaNPsIMMNhP1YnA+jRRxoOAFrA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.3.11': + resolution: {integrity: sha512-fh7nnvbweDPm2xEmFjfmq7zSUiox88plgdHF9OIW4i99WnXrAC3o2P3ag9judoUMv8FCSUnlwJCM1B64nO5Fbg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.3.11': + resolution: {integrity: sha512-XPSQ+XIPZMLaZ6zveQdwNjbX+QdROEd1zPgMwD47zvHV+tCGB88VH+aynyGxAHdzL+Tm/+DtKST5SECs4iwCLg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@2.3.11': + resolution: {integrity: sha512-l4xkGa9E7Uc0/05qU2lMYfN1H+fzzkHgaJoy98wO+b/7Gl78srbCRRgwYSW+BTLixTBrM6Ede5NSBwt7rd/i6g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@2.3.11': + resolution: {integrity: sha512-vU7a8wLs5C9yJ4CB8a44r12aXYb8yYgBn+WeyzbMjaCMklzCv1oXr8x+VEyWodgJt9bDmhiaW/I0RHbn7rsNmw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@2.3.11': + resolution: {integrity: sha512-/1s9V/H3cSe0r0Mv/Z8JryF5x9ywRxywomqZVLHAoa/uN0eY7F8gEngWKNS5vbbN/BsfpCG5yeBT5ENh50Frxg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@2.3.11': + resolution: {integrity: sha512-PZQ6ElCOnkYapSsysiTy0+fYX+agXPlWugh6+eQ6uPKI3vKAqNp6TnMhoM3oY2NltSB89hz59o8xIfOdyhi9Iw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.3.11': + resolution: {integrity: sha512-43VrG813EW+b5+YbDbz31uUsheX+qFKCpXeY9kfdAx+ww3naKxeVkTD9zLIWxUPfJquANMHrmW3wbe/037G0Qg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + '@chevrotain/cst-dts-gen@10.5.0': resolution: {integrity: sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==} @@ -769,6 +849,24 @@ packages: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@rolldown/pluginutils@1.0.0-beta.40': resolution: {integrity: sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w==} @@ -933,6 +1031,96 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@tailwindcss/node@4.1.18': + resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==} + + '@tailwindcss/oxide-android-arm64@4.1.18': + resolution: {integrity: sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.1.18': + resolution: {integrity: sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.1.18': + resolution: {integrity: sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.1.18': + resolution: {integrity: sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': + resolution: {integrity: sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': + resolution: {integrity: sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.1.18': + resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.1.18': + resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.1.18': + resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.1.18': + resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': + resolution: {integrity: sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.18': + resolution: {integrity: sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.18': + resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==} + engines: {node: '>= 10'} + + '@tailwindcss/vite@4.1.18': + resolution: {integrity: sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 + '@tanstack/devtools-client@0.0.3': resolution: {integrity: sha512-kl0r6N5iIL3t9gGDRAv55VRM3UIyMKVH83esRGq7xBjYsRLe/BeCIN2HqrlJkObUXQMKhy7i8ejuGOn+bDqDBw==} engines: {node: '>=18'} @@ -1337,6 +1525,9 @@ packages: citty@0.1.6: resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -1445,6 +1636,10 @@ packages: destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + diff@8.0.3: resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} engines: {node: '>=0.3.1'} @@ -1469,6 +1664,10 @@ packages: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + effect@3.18.4: resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} @@ -1482,6 +1681,10 @@ packages: encoding-sniffer@0.2.1: resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} + enhanced-resolve@5.18.4: + resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + engines: {node: '>=10.13.0'} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -1691,6 +1894,76 @@ packages: launch-editor@2.12.0: resolution: {integrity: sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg==} + lightningcss-android-arm64@1.30.2: + resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.30.2: + resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.30.2: + resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.30.2: + resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.30.2: + resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.30.2: + resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.30.2: + resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.30.2: + resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.30.2: + resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.2: + resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.2: + resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.2: + resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} + engines: {node: '>= 12.0.0'} + lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -2034,6 +2307,16 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + tailwind-merge@3.4.0: + resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==} + + tailwindcss@4.1.18: + resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -2103,6 +2386,9 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + tw-animate-css@1.4.0: + resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} + type-fest@4.41.0: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} @@ -2532,6 +2818,41 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@biomejs/biome@2.3.11': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.3.11 + '@biomejs/cli-darwin-x64': 2.3.11 + '@biomejs/cli-linux-arm64': 2.3.11 + '@biomejs/cli-linux-arm64-musl': 2.3.11 + '@biomejs/cli-linux-x64': 2.3.11 + '@biomejs/cli-linux-x64-musl': 2.3.11 + '@biomejs/cli-win32-arm64': 2.3.11 + '@biomejs/cli-win32-x64': 2.3.11 + + '@biomejs/cli-darwin-arm64@2.3.11': + optional: true + + '@biomejs/cli-darwin-x64@2.3.11': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.3.11': + optional: true + + '@biomejs/cli-linux-arm64@2.3.11': + optional: true + + '@biomejs/cli-linux-x64-musl@2.3.11': + optional: true + + '@biomejs/cli-linux-x64@2.3.11': + optional: true + + '@biomejs/cli-win32-arm64@2.3.11': + optional: true + + '@biomejs/cli-win32-x64@2.3.11': + optional: true + '@chevrotain/cst-dts-gen@10.5.0': dependencies: '@chevrotain/gast': 10.5.0 @@ -2926,6 +3247,19 @@ snapshots: react: 19.2.3 react-dom: 19.2.3(react@19.2.3) + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.8)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.8 + + '@radix-ui/react-slot@1.2.4(@types/react@19.2.8)(react@19.2.3)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.8)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.8 + '@rolldown/pluginutils@1.0.0-beta.40': {} '@rolldown/pluginutils@1.0.0-beta.53': {} @@ -3041,6 +3375,74 @@ snapshots: '@standard-schema/spec@1.1.0': {} + '@tailwindcss/node@4.1.18': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.18.4 + jiti: 2.6.1 + lightningcss: 1.30.2 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.1.18 + + '@tailwindcss/oxide-android-arm64@4.1.18': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.18': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.18': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.18': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.1.18': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.18': + optional: true + + '@tailwindcss/oxide@4.1.18': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.18 + '@tailwindcss/oxide-darwin-arm64': 4.1.18 + '@tailwindcss/oxide-darwin-x64': 4.1.18 + '@tailwindcss/oxide-freebsd-x64': 4.1.18 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.18 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.18 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.18 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.18 + '@tailwindcss/oxide-linux-x64-musl': 4.1.18 + '@tailwindcss/oxide-wasm32-wasi': 4.1.18 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 + + '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': + dependencies: + '@tailwindcss/node': 4.1.18 + '@tailwindcss/oxide': 4.1.18 + tailwindcss: 4.1.18 + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) + '@tanstack/devtools-client@0.0.3': dependencies: '@tanstack/devtools-event-client': 0.3.5 @@ -3068,7 +3470,7 @@ snapshots: transitivePeerDependencies: - csstype - '@tanstack/devtools-vite@0.3.12(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0))': + '@tanstack/devtools-vite@0.3.12(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': dependencies: '@babel/core': 7.28.6 '@babel/generator': 7.28.6 @@ -3080,7 +3482,7 @@ snapshots: chalk: 5.6.2 launch-editor: 2.12.0 picomatch: 4.0.3 - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) transitivePeerDependencies: - bufferutil - supports-color @@ -3179,19 +3581,19 @@ snapshots: transitivePeerDependencies: - crossws - '@tanstack/react-start@1.153.0(crossws@0.4.1(srvx@0.10.0))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0))': + '@tanstack/react-start@1.153.0(crossws@0.4.1(srvx@0.10.0))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': dependencies: '@tanstack/react-router': 1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start-client': 1.153.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-start-server': 1.153.0(crossws@0.4.1(srvx@0.10.0))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/router-utils': 1.143.11 '@tanstack/start-client-core': 1.153.0 - '@tanstack/start-plugin-core': 1.153.0(@tanstack/react-router@1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.1(srvx@0.10.0))(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)) + '@tanstack/start-plugin-core': 1.153.0(@tanstack/react-router@1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.1(srvx@0.10.0))(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) '@tanstack/start-server-core': 1.153.0(crossws@0.4.1(srvx@0.10.0)) pathe: 2.0.3 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) transitivePeerDependencies: - '@rsbuild/core' - crossws @@ -3238,7 +3640,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.151.6(@tanstack/react-router@1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0))': + '@tanstack/router-plugin@1.151.6(@tanstack/react-router@1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': dependencies: '@babel/core': 7.28.6 '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.28.6) @@ -3256,7 +3658,7 @@ snapshots: zod: 3.25.76 optionalDependencies: '@tanstack/react-router': 1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) transitivePeerDependencies: - supports-color @@ -3288,7 +3690,7 @@ snapshots: '@tanstack/start-fn-stubs@1.151.3': {} - '@tanstack/start-plugin-core@1.153.0(@tanstack/react-router@1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.1(srvx@0.10.0))(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0))': + '@tanstack/start-plugin-core@1.153.0(@tanstack/react-router@1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.1(srvx@0.10.0))(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': dependencies: '@babel/code-frame': 7.27.1 '@babel/core': 7.28.6 @@ -3296,7 +3698,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.40 '@tanstack/router-core': 1.151.6 '@tanstack/router-generator': 1.151.6 - '@tanstack/router-plugin': 1.151.6(@tanstack/react-router@1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)) + '@tanstack/router-plugin': 1.151.6(@tanstack/react-router@1.151.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) '@tanstack/router-utils': 1.143.11 '@tanstack/start-client-core': 1.153.0 '@tanstack/start-server-core': 1.153.0(crossws@0.4.1(srvx@0.10.0)) @@ -3307,8 +3709,8 @@ snapshots: srvx: 0.10.0 tinyglobby: 0.2.15 ufo: 1.6.3 - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) - vitefu: 1.1.1(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) + vitefu: 1.1.1(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) xmlbuilder2: 4.0.3 zod: 3.25.76 transitivePeerDependencies: @@ -3409,7 +3811,7 @@ snapshots: dependencies: csstype: 3.2.3 - '@vitejs/plugin-react@5.1.2(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0))': + '@vitejs/plugin-react@5.1.2(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': dependencies: '@babel/core': 7.28.6 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.6) @@ -3417,7 +3819,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.53 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) transitivePeerDependencies: - supports-color @@ -3429,13 +3831,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0))': + '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) '@vitest/pretty-format@3.2.4': dependencies: @@ -3606,6 +4008,10 @@ snapshots: dependencies: consola: 3.4.2 + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + clsx@2.1.1: {} confbox@0.2.2: {} @@ -3678,6 +4084,8 @@ snapshots: destr@2.0.5: {} + detect-libc@2.1.2: {} + diff@8.0.3: {} dom-accessibility-api@0.5.16: {} @@ -3702,6 +4110,8 @@ snapshots: dotenv@16.6.1: {} + dotenv@17.2.3: {} + effect@3.18.4: dependencies: '@standard-schema/spec': 1.1.0 @@ -3716,6 +4126,11 @@ snapshots: iconv-lite: 0.6.3 whatwg-encoding: 3.1.1 + enhanced-resolve@5.18.4: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + entities@4.5.0: {} entities@6.0.1: {} @@ -3938,6 +4353,55 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.8.3 + lightningcss-android-arm64@1.30.2: + optional: true + + lightningcss-darwin-arm64@1.30.2: + optional: true + + lightningcss-darwin-x64@1.30.2: + optional: true + + lightningcss-freebsd-x64@1.30.2: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.2: + optional: true + + lightningcss-linux-arm64-gnu@1.30.2: + optional: true + + lightningcss-linux-arm64-musl@1.30.2: + optional: true + + lightningcss-linux-x64-gnu@1.30.2: + optional: true + + lightningcss-linux-x64-musl@1.30.2: + optional: true + + lightningcss-win32-arm64-msvc@1.30.2: + optional: true + + lightningcss-win32-x64-msvc@1.30.2: + optional: true + + lightningcss@1.30.2: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.30.2 + lightningcss-darwin-arm64: 1.30.2 + lightningcss-darwin-x64: 1.30.2 + lightningcss-freebsd-x64: 1.30.2 + lightningcss-linux-arm-gnueabihf: 1.30.2 + lightningcss-linux-arm64-gnu: 1.30.2 + lightningcss-linux-arm64-musl: 1.30.2 + lightningcss-linux-x64-gnu: 1.30.2 + lightningcss-linux-x64-musl: 1.30.2 + lightningcss-win32-arm64-msvc: 1.30.2 + lightningcss-win32-x64-msvc: 1.30.2 + lilconfig@2.1.0: {} lodash@4.17.21: {} @@ -3988,7 +4452,7 @@ snapshots: nf3@0.3.4: {} - nitro-nightly@3.0.1-20260115-135431-98fc91c5(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.4)(mysql2@3.15.3)(rollup@4.55.1)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)): + nitro-nightly@3.0.1-20260115-135431-98fc91c5(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.4)(mysql2@3.15.3)(rollup@4.55.1)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)): dependencies: consola: 3.4.2 crossws: 0.4.1(srvx@0.10.0) @@ -4006,7 +4470,7 @@ snapshots: unstorage: 2.0.0-alpha.5(chokidar@4.0.3)(db0@0.3.4(@electric-sql/pglite@0.3.2)(mysql2@3.15.3))(lru-cache@11.2.4)(ofetch@2.0.0-alpha.3) optionalDependencies: rollup: 4.55.1 - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -4324,6 +4788,12 @@ snapshots: symbol-tree@3.2.4: {} + tailwind-merge@3.4.0: {} + + tailwindcss@4.1.18: {} + + tapable@2.3.0: {} + tiny-invariant@1.3.3: {} tiny-warning@1.0.3: {} @@ -4376,6 +4846,8 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tw-animate-css@1.4.0: {} + type-fest@4.41.0: {} typescript@5.9.3: {} @@ -4418,13 +4890,13 @@ snapshots: optionalDependencies: typescript: 5.9.3 - vite-node@3.2.4(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0): + vite-node@3.2.4(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) transitivePeerDependencies: - '@types/node' - jiti @@ -4439,18 +4911,18 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@6.0.4(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)): + vite-tsconfig-paths@6.0.4(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) transitivePeerDependencies: - supports-color - typescript - vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0): + vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0): dependencies: esbuild: 0.27.2 fdir: 6.5.0(picomatch@4.0.3) @@ -4462,17 +4934,18 @@ snapshots: '@types/node': 22.19.7 fsevents: 2.3.3 jiti: 2.6.1 + lightningcss: 1.30.2 tsx: 4.21.0 - vitefu@1.1.1(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)): + vitefu@1.1.1(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)): optionalDependencies: - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) - vitest@3.2.4(@types/node@22.19.7)(jiti@2.6.1)(jsdom@27.4.0)(tsx@4.21.0): + vitest@3.2.4(@types/node@22.19.7)(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(tsx@4.21.0): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0)) + '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -4490,8 +4963,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) - vite-node: 3.2.4(@types/node@22.19.7)(jiti@2.6.1)(tsx@4.21.0) + vite: 7.3.1(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) + vite-node: 3.2.4(@types/node@22.19.7)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.19.7 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..7601e62 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,4 @@ +onlyBuiltDependencies: + - '@prisma/engines' + - esbuild + - prisma diff --git a/prisma/migrations/20260119121104_init/migration.sql b/prisma/migrations/20260119121104_init/migration.sql new file mode 100644 index 0000000..b72ad73 --- /dev/null +++ b/prisma/migrations/20260119121104_init/migration.sql @@ -0,0 +1,187 @@ +-- CreateEnum +CREATE TYPE "TeamType" AS ENUM ('MAIN', 'SECONDARY', 'CUSTOM'); + +-- CreateEnum +CREATE TYPE "ProgressionType" AS ENUM ('QUEST', 'DUNGEON', 'ACHIEVEMENT', 'DOFUS'); + +-- CreateTable +CREATE TABLE "users" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "password_hash" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "users_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "sessions" ( + "id" TEXT NOT NULL, + "user_id" TEXT NOT NULL, + "expires_at" TIMESTAMP(3) NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "sessions_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "accounts" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "user_id" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "accounts_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "characters" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "level" INTEGER NOT NULL DEFAULT 1, + "class_id" INTEGER NOT NULL, + "class_name" TEXT NOT NULL, + "server_id" INTEGER NOT NULL, + "server_name" TEXT NOT NULL, + "account_id" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "characters_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "teams" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "type" "TeamType" NOT NULL DEFAULT 'CUSTOM', + "user_id" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "teams_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "team_members" ( + "id" TEXT NOT NULL, + "team_id" TEXT NOT NULL, + "character_id" TEXT NOT NULL, + "joined_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "team_members_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "progressions" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "type" "ProgressionType" NOT NULL, + "category" TEXT NOT NULL, + "dofusdb_id" INTEGER, + + CONSTRAINT "progressions_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "character_progressions" ( + "id" TEXT NOT NULL, + "character_id" TEXT NOT NULL, + "progression_id" TEXT NOT NULL, + "completed" BOOLEAN NOT NULL DEFAULT false, + "completed_at" TIMESTAMP(3), + + CONSTRAINT "character_progressions_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "users_email_key" ON "users"("email"); + +-- CreateIndex +CREATE INDEX "sessions_user_id_idx" ON "sessions"("user_id"); + +-- CreateIndex +CREATE INDEX "sessions_expires_at_idx" ON "sessions"("expires_at"); + +-- CreateIndex +CREATE INDEX "accounts_user_id_idx" ON "accounts"("user_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "accounts_user_id_name_key" ON "accounts"("user_id", "name"); + +-- CreateIndex +CREATE INDEX "characters_account_id_idx" ON "characters"("account_id"); + +-- CreateIndex +CREATE INDEX "characters_class_id_idx" ON "characters"("class_id"); + +-- CreateIndex +CREATE INDEX "characters_server_id_idx" ON "characters"("server_id"); + +-- CreateIndex +CREATE INDEX "characters_level_idx" ON "characters"("level"); + +-- CreateIndex +CREATE UNIQUE INDEX "characters_account_id_name_key" ON "characters"("account_id", "name"); + +-- CreateIndex +CREATE INDEX "teams_user_id_idx" ON "teams"("user_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "teams_user_id_name_key" ON "teams"("user_id", "name"); + +-- CreateIndex +CREATE INDEX "team_members_team_id_idx" ON "team_members"("team_id"); + +-- CreateIndex +CREATE INDEX "team_members_character_id_idx" ON "team_members"("character_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "team_members_team_id_character_id_key" ON "team_members"("team_id", "character_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "progressions_dofusdb_id_key" ON "progressions"("dofusdb_id"); + +-- CreateIndex +CREATE INDEX "progressions_type_idx" ON "progressions"("type"); + +-- CreateIndex +CREATE INDEX "progressions_category_idx" ON "progressions"("category"); + +-- CreateIndex +CREATE INDEX "character_progressions_character_id_idx" ON "character_progressions"("character_id"); + +-- CreateIndex +CREATE INDEX "character_progressions_progression_id_idx" ON "character_progressions"("progression_id"); + +-- CreateIndex +CREATE INDEX "character_progressions_completed_idx" ON "character_progressions"("completed"); + +-- CreateIndex +CREATE UNIQUE INDEX "character_progressions_character_id_progression_id_key" ON "character_progressions"("character_id", "progression_id"); + +-- AddForeignKey +ALTER TABLE "sessions" ADD CONSTRAINT "sessions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "accounts" ADD CONSTRAINT "accounts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "characters" ADD CONSTRAINT "characters_account_id_fkey" FOREIGN KEY ("account_id") REFERENCES "accounts"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "teams" ADD CONSTRAINT "teams_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "team_members" ADD CONSTRAINT "team_members_team_id_fkey" FOREIGN KEY ("team_id") REFERENCES "teams"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "team_members" ADD CONSTRAINT "team_members_character_id_fkey" FOREIGN KEY ("character_id") REFERENCES "characters"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "character_progressions" ADD CONSTRAINT "character_progressions_character_id_fkey" FOREIGN KEY ("character_id") REFERENCES "characters"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "character_progressions" ADD CONSTRAINT "character_progressions_progression_id_fkey" FOREIGN KEY ("progression_id") REFERENCES "progressions"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..044d57c --- /dev/null +++ b/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (e.g., Git) +provider = "postgresql" diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 5408445..ba647d3 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -4,23 +4,17 @@ generator client { datasource db { provider = "postgresql" - url = env("DATABASE_URL") } -// ============================================ -// USER & AUTHENTICATION -// ============================================ - model User { id String @id @default(cuid()) email String @unique passwordHash String @map("password_hash") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") - - accounts Account[] - teams Team[] - sessions Session[] + accounts Account[] + sessions Session[] + teams Team[] @@map("users") } @@ -30,25 +24,19 @@ model Session { userId String @map("user_id") expiresAt DateTime @map("expires_at") createdAt DateTime @default(now()) @map("created_at") - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) @@index([expiresAt]) @@map("sessions") } -// ============================================ -// CORE ENTITIES -// ============================================ - model Account { - id String @id @default(cuid()) - name String - userId String @map("user_id") - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") - + id String @id @default(cuid()) + name String + userId String @map("user_id") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") user User @relation(fields: [userId], references: [id], onDelete: Cascade) characters Character[] @@ -58,20 +46,19 @@ model Account { } model Character { - id String @id @default(cuid()) - name String - level Int @default(1) - classId Int @map("class_id") - className String @map("class_name") - serverId Int @map("server_id") - serverName String @map("server_name") - accountId String @map("account_id") - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") - + id String @id @default(cuid()) + name String + level Int @default(1) + classId Int @map("class_id") + className String @map("class_name") + serverId Int @map("server_id") + serverName String @map("server_name") + accountId String @map("account_id") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + progressions CharacterProgression[] account Account @relation(fields: [accountId], references: [id], onDelete: Cascade) teamMembers TeamMember[] - progressions CharacterProgression[] @@unique([accountId, name]) @@index([accountId]) @@ -81,26 +68,15 @@ model Character { @@map("characters") } -// ============================================ -// TEAMS -// ============================================ - -enum TeamType { - MAIN - SECONDARY - CUSTOM -} - model Team { - id String @id @default(cuid()) + id String @id @default(cuid()) name String - type TeamType @default(CUSTOM) - userId String @map("user_id") - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - members TeamMember[] + type TeamType @default(CUSTOM) + userId String @map("user_id") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + members TeamMember[] + user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([userId, name]) @@index([userId]) @@ -108,13 +84,12 @@ model Team { } model TeamMember { - id String @id @default(cuid()) - teamId String @map("team_id") - characterId String @map("character_id") - joinedAt DateTime @default(now()) @map("joined_at") - - team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) - character Character @relation(fields: [characterId], references: [id], onDelete: Cascade) + id String @id @default(cuid()) + teamId String @map("team_id") + characterId String @map("character_id") + joinedAt DateTime @default(now()) @map("joined_at") + character Character @relation(fields: [characterId], references: [id], onDelete: Cascade) + team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) @@unique([teamId, characterId]) @@index([teamId]) @@ -122,24 +97,12 @@ model TeamMember { @@map("team_members") } -// ============================================ -// PROGRESSIONS -// ============================================ - -enum ProgressionType { - QUEST - DUNGEON - ACHIEVEMENT - DOFUS -} - model Progression { - id String @id @default(cuid()) - name String - type ProgressionType - category String - dofusDbId Int? @unique @map("dofusdb_id") - + id String @id @default(cuid()) + name String + type ProgressionType + category String + dofusDbId Int? @unique @map("dofusdb_id") characterProgressions CharacterProgression[] @@index([type]) @@ -148,14 +111,13 @@ model Progression { } model CharacterProgression { - id String @id @default(cuid()) - characterId String @map("character_id") - progressionId String @map("progression_id") - completed Boolean @default(false) - completedAt DateTime? @map("completed_at") - - character Character @relation(fields: [characterId], references: [id], onDelete: Cascade) - progression Progression @relation(fields: [progressionId], references: [id], onDelete: Cascade) + id String @id @default(cuid()) + characterId String @map("character_id") + progressionId String @map("progression_id") + completed Boolean @default(false) + completedAt DateTime? @map("completed_at") + character Character @relation(fields: [characterId], references: [id], onDelete: Cascade) + progression Progression @relation(fields: [progressionId], references: [id], onDelete: Cascade) @@unique([characterId, progressionId]) @@index([characterId]) @@ -163,3 +125,16 @@ model CharacterProgression { @@index([completed]) @@map("character_progressions") } + +enum TeamType { + MAIN + SECONDARY + CUSTOM +} + +enum ProgressionType { + QUEST + DUNGEON + ACHIEVEMENT + DOFUS +} diff --git a/src/app/globals.css b/src/app/globals.css index 5d3b359..58639a2 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -5,75 +5,75 @@ /* Updated to Dofus Manager dark gaming theme */ :root { - --background: #0f172a; - --foreground: #f8fafc; - --card: #1e293b; - --card-foreground: #f8fafc; - --popover: #1e293b; - --popover-foreground: #f8fafc; - --primary: #60a5fa; - --primary-foreground: #0f172a; - --secondary: #334155; - --secondary-foreground: #f8fafc; - --muted: #334155; - --muted-foreground: #94a3b8; - --accent: #334155; - --accent-foreground: #f8fafc; - --destructive: #ef4444; + --background: oklch(1 0 0); + --foreground: oklch(0.147 0.004 49.25); + --card: oklch(1 0 0); + --card-foreground: oklch(0.147 0.004 49.25); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.147 0.004 49.25); + --primary: oklch(0.216 0.006 56.043); + --primary-foreground: oklch(0.985 0.001 106.423); + --secondary: oklch(0.97 0.001 106.424); + --secondary-foreground: oklch(0.216 0.006 56.043); + --muted: oklch(0.97 0.001 106.424); + --muted-foreground: oklch(0.553 0.013 58.071); + --accent: oklch(0.97 0.001 106.424); + --accent-foreground: oklch(0.216 0.006 56.043); + --destructive: oklch(0.577 0.245 27.325); --destructive-foreground: #f8fafc; - --border: #334155; - --input: #334155; - --ring: #60a5fa; - --chart-1: #60a5fa; - --chart-2: #4ade80; - --chart-3: #f87171; - --chart-4: #fbbf24; - --chart-5: #a78bfa; - --radius: 0.5rem; - --sidebar: #1e293b; - --sidebar-foreground: #f8fafc; - --sidebar-primary: #60a5fa; - --sidebar-primary-foreground: #0f172a; - --sidebar-accent: #334155; - --sidebar-accent-foreground: #f8fafc; - --sidebar-border: #334155; - --sidebar-ring: #60a5fa; + --border: oklch(0.923 0.003 48.717); + --input: oklch(0.923 0.003 48.717); + --ring: oklch(0.709 0.01 56.259); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --radius: 0.625rem; + --sidebar: oklch(0.985 0.001 106.423); + --sidebar-foreground: oklch(0.147 0.004 49.25); + --sidebar-primary: oklch(0.216 0.006 56.043); + --sidebar-primary-foreground: oklch(0.985 0.001 106.423); + --sidebar-accent: oklch(0.97 0.001 106.424); + --sidebar-accent-foreground: oklch(0.216 0.006 56.043); + --sidebar-border: oklch(0.923 0.003 48.717); + --sidebar-ring: oklch(0.709 0.01 56.259); } /* Keep dark class same as root for dark-first approach */ .dark { - --background: #0f172a; - --foreground: #f8fafc; - --card: #1e293b; - --card-foreground: #f8fafc; - --popover: #1e293b; - --popover-foreground: #f8fafc; - --primary: #60a5fa; - --primary-foreground: #0f172a; - --secondary: #334155; - --secondary-foreground: #f8fafc; - --muted: #334155; - --muted-foreground: #94a3b8; - --accent: #334155; - --accent-foreground: #f8fafc; - --destructive: #ef4444; + --background: oklch(0.147 0.004 49.25); + --foreground: oklch(0.985 0.001 106.423); + --card: oklch(0.216 0.006 56.043); + --card-foreground: oklch(0.985 0.001 106.423); + --popover: oklch(0.216 0.006 56.043); + --popover-foreground: oklch(0.985 0.001 106.423); + --primary: oklch(0.923 0.003 48.717); + --primary-foreground: oklch(0.216 0.006 56.043); + --secondary: oklch(0.268 0.007 34.298); + --secondary-foreground: oklch(0.985 0.001 106.423); + --muted: oklch(0.268 0.007 34.298); + --muted-foreground: oklch(0.709 0.01 56.259); + --accent: oklch(0.268 0.007 34.298); + --accent-foreground: oklch(0.985 0.001 106.423); + --destructive: oklch(0.704 0.191 22.216); --destructive-foreground: #f8fafc; - --border: #334155; - --input: #334155; - --ring: #60a5fa; - --chart-1: #60a5fa; - --chart-2: #4ade80; - --chart-3: #f87171; - --chart-4: #fbbf24; - --chart-5: #a78bfa; - --sidebar: #1e293b; - --sidebar-foreground: #f8fafc; - --sidebar-primary: #60a5fa; - --sidebar-primary-foreground: #0f172a; - --sidebar-accent: #334155; - --sidebar-accent-foreground: #f8fafc; - --sidebar-border: #334155; - --sidebar-ring: #60a5fa; + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.553 0.013 58.071); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.216 0.006 56.043); + --sidebar-foreground: oklch(0.985 0.001 106.423); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0.001 106.423); + --sidebar-accent: oklch(0.268 0.007 34.298); + --sidebar-accent-foreground: oklch(0.985 0.001 106.423); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.553 0.013 58.071); } @theme inline { @@ -115,6 +115,9 @@ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); --color-sidebar-ring: var(--sidebar-ring); + --radius-2xl: calc(var(--radius) + 8px); + --radius-3xl: calc(var(--radius) + 12px); + --radius-4xl: calc(var(--radius) + 16px); } @layer base { diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx new file mode 100644 index 0000000..37a7d4b --- /dev/null +++ b/src/components/ui/button.tsx @@ -0,0 +1,62 @@ +import * as React from "react" +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 gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2 has-[>svg]:px-3", + sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", + icon: "size-9", + "icon-sm": "size-8", + "icon-lg": "size-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +function Button({ + className, + variant = "default", + size = "default", + asChild = false, + ...props +}: React.ComponentProps<"button"> & + VariantProps & { + asChild?: boolean + }) { + const Comp = asChild ? Slot : "button" + + return ( + + ) +} + +export { Button, buttonVariants } diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx new file mode 100644 index 0000000..681ad98 --- /dev/null +++ b/src/components/ui/card.tsx @@ -0,0 +1,92 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +function Card({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardTitle({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardDescription({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardAction({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardContent({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +export { + Card, + CardHeader, + CardFooter, + CardTitle, + CardAction, + CardDescription, + CardContent, +} diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx new file mode 100644 index 0000000..8916905 --- /dev/null +++ b/src/components/ui/input.tsx @@ -0,0 +1,21 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +function Input({ className, type, ...props }: React.ComponentProps<"input">) { + return ( + + ) +} + +export { Input } diff --git a/src/components/ui/table.tsx b/src/components/ui/table.tsx new file mode 100644 index 0000000..5513a5c --- /dev/null +++ b/src/components/ui/table.tsx @@ -0,0 +1,114 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +function Table({ className, ...props }: React.ComponentProps<"table">) { + return ( +
+ + + ) +} + +function TableHeader({ className, ...props }: React.ComponentProps<"thead">) { + return ( + + ) +} + +function TableBody({ className, ...props }: React.ComponentProps<"tbody">) { + return ( + + ) +} + +function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) { + return ( + tr]:last:border-b-0", + className + )} + {...props} + /> + ) +} + +function TableRow({ className, ...props }: React.ComponentProps<"tr">) { + return ( + + ) +} + +function TableHead({ className, ...props }: React.ComponentProps<"th">) { + return ( +
[role=checkbox]]:translate-y-[2px]", + className + )} + {...props} + /> + ) +} + +function TableCell({ className, ...props }: React.ComponentProps<"td">) { + return ( + [role=checkbox]]:translate-y-[2px]", + className + )} + {...props} + /> + ) +} + +function TableCaption({ + className, + ...props +}: React.ComponentProps<"caption">) { + return ( +
+ ) +} + +export { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +} diff --git a/src/lib/server/db.ts b/src/lib/server/db.ts index e69de29..64e0259 100644 --- a/src/lib/server/db.ts +++ b/src/lib/server/db.ts @@ -0,0 +1,18 @@ +import { PrismaClient } from "@prisma/client"; + +const globalForPrisma = globalThis as unknown as { + prisma: PrismaClient | undefined; +}; + +export const prisma = + globalForPrisma.prisma ?? + new PrismaClient({ + log: + process.env.NODE_ENV === "development" + ? ["query", "error", "warn"] + : ["error"], + }); + +if (process.env.NODE_ENV !== "production") { + globalForPrisma.prisma = prisma; +} diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..bd0c391 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +}