style: customize not found badge component

This commit is contained in:
Mahen 2026-02-21 10:21:28 +07:00
parent f8bd5a15d6
commit c2c5d433ce
4 changed files with 45 additions and 21 deletions

View File

@ -1,7 +1,15 @@
"use client";
import { Header } from "./Header";
import { Frown, Meh, MessageSquareText, Smile, TrendingUp } from "lucide-react";
import {
ChartNoAxesGantt,
FileLock,
Frown,
Meh,
MessageSquareText,
Smile,
TrendingUp,
} from "lucide-react";
import { StatCard } from "./StatCard";
import { ModelInfoSkeleton } from "../skeletons/ModelInfoSkeleton";
import { ModelInfo } from "./ModelInfo";
@ -103,7 +111,10 @@ export default function DashboardClient() {
<div className="mb-8 grid gap-6 lg:grid-cols-2">
<div className="rounded-xl border bg-card p-6">
<h3 className="mb-4 text-lg font-semibold">Kata Kunci Populer</h3>
<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
@ -129,7 +140,10 @@ export default function DashboardClient() {
<div className="space-y-6">
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<div>
<h3 className="text-lg font-semibold">Ulasan Terbaru</h3>
<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>

View File

@ -65,7 +65,7 @@ export function ReviewTable() {
<TableRow>
<TableCell colSpan={5} className="h-75 text-center">
<div className="flex flex-col items-center justify-center gap-2 text-muted-foreground">
<div className="rounded-full bg-muted p-4">
<div className="rounded-full bg-muted">
<Inbox className="h-8 w-8" />
</div>
<p className="text-lg font-medium text-foreground">

View File

@ -2,28 +2,36 @@
import { useWordCloud } from "@/src/hooks/useWordCloud";
import WordCloudItem from "./WordCloudItem";
import { Inbox } from "lucide-react";
export function WordCloud() {
const mounted = true;
const { maxValue, minValue, shuffledWords } = useWordCloud();
if (!mounted) {
return (
<div className="flex flex-wrap items-center justify-center gap-2 p-4 min-h-37.5" />
);
}
const { maxValue, minValue, shuffledWords, isEmpty } = useWordCloud();
return (
<div className="flex flex-wrap items-center justify-center gap-2 p-4">
{shuffledWords.map((word, index) => (
<WordCloudItem
key={`${word.text}-${index}`}
word={word}
index={index}
maxValue={maxValue}
minValue={minValue}
/>
))}
{isEmpty ? (
<div className="flex flex-col gap-2 items-center py-22 text-muted-foreground">
<div className="rounded-full bg-muted">
<Inbox className="h-8 w-8" />
</div>
<p className="text-lg font-medium text-foreground">Belum ada data</p>
<p className="text-sm text-center">
Belum ada kata kunci yang dianalisis oleh sistem.
</p>
</div>
) : (
<>
{shuffledWords.map((word, index) => (
<WordCloudItem
key={`${word.text}-${index}`}
word={word}
index={index}
maxValue={maxValue}
minValue={minValue}
/>
))}
</>
)}
</div>
);
}

View File

@ -6,6 +6,7 @@ export const useWordCloud = () => {
const [words, setWords] = useState<WordItem[]>([]);
const [shuffledWords, setShuffledWords] = useState<WordItem[]>([]);
const [ready, setReady] = useState(false);
const isEmpty = shuffledWords.length === 0;
useEffect(() => {
const fetchWords = async () => {
@ -105,5 +106,6 @@ export const useWordCloud = () => {
minValue,
shuffledWords,
ready,
isEmpty,
};
};