OnboardingPozoAppv1/src/components/SetupCompleteScreen.tsx

168 lines
7.3 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { Check, Store, Receipt, Sparkles } from 'lucide-react';
import { OnboardingState, BUSINESS_TYPES } from '../types';
interface SetupCompleteProps {
onContinue: () => void;
state: OnboardingState;
}
interface ConfettiPart {
id: number;
left: string;
size: string;
delay: string;
duration: string;
color: string;
shape: string;
}
export default function SetupCompleteScreen({ onContinue, state }: SetupCompleteProps) {
const [confetti, setConfetti] = useState<ConfettiPart[]>([]);
useEffect(() => {
// Generate simulated paper confetti arrays on mount
const colors = ['#af101a', '#54a0fe', '#298030', '#ffb3ac', '#ffdad6', '#a5c8ff', '#82db7e'];
const shapes = ['circle', 'square', 'triangle'];
const items = Array.from({ length: 45 }).map((_, i) => ({
id: i,
left: `${Math.random() * 100}vw`,
size: `${Math.random() * 8 + 6}px`,
delay: `${Math.random() * 3}s`,
duration: `${Math.random() * 2.5 + 2.5}s`,
color: colors[Math.floor(Math.random() * colors.length)],
shape: shapes[Math.floor(Math.random() * shapes.length)]
}));
setConfetti(items);
}, []);
const getBusinessTypeName = (typeId: string) => {
const matched = BUSINESS_TYPES.find(b => b.id === typeId);
if (matched) return matched.name;
return 'Retail / Grocery';
};
const businessTitle = state.businessName || 'Sharma General Store';
const typeDisplay = state.businessType ? getBusinessTypeName(state.businessType) : 'Retail / Grocery';
return (
<div className="flex-1 flex flex-col h-full bg-background relative overflow-hidden select-none bg-pattern animate-fade-in-up">
{/* Dynamic Cascading Confetti Layers */}
<div className="absolute inset-0 pointer-events-none z-0 overflow-hidden opacity-85">
{confetti.map((c) => (
<div
key={c.id}
className="absolute"
style={{
left: c.left,
top: '-20px',
width: c.size,
height: c.size,
backgroundColor: c.color,
borderRadius: c.shape === 'circle' ? '50%' : c.shape === 'triangle' ? '0 50% 50% 100%' : '2px',
animationName: 'fall',
animationDuration: c.duration,
animationDelay: c.delay,
animationTimingFunction: 'linear',
animationIterationCount: 'infinite',
transform: `rotate(${Math.random() * 350}deg)`
}}
/>
))}
</div>
{/* Embedded falling animation style injection */}
<style>{`
@keyframes fall {
0% {
transform: translateY(-20px) rotate(0deg);
opacity: 1;
}
90% {
opacity: 0.9;
}
100% {
transform: translateY(105vh) rotate(360deg);
opacity: 0;
}
}
`}</style>
{/* Top micro progress indicator (Completely active 100% completed) */}
<div className="w-full h-1.5 bg-primary relative z-10 transition-all duration-300"></div>
<div className="px-margin-page py-2.5 bg-slate-100 border-b border-surface-container-high/40 flex items-center justify-between text-[11px] font-sans font-bold text-on-surface-variant z-10">
<span>Step 5 of 5 Completed</span>
<span className="text-emerald-700 italic font-display flex items-center gap-1">
<Sparkles className="w-3 h-3 text-emerald-600 shrink-0" />
Onboarding Done
</span>
</div>
{/* Main Stream centered scroll wrapper */}
<main className="flex-grow w-full max-w-md mx-auto flex flex-col items-center justify-center px-margin-page pt-4 pb-32 relative z-10 overflow-y-auto no-scrollbar">
{/* Rounded double rings success check icon bubble */}
<div className="w-24 h-24 rounded-full bg-surface-container-lowest border-4 border-white shadow-[0_8px_24px_rgba(0,0,0,0.085)] flex items-center justify-center mb-6 animate-pop-in relative">
<div className="w-18 h-18 rounded-full bg-emerald-500 flex items-center justify-center animate-pulse">
<Check className="w-9 h-9 text-white stroke-[4]" />
</div>
{/* Echo ping ring */}
<div className="absolute inset-x-0 inset-y-0 border-2 border-emerald-500 rounded-full animate-ping opacity-25"></div>
</div>
{/* Celebrating message */}
<div className="text-center space-y-2.5 mb-8">
<h1 className="font-display font-extrabold text-[24px] sm:text-[27px] text-on-surface tracking-tight">
Setup Complete! 🎉
</h1>
<p className="font-sans text-[13px] sm:text-[14px] text-on-surface-variant leading-relaxed max-w-[270px] mx-auto">
Your billing dashboard is ready for action.
</p>
</div>
{/* Dynamic Glassmorphic Recap Card */}
<div className="w-full bg-white/90 backdrop-blur-md rounded-2xl p-5 sm:p-6 shadow-[0_4px_22px_rgba(0,0,0,0.06)] border border-surface-container-highest/85 flex flex-col gap-4 text-left transition-all duration-300 transform hover:translate-y-[-2px]">
{/* Section Row 1: Business name */}
<div className="flex items-start gap-4">
<div className="w-11 h-11 rounded-full bg-slate-100 flex items-center justify-center shrink-0">
<Store className="w-5.5 h-5.5 text-on-surface-variant stroke-[1.8]" />
</div>
<div className="space-y-0.5">
<p className="font-sans text-[10px] font-bold text-on-surface-variant/80 uppercase tracking-widest">Business Name</p>
<h4 className="font-display font-extrabold text-base sm:text-lg text-on-surface tracking-tight line-clamp-1">{businessTitle}</h4>
</div>
</div>
{/* Dividing border */}
<div className="h-[1px] bg-slate-100 w-full" />
{/* Section Row 2: Category */}
<div className="flex items-start gap-4">
<div className="w-11 h-11 rounded-full bg-slate-100 flex items-center justify-center shrink-0">
<span className="material-symbols-outlined text-on-surface-variant text-xl" style={{ fontVariationSettings: "'FILL' 0" }}>category</span>
</div>
<div className="space-y-0.5">
<p className="font-sans text-[10px] font-bold text-on-surface-variant/80 uppercase tracking-widest">Business Type</p>
<p className="font-sans font-bold text-sm sm:text-[15px] text-on-surface-variant">{typeDisplay}</p>
</div>
</div>
</div>
</main>
{/* Pinned Bottom final launcher button */}
<div className="absolute bottom-0 left-0 w-full bg-white border-t border-surface-container-high shadow-[0_-4px_16px_rgba(0,0,0,0.05)] px-margin-page pt-4 pb-6 z-30">
<div className="max-w-md mx-auto">
<button
onClick={onContinue}
className="w-full h-[54px] bg-primary hover:bg-primary-container text-white font-display font-bold text-base rounded-2xl shadow-[0_4px_16px_rgba(175,16,26,0.3)] flex items-center justify-center gap-2 transition-all active:scale-[0.98]"
id="btn-complete-create-bill"
>
<Receipt className="w-5 h-5" strokeWidth={2.3} />
<span>Create Your First Bill</span>
</button>
</div>
</div>
</div>
);
}