300 lines
10 KiB
TypeScript
300 lines
10 KiB
TypeScript
|
|
"use client";
|
||
|
|
|
||
|
|
import { Button } from "@/shared/components/ui/button";
|
||
|
|
import {
|
||
|
|
Form,
|
||
|
|
FormControl,
|
||
|
|
FormField,
|
||
|
|
FormItem,
|
||
|
|
FormLabel,
|
||
|
|
FormMessage,
|
||
|
|
} from "@/shared/components/ui/form";
|
||
|
|
import { FeedbackFormValues, feedbackSchema } from "@/shared/schemas/feedback";
|
||
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||
|
|
import React from "react";
|
||
|
|
import { useForm } from "react-hook-form";
|
||
|
|
import EmojiRatingFeedback from "./_components/emoji-rating";
|
||
|
|
import { Feedback } from "@/shared/types/feedback";
|
||
|
|
import SelectSector from "./_components/select-sector";
|
||
|
|
import SelectPurpose from "./_components/select-purpose";
|
||
|
|
import { RadioGroup, RadioGroupItem } from "@/shared/components/ui/radio-group";
|
||
|
|
import { Textarea } from "@/shared/components/ui/textarea";
|
||
|
|
import { Input } from "@/shared/components/ui/input";
|
||
|
|
|
||
|
|
type FeedbackFormProps = {
|
||
|
|
defaultValues?: Partial<Feedback>;
|
||
|
|
onSubmitAction: (data: FeedbackFormValues) => void;
|
||
|
|
isSubmitting?: boolean;
|
||
|
|
onCancelAction?: () => void;
|
||
|
|
};
|
||
|
|
export function FeedbackForm({
|
||
|
|
defaultValues,
|
||
|
|
onSubmitAction,
|
||
|
|
isSubmitting,
|
||
|
|
onCancelAction,
|
||
|
|
}: FeedbackFormProps) {
|
||
|
|
const form = useForm<FeedbackFormValues>({
|
||
|
|
resolver: zodResolver(feedbackSchema),
|
||
|
|
defaultValues: {
|
||
|
|
id: defaultValues?.id || "",
|
||
|
|
score: defaultValues?.score || null,
|
||
|
|
tujuan_tercapai: defaultValues?.tujuan_tercapai || null,
|
||
|
|
tujuan_ditemukan: defaultValues?.tujuan_ditemukan || null,
|
||
|
|
tujuan: defaultValues?.tujuan || null,
|
||
|
|
sektor: defaultValues?.sektor || null,
|
||
|
|
email: defaultValues?.email || undefined,
|
||
|
|
saran: defaultValues?.saran || null,
|
||
|
|
source_url: "",
|
||
|
|
source_access: "Floating button",
|
||
|
|
notes: defaultValues?.notes || "",
|
||
|
|
gender: defaultValues?.gender || undefined,
|
||
|
|
datetime: new Date() || undefined,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
return (
|
||
|
|
<>
|
||
|
|
<h1 className="text-center text-gray-700 text-xs mb-5">
|
||
|
|
Bantu kami meingkatkan layanan dengan feedback Anda
|
||
|
|
</h1>
|
||
|
|
<Form {...form}>
|
||
|
|
<form
|
||
|
|
onSubmit={form.handleSubmit(
|
||
|
|
async (values) => {
|
||
|
|
console.log("submit", values);
|
||
|
|
await onSubmitAction(values); // <- ini memanggil hook kamu
|
||
|
|
form.reset();
|
||
|
|
},
|
||
|
|
(errors) => {
|
||
|
|
console.log("[FeedbackForm] invalid submit", errors);
|
||
|
|
}
|
||
|
|
)}
|
||
|
|
className="flex flex-col space-y-4"
|
||
|
|
>
|
||
|
|
<FormField
|
||
|
|
control={form.control}
|
||
|
|
name="score"
|
||
|
|
render={({ field }) => (
|
||
|
|
<FormItem>
|
||
|
|
<FormLabel className="mb-2">
|
||
|
|
Seberapa puaskah Anda dengan layanan yang kami berikan?
|
||
|
|
<span className="text-red-500">*</span>
|
||
|
|
</FormLabel>
|
||
|
|
<FormControl>
|
||
|
|
<EmojiRatingFeedback
|
||
|
|
value={Number(field.value)}
|
||
|
|
onChange={(v) => field.onChange(v)}
|
||
|
|
showLabel
|
||
|
|
size={44}
|
||
|
|
name={field.name}
|
||
|
|
/>
|
||
|
|
</FormControl>
|
||
|
|
<FormMessage />
|
||
|
|
</FormItem>
|
||
|
|
)}
|
||
|
|
/>
|
||
|
|
|
||
|
|
<FormField
|
||
|
|
control={form.control}
|
||
|
|
name="sektor"
|
||
|
|
render={({ field }) => (
|
||
|
|
<FormItem>
|
||
|
|
<FormLabel>
|
||
|
|
Pilih sektor/grup berikut yang mewakili posisi Anda saat ini{" "}
|
||
|
|
<span className="text-red-500">*</span>
|
||
|
|
</FormLabel>
|
||
|
|
<FormControl>
|
||
|
|
<SelectSector
|
||
|
|
value={field.value ?? ""}
|
||
|
|
onChange={(v) => field.onChange(v)}
|
||
|
|
name={field.name}
|
||
|
|
/>
|
||
|
|
</FormControl>
|
||
|
|
</FormItem>
|
||
|
|
)}
|
||
|
|
></FormField>
|
||
|
|
|
||
|
|
<FormField
|
||
|
|
control={form.control}
|
||
|
|
name="tujuan"
|
||
|
|
render={({ field }) => (
|
||
|
|
<FormItem>
|
||
|
|
<FormLabel>
|
||
|
|
Apakah tujuan utama Anda mengunjungi laman Satu Peta Provinsi
|
||
|
|
Jawa Timur hari ini?<span className="text-red-500">*</span>
|
||
|
|
</FormLabel>
|
||
|
|
<FormControl>
|
||
|
|
<SelectPurpose
|
||
|
|
value={field.value ?? ""}
|
||
|
|
onChange={(v) => field.onChange(v)}
|
||
|
|
name={field.name}
|
||
|
|
/>
|
||
|
|
</FormControl>
|
||
|
|
</FormItem>
|
||
|
|
)}
|
||
|
|
></FormField>
|
||
|
|
|
||
|
|
<FormField
|
||
|
|
control={form.control}
|
||
|
|
name="tujuan_tercapai"
|
||
|
|
render={({ field }) => (
|
||
|
|
<FormItem>
|
||
|
|
<FormLabel>
|
||
|
|
Apakah Anda berhasil menemukan data atau informasi yang Anda
|
||
|
|
cari? <span className="text-red-500">*</span>
|
||
|
|
</FormLabel>
|
||
|
|
<FormControl>
|
||
|
|
<RadioGroup
|
||
|
|
value={
|
||
|
|
field.value == null ? undefined : String(field.value)
|
||
|
|
}
|
||
|
|
onValueChange={(v) => field.onChange(v === "true")}
|
||
|
|
className="flex flex-col space-y-2"
|
||
|
|
>
|
||
|
|
<FormItem className="flex items-center space-x-1 space-y-0">
|
||
|
|
<FormControl>
|
||
|
|
<RadioGroupItem value="true" />
|
||
|
|
</FormControl>
|
||
|
|
<FormLabel className="font-normal">Ya</FormLabel>
|
||
|
|
</FormItem>
|
||
|
|
<FormItem className="flex items-center space-x-1 space-y-0">
|
||
|
|
<FormControl>
|
||
|
|
<RadioGroupItem value="false" />
|
||
|
|
</FormControl>
|
||
|
|
<FormLabel className="font-normal">Tidak</FormLabel>
|
||
|
|
</FormItem>
|
||
|
|
</RadioGroup>
|
||
|
|
</FormControl>
|
||
|
|
</FormItem>
|
||
|
|
)}
|
||
|
|
></FormField>
|
||
|
|
|
||
|
|
<FormField
|
||
|
|
control={form.control}
|
||
|
|
name="tujuan_ditemukan"
|
||
|
|
render={({ field }) => (
|
||
|
|
<FormItem>
|
||
|
|
<FormLabel>
|
||
|
|
Apakah informasi yang Anda cari mudah untuk didapatkan?{" "}
|
||
|
|
<span className="text-red-500">*</span>
|
||
|
|
</FormLabel>
|
||
|
|
<FormControl>
|
||
|
|
<RadioGroup
|
||
|
|
value={
|
||
|
|
field.value == null ? undefined : String(field.value)
|
||
|
|
}
|
||
|
|
onValueChange={(v) => field.onChange(v === "true")}
|
||
|
|
className="flex flex-col space-y-2"
|
||
|
|
>
|
||
|
|
<FormItem className="flex items-center space-x-1 space-y-0">
|
||
|
|
<FormControl>
|
||
|
|
<RadioGroupItem value="true" />
|
||
|
|
</FormControl>
|
||
|
|
<FormLabel className="font-normal">Ya</FormLabel>
|
||
|
|
</FormItem>
|
||
|
|
<FormItem className="flex items-center space-x-1 space-y-0">
|
||
|
|
<FormControl>
|
||
|
|
<RadioGroupItem value="false" />
|
||
|
|
</FormControl>
|
||
|
|
<FormLabel className="font-normal">Tidak</FormLabel>
|
||
|
|
</FormItem>
|
||
|
|
</RadioGroup>
|
||
|
|
</FormControl>
|
||
|
|
</FormItem>
|
||
|
|
)}
|
||
|
|
></FormField>
|
||
|
|
|
||
|
|
<FormField
|
||
|
|
control={form.control}
|
||
|
|
name="gender"
|
||
|
|
render={({ field }) => (
|
||
|
|
<FormItem>
|
||
|
|
<FormLabel>
|
||
|
|
Apa jenis kelamin Anda?
|
||
|
|
<span className="text-red-500">*</span>
|
||
|
|
</FormLabel>
|
||
|
|
<FormControl>
|
||
|
|
<RadioGroup
|
||
|
|
value={
|
||
|
|
field.value == null ? undefined : String(field.value)
|
||
|
|
}
|
||
|
|
onValueChange={(v) => field.onChange(Number(v))}
|
||
|
|
className="flex flex-col space-y-2"
|
||
|
|
>
|
||
|
|
<FormItem className="flex items-center space-x-1 space-y-0">
|
||
|
|
<FormControl>
|
||
|
|
<RadioGroupItem value="1" />
|
||
|
|
</FormControl>
|
||
|
|
<FormLabel className="font-normal">Laki-laki</FormLabel>
|
||
|
|
</FormItem>
|
||
|
|
<FormItem className="flex items-center space-x-1 space-y-0">
|
||
|
|
<FormControl>
|
||
|
|
<RadioGroupItem value="0" />
|
||
|
|
</FormControl>
|
||
|
|
<FormLabel className="font-normal">Perempuan</FormLabel>
|
||
|
|
</FormItem>
|
||
|
|
</RadioGroup>
|
||
|
|
</FormControl>
|
||
|
|
</FormItem>
|
||
|
|
)}
|
||
|
|
></FormField>
|
||
|
|
|
||
|
|
<FormField
|
||
|
|
control={form.control}
|
||
|
|
name="saran"
|
||
|
|
render={({ field }) => (
|
||
|
|
<FormItem>
|
||
|
|
<FormLabel>
|
||
|
|
Tuliskan saran atau kendala yang Anda alami dalam penggunaan
|
||
|
|
Satu Peta Provinsi Jawa Timur agar kami dapat memberikan
|
||
|
|
layanan lebih baik lagi
|
||
|
|
</FormLabel>
|
||
|
|
<FormControl>
|
||
|
|
<Textarea
|
||
|
|
{...field}
|
||
|
|
value={field.value ?? ""}
|
||
|
|
placeholder="Tuliskan saran Anda"
|
||
|
|
/>
|
||
|
|
</FormControl>
|
||
|
|
<FormMessage />
|
||
|
|
</FormItem>
|
||
|
|
)}
|
||
|
|
/>
|
||
|
|
|
||
|
|
<FormField
|
||
|
|
control={form.control}
|
||
|
|
name="email"
|
||
|
|
render={({ field }) => (
|
||
|
|
<FormItem>
|
||
|
|
<FormLabel>Email</FormLabel>
|
||
|
|
<FormControl>
|
||
|
|
<Input
|
||
|
|
type="email"
|
||
|
|
placeholder="Masukkan alamat email"
|
||
|
|
{...field}
|
||
|
|
/>
|
||
|
|
</FormControl>
|
||
|
|
<FormMessage />
|
||
|
|
</FormItem>
|
||
|
|
)}
|
||
|
|
/>
|
||
|
|
<div className="flex justify-end space-x-4">
|
||
|
|
{onCancelAction && (
|
||
|
|
<Button
|
||
|
|
type="button"
|
||
|
|
variant="outline"
|
||
|
|
onClick={onCancelAction}
|
||
|
|
disabled={isSubmitting}
|
||
|
|
>
|
||
|
|
Batal
|
||
|
|
</Button>
|
||
|
|
)}
|
||
|
|
<Button type="submit" disabled={isSubmitting}>
|
||
|
|
{isSubmitting ? "Mengirim..." : "Kirim"}
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
</form>
|
||
|
|
</Form>
|
||
|
|
</>
|
||
|
|
);
|
||
|
|
}
|