TIFNGK_E41222719/src/components/dashboards/DashboardClient.tsx

165 lines
5.1 KiB
TypeScript

"use client";
import { Header } from "./Header";
import {
ChartNoAxesGantt,
FileLock,
Frown,
Meh,
MessageSquareText,
Smile,
Sparkles,
TrendingUp,
} from "lucide-react";
import { StatCard } from "./StatCard";
import { ModelInfoSkeleton } from "../skeletons/ModelInfoSkeleton";
import { ModelInfo } from "./ModelInfo";
import { BrandFilter } from "./BrandFilter";
import { ReviewTable } from "./ReviewTable";
import { useDashboards } from "@/src/hooks/useDashboard";
import { WordCloud } from "./WordCloud";
import AnalysisClient from "./AnalysisClient";
import Footer from "./Footer";
import { Button } from "../ui/button";
export default function DashboardClient() {
const {
totalReviews,
positiveCount,
negativeCount,
neutralCount,
loading,
modelData,
percentage,
scrollToResult,
} = useDashboards();
return (
<div className="min-h-screen bg-[#F8FBFF]" suppressHydrationWarning>
<Header />
<main className="container mx-auto px-4 py-8">
<div
className="mb-8 rounded-2xl p-8 text-center"
style={{ background: "hsl(var(--primary))" }}
>
<h2 className="mb-2 text-3xl font-bold text-white md:text-4xl">
Analisis Sentimen Ulasan Laptop
</h2>
<p className="mx-auto max-w-2xl text-lg text-white/80">
Sistem klasifikasi sentimen menggunakan algoritma XGBoost untuk
menganalisis ulasan produk laptop pada platform Tokopedia
</p>
<div className="flex items-center justify-center gap-4 text-sm text-white/70">
<Button
onClick={scrollToResult}
className="bg-[#F8FBFF] cursor-pointer hover:bg-card hover:text-primary text-black mt-4"
>
<Sparkles className="h-5 w-5" />
<span>Coba Analisis Sentimen</span>
</Button>
</div>
</div>
<div className="mb-8 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
<StatCard
title="Total Ulasan"
value={totalReviews}
icon={MessageSquareText}
trend={{ value: 12.5, isPositive: true }}
delay={0}
/>
<StatCard
title="Sentimen Positif"
value={positiveCount}
suffix={`(${percentage(positiveCount, totalReviews)}%)`}
icon={Smile}
variant="positive"
delay={100}
/>
<StatCard
title="Sentimen Negatif"
value={negativeCount}
suffix={`(${percentage(negativeCount, totalReviews)}%)`}
icon={Frown}
variant="negative"
delay={200}
/>
<StatCard
title="Sentimen Netral"
value={neutralCount}
suffix={`(${percentage(neutralCount, totalReviews)}%)`}
icon={Meh}
variant="neutral"
delay={300}
/>
</div>
{/* <div className="mb-8 grid gap-6 lg:grid-cols-3">
<div className="rounded-xl border bg-card p-6 lg:col-span-2">
<h3 className="mb-4 text-lg font-semibold">
Tren Sentimen Bulanan
</h3>
<TrendChart data={trendData} />
</div>
<div className="rounded-xl border bg-card p-6">
<h3 className="mb-4 text-lg font-semibold">Distribusi Sentimen</h3>
<SentimentChart data={sentimentDistribution} />
</div>
</div> */}
<div className="mb-8 grid gap-4 lg:grid-cols-2">
<div className="rounded-xl border bg-card p-6">
<div className="flex items-center gap-2 mb-2">
<FileLock className="h-5 w-5 text-primary" />
<h3 className="text-lg font-semibold">Kata Kunci Populer</h3>
</div>
<p className="mb-4 text-sm text-muted-foreground">
Kata-kata yang sering muncul dalam ulasan berdasarkan kategori
sentimen
</p>
<WordCloud />
</div>
{loading ? (
<ModelInfoSkeleton />
) : modelData.length > 0 ? (
<ModelInfo data={modelData} />
) : (
<div className="rounded-xl border bg-card p-6 text-center text-muted-foreground">
Data model tidak tersedia.
</div>
)}
</div>
<section id="analysis-form" className="scroll-mt-60">
<div className="mb-8 ">
<AnalysisClient />
</div>
</section>
<div className="space-y-6">
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<div>
<div className="flex items-center gap-2 mb-2">
<ChartNoAxesGantt className="w-5 h-5" />
<h3 className="text-lg font-semibold">Ulasan Terbaru</h3>
</div>
<p className="text-sm text-muted-foreground">
Hasil klasifikasi sentimen ulasan produk laptop
</p>
</div>
<BrandFilter />
</div>
<ReviewTable />
</div>
<Footer />
</main>
</div>
);
}