Files
AOS/src/components/aos/onboarding-checklist.tsx
T

102 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import { useAos } from '@/store/aos'
import { Card, CardContent } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Progress } from '@/components/ui/progress'
import { Check, ChevronRight, Rocket } from 'lucide-react'
import { cn } from '@/lib/utils'
import { useI18n } from '@/hooks/use-i18n'
const CHECKLIST_ITEMS = [
{ key: 'visit_leads', view: 'leads', label_de: 'Leads Finder erkunden', label_en: 'Explore Leads Finder', label_tr: 'Leads Finder keşfet' },
{ key: 'visit_projects', view: 'projects', label_de: 'Projekte ansehen', label_en: 'View Projects', label_tr: 'Projeleri görüntüle' },
{ key: 'visit_finance', view: 'finance', label_de: 'Rechnungen prüfen', label_en: 'Check Invoices', label_tr: 'Faturaları kontrol et' },
{ key: 'visit_accounting', view: 'accounting', label_de: 'Buchhaltung (UStVA) ansehen', label_en: 'View Accounting (VAT)', label_tr: 'Muhasebeyi (KDV) görüntüle' },
{ key: 'visit_api', view: 'api', label_de: 'API-Token erstellen', label_en: 'Create API Token', label_tr: 'API Token oluştur' },
{ key: 'visit_portal', view: 'dashboard', label_de: 'Client-Portal öffnen', label_en: 'Open Client Portal', label_tr: 'Müşteri Portalını aç' },
] as const
export function OnboardingChecklist() {
const { checklist, toggleChecklist, setView, setPortalMode } = useAos()
const { locale } = useI18n()
const completed = CHECKLIST_ITEMS.filter((item) => checklist[item.key]).length
const total = CHECKLIST_ITEMS.length
const pct = Math.round((completed / total) * 100)
const allDone = completed === total
const label = (item: typeof CHECKLIST_ITEMS[number]) => {
if (locale === 'en') return item.label_en
if (locale === 'tr') return item.label_tr
return item.label_de
}
const go = (item: typeof CHECKLIST_ITEMS[number]) => {
if (item.view === 'dashboard' && item.key === 'visit_portal') {
setPortalMode(true)
} else {
setView(item.view as 'leads' | 'projects' | 'finance' | 'accounting' | 'api' | 'dashboard')
}
if (!checklist[item.key]) toggleChecklist(item.key)
}
if (allDone) {
return (
<Card className="border-foreground/30 bg-foreground/5">
<CardContent className="flex items-center gap-3 p-4">
<div className="flex size-10 items-center justify-center rounded-full bg-foreground text-background">
<Check className="size-5" />
</div>
<div className="flex-1">
<p className="text-sm font-semibold">Onboarding abgeschlossen!</p>
<p className="text-xs text-muted-foreground">Du kennst nun alle Kernfunktionen. Bei Fragen sieh im Handbuch (Wissensdatenbank) nach.</p>
</div>
<Button variant="ghost" size="sm" onClick={() => setView('kb')}>Zum Handbuch</Button>
</CardContent>
</Card>
)
}
return (
<Card>
<CardContent className="p-4">
<div className="mb-3 flex items-center justify-between">
<div className="flex items-center gap-2">
<Rocket className="size-4 text-muted-foreground" />
<span className="text-sm font-semibold">Onboarding-Checkliste</span>
<Badge variant="outline" className="text-[10px]">{completed}/{total}</Badge>
</div>
<span className="text-xs text-muted-foreground">{pct}%</span>
</div>
<Progress value={pct} className="mb-3 h-1.5" />
<div className="grid grid-cols-1 gap-1.5 sm:grid-cols-2 lg:grid-cols-3">
{CHECKLIST_ITEMS.map((item) => {
const done = checklist[item.key]
return (
<button
key={item.key}
onClick={() => go(item)}
className={cn(
'flex items-center gap-2 rounded-md border p-2 text-left transition hover:bg-muted/50',
done ? 'border-foreground/30 bg-foreground/5' : 'border-border'
)}
>
<div className={cn(
'flex size-5 shrink-0 items-center justify-center rounded border',
done ? 'border-foreground bg-foreground text-background' : 'border-muted-foreground/40'
)}>
{done && <Check className="size-3" />}
</div>
<span className={cn('flex-1 text-xs', done && 'text-muted-foreground line-through')}>{label(item)}</span>
{!done && <ChevronRight className="size-3 shrink-0 text-muted-foreground" />}
</button>
)
})}
</div>
</CardContent>
</Card>
)
}