mediahub-fe/components/landing-page/survey-box.tsx

291 lines
8.8 KiB
TypeScript

import React, { useEffect, useState } from "react";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../ui/dialog";
import FormSurvey from "./survey";
import { Controller, useForm } from "react-hook-form";
import { Textarea } from "../ui/textarea";
import { Button } from "../ui/button";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { Checkbox } from "../ui/checkbox";
import { createSurveyData } from "@/service/survey/survey";
import { useTranslations } from "next-intl";
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>;
const UserSurveyBox = () => {
const [openPolda, setOpenPolda] = useState<any>();
const [showSurvey, setShowSurvey] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const t = useTranslations("LandingPage");
const {
control,
handleSubmit,
formState: { errors },
} = useForm<SurveySchema>({
resolver: zodResolver(surveySchema),
mode: "all",
defaultValues: {
accessFrequency: "",
uiExperienceDesign: "",
uiExperienceNavigation: "",
uiExperienceSpeed: "",
infoAccuracy: "",
infoCompleteness: "",
usefulness: "",
suggestion: "",
},
});
const options = {
accessFrequency: [t("everyDay"), t("week"), t("month"), t("firstTime")],
uiExperienceDesign: [
t("veryGood"),
t("good"),
t("enough"),
t("notEnough"),
t("bad"),
],
uiExperienceNavigation: [
t("veryEasy"),
t("easy"),
t("enough"),
t("difficult"),
t("veryDifficult"),
],
uiExperienceSpeed: [
t("veryFast"),
t("fast"),
t("enough"),
t("slow"),
t("verySlow"),
],
infoAccuracy: [
t("verySatisfied"),
t("satisfied"),
t("enough"),
t("lessSatisfied"),
t("notSatisfied"),
],
infoCompleteness: [
t("veryComplete"),
t("completely"),
t("enough"),
t("incomplete"),
t("notComplete"),
],
usefulness: [
t("veryHelpful"),
t("helping"),
t("quiteHelpful"),
t("lessHelpful"),
t("notHelpful"),
],
};
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("API Response:", response);
setShowSurvey(false);
setOpenPolda(false);
} catch (error) {
console.error("Error submitting survey:", error);
} finally {
setIsLoading(false);
}
};
return (
<div className="relative mt-8 rounded-lg bg-white dark:bg-zinc-900 p-6 shadow overflow-hidden">
{/* Garis menyerong */}
<div className="hidden lg:block absolute right-64 top-0">
<img src="/assets/line1.png" alt="line" className="" />
</div>
<div className="hidden lg:block absolute right-60 top-0">
<img src="/assets/line1.png" alt="line" className="" />
</div>
<div className="hidden lg:block absolute right-56 top-0">
<img src="/assets/line1.png" alt="line" className="" />
</div>
{/* Grid konten */}
<div className="relative z-10 grid grid-cols-1 md:grid-cols-2 gap-4 items-center">
{/* Kiri: Teks dan tombol */}
<div>
<h2 className="text-2xl font-bold mb-2">{t("survey1", { defaultValue: "Survey1" })}</h2>
<p className="text-sm text-gray-700 dark:text-gray-300 mb-6">
{t("survey2", { defaultValue: "Survey2" })}
</p>
<Dialog open={openPolda} onOpenChange={setOpenPolda}>
<DialogTrigger asChild>
<Button
size="md"
onClick={() => setOpenPolda(true)}
className="bg-[#bb3523] hover:bg-[#9e2e1e] text-white font-bold px-6 py-3 rounded shadow-md transition-all duration-300"
>
{t("survey3", { defaultValue: "Survey3" })}
</Button>
</DialogTrigger>
<DialogContent
size="md"
className="max-h-[90vh] overflow-auto flex flex-col"
data-lenis-prevent
>
<DialogHeader>
<DialogTitle className="text-lg font-bold">
{t("survey4", { defaultValue: "Survey4" })}
</DialogTitle>
<DialogDescription className="text-sm">
{t("survey5", { defaultValue: "Survey5" })}
</DialogDescription>
</DialogHeader>
<form
onSubmit={handleSubmit(onSubmit)}
className="space-y-6 mt-4"
>
{renderControllerGroup(
"accessFrequency",
t("survey6", { defaultValue: "Survey6" }),
options.accessFrequency
)}
<div>
<p className="font-medium">{t("survey7", { defaultValue: "Survey7" })}</p>
<div className="space-y-3 mt-2">
{renderControllerGroup(
"uiExperienceDesign",
t("websiteDesign"),
options.uiExperienceDesign
)}
{renderControllerGroup(
"uiExperienceNavigation",
t("easeNavigation"),
options.uiExperienceNavigation
)}
{renderControllerGroup(
"uiExperienceSpeed",
t("speed"),
options.uiExperienceSpeed
)}
</div>
</div>
<div>
<p className="font-medium">{t("survey8", { defaultValue: "Survey8" })}</p>
<div className="space-y-3 mt-2">
{renderControllerGroup(
"infoAccuracy",
t("accurate"),
options.infoAccuracy
)}
{renderControllerGroup(
"infoCompleteness",
t("complete"),
options.infoCompleteness
)}
</div>
</div>
{renderControllerGroup(
"usefulness",
t("survey9", { defaultValue: "Survey9" }),
options.usefulness
)}
<div>
<p className="font-medium">{t("survey10", { defaultValue: "Survey10" })}</p>
<Controller
name="suggestion"
control={control}
render={({ field }) => (
<Textarea
placeholder={t("write")}
value={field.value}
onChange={field.onChange}
/>
)}
/>
</div>
<div className="flex justify-end gap-2">
<Button variant="outline" onClick={() => setOpenPolda(false)}>
{t("cancel", { defaultValue: "Cancel" })}
</Button>
<Button type="submit" disabled={isLoading}>
{isLoading ? t("sending") : t("send")}
</Button>
</div>
</form>
</DialogContent>
</Dialog>
</div>
{/* Kanan: Gambar survey */}
<div className="hidden lg:flex justify-center md:justify-end">
<img
src="/assets/survey.png"
alt="Survey Illustration"
className="w-48 h-auto"
/>
</div>
</div>
</div>
);
};
export default UserSurveyBox;