diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2025-01-15 10:02:39 +0000 |
|---|---|---|
| committer | IT Fixcomart <it@fixcomart.co.id> | 2025-01-15 10:02:39 +0000 |
| commit | 8035f129863f0a401f529cc0cd69a2131ccaba80 (patch) | |
| tree | 21e0300680a724c8a24ed815ea4e9a32ab13a895 /src/lib | |
| parent | 7a14ed5ccdde86d0400d6aa02ac866317d4add63 (diff) | |
| parent | 98236a47c3558c4b701009a275c7ae917ee8bf67 (diff) | |
Merged in Feature/switch-account (pull request #402)
Feature/switch account
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/auth/api/switchAccountApi.js | 14 | ||||
| -rw-r--r-- | src/lib/auth/api/switchAccountProgresApi.js | 13 | ||||
| -rw-r--r-- | src/lib/auth/components/CompanyProfile.jsx | 125 | ||||
| -rw-r--r-- | src/lib/auth/components/Menu.jsx | 282 | ||||
| -rw-r--r-- | src/lib/auth/components/PersonalProfile.jsx | 154 | ||||
| -rw-r--r-- | src/lib/auth/components/StatusSwitchAccount.jsx | 5 | ||||
| -rw-r--r-- | src/lib/auth/components/SwitchAccount.jsx | 301 |
7 files changed, 695 insertions, 199 deletions
diff --git a/src/lib/auth/api/switchAccountApi.js b/src/lib/auth/api/switchAccountApi.js new file mode 100644 index 00000000..79ca2553 --- /dev/null +++ b/src/lib/auth/api/switchAccountApi.js @@ -0,0 +1,14 @@ +import odooApi from '@/core/api/odooApi'; +import { getAuth } from '@/core/utils/auth'; + +const switchAccountApi = async ({ data }) => { + const auth = getAuth(); + const switchAccount = await odooApi( + 'PUT', + `/api/v1/user/${auth.partnerId}/switch`, + data + ); + return switchAccount; +}; + +export default switchAccountApi; diff --git a/src/lib/auth/api/switchAccountProgresApi.js b/src/lib/auth/api/switchAccountProgresApi.js new file mode 100644 index 00000000..6289a5dd --- /dev/null +++ b/src/lib/auth/api/switchAccountProgresApi.js @@ -0,0 +1,13 @@ +import odooApi from '@/core/api/odooApi'; +import { getAuth } from '@/core/utils/auth'; + +const switchAccountProgresApi = async () => { + const auth = getAuth(); + const switchAccount = await odooApi( + 'GET', + `/api/v1/user/${auth.partnerId}/switch_progres` + ); + return switchAccount; +}; + +export default switchAccountProgresApi; diff --git a/src/lib/auth/components/CompanyProfile.jsx b/src/lib/auth/components/CompanyProfile.jsx index 220d5be1..410d6a23 100644 --- a/src/lib/auth/components/CompanyProfile.jsx +++ b/src/lib/auth/components/CompanyProfile.jsx @@ -9,9 +9,14 @@ import { toast } from 'react-hot-toast'; import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; import { yupResolver } from '@hookform/resolvers/yup'; import * as Yup from 'yup'; +import SwitchAccount from '@/lib/auth/components/SwitchAccount'; +import { Checkbox } from '@chakra-ui/react'; const CompanyProfile = () => { const [changeConfirmation, setChangeConfirmation] = useState(false); + const [changeType, setChangeType] = useState(false); + const [isChecked, setIsChecked] = useState(false); + const [company_type, setCompany_type] = useState('nonpkp'); const auth = useAuth(); const [isOpen, setIsOpen] = useState(false); const toggle = () => setIsOpen(!isOpen); @@ -53,14 +58,18 @@ const CompanyProfile = () => { useEffect(() => { const loadProfile = async () => { - const dataProfile = await addressApi({ id: auth.parentId }); - setValue('name', dataProfile.name); - setValue('industry', dataProfile.industryId); - setValue('companyType', dataProfile.companyTypeId); - setValue('taxName', dataProfile.taxName); - setValue('npwp', dataProfile.npwp); - setValue('alamat_wajib_pajak', dataProfile.alamatWajibPajak); - setValue('alamat_bisnis', dataProfile.alamatBisnis); + const dataProfile = await addressApi({ + id: auth.parentId ? auth.parentId : auth.parent_id, + }); + setCompany_type(dataProfile?.companyType); + setValue('name', dataProfile?.name); + setValue('industry', dataProfile?.industryId); + setValue('companyType', dataProfile?.companyTypeId); + setValue('taxName', dataProfile?.taxName); + setValue('npwp', dataProfile?.npwp); + setValue('alamat_wajib_pajak', dataProfile?.alamatWajibPajak); + setValue('alamat_bisnis', dataProfile?.alamatBisnis); + setValue('company_type', dataProfile?.companyType); setValue('email_bisnis', dataProfile.email); setValue('mobile_bisnis', dataProfile.mobile); }; @@ -97,10 +106,49 @@ const CompanyProfile = () => { setChangeConfirmation(false); handleSubmit(onSubmitHandler)(); }; + const handleConfirmSubmitType = () => { + setChangeType(false); + setIsChecked(true); + setIsOpen(!isOpen); + }; + const handleChange = async () => { + if (isChecked) { + setIsChecked(!isChecked); + setIsOpen(!isOpen); + } else { + setIsChecked(!isChecked); + setChangeType(true); + } + }; return ( <> <BottomPopup + active={changeType} + close={() => setChangeType(false)} // Menutup popup + title='Ubah type akun' + > + <div className='leading-7 text-gray_r-12/80'> + Anda akan mengubah type akun anda? + </div> + <div className='flex mt-6 gap-x-4 md:justify-end'> + <button + className='btn-solid-red flex-1 md:flex-none' + type='button' + onClick={handleConfirmSubmitType} + > + Yakin + </button> + <button + className='btn-light flex-1 md:flex-none' + type='button' + onClick={() => setChangeType(false)} + > + Batal + </button> + </div> + </BottomPopup> + <BottomPopup active={changeConfirmation} close={() => setChangeConfirmation(true)} title='Ubah profil Bisnis' @@ -125,25 +173,37 @@ const CompanyProfile = () => { </button> </div> </BottomPopup> - <button - type='button' - onClick={toggle} - className='p-4 flex items-center text-left w-full' - > + <div className='p-4 flex-row items-center text-left w-full'> + {company_type === 'nonpkp' && ( + <div className='text-sm mb-2 flex items-center'> + <Checkbox + borderColor='gray.600' + colorScheme='red' + size='lg' + isChecked={isChecked} + onChange={handleChange} + /> + <p className='ml-2'>Ubah ke akun PKP</p> + </div> + )} <div> - <div className='font-semibold mb-2'>Informasi Usaha</div> + <div className='font-semibold mb-2 flex flex-row gap-x-2'> + <h2>Informasi Usaha</h2> + <div className='badge-red'>{company_type.toUpperCase()}</div> + </div> <div className='text-gray_r-11'> Dibawah ini adalah data usaha yang anda masukkan, periksa kembali data usaha anda. </div> </div> - <div className='ml-auto p-2 bg-gray_r-3 rounded'> - {!isOpen && <ChevronDownIcon className='w-6' />} - {isOpen && <ChevronUpIcon className='w-6' />} - </div> - </button> - - {isOpen && ( + {/* <button + onClick={toggle} + className='btn-yellow w-full sm:w-fit sm:ml-auto min-w-[92px]' + > + Ubah + </button> */} + </div> + {!isOpen && ( <form className='p-4 border-t border-gray_r-6' onSubmit={(e) => { @@ -264,6 +324,7 @@ const CompanyProfile = () => { </button> </form> )} + {isOpen && <SwitchAccount company_type={company_type} />} </> ); }; @@ -272,14 +333,30 @@ export default CompanyProfile; const validationSchema = Yup.object().shape({ alamat_bisnis: Yup.string().required('Harus di-isi'), - alamat_wajib_pajak: Yup.string().required('Harus di-isi'), - taxName: Yup.string().required('Harus di-isi'), - npwp: Yup.string().required('Harus di-isi'), name: Yup.string().required('Harus di-isi'), email_bisnis: Yup.string().required('Harus di-isi'), mobile_bisnis: Yup.string().required('Harus di-isi'), industry: Yup.string().required('Harus di-pilih'), companyType: Yup.string().required('Harus di-pilih'), + taxName: Yup.string(), + npwp: Yup.string(), + alamat_wajib_pajak: Yup.string(), + company_type: Yup.string(), + taxName: Yup.string().when('company_type', { + is: (company_type) => company_type !== 'Non PKP', + then: Yup.string().required('Harus di-isi'), + otherwise: Yup.string().notRequired(), + }), + npwp: Yup.string().when('company_type', { + is: (company_type) => company_type !== 'Non PKP', + then: Yup.string().required('Harus di-isi'), + otherwise: Yup.string().notRequired(), + }), + alamat_wajib_pajak: Yup.string().when('company_type', { + is: (company_type) => company_type !== 'Non PKP', + then: Yup.string().required('Harus di-isi'), + otherwise: Yup.string().notRequired(), + }), }); const defaultValues = { diff --git a/src/lib/auth/components/Menu.jsx b/src/lib/auth/components/Menu.jsx index d99917d0..4682dbab 100644 --- a/src/lib/auth/components/Menu.jsx +++ b/src/lib/auth/components/Menu.jsx @@ -2,11 +2,24 @@ import Link from '@/core/components/elements/Link/Link'; import { useRouter } from 'next/router'; import ImageNext from 'next/image'; import whatsappUrl from '@/core/utils/whatsappUrl'; -import { deleteAuth } from '@/core/utils/auth'; import useAuth from '@/core/hooks/useAuth'; +import switchAccountProgresApi from '@/lib/auth/api/switchAccountProgresApi.js'; +import { useState, useEffect } from 'react'; +import { InfoIcon } from 'lucide-react'; +import { deleteAuth } from '@/core/utils/auth'; const Menu = () => { const router = useRouter(); const auth = useAuth(); + const [ubahAkun, setUbahAkun] = useState(); + useEffect(() => { + const loadProgres = async () => { + const progresSwitchAccount = await switchAccountProgresApi(); + if (progresSwitchAccount) { + setUbahAkun(progresSwitchAccount.status); + } + }; + loadProgres(); + }, []); const routeStartWith = (route) => router.pathname.startsWith(route); @@ -15,78 +28,134 @@ const Menu = () => { router.push('/login'); }); }; - return ( <div className='grid grid-cols-1 bg-white border border-gray_r-6 rounded py-2 px-4 sticky top-48'> - <div className='mt-4 mb-1 font-medium'>Menu</div> - <LinkItem href='/my/quotations' active={routeStartWith('/my/quotations')}> - <div className='flex gap-x-3 items-center'> - <ImageNext - src='/images/icon/icon_daftar_quotation.svg' - width={18} - height={20} - /> - <p>Daftar Quotation</p> - </div> - </LinkItem> - <LinkItem - href='/my/transactions' - active={routeStartWith('/my/transactions')} - > - <div className='flex gap-x-3 items-center'> - <ImageNext - src='/images/icon/icon_daftar_transaksi.svg' - width={18} - height={20} - /> - <p>Daftar Transaksi</p> - </div> - </LinkItem> - <LinkItem href='/my/shipments' active={routeStartWith('/my/shipments')}> - <div className='flex gap-x-3 items-center'> - <ImageNext - src='/images/icon/icon_pengiriman.svg' - width={18} - height={20} - /> - <p>Daftar Pengiriman</p> - </div> - </LinkItem> - <LinkItem href='/my/invoices' active={routeStartWith('/my/invoices')}> - <div className='flex gap-x-3 items-center'> - <ImageNext - src='/images/icon/icon_invoice.svg' - width={18} - height={20} - /> - <p>Invoice & Faktur Pajak</p> - </div> - </LinkItem> - {auth && - auth.partnerTempo && - (auth.partnerTempo || - auth.tempoProgres === 'review') && ( - <LinkItem href='/my/tempo' active={routeStartWith('/my/tempo')}> - <div className='flex gap-x-3 items-center'> - <ImageNext - src='/images/icon/icon_tempo.svg' - width={18} - height={20} - /> - <p>Pembayaran Tempo</p> - </div> - </LinkItem> - )} - <LinkItem href='/my/wishlist' active={routeStartWith('/my/wishlist')}> - <div className='flex gap-x-3 items-center'> - <ImageNext - src='/images/icon/icon_wishlist.svg' - width={18} - height={20} - /> - <p>Wishlist</p> + <div className='flex justify-between py-4'> + <div className='font-semibold text-gray_r-12'>Akun Saya</div> + <div className='relative group'> + {auth?.company && !(ubahAkun === 'pending') && ( + <> + <Link + href='/my/profile' + className='badge-solid-red mt-1 p-2 flex flex-row items-center gap-x-2' + > + <p className='text-white'>Akun Bisnis</p>{' '} + <InfoIcon size={14} color='white' /> + </Link> + <div className='absolute bottom-full transform -translate-x-1/2 mb-2 hidden group-hover:block bg-gray-700 text-white text-xs rounded py-1 px-2 w-72 text-justify left-36'> + Anda terdaftar sebagai akun bisnis, segala bentuk transaksi anda + untuk perusahaan yang sudah anda daftarkan di Indoteknik.com + </div> + </> + )} + {ubahAkun === 'pending' && ( + <> + <Link + href='/my/profile' + className='badge-yellow mt-1 p-2 flex flex-row items-center gap-x-2' + > + <p className='text-warning-900'>Review</p> + <InfoIcon size={14} className='text-warning-900' /> + </Link> + <div className='absolute bottom-full transform -translate-x-1/2 mb-2 hidden group-hover:block bg-gray-700 text-white text-xs rounded py-1 px-2 w-72 text-justify left-36'> + Proses perubahan akun anda sedang kami review, mohon menunggu + hingga 2x24 jam. + </div> + </> + )} + {!auth?.company && !(ubahAkun === 'pending') && ( + <> + <Link + href='/my/profile' + className='badge-gray mt-1 p-2 flex flex-row items-center gap-x-2' + > + <p className='text-gray_r-10'>Akun Individu</p> + <InfoIcon size={14} className='text-gray_r-10' /> + </Link> + <div className='absolute bottom-full left-36 transform -translate-x-1/2 mb-3 w-72 text-justify hidden group-hover:block bg-gray-700 text-white text-xs rounded py-1 px-2'> + <p className='whitespace-pre-wrap break-words'> + Anda terdaftar sebagai akun individu, Segala bentuk transaksi + anda untuk Pribadi/Individu. + </p> + </div> + </> + )} </div> - </LinkItem> + </div> + <div className='mt-2 mb-1 font-medium'>Menu</div> + <div className='flex flex-col gap-y-2'> + <LinkItem + href='/my/quotations' + active={routeStartWith('/my/quotations')} + className='' + > + <div className='flex gap-x-3 items-center'> + <ImageNext + src='/images/icon/icon_daftar_quotation.svg' + width={18} + height={20} + /> + <p>Daftar Quotation</p> + </div> + </LinkItem> + <LinkItem + href='/my/transactions' + active={routeStartWith('/my/transactions')} + > + <div className='flex gap-x-3 items-center'> + <ImageNext + src='/images/icon/icon_daftar_transaksi.svg' + width={18} + height={20} + /> + <p>Daftar Transaksi</p> + </div> + </LinkItem> + <LinkItem href='/my/shipments' active={routeStartWith('/my/shipments')}> + <div className='flex gap-x-3 items-center'> + <ImageNext + src='/images/icon/icon_pengiriman.svg' + width={18} + height={20} + /> + <p>Daftar Pengiriman</p> + </div> + </LinkItem> + <LinkItem href='/my/invoices' active={routeStartWith('/my/invoices')}> + <div className='flex gap-x-3 items-center'> + <ImageNext + src='/images/icon/icon_invoice.svg' + width={18} + height={20} + /> + <p>Invoice & Faktur Pajak</p> + </div> + </LinkItem> + {auth && + auth.partnerTempo && + (auth.partnerTempo || auth.tempoProgres === 'review') && ( + <LinkItem href='/my/tempo' active={routeStartWith('/my/tempo')}> + <div className='flex gap-x-3 items-center'> + <ImageNext + src='/images/icon/icon_tempo.svg' + width={18} + height={20} + /> + <p>Pembayaran Tempo</p> + </div> + </LinkItem> + )} + <LinkItem href='/my/wishlist' active={routeStartWith('/my/wishlist')}> + <div className='flex gap-x-3 items-center'> + <ImageNext + src='/images/icon/icon_wishlist.svg' + width={18} + height={20} + /> + <p>Wishlist</p> + </div> + </LinkItem> + </div> <div className='mt-4 mb-1 font-medium'>Pusat Bantuan</div> <LinkItem @@ -104,40 +173,41 @@ const Menu = () => { </div> </LinkItem> <div className='mt-4 mb-1 font-medium'>Pengaturan Akun</div> - <LinkItem href='/my/address' active={routeStartWith('/my/address')}> - <div className='flex gap-x-3 items-center'> - <ImageNext - src='/images/icon/icon_daftar_alamat.svg' - width={18} - height={20} - /> - <p>Daftar Alamat</p> - </div> - </LinkItem> - <LinkItem href='/my/profile' active={routeStartWith('/my/profile')}> - <div className='flex gap-x-3 items-center'> - <ImageNext - src='/images/icon/icon_profile.svg' - width={18} - height={20} - /> - <p>Profil Saya</p> - </div> - </LinkItem> - <button - type='button' - onClick={logout} - className='text-gray_r-12/80 p-2 text-left' - > - <div className='flex gap-x-3 items-center'> - <ImageNext - src='/images/icon/icon_logout.svg' - width={18} - height={20} - /> - <p>Keluar Akun</p> - </div> - </button> + <div className='flex flex-col gap-y-2'> + <LinkItem href='/my/address' active={routeStartWith('/my/address')}> + <div className='flex gap-x-3 items-center'> + <ImageNext + src='/images/icon/icon_daftar_alamat.svg' + width={18} + height={20} + /> + <p>Daftar Alamat</p> + </div> + </LinkItem> + <LinkItem href='/my/profile' active={routeStartWith('/my/profile')}> + <div className='flex gap-x-3 items-center'> + <ImageNext + src='/images/icon/icon_profile.svg' + width={18} + height={20} + /> + <p>Profil Saya</p> + </div> + </LinkItem> + <button + type='button' + className='text-gray_r-12/80 p-2 text-left hover:bg-gray_r-5 ' + > + <div className='flex gap-x-3 items-center'> + <ImageNext + src='/images/icon/icon_logout.svg' + width={18} + height={20} + /> + <p>Keluar Akun</p> + </div> + </button> + </div> </div> ); }; @@ -145,8 +215,8 @@ const Menu = () => { const LinkItem = ({ children, ...props }) => ( <Link {...props} - className={`!text-gray_r-12/80 !font-normal p-2 rounded ${ - props.active == true ? 'bg-gray_r-3' : '' + className={`!text-gray_r-12/80 !font-normal p-2 rounded transition-colors duration-200 ${ + props.active ? 'bg-gray_r-3' : 'hover:bg-gray_r-5 ' }`} > {children} diff --git a/src/lib/auth/components/PersonalProfile.jsx b/src/lib/auth/components/PersonalProfile.jsx index b9fb3f5f..3053255d 100644 --- a/src/lib/auth/components/PersonalProfile.jsx +++ b/src/lib/auth/components/PersonalProfile.jsx @@ -1,96 +1,112 @@ -import useAuth from '@/core/hooks/useAuth' -import { setAuth } from '@/core/utils/auth' -import addressApi from '@/lib/address/api/addressApi' -import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline' -import { useEffect, useState } from 'react' -import { useForm } from 'react-hook-form' -import { toast } from 'react-hot-toast' -import editPersonalProfileApi from '../api/editPersonalProfileApi' +import useAuth from '@/core/hooks/useAuth'; +import { setAuth } from '@/core/utils/auth'; +import addressApi from '@/lib/address/api/addressApi'; +import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline'; +import { useEffect, useState } from 'react'; +import { useForm } from 'react-hook-form'; +import { toast } from 'react-hot-toast'; +import editPersonalProfileApi from '../api/editPersonalProfileApi'; const PersonalProfile = () => { - const auth = useAuth() - const [isOpen, setIsOpen] = useState(true) - const toggle = () => setIsOpen(!isOpen) + const auth = useAuth(); + const [isOpen, setIsOpen] = useState(true); + const toggle = () => setIsOpen(!isOpen); const { register, setValue, handleSubmit } = useForm({ defaultValues: { email: '', name: '', mobile: '', - password: '' - } - }) + password: '', + }, + }); useEffect(() => { const loadProfile = async () => { - const dataProfile = await addressApi({ id: auth.partnerId }) - setValue('email', dataProfile?.email) - setValue('name', dataProfile?.name) - setValue('mobile', dataProfile?.mobile) - } - if (auth) loadProfile() - }, [auth, setValue]) + const dataProfile = await addressApi({ + id: auth.partnerId ? auth.partnerId : auth.partner_id, + }); + setValue('email', dataProfile?.email); + setValue('name', dataProfile?.name); + setValue('mobile', dataProfile?.mobile); + }; + if (auth) loadProfile(); + }, [auth, setValue]); const onSubmitHandler = async (values) => { - let data = values - if (!values.password) delete data.password - const isUpdated = await editPersonalProfileApi({ data }) + let data = values; + if (!values.password) delete data.password; + const isUpdated = await editPersonalProfileApi({ data }); if (isUpdated?.user) { - setAuth(isUpdated.user) - setValue('password', '') - toast.success('Berhasil mengubah profil', { duration: 1500 }) - return + setAuth(isUpdated.user); + setValue('password', ''); + toast.success('Berhasil mengubah profil', { duration: 1500 }); + return; } - toast.error('Terjadi kesalahan internal') - } + toast.error('Terjadi kesalahan internal'); + }; return ( <> - <button type='button' onClick={toggle} className='p-4 flex items-center text-left w-full'> + <div type='button' className='p-4 flex items-center text-left w-full'> <div> <div className='font-semibold mb-2'>Informasi Akun</div> <div className='text-gray_r-11'> - Dibawah ini adalah data diri yang anda masukan, periksa kembali data diri anda + Dibawah ini adalah data diri yang anda masukan, periksa kembali data + diri anda </div> </div> - <div className='ml-auto p-2 bg-gray_r-3 rounded'> - {!isOpen && <ChevronDownIcon className='w-6' />} - {isOpen && <ChevronUpIcon className='w-6' />} - </div> - </button> + </div> - {isOpen && ( - <form className='p-4 border-t border-gray_r-6' onSubmit={handleSubmit(onSubmitHandler)}> - <div className='grid grid-cols-1 sm:grid-cols-2 gap-4'> - <div> - <label>Email</label> - <input {...register('email')} type='text' disabled className='form-input mt-3' /> - </div> - <div> - <label>Nama Lengkap</label> - <input {...register('name')} type='text' className='form-input mt-3' /> - </div> - <div> - <label>No. Handphone</label> - <input {...register('mobile')} type='tel' className='form-input mt-3' /> - </div> - <div> - <label>Kata Sandi</label> - <input - {...register('password')} - type='password' - className='form-input mt-3' - placeholder='Isi jika ingin mengubah kata sandi' - /> - </div> + <form + className='p-4 border-t border-gray_r-6' + onSubmit={handleSubmit(onSubmitHandler)} + > + <div className='grid grid-cols-1 sm:grid-cols-2 gap-4'> + <div> + <label>Email</label> + <input + {...register('email')} + type='text' + disabled + className='form-input mt-3' + /> + </div> + <div> + <label>Nama Lengkap</label> + <input + {...register('name')} + type='text' + className='form-input mt-3' + /> </div> - <button type='submit' className='btn-yellow w-full sm:w-fit sm:ml-auto mt-6'> - Simpan - </button> - </form> - )} + <div> + <label>No. Handphone</label> + <input + {...register('mobile')} + type='tel' + className='form-input mt-3' + /> + </div> + <div> + <label>Kata Sandi</label> + <input + {...register('password')} + type='password' + className='form-input mt-3' + placeholder='Isi jika ingin mengubah kata sandi' + /> + </div> + </div> + <button + type='submit' + className='btn-yellow w-full sm:w-fit sm:ml-auto mt-6 max-w-28' + > + Simpan + </button> + </form> </> - ) -} + ); +}; -export default PersonalProfile +export default PersonalProfile; diff --git a/src/lib/auth/components/StatusSwitchAccount.jsx b/src/lib/auth/components/StatusSwitchAccount.jsx new file mode 100644 index 00000000..73316616 --- /dev/null +++ b/src/lib/auth/components/StatusSwitchAccount.jsx @@ -0,0 +1,5 @@ +const StatusSwitchAccount = ({ status }) => { + return <>Perpindahan akun anda masih {status}</>; +}; + +export default StatusSwitchAccount; diff --git a/src/lib/auth/components/SwitchAccount.jsx b/src/lib/auth/components/SwitchAccount.jsx new file mode 100644 index 00000000..46e57348 --- /dev/null +++ b/src/lib/auth/components/SwitchAccount.jsx @@ -0,0 +1,301 @@ +import useAuth from '@/core/hooks/useAuth'; +import { setAuth } from '@/core/utils/auth'; +import addressApi from '@/lib/address/api/addressApi'; +import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline'; +import { useEffect, useState, useMemo } from 'react'; +import { useForm } from 'react-hook-form'; +import { toast } from 'react-hot-toast'; +import switchAccountApi from '../api/switchAccountApi'; +import FormBisnis from '~/modules/register/components/FormBisnis.tsx'; +import RegistrasiBisnis from '~/modules/register/components/RegistrasiBisnis.tsx'; +import { Radio, RadioGroup, Stack, Divider, Button } from '@chakra-ui/react'; +import { useRegisterStore } from '~/modules/register/stores/useRegisterStore.ts'; +import { registerUser } from '~/services/auth'; +import { useMutation } from 'react-query'; +import { isValid } from 'zod'; +import useDevice from '@/core/hooks/useDevice'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +const SwitchAccount = ({ company_type }) => { + const { isDesktop, isMobile } = useDevice(); + const auth = useAuth(); + const [isOpen, setIsOpen] = useState(true); + const toggle = () => setIsOpen(!isOpen); + const [isPKP, setIsPKP] = useState(true); + const [isTerdaftar, setIsTerdaftar] = useState(false); + const [isChecked, setIsChecked] = useState(false); + const [selectedValueBisnis, setSelectedValueBisnis] = useState('false'); + const [selectedValue, setSelectedValue] = useState('PKP'); + const [buttonSubmitClick, setButtonSubmitClick] = useState(false); + const [changeConfirmation, setChangeConfirmation] = useState(false); + const { register, setValue, handleSubmit } = useForm({ + defaultValues: { + email: '', + name: '', + phone: '', + password: '', + }, + }); + const mutation = useMutation({ + mutationFn: (data) => registerUser(data), + }); + const [notValid, setNotValid] = useState(false); + const { + form, + isCheckedTNC, + isValidCaptcha, + errors, + validate, + updateForm, + resetForm, + } = useRegisterStore(); + const isFormValid = useMemo(() => Object.keys(errors).length === 0, [errors]); + useEffect(() => { + const loadProfile = async () => { + const dataProfile = await addressApi({ id: auth.partnerId }); + setValue('email', dataProfile?.email); + setValue('name', dataProfile?.name); + setValue('phone', dataProfile?.phone); + }; + if (auth) loadProfile(); + }, [auth, setValue]); + + useEffect(() => { + if (selectedValue === 'PKP') { + updateForm('is_pkp', 'true'); + validate(); + } else { + updateForm('is_pkp', 'false'); + validate(); + } + }, [selectedValue]); + + useEffect(() => { + if (isTerdaftar) { + updateForm('is_terdaftar', 'true'); + validate(); + } else { + updateForm('is_terdaftar', 'false'); + validate(); + } + }, [isTerdaftar]); + useEffect(() => { + const loadProfile = async () => { + const dataProfile = await addressApi({ + id: auth.parentId ? auth.parentId : auth.parent_id, + }); + if (dataProfile?.companyType === 'nonpkp') { + setSelectedValue('PKP'); + } + if (auth?.company) { + updateForm('email_partner', dataProfile?.email); + updateForm('business_name', dataProfile?.name); + updateForm('industry_id', `${dataProfile?.industryId}`); + updateForm('company_type_id', `${dataProfile?.companyTypeId}`); + updateForm('nama_wajib_pajak', dataProfile?.taxName); + updateForm('npwp', dataProfile?.npwp); + updateForm('sppkp', dataProfile?.sppkp); + updateForm('alamat_wajib_pajak', dataProfile?.alamatWajibPajak); + updateForm('alamat_bisnis', dataProfile?.alamatBisnis); + validate(); + } + }; + if (auth) loadProfile(); + }, [auth, setValue]); + useEffect(() => { + updateForm('name', '-'); + updateForm('email', 'example@mail.com'); + updateForm('password', 'example@mail.com'); + updateForm('phone', '081234567890'); + validate(); + }, [buttonSubmitClick, changeConfirmation]); + + const handleChangeBisnis = (value) => { + resetForm(); + setSelectedValueBisnis(value); + if (value === 'true') { + validate(); + setIsTerdaftar(true); + } else { + validate(); + setIsTerdaftar(false); + } + }; + const handleChange = (value) => { + setSelectedValue(value); + if (value === 'PKP') { + validate(); + setIsPKP(true); + } else { + validate(); + setIsPKP(false); + setIsPKP(false); + } + }; + const onSubmitHandler = async (values) => { + toast.loading('Mengubah status akun...'); + updateForm('parent_id', `${auth.parentId}`); + setChangeConfirmation(false); + // let data = { ...form, id: `${auth.partnerId}` }; + const data = form; + if (!isFormValid) { + setNotValid(true); + setButtonSubmitClick(!buttonSubmitClick); + return; + } else { + setButtonSubmitClick(!buttonSubmitClick); + setNotValid(false); + } + // if (!values.password) delete data.password; + const isUpdated = await switchAccountApi({ data }); + + if (isUpdated?.switch === 'Pending') { + // setAuth(isUpdated.user); + // setValue('password', ''); + toast.success('Berhasil mengubah akun', { duration: 1500 }); + setTimeout(() => { + window.location.reload(); + }, 1500); + return; + } + toast.error('Terjadi kesalahan internal'); + }; + + const onSubmitHandlerCancel = async (values) => { + window.location.reload(); + }; + + return ( + <> + <BottomPopup + active={changeConfirmation} + close={() => setChangeConfirmation(false)} + title='Ubah profil Bisnis' + > + <div className='leading-7 text-gray_r-12/80'> + Anda yakin akan merubah profil bisnis anda dari INDIVIDU menjadi{' '} + {selectedValue}? + </div> + <div className='flex mt-6 gap-x-4 md:justify-end'> + <button + className='btn-solid-red flex-1 md:flex-none' + type='button' + onClick={onSubmitHandler} + > + Ya, Ubah + </button> + <button + className='btn-light flex-1 md:flex-none' + type='button' + onClick={() => setChangeConfirmation(false)} + > + Batal + </button> + </div> + </BottomPopup> + {/* <div type='button' className='ml-4 flex items-center text-left w-full'> + <div + className={`flex ${ + isDesktop ? 'flex-row' : 'flex-col gap-y-2' + } items-start justify-start bg-slate-50`} + > + <div className='flex font-semibold mr-2'>Informasi Bisnis</div> + <div className='text-red-500 text-xs'> + *Perubahan akun tidak dapat diubah kembali + </div> + </div> + </div> */} + <div className='px-4 '> + <div + class='flex items-center p-4 mb-4 text-sm border border-red-500 text-red-800 rounded-lg bg-red-50' + role='alert' + > + <svg + class='flex-shrink-0 inline w-4 h-4 mr-3' + aria-hidden='true' + fill='currentColor' + viewBox='0 0 20 20' + > + <path d='M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z' /> + </svg> + <span class='sr-only'>Info</span> + <div className='text-justify'> + Mohon diperhatikan bahwa perubahan data akun bisnis akan + mengakibatkan perubahan pada informasi yang tertera di faktur pajak + dan invoice. + </div> + </div> + </div> + + <div className='px-4 mb-4'> + {!auth?.company && company_type === 'nonpkp' && ( + <> + <div className='mb-4'> + <p className='text-black font-bold mb-2'> + Bisnis Terdaftar di Indoteknik? + </p> + <RadioGroup + onChange={handleChangeBisnis} + value={selectedValueBisnis} + > + <Stack direction='row'> + <Radio colorScheme='red' value='true'> + Sudah Terdaftar + </Radio> + <Radio colorScheme='red' value='false' className='ml-2'> + Belum Terdaftar + </Radio> + </Stack> + </RadioGroup> + </div> + {!isTerdaftar && ( + <div className=''> + <p className='text-black font-bold mb-2'>Tipe Bisnis</p> + <RadioGroup onChange={handleChange} value={selectedValue}> + <Stack direction='row' className='font-bold'> + <Radio colorScheme='red' value='PKP'> + PKP + </Radio> + {!auth?.company && company_type === 'nonpkp' && ( + <Radio colorScheme='red' value='Non-PKP' className='ml-4'> + Non-PKP + </Radio> + )} + </Stack> + </RadioGroup> + </div> + )} + </> + )} + <FormBisnis + type={isDesktop ? 'profil' : 'bisnis'} + required={isTerdaftar} + isPKP={isPKP} + chekValid={notValid} + buttonSubmitClick={buttonSubmitClick} + /> + <div className='flex flex-row justify-end mt-4 '> + <div className='mr-4'> + <button + type='submit' + onClick={() => setChangeConfirmation(true)} + className='btn-yellow w-full sm:w-fit sm:ml-auto mt-6 mr-8 md:mr-4' + > + {mutation.isLoading ? 'Loading...' : 'Simpan Perubahan'} + </button> + </div> + <div> + <button + type='submit' + onClick={onSubmitHandlerCancel} + className='btn-solid-red w-full sm:w-fit sm:ml-auto mt-6' + > + {mutation.isLoading ? 'Loading...' : 'Batal'} + </button> + </div> + </div> + </div> + </> + ); +}; + +export default SwitchAccount; |
