135 lines
4.7 KiB
TypeScript
135 lines
4.7 KiB
TypeScript
"use client";
|
||
|
||
import { useState, useEffect } from "react";
|
||
import { CheckCircle, Circle } from '@/lib/icons';
|
||
import { cn } from "@/lib/utils";
|
||
import { ACADEMY_MODULES } from "@/lib/academy/tours";
|
||
import { getCompletedModules, resetProgress } from "@/lib/academy/progress";
|
||
import { AcademyTourButton } from "./academy-tour-button";
|
||
import { Button } from "@/components/ui/button";
|
||
|
||
export function AcademyClient() {
|
||
const [completed, setCompleted] = useState<string[]>([]);
|
||
|
||
useEffect(() => {
|
||
setCompleted(getCompletedModules());
|
||
}, []);
|
||
|
||
function handleComplete() {
|
||
setCompleted(getCompletedModules());
|
||
}
|
||
|
||
function handleReset() {
|
||
resetProgress();
|
||
setCompleted([]);
|
||
}
|
||
|
||
const percent = Math.round((completed.length / ACADEMY_MODULES.length) * 100);
|
||
const allDone = completed.length === ACADEMY_MODULES.length;
|
||
|
||
return (
|
||
<div className="space-y-6">
|
||
{/* Progress header */}
|
||
<div className="bg-card border rounded-xl p-5 space-y-3">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<p className="font-semibold text-sm">Genel İlerleme</p>
|
||
<p className="text-muted-foreground text-xs mt-0.5">
|
||
{completed.length} / {ACADEMY_MODULES.length} modül tamamlandı
|
||
</p>
|
||
</div>
|
||
<span className={cn(
|
||
"text-2xl font-bold",
|
||
allDone ? "text-green-600" : "text-primary"
|
||
)}>
|
||
%{percent}
|
||
</span>
|
||
</div>
|
||
{/* Progress bar */}
|
||
<div className="h-2 bg-muted rounded-full overflow-hidden">
|
||
<div
|
||
className={cn(
|
||
"h-full rounded-full transition-all duration-500",
|
||
allDone ? "bg-green-500" : "bg-primary"
|
||
)}
|
||
style={{ width: `${percent}%` }}
|
||
/>
|
||
</div>
|
||
{allDone && (
|
||
<p className="text-green-600 text-sm font-medium">
|
||
🎉 Tüm modülleri tamamladınız! Artık KovakEmlak CRM'i tam verimle kullanabilirsiniz.
|
||
</p>
|
||
)}
|
||
</div>
|
||
|
||
{/* Module grid */}
|
||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
||
{ACADEMY_MODULES.map((mod) => {
|
||
const isDone = completed.includes(mod.id);
|
||
return (
|
||
<div
|
||
key={mod.id}
|
||
className={cn(
|
||
"bg-card border rounded-xl p-5 flex flex-col gap-3 transition-colors",
|
||
isDone && "border-green-200 bg-green-50/40 dark:bg-green-950/20 dark:border-green-900"
|
||
)}
|
||
>
|
||
<div className="flex items-start justify-between gap-2">
|
||
<div className="flex items-center gap-2.5">
|
||
<span className="text-2xl">{mod.icon}</span>
|
||
<div>
|
||
<p className="font-semibold text-sm leading-tight">{mod.title}</p>
|
||
<p className="text-muted-foreground text-xs mt-0.5">
|
||
{mod.steps.length} adım
|
||
</p>
|
||
</div>
|
||
</div>
|
||
{isDone ? (
|
||
<CheckCircle className="size-5 text-green-500 shrink-0 mt-0.5" />
|
||
) : (
|
||
<Circle className="size-5 text-muted-foreground/40 shrink-0 mt-0.5" />
|
||
)}
|
||
</div>
|
||
|
||
<p className="text-muted-foreground text-xs leading-relaxed flex-1">
|
||
{mod.description}
|
||
</p>
|
||
|
||
{/* Step previews */}
|
||
<div className="space-y-1">
|
||
{mod.steps.slice(0, 3).map((step, i) => (
|
||
<div key={i} className="flex items-center gap-2 text-xs text-muted-foreground">
|
||
<span className={cn(
|
||
"size-4 rounded-full flex items-center justify-center text-[10px] font-medium shrink-0",
|
||
isDone
|
||
? "bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300"
|
||
: "bg-muted text-muted-foreground"
|
||
)}>
|
||
{i + 1}
|
||
</span>
|
||
<span className="truncate">{step.title}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
<AcademyTourButton
|
||
module={mod}
|
||
onComplete={handleComplete}
|
||
variant={isDone ? "ghost" : "outline"}
|
||
/>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
{completed.length > 0 && (
|
||
<div className="flex justify-end">
|
||
<Button variant="ghost" size="sm" onClick={handleReset} className="text-muted-foreground text-xs">
|
||
İlerlemeyi sıfırla
|
||
</Button>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|