From 6ff5efdb4b7eec25f991f5bfcc02b4a3f883981b Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 11 Sep 2024 10:04:31 +0700 Subject: update error handling hanya muncul saat button daftar di click --- .../modules/register/components/FormBisnis.tsx | 776 ++++++++++++--------- 1 file changed, 460 insertions(+), 316 deletions(-) (limited to 'src-migrate/modules/register/components/FormBisnis.tsx') diff --git a/src-migrate/modules/register/components/FormBisnis.tsx b/src-migrate/modules/register/components/FormBisnis.tsx index 1004d944..2080ae75 100644 --- a/src-migrate/modules/register/components/FormBisnis.tsx +++ b/src-migrate/modules/register/components/FormBisnis.tsx @@ -1,26 +1,31 @@ -import { ChangeEvent, useEffect, useMemo, useState } from "react"; -import { useMutation } from "react-query"; -import { useRegisterStore } from "../stores/useRegisterStore"; -import { RegisterProps } from "~/types/auth"; -import { registerUser } from "~/services/auth"; -import { useRouter } from "next/router"; -import { Button, Checkbox, UseToastOptions, color, useToast } from "@chakra-ui/react"; -import Link from "next/link"; -import getFileBase64 from '@/core/utils/getFileBase64' -import { Controller, useForm } from 'react-hook-form' -import HookFormSelect from '@/core/components/elements/Select/HookFormSelect' -import odooApi from "~/libs/odooApi"; -import { toast } from 'react-hot-toast'; +import { ChangeEvent, useEffect, useMemo, useState } from 'react'; +import { useMutation } from 'react-query'; +import { useRegisterStore } from '../stores/useRegisterStore'; +import { RegisterProps } from '~/types/auth'; +import { registerUser } from '~/services/auth'; +import { useRouter } from 'next/router'; import { - EyeIcon -} from '@heroicons/react/24/outline'; + Button, + Checkbox, + UseToastOptions, + color, + useToast, +} from '@chakra-ui/react'; +import Link from 'next/link'; +import getFileBase64 from '@/core/utils/getFileBase64'; +import { Controller, useForm } from 'react-hook-form'; +import HookFormSelect from '@/core/components/elements/Select/HookFormSelect'; +import odooApi from '~/libs/odooApi'; +import { toast } from 'react-hot-toast'; +import { EyeIcon } from '@heroicons/react/24/outline'; import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; -import Image from 'next/image' -import useDevice from '@/core/hooks/useDevice' +import Image from 'next/image'; +import useDevice from '@/core/hooks/useDevice'; interface FormProps { type: string; required: boolean; isPKP: boolean; + chekValid: boolean; } interface industry_id { @@ -34,22 +39,16 @@ interface companyType { label: string; } -const form: React.FC = ({ type, required, isPKP }) => { - const { - form, - errors, - updateForm, - validate - } = useRegisterStore() +const form: React.FC = ({ type, required, isPKP, chekValid }) => { + const { form, errors, updateForm, validate } = useRegisterStore(); const { control, watch, setValue } = useForm(); const [selectedCategory, setSelectedCategory] = useState(''); const [isChekBox, setIsChekBox] = useState(false); const [isExample, setIsExample] = useState(false); - const { isDesktop, isMobile } = useDevice() + const { isDesktop, isMobile } = useDevice(); // Inside your component - const [formattedNpwp, setFormattedNpwp] = useState(""); // State for formatted NPWP - const [unformattedNpwp, setUnformattedNpwp] = useState(""); // State for unformatted NPWP - + const [formattedNpwp, setFormattedNpwp] = useState(''); // State for formatted NPWP + const [unformattedNpwp, setUnformattedNpwp] = useState(''); // State for unformatted NPWP const [industries, setIndustries] = useState([]); const [companyTypes, setCompanyTypes] = useState([]); @@ -59,24 +58,36 @@ const form: React.FC = ({ type, required, isPKP }) => { useEffect(() => { const loadCompanyTypes = async () => { - const dataCompanyTypes = await odooApi('GET', '/api/v1/partner/company_type'); - setCompanyTypes(dataCompanyTypes?.map((o: { id: any; name: any; }) => ({ value: o.id, label: o.name }))); + const dataCompanyTypes = await odooApi( + 'GET', + '/api/v1/partner/company_type' + ); + setCompanyTypes( + dataCompanyTypes?.map((o: { id: any; name: any }) => ({ + value: o.id, + label: o.name, + })) + ); }; loadCompanyTypes(); }, []); useEffect(() => { - const selectedCompanyType = companyTypes.find(company => company.value === watch('companyType')); + const selectedCompanyType = companyTypes.find( + (company) => company.value === watch('companyType') + ); if (selectedCompanyType) { - updateForm("company_type_id", `${selectedCompanyType?.value}`); + updateForm('company_type_id', `${selectedCompanyType?.value}`); validate(); } }, [watch('companyType'), companyTypes]); useEffect(() => { - const selectedIndustryType = industries.find(industry => industry.value === watch('industry_id')); + const selectedIndustryType = industries.find( + (industry) => industry.value === watch('industry_id') + ); if (selectedIndustryType) { - updateForm("industry_id", `${selectedIndustryType?.value}`); + updateForm('industry_id', `${selectedIndustryType?.value}`); setSelectedCategory(selectedIndustryType.category); validate(); } @@ -85,107 +96,135 @@ const form: React.FC = ({ type, required, isPKP }) => { useEffect(() => { const loadIndustries = async () => { const dataIndustries = await odooApi('GET', '/api/v1/partner/industry'); - setIndustries(dataIndustries?.map((o: { id: any; name: any; category: any; }) => ({ value: o.id, label: o.name, category: o.category }))); + setIndustries( + dataIndustries?.map((o: { id: any; name: any; category: any }) => ({ + value: o.id, + label: o.name, + category: o.category, + })) + ); }; loadIndustries(); }, []); const handleInputChange = (event: ChangeEvent) => { const { name, value } = event.target; - updateForm('type_acc',`business`) - updateForm('is_pkp',`${isPKP}`) + updateForm('type_acc', `business`); + updateForm('is_pkp', `${isPKP}`); updateForm(name, value); validate(); }; const handleInputChangeNpwp = (event: ChangeEvent) => { const { name, value } = event.target; - updateForm('type_acc',`business`) - updateForm('is_pkp',`${isPKP}`) + updateForm('type_acc', `business`); + updateForm('is_pkp', `${isPKP}`); updateForm('npwp', value); validate(); }; const handleChange = (event: ChangeEvent) => { - setIsChekBox(!isChekBox) + setIsChekBox(!isChekBox); }; - + const formatNpwp = (value: string) => { try { - const cleaned = ("" + value).replace(/\D/g, ""); - let match - if(cleaned.length <= 15){ - match = cleaned.match(/(\d{0,2})?(\d{0,3})?(\d{0,3})?(\d{0,1})?(\d{0,3})?(\d{0,3})$/); - }else{ - match = cleaned.match(/(\d{0,3})?(\d{0,3})?(\d{0,3})?(\d{0,1})?(\d{0,3})?(\d{0,3})$/); + const cleaned = ('' + value).replace(/\D/g, ''); + let match; + if (cleaned.length <= 15) { + match = cleaned.match( + /(\d{0,2})?(\d{0,3})?(\d{0,3})?(\d{0,1})?(\d{0,3})?(\d{0,3})$/ + ); + } else { + match = cleaned.match( + /(\d{0,3})?(\d{0,3})?(\d{0,3})?(\d{0,1})?(\d{0,3})?(\d{0,3})$/ + ); } - - + if (match) { return [ match[1], - match[2] ? "." : "", + match[2] ? '.' : '', match[2], - match[3] ? "." : "", + match[3] ? '.' : '', match[3], - match[4] ? "." : "", + match[4] ? '.' : '', match[4], - match[5] ? "-" : "", + match[5] ? '-' : '', match[5], - match[6] ? "." : "", + match[6] ? '.' : '', match[6], - ].join(""); + ].join(''); } - + // If match is null, return the original cleaned string or handle as needed return cleaned; - } catch (error) { // Handle error or return a default value - console.error("Error formatting NPWP:", error); + console.error('Error formatting NPWP:', error); return value; } }; - useEffect(() => { if (isChekBox) { - updateForm("isChekBox", 'true'); + updateForm('isChekBox', 'true'); validate(); } else { - updateForm("isChekBox", 'false'); + updateForm('isChekBox', 'false'); validate(); } - }, [isChekBox,]); + }, [isChekBox]); const handleFileChange = async (event: ChangeEvent) => { - const toastProps: UseToastOptions = { duration: 5000, - isClosable: true + isClosable: true, + position: 'top', }; + let fileBase64 = ''; - const { name} = event.target; + const { name } = event.target; const file = event.target.files?.[0]; + + // Allowed file extensions + const allowedExtensions = ['pdf', 'doc', 'docx', 'png', 'jpg', 'jpeg']; + if (file) { - if (typeof file !== 'undefined') { - if (file.size > 5000000) { - toast({ - ...toastProps, - title: 'Maksimal ukuran file adalah 5MB', - status: 'warning' - }); - return; - } - fileBase64 = await getFileBase64(file); + const fileExtension = file.name.split('.').pop()?.toLowerCase(); // Extract file extension + + // Check if the file extension is allowed + if (!fileExtension || !allowedExtensions.includes(fileExtension)) { + toast({ + ...toastProps, + title: + 'Format file yang diijinkan adalah .pdf, .doc, .docx, .png, .jpg, atau .jpeg', + status: 'error', + }); + event.target.value = ''; + return; } - updateForm(name, fileBase64); - validate(); + + // Check for file size + if (file.size > 5000000) { + toast({ + ...toastProps, + title: 'Maksimal ukuran file adalah 5MB', + status: 'error', + }); + event.target.value = ''; + return; + } + + // Convert file to Base64 + fileBase64 = await getFileBase64(file); + updateForm(name, fileBase64); // Update form with the Base64 string + validate(); // Perform form validation } }; const mutation = useMutation({ - mutationFn: (data: RegisterProps) => registerUser(data) + mutationFn: (data: RegisterProps) => registerUser(data), }); const handleSubmit = async (e: ChangeEvent) => { @@ -197,14 +236,15 @@ const form: React.FC = ({ type, required, isPKP }) => { const urlParams = new URLSearchParams({ activation: 'otp', email: form.email, - redirect: (router.query?.next || '/') as string + redirect: (router.query?.next || '/') as string, }); router.push(`${router.route}?${urlParams}`); } const toastProps: UseToastOptions = { duration: 5000, - isClosable: true + isClosable: true, + position: 'top', }; switch (response?.reason) { @@ -212,7 +252,7 @@ const form: React.FC = ({ type, required, isPKP }) => { toast({ ...toastProps, title: 'Email sudah digunakan', - status: 'warning' + status: 'warning', }); break; case 'NOT_ACTIVE': @@ -220,147 +260,205 @@ const form: React.FC = ({ type, required, isPKP }) => { toast({ ...toastProps, title: 'Akun belum aktif', - description: <>Akun sudah terdaftar namun belum aktif. Klik untuk aktivasi akun, - status: 'warning' + description: ( + <> + Akun sudah terdaftar namun belum aktif.{' '} + + Klik untuk aktivasi akun + + + ), + status: 'warning', }); break; } }; return ( <> - setIsExample(false)} >
- Contoh SPPKP + Contoh SPPKP
-
-
- - - - - {!required && isPKP && !!errors.email_partner && {errors.email_partner}} -
- -
- -
-
- } + +
+ + + + + {chekValid && !required && isPKP && !!errors.email_partner && ( + {errors.email_partner} + )} +
+ +
+ +
+
+ ( + + )} /> - {!required && !!errors.company_type_id && {errors.company_type_id}} -
-
- + {errors.company_type_id} + + )} +
+
+ - { !!errors.business_name && {errors.business_name}} + {chekValid && !!errors.business_name && ( + {errors.business_name} + )} +
-
- -
- - } + +
+ + ( + + )} + /> + {selectedCategory && ( + + Kategori : {selectedCategory} + + )} + {chekValid && !required && !!errors.industry_id && ( + {errors.industry_id} + )} +
+ +
+ + + + + {chekValid && !required && !!errors.alamat_bisnis && ( + {errors.alamat_bisnis} + )} +
+ +
+ + + - {selectedCategory && - Kategori : {selectedCategory} - } - {!required && !!errors.industry_id && {errors.industry_id}} -
- -
- - - - - {!required && !!errors.alamat_bisnis && {errors.alamat_bisnis}} -
- -
- - - - - {isPKP && !required && !!errors.nama_wajib_pajak && {errors.nama_wajib_pajak}} -
- -
- + + + className={`form-input mt-3 ${required ? 'cursor-no-drop' : ''}`} + disabled={isChekBox || required} + contentEditable={required} + readOnly={required} + onChange={handleInputChange} + aria-invalid={ + chekValid && isPKP && !required && !!errors.alamat_wajib_pajak + } + /> - {!required && !!errors.npwp && {errors.npwp}} -
+ {chekValid && isPKP && !required && !!errors.alamat_wajib_pajak && ( + {errors.alamat_wajib_pajak} + )} +
-
-
- -
- - - - - {isPKP && !required && !!errors.npwp_document && {errors.npwp_document}} -
- -
- - - - - {isPKP && !required && !!errors.sppkp_document && {errors.sppkp_document}} -
- +
+ + + + + {chekValid && isPKP && !required && !!errors.npwp_document && ( + {errors.npwp_document} + )} +
+ +
+ + + + + {chekValid && isPKP && !required && !!errors.sppkp_document && ( + {errors.sppkp_document} + )} +
+ - ) -} + ); +}; export default form; -- cgit v1.2.3