diff --git a/.cursorignore b/.cursorignore new file mode 100644 index 0000000..8aa44f0 --- /dev/null +++ b/.cursorignore @@ -0,0 +1,38 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist/ +build/ +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +.env +.env.local +.env.*.local +.env* +.env.* +.env.production +.env.development + +# Backup files +*copy* +*.bak diff --git a/package-lock.json b/package-lock.json index 662b065..edf6ee8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,12 +13,14 @@ "@radix-ui/react-accordion": "^1.2.2", "@radix-ui/react-dialog": "^1.1.4", "@radix-ui/react-tabs": "^1.1.2", + "@radix-ui/react-toast": "^1.2.4", "@supabase/supabase-js": "^2.39.7", "@tanstack/react-query": "^5.62.8", "@testing-library/react": "^16.1.0", "@types/ioredis": "^4.28.10", "@types/jest": "^29.5.14", "@types/next": "^8.0.7", + "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "ioredis": "^5.4.2", "lucide-react": "^0.344.0", @@ -30,7 +32,7 @@ "recharts": "^2.15.0", "resend": "^3.2.0", "shadcn-ui": "^0.9.4", - "tailwind-merge": "^2.5.5", + "tailwind-merge": "^2.6.0", "uuid": "^11.0.3", "vitest": "^2.1.8" }, @@ -2199,6 +2201,40 @@ } } }, + "node_modules/@radix-ui/react-toast": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.4.tgz", + "integrity": "sha512-Sch9idFJHJTMH9YNpxxESqABcAFweJG4tKv+0zo0m5XBvUSL8FM5xKcJLFLXononpePs8IclyX1KieL5SDUNgA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", @@ -2265,6 +2301,29 @@ } } }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.1.tgz", + "integrity": "sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@react-email/render": { "version": "0.0.16", "resolved": "https://registry.npmjs.org/@react-email/render/-/render-0.0.16.tgz", @@ -4091,6 +4150,18 @@ "node": ">=8" } }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -8422,9 +8493,9 @@ } }, "node_modules/tailwind-merge": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.5.tgz", - "integrity": "sha512-0LXunzzAZzo0tEPxV3I297ffKZPlKDrjj7NXphC8V5ak9yHC5zRmxnOe2m/Rd/7ivsOMJe3JZ2JVocoDdQTRBA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", + "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", "license": "MIT", "funding": { "type": "github", diff --git a/package.json b/package.json index 1364ef7..564e8e3 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,14 @@ "@radix-ui/react-accordion": "^1.2.2", "@radix-ui/react-dialog": "^1.1.4", "@radix-ui/react-tabs": "^1.1.2", + "@radix-ui/react-toast": "^1.2.4", "@supabase/supabase-js": "^2.39.7", "@tanstack/react-query": "^5.62.8", "@testing-library/react": "^16.1.0", "@types/ioredis": "^4.28.10", "@types/jest": "^29.5.14", "@types/next": "^8.0.7", + "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "ioredis": "^5.4.2", "lucide-react": "^0.344.0", @@ -37,7 +39,7 @@ "recharts": "^2.15.0", "resend": "^3.2.0", "shadcn-ui": "^0.9.4", - "tailwind-merge": "^2.5.5", + "tailwind-merge": "^2.6.0", "uuid": "^11.0.3", "vitest": "^2.1.8" }, diff --git a/src/App.tsx b/src/App.tsx index 12a37e7..9c72211 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,6 +11,7 @@ import { User, Theme } from './types'; import { AuthProvider } from './contexts/AuthContext' import { useNavigate } from 'react-router-dom'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { Toaster } from './components/ui/toaster'; type AppStep = | 'welcome' @@ -122,6 +123,7 @@ export function App() { onStorySelect={handleStorySelect} /> )} + diff --git a/tailwind.config.js b/tailwind.config.js index 99761a2..85a04f7 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -6,6 +6,45 @@ export default { fontFamily: { sans: ['Inter', 'sans-serif'], }, + animation: { + 'in': 'in 200ms ease-in', + 'out': 'out 200ms ease-out', + 'slide-in-from-top': 'slide-in-from-top 200ms ease-out', + 'slide-in-from-bottom': 'slide-in-from-bottom 200ms ease-out', + 'slide-out-to-right': 'slide-out-to-right 200ms ease-out', + 'fade-in': 'fade-in 200ms ease-in', + 'fade-out': 'fade-out 200ms ease-out', + }, + keyframes: { + in: { + '0%': { transform: 'translateX(100%)' }, + '100%': { transform: 'translateX(0)' }, + }, + out: { + '0%': { transform: 'translateX(0)' }, + '100%': { transform: 'translateX(100%)' }, + }, + 'slide-in-from-top': { + '0%': { transform: 'translateY(-100%)' }, + '100%': { transform: 'translateY(0)' }, + }, + 'slide-in-from-bottom': { + '0%': { transform: 'translateY(100%)' }, + '100%': { transform: 'translateY(0)' }, + }, + 'slide-out-to-right': { + '0%': { transform: 'translateX(0)' }, + '100%': { transform: 'translateX(100%)' }, + }, + 'fade-in': { + '0%': { opacity: 0 }, + '100%': { opacity: 1 }, + }, + 'fade-out': { + '0%': { opacity: 1 }, + '100%': { opacity: 0 }, + }, + }, }, }, plugins: [],