102 lines
4.6 KiB
TypeScript
102 lines
4.6 KiB
TypeScript
'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>
|
||
)
|
||
}
|