-
-
- Rekomendasi Terbaik
-
+ {result && (
+
+
+
+
+ Rekomendasi Terbaik Berdasarkan Analisis
+
+
+ {result.winning_product}
+
+
+
+
+ {result.analysis_type.replace(/_/g, " ")}
+
+
-
- {result.winning_product}
-
-
-
- Pilihan paling tepat dan efisien untuk kebutuhan{" "}
-
- {result.profession_target}
-
-
+
+
+
+
-
-
-
- {result.details.map((item, index) => {
- const isWinner = item.name === result.winning_product;
-
- return (
-
- {isWinner && (
-
-
-
- Pemenang
-
-
- )}
-
-
-
-
-
-
-
-
-
- Kecocokan
-
-
- {item.profession_compatibility_score}%
-
-
-
-
-
-
-
-
-
-
-
- Sentimen
-
-
- {item.general_sentiment_score}% Positif
-
-
-
-
-
-
-
-
-
-
- Kata Kunci
-
-
- {item.top_keywords.map((kw, i) => (
-
- #{kw}
-
- ))}
-
-
-
-
- );
- })}
-
+ )}
);
}
diff --git a/src/hooks/useResultDetails.ts b/src/hooks/useResultDetails.ts
new file mode 100644
index 0000000..91146b4
--- /dev/null
+++ b/src/hooks/useResultDetails.ts
@@ -0,0 +1,24 @@
+import { useState } from "react";
+import { ResultProps } from "../types";
+
+export const useResultDetails = ({ result }: ResultProps) => {
+ const [activeProductIndex, setActiveProductIndex] = useState(0);
+
+ if (!result || !result.details || result.details.length === 0) return null;
+
+ const totalProducts = result.details.length;
+
+ const nextProduct = () => {
+ if (activeProductIndex < totalProducts - 1) {
+ setActiveProductIndex((prev) => prev + 1);
+ }
+ };
+
+ const prevProduct = () => {
+ if (activeProductIndex > 0) {
+ setActiveProductIndex((prev) => prev - 1);
+ }
+ };
+
+ return { activeProductIndex, totalProducts, nextProduct, prevProduct };
+};
diff --git a/src/types/index.ts b/src/types/index.ts
index b71755b..aaffe1d 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -323,3 +323,7 @@ export interface VisiblePageProps {
totalPages: number;
currentPage: number;
}
+
+export interface RadarProps {
+ data: any[];
+}
diff --git a/src/utils/datas.ts b/src/utils/datas.ts
index 0dbaf8d..97cf905 100644
--- a/src/utils/datas.ts
+++ b/src/utils/datas.ts
@@ -1,5 +1,6 @@
import { useReviewTable } from "../hooks/useReviewTable";
import {
+ RadarProps,
ScrapeResult,
VisiblePageProps,
WordCloudConfig,
@@ -114,3 +115,30 @@ export const getGridClass = (count: number) => {
if (count === 2) return "grid-cols-1 md:grid-cols-2";
return "grid-cols-1 md:grid-cols-2 lg:grid-cols-3";
};
+
+export const getHighlights = (aspectScores: Record
) => {
+ const entries = Object.entries(aspectScores);
+ if (entries.length === 0)
+ return { strongest: ["N/A", 0], weakest: ["N/A", 0] };
+
+ const strongest = entries.reduce((a, b) => (a[1] > b[1] ? a : b));
+ const weakest = entries.reduce((a, b) => (a[1] < b[1] ? a : b));
+
+ return { strongest, weakest };
+};
+
+export const radarFormat = ({ data }: RadarProps) => {
+ const subjects = ["performa", "layar", "baterai", "harga"];
+
+ const chartData = subjects.map((subject) => {
+ const entry: any = { subject: subject.toUpperCase() };
+ data.forEach((product) => {
+ entry[product.name] = product.aspect_scores[subject];
+ });
+ return entry;
+ });
+
+ const colors = ["#8884d8", "#82ca9d", "#ffc658", "#ff7300"];
+
+ return { chartData, colors };
+};