diff --git a/package.json b/package.json index c1e6bdbf..8484817c 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "argon2": "^0.43.1", "bcrypt": "^6.0.0", "better-auth": "1.6.11", + "canvas-confetti": "^1.9.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", @@ -116,6 +117,7 @@ "@release-it/bumper": "^7.0.5", "@release-it/conventional-changelog": "^10.0.6", "@tailwindcss/postcss": "^4.3.0", + "@types/canvas-confetti": "^1.9.0", "@types/eslint-plugin-tailwindcss": "^3.17.0", "@types/node": "^22.19.19", "@types/node-forge": "^1.3.14", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9990dc29..0cd5ad8b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -146,6 +146,9 @@ importers: better-auth: specifier: 1.6.11 version: 1.6.11(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.17)(pg@8.21.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.3(@babel/core@7.29.7)(@playwright/test@1.58.2)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(pg@8.21.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + canvas-confetti: + specifier: ^1.9.4 + version: 1.9.4 class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -306,6 +309,9 @@ importers: '@tailwindcss/postcss': specifier: ^4.3.0 version: 4.3.0 + '@types/canvas-confetti': + specifier: ^1.9.0 + version: 1.9.0 '@types/eslint-plugin-tailwindcss': specifier: ^3.17.0 version: 3.17.0 @@ -3807,6 +3813,9 @@ packages: '@tybys/wasm-util@0.10.2': resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + '@types/canvas-confetti@1.9.0': + resolution: {integrity: sha512-aBGj/dULrimR1XDZLtG9JwxX1b4HPRF6CX9Yfwh3NvstZEm1ZL7RBnel4keCPSqs1ANRu1u2Aoz9R+VmtjYuTg==} + '@types/cors@2.8.19': resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} @@ -4610,6 +4619,9 @@ packages: caniuse-lite@1.0.30001797: resolution: {integrity: sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==} + canvas-confetti@1.9.4: + resolution: {integrity: sha512-yxQbJkAVrFXWNbTUjPqjF7G+g6pDotOUHGbkZq2NELZUMDpiJ85rIEazVb8GTaAptNW2miJAXbs1BtioA251Pw==} + capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} @@ -11695,6 +11707,8 @@ snapshots: tslib: 2.8.1 optional: true + '@types/canvas-confetti@1.9.0': {} + '@types/cors@2.8.19': dependencies: '@types/node': 22.19.20 @@ -12643,6 +12657,8 @@ snapshots: caniuse-lite@1.0.30001797: {} + canvas-confetti@1.9.4: {} + capital-case@1.0.4: dependencies: no-case: 3.0.4 diff --git a/src/features/onboarding/steps/step-finish.tsx b/src/features/onboarding/steps/step-finish.tsx new file mode 100644 index 00000000..426568a1 --- /dev/null +++ b/src/features/onboarding/steps/step-finish.tsx @@ -0,0 +1,29 @@ +"use client"; + +import { useEffect, useRef } from "react"; +import { useRouter } from "next/navigation"; +import confetti from "canvas-confetti"; +import { CheckCircle2 } from "lucide-react"; +import { Button } from "@/components/ui/button"; + +export const StepFinish = () => { + const router = useRouter(); + const fired = useRef(false); + + useEffect(() => { + if (fired.current) return; + fired.current = true; + confetti({ particleCount: 150, spread: 80, origin: { y: 0.6 } }); + }, []); + + return ( +
Your workspace is ready to use.
+ +