refactor(frontend): integrate ABSA payload and remove profession selection logic

This commit is contained in:
Mahen 2026-03-02 10:06:20 +07:00
parent 637d45a1bd
commit 125c18a000
4 changed files with 140 additions and 50 deletions

View File

@ -14,17 +14,11 @@ import z from "zod";
// "OTHER", // "OTHER",
// ]); // ]);
const professionEnum = z.enum([ // cony
"PROGRAMMER",
"STUDENT",
"GAMER",
"DESIGNER",
"OTHER",
]);
export const analyzeSchema = z.object({ export const analyzeSchema = z.object({
profession: professionEnum, // profession: professionEnum,
// brands: brandEnum, // brands: brandEnum,
url1: z.string().min(10, "Tautan 1 minimal 10 karakter"), url1: z.string().min(10, "Tautan 1 minimal 10 karakter"),
url2: z.string().min(10, "Tautan 2 minimal 10 karakter"), url2: z.string().min(10, "Tautan 2 minimal 10 karakter"),
url3: z.string().optional().or(z.literal("")), url3: z.string().optional().or(z.literal("")),

View File

@ -36,29 +36,66 @@ export const useAnalyseText = () => {
}, },
}); });
useEffect(() => { // useEffect(() => {
const fetchProfession = async () => { // const fetchProfession = async () => {
try { // try {
const user = await getAnotherUserData(); // const user = await getAnotherUserData();
const userProfession = // const userProfession =
user?.preference?.profession || user?.preference?.profession; // user?.preference?.profession || user?.preference?.profession;
if (userProfession) { // if (userProfession) {
setValue("profession", userProfession, { // setValue("profession", userProfession, {
shouldValidate: true, // shouldValidate: true,
shouldDirty: true, // shouldDirty: true,
}); // });
} // }
} catch (error) { // } catch (error) {
console.error("Gagal mengambil data profesi user:", error); // console.error("Gagal mengambil data profesi user:", error);
} // }
}; // };
if (session?.user) { // if (session?.user) {
fetchProfession(); // fetchProfession();
} // }
}, [session, setValue]); // }, [session, setValue]);
// const onSubmit = async (data: AnalyzeFormData) => {
// if (!session?.user?.email) {
// alert("Anda harus login terlebih dahulu.");
// return;
// }
// setLoading(true);
// setResult(null);
// try {
// const urlsToScrape = [data.url1, data.url2, data.url3].filter(
// (url) => url && url.trim() !== "",
// ) as string[];
// const scrapePromises = urlsToScrape.map((url) => scrapeProduct(url));
// const scrapeResults = await Promise.all(scrapePromises);
// const candidates = scrapeResults.map((res) => ({
// name: res.data.name,
// url: res.data.url,
// reviews: res.data.reviews,
// }));
// const aiResult = await getAIRecommendation({
// user_email: session.user.email,
// // profession: data.profession,
// candidates,
// });
// setResult(aiResult);
// } catch (error: any) {
// alert("Terjadi kesalahan: " + error.message);
// } finally {
// setLoading(false);
// }
// };
const onSubmit = async (data: AnalyzeFormData) => { const onSubmit = async (data: AnalyzeFormData) => {
if (!session?.user?.email) { if (!session?.user?.email) {
@ -85,13 +122,21 @@ export const useAnalyseText = () => {
const aiResult = await getAIRecommendation({ const aiResult = await getAIRecommendation({
user_email: session.user.email, user_email: session.user.email,
profession: data.profession, candidates: candidates,
candidates,
}); });
setResult(aiResult); setResult(aiResult);
setTimeout(() => {
document
.getElementById("analysis-result")
?.scrollIntoView({ behavior: "smooth" });
}, 100);
} catch (error: any) { } catch (error: any) {
alert("Terjadi kesalahan: " + error.message); console.error("Analysis Error:", error);
alert(
"Terjadi kesalahan: " + (error.message || "Gagal menganalisis ulasan."),
);
} finally { } finally {
setLoading(false); setLoading(false);
} }

View File

@ -1,4 +1,5 @@
import prisma from "@/lib/prisma"; import prisma from "@/lib/prisma";
import { AIRecommendationResponse } from "../types";
export const scrapeProduct = async (url: string) => { export const scrapeProduct = async (url: string) => {
const res = await fetch("/api/scrape", { const res = await fetch("/api/scrape", {
@ -18,24 +19,23 @@ export const scrapeProduct = async (url: string) => {
return data; return data;
}; };
export const getAIRecommendation = async (payload: { // export const getAIRecommendation = async (payload: {
user_email: string; // user_email: string;
profession: string; // // profession: string;
candidates: { name: string; url: string; reviews: any[] }[]; // candidates: { name: string; url: string; reviews: any[] }[];
}) => { // }) => {
const aiRes = await fetch("http://localhost:8000/recommend", { // const aiRes = await fetch("http://localhost:8000/recommend", {
method: "POST", // method: "POST",
headers: { "Content-Type": "application/json" }, // headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload), // body: JSON.stringify(payload),
}); // });
if (!aiRes.ok) throw new Error("Gagal melakukan analisis AI"); // if (!aiRes.ok) throw new Error("Gagal melakukan analisis AI");
return await aiRes.json(); // return await aiRes.json();
}; // };
export const getAnalysisData = async (email: string) => { export const getAnalysisData = async (email: string) => {
const userAnalyses = await prisma.analysis.findMany({ const userAnalyses = await prisma.analysis.findMany({
where: { where: {
user: { user: {
@ -64,3 +64,21 @@ export const getAnalysisData = async (email: string) => {
}); });
return userAnalyses; return userAnalyses;
}; };
export const getAIRecommendation = async (payload: {
user_email: string;
candidates: { name: string; url: string; reviews: string[] }[];
}): Promise<AIRecommendationResponse> => {
const aiRes = await fetch("http://localhost:8000/recommend", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
if (!aiRes.ok) {
const errorData = await aiRes.json();
throw new Error(errorData.detail || "Gagal melakukan analisis AI");
}
return await aiRes.json();
};

View File

@ -198,10 +198,43 @@ export interface ProductDetail {
top_keywords: string[]; top_keywords: string[];
} }
export interface AnalysisResults { // export interface AnalysisResults {
profession_target: string; // // profession_target: string;
// winning_product: string;
// details: ProductDetail[];
// }
export interface AspectScores {
performa: number;
layar: number;
baterai: number;
harga: number;
}
export interface ProductAnalysisResult {
name: string;
url: string;
general_score: number;
aspect_scores: AspectScores;
verdict: string;
description: string;
total_reviews: number;
positive_count: number;
negative_count: number;
}
export interface AIRecommendationResponse {
user_email: string;
analysis_type: string;
winning_product: string; winning_product: string;
details: ProductDetail[]; details: ProductAnalysisResult[];
}
export interface AnalysisResults {
user_email: string;
analysis_type: string;
winning_product: string;
details: ProductAnalysisResult[];
} }
export interface ResultProps { export interface ResultProps {