web-humas-fe/components/landing/suggestions.tsx

290 lines
9.8 KiB
TypeScript

"use client";
import { Button } from "@heroui/button";
import {
Image,
Input,
InputOtp,
Modal,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
ModalProps,
Textarea,
useDisclosure,
} from "@heroui/react";
import { ChevronLeftWhite, ChevronRightWhite } from "../icons";
import React, { useEffect, useState } from "react";
import Link from "next/link";
import { useTranslations } from "next-intl";
import * as z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { Controller, useForm } from "react-hook-form";
import { close, error, loading } from "@/config/swal";
import OTPInput from "react-otp-input";
import { otpRequest, otpValidation } from "@/service/master-user";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import { createFeedback } from "@/service/feedbacks";
const createArticleSchema = z.object({
email: z.string().min(2, {
message: "Email harus diisi",
}),
name: z.string().min(2, {
message: "Nama harus diisi",
}),
description: z.string().min(2, {
message: "Deskripsi harus diisi",
}),
});
export default function SuggestionsModal(props: {
opened: boolean;
modalStatus: (status: boolean) => void;
}) {
const { isOpen, onOpen, onOpenChange } = useDisclosure();
const [needOtp, setNeedOtp] = useState(false);
const [otpValue, setOtpValue] = useState("");
const MySwal = withReactContent(Swal);
const t = useTranslations("Landing");
useEffect(() => {
if (props.opened) {
onOpen();
}
}, [props.opened]);
const formOptions = {
resolver: zodResolver(createArticleSchema),
defaultValues: { name: "", description: "", email: "" },
};
type UserSettingSchema = z.infer<typeof createArticleSchema>;
const {
control,
handleSubmit,
reset,
formState: { errors },
} = useForm<UserSettingSchema>(formOptions);
const onSubmit = async (values: z.infer<typeof createArticleSchema>) => {
if (!needOtp) {
loading();
const res = await otpRequest(values.email, values?.name);
if (res?.error) {
error(res.message);
return false;
}
close();
setNeedOtp(true);
} else {
const validation = await otpValidation(values.email, otpValue);
if (validation?.error) {
error("OTP Tidak Sesuai");
return false;
}
const req = {
commentFromName: values.name,
message: values.description,
commentFromEmail: values.email,
};
const res = await createFeedback(req);
if (res?.error) {
error(res?.message);
return false;
}
MySwal.fire({
title: "Berhasil Kirim",
text: "",
icon: "success",
showCancelButton: false,
confirmButtonColor: "#3085d6",
confirmButtonText: "Oke",
}).then((result) => {
if (result.isConfirmed) {
}
});
reset();
setNeedOtp(false);
setOtpValue("");
props.modalStatus(!props.opened);
onOpenChange();
}
};
return (
<>
<Modal
isOpen={isOpen}
onOpenChange={() => {
props.modalStatus(!props.opened);
onOpenChange();
}}
size="3xl"
className="bg-white"
placement="top-center"
>
<ModalContent>
{(onClose) => (
<>
<ModalHeader className="flex flex-col text-black justify-center items-center min-h mb- text-3xl font-semibold">
<div className="text-xl text-black w-full justify-center flex">
<p className="border-b-3 border-[#C3170F] py-2 w-fit">
Kritik & Saran
</p>
</div>
</ModalHeader>
<ModalBody>
<form
onSubmit={handleSubmit(onSubmit)}
className="flex flex-col gap-3"
>
{needOtp ? (
<div className="flex flex-col gap-1 text-black">
<p className="text-xs">
Kode verifikasi sudah dikirmkan. Silahkan cek Email
Anda!
</p>
<p>OTP</p>
{/* <OTPInput
value={otpValue}
onChange={setOtpValue}
numInputs={6}
renderSeparator={<span>-</span>}
renderInput={(props) => (
<input
{...props}
className="!w-[30px] h-[30px] dark:text-white rounded-sm"
/>
)}
/> */}
<InputOtp
length={6}
value={otpValue}
onValueChange={setOtpValue}
className="dark:text-white"
/>
</div>
) : (
<>
<div className="flex flex-col gap-1">
<p className="text-sm text-black">Nama</p>
<Controller
control={control}
name="name"
render={({ field: { onChange, value } }) => (
<Input
type="text"
id="title"
placeholder=""
label=""
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full text-black"
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
/>
)}
/>
{errors?.name && (
<p className="text-red-400 text-sm">
{errors.name?.message}
</p>
)}
</div>
<div className="flex flex-col gap-1">
<p className="text-sm text-black">Email</p>
<Controller
control={control}
name="email"
render={({ field: { onChange, value } }) => (
<Input
type="email"
id="email"
placeholder=""
label=""
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full text-black"
classNames={{
inputWrapper: [
"border-1 rounded-lg !text-black",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400 !text-black",
"dark:group-data-[focused=true]:!text-black",
],
}}
variant="bordered"
/>
)}
/>
{errors?.email && (
<p className="text-red-400 text-sm">
{errors.email?.message}
</p>
)}
</div>
<div className="flex flex-col gap-1">
<p className="text-sm text-black">Kritik & Saran</p>
<Controller
control={control}
name="description"
render={({ field: { onChange, value } }) => (
<Textarea
type="text"
id="description"
placeholder=""
label=""
value={value}
onChange={onChange}
labelPlacement="outside"
className="w-full text-black"
classNames={{
inputWrapper: [
"border-1 rounded-lg",
"dark:group-data-[focused=false]:bg-transparent !border-1 dark:!border-gray-400",
],
}}
variant="bordered"
/>
)}
/>
{errors?.description && (
<p className="text-red-400 text-sm">
{errors.description?.message}
</p>
)}
</div>
</>
)}
<ModalFooter className="self-end grow items-end">
<Button color="primary" type="submit">
Kirim
</Button>
<Button color="danger" variant="light" onPress={onClose}>
Tutup
</Button>
</ModalFooter>
</form>
</ModalBody>
</>
)}
</ModalContent>
</Modal>
</>
);
}