265 lines
7.4 KiB
TypeScript
265 lines
7.4 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { z } from "zod";
|
|
import { useForm, Controller } from "react-hook-form";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
|
|
import { createSurveyData, getSurveyById } from "@/service/survey/survey";
|
|
|
|
import { Checkbox } from "@/components/ui/checkbox";
|
|
import { Textarea } from "@/components/ui/textarea";
|
|
import { Button } from "@/components/ui/button";
|
|
import { useParams } from "next/navigation";
|
|
|
|
const surveySchema = z.object({
|
|
accessFrequency: z.string(),
|
|
uiExperienceDesign: z.string(),
|
|
uiExperienceNavigation: z.string(),
|
|
uiExperienceSpeed: z.string(),
|
|
infoAccuracy: z.string(),
|
|
infoCompleteness: z.string(),
|
|
usefulness: z.string(),
|
|
suggestion: z.string().optional(),
|
|
});
|
|
|
|
type SurveySchema = z.infer<typeof surveySchema>;
|
|
|
|
export default function FormSurveyDetailPage() {
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [loadingSurvey, setLoadingSurvey] = useState(true);
|
|
const [detail, setDetail] = useState<any>();
|
|
const { id } = useParams() as { id: string };
|
|
|
|
const {
|
|
control,
|
|
handleSubmit,
|
|
setValue,
|
|
formState: { errors },
|
|
} = useForm<SurveySchema>({
|
|
resolver: zodResolver(surveySchema),
|
|
defaultValues: {
|
|
accessFrequency: "",
|
|
uiExperienceDesign: "",
|
|
uiExperienceNavigation: "",
|
|
uiExperienceSpeed: "",
|
|
infoAccuracy: "",
|
|
infoCompleteness: "",
|
|
usefulness: "",
|
|
suggestion: "",
|
|
},
|
|
});
|
|
|
|
const options = {
|
|
accessFrequency: [
|
|
"Setiap hari",
|
|
"Beberapa kali seminggu",
|
|
"Beberapa kali dalam sebulan",
|
|
"Baru pertama kali",
|
|
],
|
|
uiExperienceDesign: ["Sangat baik", "Baik", "Cukup", "Kurang", "Buruk"],
|
|
uiExperienceNavigation: [
|
|
"Sangat mudah",
|
|
"Mudah",
|
|
"Cukup",
|
|
"Sulit",
|
|
"Sangat sulit",
|
|
],
|
|
uiExperienceSpeed: [
|
|
"Sangat cepat",
|
|
"Cepat",
|
|
"Cukup",
|
|
"Lambat",
|
|
"Sangat lambat",
|
|
],
|
|
infoAccuracy: ["Sangat puas", "Puas", "Cukup", "Kurang puas", "Tidak puas"],
|
|
infoCompleteness: [
|
|
"Sangat lengkap",
|
|
"Lengkap",
|
|
"Cukup",
|
|
"Kurang lengkap",
|
|
"Tidak lengkap",
|
|
],
|
|
usefulness: [
|
|
"Sangat membantu",
|
|
"Membantu",
|
|
"Cukup membantu",
|
|
"Kurang membantu",
|
|
"Tidak membantu",
|
|
],
|
|
};
|
|
|
|
const renderControllerGroup = (
|
|
name: keyof SurveySchema,
|
|
question: string,
|
|
choices: string[]
|
|
) => (
|
|
<div className="space-y-2">
|
|
<p className="font-medium">{question}</p>
|
|
<div className="grid grid-cols-2 gap-2">
|
|
{choices.map((choice, i) => (
|
|
<Controller
|
|
key={i}
|
|
name={name}
|
|
control={control}
|
|
render={({ field }) => (
|
|
<label className="flex items-center space-x-2">
|
|
<Checkbox
|
|
checked={field.value === choice}
|
|
onCheckedChange={() => field.onChange(choice)}
|
|
/>
|
|
<span>{choice}</span>
|
|
</label>
|
|
)}
|
|
/>
|
|
))}
|
|
</div>
|
|
{errors[name] && (
|
|
<p className="text-red-500 text-sm">
|
|
{errors[name]?.message as string}
|
|
</p>
|
|
)}
|
|
</div>
|
|
);
|
|
|
|
const onSubmit = async (data: SurveySchema) => {
|
|
setIsLoading(true);
|
|
try {
|
|
const response = await createSurveyData(data);
|
|
console.log("Survey submitted:", response);
|
|
} catch (error) {
|
|
console.error("Failed to submit survey:", error);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
const fetchSurvey = async () => {
|
|
if (id) {
|
|
setLoadingSurvey(true);
|
|
try {
|
|
const response = await getSurveyById(id);
|
|
const details = response?.data?.data;
|
|
|
|
setDetail(details);
|
|
|
|
// Set value dari data detail ke form
|
|
if (details) {
|
|
setValue("accessFrequency", details.accessFrequency || "");
|
|
setValue("uiExperienceDesign", details.uiExperienceDesign || "");
|
|
setValue(
|
|
"uiExperienceNavigation",
|
|
details.uiExperienceNavigation || ""
|
|
);
|
|
setValue("uiExperienceSpeed", details.uiExperienceSpeed || "");
|
|
setValue("infoAccuracy", details.infoAccuracy || "");
|
|
setValue("infoCompleteness", details.infoCompleteness || "");
|
|
setValue("usefulness", details.usefulness || "");
|
|
setValue("suggestion", details.suggestion || "");
|
|
}
|
|
} catch (error) {
|
|
console.error("Failed to fetch survey detail:", error);
|
|
} finally {
|
|
setLoadingSurvey(false);
|
|
}
|
|
}
|
|
};
|
|
|
|
fetchSurvey();
|
|
}, [id, setValue]);
|
|
|
|
if (loadingSurvey) {
|
|
return <div className="p-6">Loading survey data...</div>;
|
|
}
|
|
|
|
return (
|
|
<div className="w-full mx-auto p-6">
|
|
<h1 className="text-2xl font-bold mb-2">
|
|
SURVEI KEPUASAN PENGGUNA MEDIAHUB POLRI
|
|
</h1>
|
|
<p className="text-sm mb-6 text-gray-600">
|
|
Kami menghargai pendapat Anda! Survei ini bertujuan untuk meningkatkan
|
|
kualitas layanan MediaHub Polri.
|
|
</p>
|
|
|
|
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
|
|
{renderControllerGroup(
|
|
"accessFrequency",
|
|
"1. Seberapa sering Anda mengakses MediaHub Polri?",
|
|
options.accessFrequency
|
|
)}
|
|
|
|
<div>
|
|
<p className="font-medium">
|
|
2. Bagaimana pengalaman Anda dalam mengakses website ini?
|
|
</p>
|
|
<div className="space-y-3 mt-2">
|
|
{renderControllerGroup(
|
|
"uiExperienceDesign",
|
|
"a) Tampilan dan desain website",
|
|
options.uiExperienceDesign
|
|
)}
|
|
{renderControllerGroup(
|
|
"uiExperienceNavigation",
|
|
"b) Kemudahan navigasi",
|
|
options.uiExperienceNavigation
|
|
)}
|
|
{renderControllerGroup(
|
|
"uiExperienceSpeed",
|
|
"c) Kecepatan akses website",
|
|
options.uiExperienceSpeed
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<p className="font-medium">
|
|
3. Seberapa puas Anda dengan informasi yang tersedia di MediaHub
|
|
Polri?
|
|
</p>
|
|
<div className="space-y-3 mt-2">
|
|
{renderControllerGroup(
|
|
"infoAccuracy",
|
|
"a) Akurat dan terpercaya",
|
|
options.infoAccuracy
|
|
)}
|
|
{renderControllerGroup(
|
|
"infoCompleteness",
|
|
"b) Kelengkapan berita dan informasi",
|
|
options.infoCompleteness
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{renderControllerGroup(
|
|
"usefulness",
|
|
"4. Apakah Anda merasa website ini membantu dalam mendapatkan informasi terkait Polri?",
|
|
options.usefulness
|
|
)}
|
|
|
|
<div>
|
|
<p className="font-medium">5. Apa saran atau masukan Anda?</p>
|
|
<Controller
|
|
name="suggestion"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<Textarea
|
|
placeholder="Tulis pesan Anda..."
|
|
value={field.value}
|
|
onChange={field.onChange}
|
|
/>
|
|
)}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex justify-end gap-2">
|
|
<Button type="submit" disabled={isLoading}>
|
|
{isLoading ? "Mengirim..." : "Kirim"}
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|