style: fix URL input visibility handling
This commit is contained in:
parent
7cc79f31c3
commit
225b3e842e
|
|
@ -9,19 +9,50 @@ import ResultSection from "./ResultSection";
|
||||||
export default function AnalysisClient() {
|
export default function AnalysisClient() {
|
||||||
const {
|
const {
|
||||||
errors,
|
errors,
|
||||||
isValid,
|
|
||||||
loading,
|
loading,
|
||||||
result,
|
result,
|
||||||
showField,
|
|
||||||
resultRef,
|
resultRef,
|
||||||
progress,
|
progress,
|
||||||
|
visibleFields,
|
||||||
|
urlDatas,
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
setShowField,
|
|
||||||
handleCancel,
|
handleCancel,
|
||||||
|
setVisibleFields,
|
||||||
} = useAnalyseText();
|
} = 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>
|
||||||
|
<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 (
|
return (
|
||||||
<div className="w-full mx-auto">
|
<div className="w-full mx-auto">
|
||||||
<form
|
<form
|
||||||
|
|
@ -35,44 +66,6 @@ export default function AnalysisClient() {
|
||||||
|
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 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">
|
|
||||||
Pilih Profesi
|
|
||||||
</label>
|
|
||||||
<Controller
|
|
||||||
name="profession"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<Select onValueChange={field.onChange} value={field.value}>
|
|
||||||
<SelectTrigger
|
|
||||||
className={`w-full ${errors.profession ? "border-sentiment-negative" : ""}`}
|
|
||||||
>
|
|
||||||
<SelectValue placeholder="Pilih Profesi" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent className="bg-card" position="popper">
|
|
||||||
{professionItems.map((item) => (
|
|
||||||
<SelectItem
|
|
||||||
key={item.value}
|
|
||||||
value={item.value}
|
|
||||||
className="focus:bg-primary focus:text-card"
|
|
||||||
>
|
|
||||||
<div className="flex gap-2 items-center">
|
|
||||||
<item.icon className="h-4 w-4" />
|
|
||||||
<span>{item.label}</span>
|
|
||||||
</div>
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{errors.profession && (
|
|
||||||
<p className="text-sentiment-negative text-xs mt-1">
|
|
||||||
{errors.profession.message}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<label className="block mb-1 text-sm font-medium text-gray-700">
|
<label className="block mb-1 text-sm font-medium text-gray-700">
|
||||||
Tautan Produk 1
|
Tautan Produk 1
|
||||||
|
|
@ -89,6 +82,7 @@ export default function AnalysisClient() {
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<label className="block mb-1 text-sm font-medium text-gray-700">
|
<label className="block mb-1 text-sm font-medium text-gray-700">
|
||||||
Tautan Produk 2
|
Tautan Produk 2
|
||||||
|
|
@ -107,64 +101,19 @@ export default function AnalysisClient() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 items-end">
|
||||||
<div className="w-full">
|
{urlInput()}
|
||||||
<label className="block mb-1 text-sm font-medium text-gray-700">
|
{visibleFields < 2 && (
|
||||||
Tautan Produk 3
|
<Button
|
||||||
</label>
|
type="button"
|
||||||
<Input
|
onClick={() => setVisibleFields((prev) => prev + 1)}
|
||||||
type="url"
|
className="h-max bg-card text-primary hover:bg-[#F8FBFF] border-dashed border border-primary/20 transition-all shadow-xs"
|
||||||
placeholder="Contoh: https://tokopedia.com/..."
|
>
|
||||||
className={`w-full ${errors.url3 ? "border-sentiment-negative" : "focus:ring-primary"}`}
|
{visibleFields === 0
|
||||||
{...register("url3")}
|
? "+ Tambah Tautan Produk"
|
||||||
/>
|
: "+ Tambah Tautan Produk Lainnya"}
|
||||||
{errors.url3 && (
|
</Button>
|
||||||
<p className="text-sentiment-negative text-xs mt-1">
|
)}
|
||||||
{errors.url3.message}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="w-full flex flex-col justify-end">
|
|
||||||
{showField ? (
|
|
||||||
<div className="animate-in fade-in slide-in-from-bottom-2 duration-300">
|
|
||||||
<label className="block mb-1 text-sm font-medium text-gray-700">
|
|
||||||
Tautan Produk 4
|
|
||||||
</label>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<div className="flex-1">
|
|
||||||
<Input
|
|
||||||
type="url"
|
|
||||||
placeholder="Contoh: https://tokopedia.com/..."
|
|
||||||
className={`${errors.url4 ? "border-sentiment-negative" : "focus:ring-primary"}`}
|
|
||||||
{...register("url4")}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
variant="ghost"
|
|
||||||
onClick={() => setShowField(false)}
|
|
||||||
className="text-sentiment-negative hover:text-sentiment-negative hover:bg-sentiment-negative-light shrink-0"
|
|
||||||
>
|
|
||||||
✕
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
{errors.url4 && (
|
|
||||||
<p className="text-sentiment-negative text-xs mt-1">
|
|
||||||
{errors.url4.message}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
onClick={() => setShowField(true)}
|
|
||||||
className="w-full h-max bg-card text-primary hover:bg-[#F8FBFF] border-dashed border border-primary/20 transition-all shadow-xs"
|
|
||||||
>
|
|
||||||
+ Tambah Tautan Produk Lainnya
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,10 @@ export const useAnalyseText = () => {
|
||||||
const { data: session } = useSession();
|
const { data: session } = useSession();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [result, setResult] = useState<AnalysisResults | null>(null);
|
const [result, setResult] = useState<AnalysisResults | null>(null);
|
||||||
const [showField, setShowField] = useState(false);
|
|
||||||
const resultRef = useRef<HTMLDivElement>(null);
|
const resultRef = useRef<HTMLDivElement>(null);
|
||||||
const [progress, setProgress] = useState({ status: "", percent: 0 });
|
const [progress, setProgress] = useState({ status: "", percent: 0 });
|
||||||
const abortControllerRef = useRef<AbortController | null>(null);
|
const abortControllerRef = useRef<AbortController | null>(null);
|
||||||
|
const [visibleFields, setVisibleFields] = useState(0);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
|
|
@ -208,20 +208,36 @@ export const useAnalyseText = () => {
|
||||||
}
|
}
|
||||||
}, [loading, result]);
|
}, [loading, result]);
|
||||||
|
|
||||||
|
const urlDatas = [
|
||||||
|
{
|
||||||
|
labels: "Tautan Produk 3",
|
||||||
|
errors: errors.url3,
|
||||||
|
title: { ...register("url3") },
|
||||||
|
type: "url3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
labels: "Tautan Produk 4",
|
||||||
|
errors: errors.url4,
|
||||||
|
title: { ...register("url4") },
|
||||||
|
type: "url4",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
control,
|
control,
|
||||||
errors,
|
errors,
|
||||||
isValid,
|
isValid,
|
||||||
loading,
|
loading,
|
||||||
result,
|
result,
|
||||||
showField,
|
visibleFields,
|
||||||
resultRef,
|
resultRef,
|
||||||
progress,
|
progress,
|
||||||
|
urlDatas,
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
setValue,
|
setValue,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
setShowField,
|
setVisibleFields,
|
||||||
handleCancel,
|
handleCancel,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {
|
||||||
import { SiAcer, SiAsus, SiLenovo, SiLinux, SiMacos } from "react-icons/si";
|
import { SiAcer, SiAsus, SiLenovo, SiLinux, SiMacos } from "react-icons/si";
|
||||||
import { FaWindows } from "react-icons/fa";
|
import { FaWindows } from "react-icons/fa";
|
||||||
import { Sentiment } from "@prisma/client";
|
import { Sentiment } from "@prisma/client";
|
||||||
|
import { useAnalyseText } from "../hooks/useAnalyzeText";
|
||||||
|
|
||||||
export const MODEL_OPTIONS = [
|
export const MODEL_OPTIONS = [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue