feat:kritik saran popup
This commit is contained in:
parent
1eede31961
commit
c52c351bf0
|
|
@ -303,7 +303,7 @@ export default function CategorySatker(props: {
|
||||||
}}
|
}}
|
||||||
size="5xl"
|
size="5xl"
|
||||||
scrollBehavior={scrollBehavior}
|
scrollBehavior={scrollBehavior}
|
||||||
placement={modalPlacement}
|
placement="center"
|
||||||
className="bg-white"
|
className="bg-white"
|
||||||
>
|
>
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ export default function PolriApps(props: {
|
||||||
}}
|
}}
|
||||||
size="5xl"
|
size="5xl"
|
||||||
scrollBehavior={scrollBehavior}
|
scrollBehavior={scrollBehavior}
|
||||||
placement={modalPlacement}
|
placement={"center"}
|
||||||
className="bg-white"
|
className="bg-white"
|
||||||
>
|
>
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@ export default function RegionalNews(props: {
|
||||||
}}
|
}}
|
||||||
size="5xl"
|
size="5xl"
|
||||||
scrollBehavior={scrollBehavior}
|
scrollBehavior={scrollBehavior}
|
||||||
placement={modalPlacement}
|
placement="center"
|
||||||
className="bg-white"
|
className="bg-white"
|
||||||
>
|
>
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ export default function BannerHumasNew() {
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="ml-2 w-fit">
|
<PopoverContent className="ml-2 w-fit">
|
||||||
<div
|
<div
|
||||||
className={` px-1 py-2 text-black grid gap-2 ${
|
className={` px-1 py-2 grid gap-2 ${
|
||||||
withImage ? " grid-cols-3" : "grid-cols-1 gap-2"
|
withImage ? " grid-cols-3" : "grid-cols-1 gap-2"
|
||||||
} `}
|
} `}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,14 @@ import RegionalNews from "./RegionalNews";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import CategorySatker from "./CategorySatker";
|
import CategorySatker from "./CategorySatker";
|
||||||
import PolriApps from "./PolriApps";
|
import PolriApps from "./PolriApps";
|
||||||
|
import Link from "next/link";
|
||||||
|
import SuggestionsModal from "./suggestions";
|
||||||
|
|
||||||
export default function DigitalServices() {
|
export default function DigitalServices() {
|
||||||
const [isPoldaOpen, setIsPoldaOpen] = useState(false);
|
const [isPoldaOpen, setIsPoldaOpen] = useState(false);
|
||||||
const [isSatkerOpen, setIsSatkerOpen] = useState(false);
|
const [isSatkerOpen, setIsSatkerOpen] = useState(false);
|
||||||
const [isAppsOpen, setIsAppsOpen] = useState(false);
|
const [isAppsOpen, setIsAppsOpen] = useState(false);
|
||||||
|
const [isSuggestionOpen, setIsSuggestionOpen] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="border-1 rounded-xl py-2 w-[90%] lg:w-[75%] mx-auto bg-white text-black">
|
<div className="border-1 rounded-xl py-2 w-[90%] lg:w-[75%] mx-auto bg-white text-black">
|
||||||
|
|
@ -73,7 +76,7 @@ export default function DigitalServices() {
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
onClick={() => setIsAppsOpen(true)}
|
onClick={() => setIsSuggestionOpen(true)}
|
||||||
className="group shadow-lg rounded-lg w-full lg:w-[200px] h-[200px] flex flex-col justify-center items-center hover:border-3 hover:border-red-600 cursor-pointer mx-auto transition duration-300 ease-in-out"
|
className="group shadow-lg rounded-lg w-full lg:w-[200px] h-[200px] flex flex-col justify-center items-center hover:border-3 hover:border-red-600 cursor-pointer mx-auto transition duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
|
|
@ -90,8 +93,8 @@ export default function DigitalServices() {
|
||||||
Lihat Selengkapnya
|
Lihat Selengkapnya
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
<a
|
<Link
|
||||||
onClick={() => setIsAppsOpen(true)}
|
href="https://survey.zohopublic.com/zs/EYCOBO"
|
||||||
className="group shadow-lg rounded-lg w-full lg:w-[200px] h-[200px] flex flex-col justify-center items-center hover:border-3 hover:border-red-600 cursor-pointer mx-auto transition duration-300 ease-in-out"
|
className="group shadow-lg rounded-lg w-full lg:w-[200px] h-[200px] flex flex-col justify-center items-center hover:border-3 hover:border-red-600 cursor-pointer mx-auto transition duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
|
|
@ -107,7 +110,7 @@ export default function DigitalServices() {
|
||||||
<p className="text-xs text-primary underline transform group-hover:translate-y-2 transition duration-300 ease-in-out">
|
<p className="text-xs text-primary underline transform group-hover:translate-y-2 transition duration-300 ease-in-out">
|
||||||
Lihat Selengkapnya
|
Lihat Selengkapnya
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<RegionalNews
|
<RegionalNews
|
||||||
opened={isPoldaOpen}
|
opened={isPoldaOpen}
|
||||||
|
|
@ -121,6 +124,10 @@ export default function DigitalServices() {
|
||||||
opened={isAppsOpen}
|
opened={isAppsOpen}
|
||||||
modalStatus={(status) => setIsAppsOpen(status)}
|
modalStatus={(status) => setIsAppsOpen(status)}
|
||||||
/>
|
/>
|
||||||
|
<SuggestionsModal
|
||||||
|
opened={isSuggestionOpen}
|
||||||
|
modalStatus={(status) => setIsSuggestionOpen(status)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,293 @@
|
||||||
|
"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";
|
||||||
|
|
||||||
|
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 = {
|
||||||
|
name: values.name,
|
||||||
|
description: values.description,
|
||||||
|
email: values.email,
|
||||||
|
};
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// setRefresh(!refresh);
|
||||||
|
// MySwal.fire({
|
||||||
|
// title: "Sukses",
|
||||||
|
// icon: "success",
|
||||||
|
// confirmButtonColor: "#3085d6",
|
||||||
|
// confirmButtonText: "OK",
|
||||||
|
// }).then((result) => {
|
||||||
|
// if (result.isConfirmed) {
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
|
||||||
|
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>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue