TIFNGK_E41222719/src/components/dashboards/AnalysisClient.tsx

181 lines
6.0 KiB
TypeScript

"use client";
import { useAnalyseText } from "@/src/hooks/useAnalyzeText";
import { Sparkles, X } from "lucide-react";
import { Input } from "../ui/input";
import { Button } from "../ui/button";
import ResultSection from "./ResultSection";
export default function AnalysisClient() {
const {
isValid,
errors,
loading,
result,
resultRef,
progress,
visibleFields,
urlDatas,
register,
handleSubmit,
onSubmit,
handleCancel,
setVisibleFields,
} = useAnalyseText();
const urlInput = () => {
return urlDatas.slice(0, visibleFields).map((item, index) => (
<div
key={index}
className="animate-in fade-in slide-in-from-bottom-2 duration-300"
>
<label className="block mb-1 text-sm font-medium text-gray-700">
{item.labels}
</label>
<div className="flex gap-2">
<div className="flex-1">
<Input
type="url"
placeholder="Contoh: https://tokopedia.com/..."
className={`${item.errors ? "border-sentiment-negative" : "focus:ring-primary"}`}
{...item.title}
/>
</div>
{index === visibleFields - 1 && (
<Button
type="button"
variant="ghost"
onClick={() => setVisibleFields((prev) => prev - 1)}
className="text-sentiment-negative hover:text-sentiment-negative hover:bg-sentiment-negative-light shrink-0"
>
</Button>
)}
</div>
</div>
));
};
return (
<div className="w-full mx-auto">
<form
onSubmit={handleSubmit(onSubmit)}
className="bg-white p-6 rounded-lg border mb-8"
>
<div className="mb-4 flex items-center gap-2">
<Sparkles className="h-5 w-5 text-primary" />
<h3 className="text-lg font-semibold">Analisis Sentimen Real-time</h3>
</div>
<div className="flex flex-col gap-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="w-full">
<label className="block mb-1 text-sm font-medium text-gray-700">
Tautan Produk 1
</label>
<Input
type="url"
placeholder="Contoh: https://tokopedia.com/..."
className={`${errors.url1 ? "border-sentiment-negative" : "focus:ring-primary"}`}
{...register("url1")}
/>
{errors.url1 && (
<p className="text-sentiment-negative text-xs mt-1">
{errors.url1.message}
</p>
)}
</div>
<div className="w-full">
<label className="block mb-1 text-sm font-medium text-gray-700">
Tautan Produk 2
</label>
<Input
type="url"
placeholder="Contoh: https://tokopedia.com/..."
className={`w-full ${errors.url2 ? "border-sentiment-negative" : "focus:ring-primary"}`}
{...register("url2")}
/>
{errors.url2 && (
<p className="text-sentiment-negative text-xs mt-1">
{errors.url2.message}
</p>
)}
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 items-end transition-all duration-500">
{urlInput()}
{visibleFields < 2 && (
<div
className={`
transition-all duration-500 ease-in-out
${visibleFields === 0 ? "col-span-1 md:col-span-2 flex justify-center" : "col-span-1"}
`}
>
<Button
type="button"
onClick={() => setVisibleFields((prev) => prev + 1)}
className={`
h-max bg-card text-primary hover:bg-[#F8FBFF]
border-dashed border border-primary/20 shadow-xs
transition-all duration-500 animate-in fade-in zoom-in-95
${visibleFields === 0 ? "w-full md:w-1/2" : "w-full"}
`}
>
{visibleFields === 0
? "+ Tambah Tautan Produk"
: "+ Tambah Tautan Produk Lainnya"}
</Button>
</div>
)}
</div>
</div>
{loading && (
<div className="mt-4 bg-transparent">
<div className="flex justify-between mb-2">
<span className="text-sm font-medium">{progress.status}</span>
<span className="text-sm font-medium">{progress.percent}%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2.5">
<div
className="bg-primary h-2.5 rounded-full transition-all duration-500"
style={{ width: `${progress.percent}%` }}
></div>
</div>
</div>
)}
<div className="flex gap-2">
{loading && (
<Button
type="button"
variant="destructive"
onClick={handleCancel}
className="w-full bg-sentiment-negative text-white md:w-max px-6 py-3 mt-6 rounded-md transition-colors disabled:bg-gray-400"
>
<X className="h-4 w-4" />
<span>Cancel</span>
</Button>
)}
<Button
type="submit"
hidden={loading}
disabled={!isValid}
className="w-full md:w-max bg-primary text-white px-6 py-3 mt-6 rounded-md transition-colors disabled:bg-gray-400"
>
<Sparkles className="h-4 w-4" />
{loading ? "Menganalisis..." : "Analisis Sekarang"}
</Button>
</div>
</form>
<div ref={resultRef} id="result-section" className="scroll-mt-28">
{result && <ResultSection result={result} />}
</div>
</div>
);
}