Advertisement
xcage88

Experience

Sep 1st, 2024
7,585
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { GetServerSidePropsContext } from 'next';
  2. import { useRouter } from 'next/navigation';
  3. import { useEffect, useState } from 'react';
  4. import { useDispatch } from 'react-redux';
  5.  
  6. //* store
  7. import { setPageTitle } from '@/store/themeConfigSlice';
  8.  
  9. //* utils
  10. import { config } from '@/configs';
  11. import { getData, postData, postFile, putData } from '@/utils/fetch';
  12. import { notValidMsg, requiredMsg } from '@/utils/regex';
  13.  
  14.  
  15. //* middleware
  16. import WithAuth from '@/middlewares/WithAuth';
  17.  
  18. //* component
  19. import InputMessage from '@/components/core/Alert/InputMessage';
  20. import { showMessage } from '@/components/core/Alert/ShowMessage';
  21. import Button from '@/components/core/Button';
  22. import TextInput from '@/components/core/TextInput';
  23.  
  24. //* hook form
  25. import CKEditorComp from '@/components/core/InputTextEditor/CKEditor';
  26. import { yupResolver } from '@hookform/resolvers/yup';
  27. import { useForm } from 'react-hook-form';
  28. import * as yup from 'yup';
  29. import TextArea from '@/components/core/TextArea/TextArea';
  30. import Spinner from '@/components/core/spinner';
  31. import { CloseIcon } from '@/components/icon/close-icon';
  32. import SelectInput from '@/components/core/SelectInput';
  33. import { useTranslation } from 'react-i18next';
  34. import { EyeIcon } from '@/components/icon/eyes';
  35. import { EyeOff } from '@/components/icon/eye-off-icon';
  36. import { yearOption, monthsOptions } from '@/data/fullDate';
  37. import { regexAllCharacter, regexAlphanumeric, regexAlphabetsNumbers } from '@/utils/regex-message';
  38. import InputDropdown3 from '@/components/core/InputDropdown3';
  39. import { FormExperienceType } from '@/types/profile';
  40. import Checkbox from '@/components/core/Checkbox';
  41.  
  42. interface IInputExperience {
  43.     experience: FormExperienceType
  44. }
  45.  
  46. const schema = yup.object().shape({
  47.     company: yup.string().required().matches(regexAlphanumeric.regex, regexAlphabetsNumbers.msg),
  48.     company_position: yup.string().required().matches(regexAlphanumeric.regex, regexAlphanumeric.msg),
  49.     address: yup.string().required().matches(regexAllCharacter.regex, regexAllCharacter.msg),
  50.     position: yup.number().required(),
  51.     start_date: yup.string(),
  52.     end_date: yup.string(),
  53.     description: yup.string().required().matches(regexAllCharacter.regex, regexAllCharacter.msg),
  54.     // start_month: yup.string().required(requiredMsg('Bulan Masuk')),
  55.     // start_year: yup.string().required(requiredMsg('Tahun Masuk')),
  56.     // end_month: yup.string().required(requiredMsg('Bulan Keluar')),
  57.     // end_year: yup.string().required(requiredMsg('Tahun Keluar')),
  58. })
  59.  
  60. function InputExperience({experience}: IInputExperience) {
  61.  
  62.     const { t } = useTranslation();
  63.     const router = useRouter()
  64.     const dispatch = useDispatch()
  65.  
  66.     const [form, setForm] = useState({
  67.         company: '' || experience?.company,
  68.         company_position: '' || experience?.company_position,
  69.         address: '' || experience?.address,
  70.         position: '' || experience?.position,
  71.         start_date: '' || experience?.start_date,
  72.         end_date: experience?.end_date || '',
  73.         description: '' || experience?.description,
  74.         currently_working: experience?.currently_working || false
  75.     })
  76.  
  77.     const [select, setSelect] = useState({
  78.         start_year: '',
  79.         end_year: '',
  80.         start_month: '',
  81.         end_month: '',
  82.     })
  83.  
  84.     // schema
  85.     const {
  86.         register,
  87.         handleSubmit,
  88.         formState: {errors},
  89.         trigger,
  90.         setValue
  91.     } = useForm({
  92.         resolver: yupResolver(schema)
  93.     })
  94.  
  95.     const [isLoading, setIsLoading] = useState<boolean>(false)
  96.     const [autoField, setAutoField] = useState<any[]>([])
  97.     const [endYearOptions, setEndYearOptions] = useState(yearOption())
  98.  
  99.     // const { end_date, ...withoutEndDate } = form
  100.  
  101.     const handleChangeInput = (e: any) => {
  102.         const {name, value} = e.target
  103.         if(!autoField.includes(name)){
  104.             setForm({...form, [name]: value})
  105.             trigger(name)
  106.         }else{
  107.             setForm({...form, [name]: value})
  108.         }
  109.     }
  110.  
  111.     const handleAutoField = (e: any) => {
  112.         const {name, value} = e.target
  113.         setAutoField([...autoField, name])
  114.         setValue(name, value)
  115.         if(value != ''){
  116.             trigger(name)
  117.         }
  118.     }
  119.  
  120.     const handleChangeSelect = (e: any) => {
  121.         const {name, value} = e.target
  122.         setSelect({ ...select ,[name]: value})
  123.         if(name == 'start_year'){
  124.             updateEndYear(value)
  125.         }
  126.  
  127.         if(name == 'end_year' && parseInt(value) <= parseInt(select.start_year)){
  128.             setSelect({...select, end_year: ''})
  129.         }
  130.     }
  131.  
  132.     const updateEndYear = (startYear: string) => {
  133.         const updatedEndYearOptions = yearOption().filter(option => parseInt(option.value) >= parseInt(startYear));
  134.         setEndYearOptions(updatedEndYearOptions);
  135.  
  136.         // Reset end_year if it is before the start_year
  137.         if (select.end_year && parseInt(select.end_year) <= parseInt(startYear)) {
  138.             setSelect(prevSelect => ({ ...prevSelect, end_year: '' }));
  139.             // setValue('end_year', '');
  140.         }  
  141.     }
  142.  
  143.     const handleCheckbox = (e: any) => {
  144.         const {name, checked} = e.target
  145.         setForm({...form, [name]: checked})
  146.     }
  147.  
  148.     const convertDate = (date: string) => {
  149.         const month = date?.split("-")[1]
  150.         const year = date?.split("-")[0]
  151.         return `${month} ${year}`
  152.     }
  153.  
  154.     useEffect(() => {
  155.  
  156.         setSelect({
  157.             start_month: convertDate(form.start_date).split(" ")[0],
  158.             start_year: convertDate(form.start_date).split(" ")[1],
  159.             end_month: form.currently_working
  160.               ? ""
  161.               : convertDate(form.end_date).split(" ")[0],
  162.             end_year: form.currently_working
  163.               ? ""
  164.               : convertDate(form.end_date).split(" ")[1],
  165.         })
  166.      
  167.     },[])
  168.  
  169.     useEffect(() => {
  170.         const startDate = `${select.start_year}-${select.start_month}`
  171.         const endDate = form.currently_working ? null :`${select.end_year}-${select.end_month}`
  172.         setForm((prevForm: any) => ({
  173.             ...prevForm,
  174.             start_date: startDate,
  175.             end_date: endDate,
  176.         }))
  177.     },[select])
  178.  
  179.     const handleSaveAction = async () => {
  180.         const { company, company_position, position, address, description } = form
  181.  
  182.         if(company && company_position && position && address && description){
  183.             const postForm = {
  184.                 ...form,
  185.                 end_date: form.currently_working ? null : form.end_date
  186.             }
  187.             if(experience){
  188.                 try {
  189.                     setIsLoading(true);
  190.                     await putData(`/experience/${experience.id}`, postForm);
  191.                     showMessage(`${t("Successfully updated")}`);
  192.                     router.push('./');
  193.                     setIsLoading(false);
  194.                 } catch (error: any) {
  195.                     showMessage(`${t("Failed to update")}`, 'error');
  196.                     setIsLoading(false);
  197.                 }
  198.             } else {
  199.                 //* ADD ACTION
  200.                 try {
  201.                     setIsLoading(true);
  202.                     const data = await postData('/experience', postForm);
  203.                     showMessage(`${t("Successfully added")}`);
  204.                     router.push('./');
  205.                     console.log(data)
  206.                     setIsLoading(false);
  207.                 } catch (error: any) {
  208.                     showMessage(`${t("Failed to add")}`, 'error');
  209.                     setIsLoading(false);
  210.                 }
  211.             }
  212.         }
  213.     }
  214.  
  215.     return (
  216.         <>
  217.             <section className="">
  218.                 <form
  219.                     onSubmit={handleSubmit(handleSaveAction)}
  220.                 >
  221.                     <div className="mb-5 flex flex-col gap-5 md:flex-row md:items-center">
  222.                         <h5 className="sm:pb-2 text-lg font-semibold dark:text-white-light">{experience ? 'Edit' : t("Create")} {t("Experience")}</h5>
  223.                     </div>
  224.                     <div className="w-full border-b border-b-zinc-300 border-dashed"></div>
  225.  
  226.                     <div className="w-full flex flex-col">
  227.  
  228.                         {/* Basic Input */}
  229.                         <div className="w-full flex flex-col sm:flex-row justify-between gap-y-6 sm:gap-y-0 gap-x-10 py-6 sm:py-8 border-b border-b-zinc-300 border-dashed box-border">
  230.                             <div className="flex flex-col shrink-0 sm:py-6 sm:w-[30%]">
  231.                                 <label htmlFor="logo" className='font-semibold text-lg'>{t("Basic Info")}</label>
  232.                                 <div className="-mt-1">{t("Add some basic info about your Experience from here")}</div>
  233.                             </div>
  234.                             <div className="w-full flex flex-col gap-y-3 bg-white rounded-md drop-shadow p-5 sm:p-7">
  235.                                 {/* input company */}
  236.                                 <div className="flex flex-col w-full gap-1">
  237.                                     <label htmlFor="company" className='font-semibold'>{t("Company")}</label>
  238.                                     <TextInput
  239.                                         register={register}
  240.                                         errors={errors}
  241.                                         id="company"
  242.                                         name="company"
  243.                                         type="text"
  244.                                         placeholder=""
  245.                                         value={form.company}
  246.                                         className="w-full cursor-auto overflow-hidden rounded-md focus:outline-primary bg-white text-black"
  247.                                         onChange={handleChangeInput}
  248.                                         onInput={handleAutoField}
  249.                                     />
  250.                                 </div>
  251.  
  252.                                 {/* input company_position */}
  253.                                 <div className="flex flex-col w-full gap-1">
  254.                                     <label htmlFor="company_position" className='font-semibold'>{t("Company Position")}</label>
  255.                                     <TextInput
  256.                                         register={register}
  257.                                         errors={errors}
  258.                                         id="company_position"
  259.                                         name="company_position"
  260.                                         type="text"
  261.                                         placeholder=""
  262.                                         value={form.company_position}
  263.                                         className="w-full cursor-auto overflow-hidden rounded-md focus:outline-primary bg-white text-black"
  264.                                         onChange={handleChangeInput}
  265.                                         onInput={handleAutoField}
  266.                                     />
  267.                                 </div>
  268.  
  269.                                 {/* input company */}
  270.                                 <div className="flex flex-col w-full gap-1">
  271.                                     <label htmlFor="position" className='font-semibold'>{t("Position")}</label>
  272.                                     <TextInput
  273.                                         register={register}
  274.                                         errors={errors}
  275.                                         id="position"
  276.                                         name="position"
  277.                                         type="number"
  278.                                         placeholder=""
  279.                                         value={form.position}
  280.                                         className="w-full cursor-auto overflow-hidden rounded-md focus:outline-primary bg-white text-black"
  281.                                         onChange={handleChangeInput}
  282.                                         onInput={handleAutoField}
  283.                                     />
  284.                                 </div>
  285.  
  286.                                 {/* input company */}
  287.                                 <div className="flex flex-col w-full gap-1">
  288.                                     <label htmlFor="address" className='font-semibold'>{t("Address")}</label>
  289.                                     <TextArea
  290.                                         register={register}
  291.                                         errors={errors}
  292.                                         id="address"
  293.                                         name="address"
  294.                                         type="text"
  295.                                         placeholder=""
  296.                                         value={form.address}
  297.                                         className="w-full cursor-auto overflow-hidden rounded-md focus:outline-primary bg-white text-black"
  298.                                         onChange={handleChangeInput}
  299.                                         onInput={handleAutoField}
  300.                                     />
  301.                                 </div>
  302.  
  303.                                 <div className="flex flex-col w-full gap-1">
  304.                                     <label htmlFor="position" className='font-semibold'>{t("Description")}</label>
  305.                                     <TextArea
  306.                                         register={register}
  307.                                         errors={errors}
  308.                                         id="description"
  309.                                         name="description"
  310.                                         type="text"
  311.                                         placeholder=""
  312.                                         value={form.description}
  313.                                         className="w-full cursor-auto overflow-hidden rounded-md focus:outline-primary bg-white text-black"
  314.                                         onChange={handleChangeInput}
  315.                                         onInput={handleAutoField}
  316.                                     />
  317.                                 </div>
  318.  
  319.                                
  320.                             </div>
  321.                         </div>
  322.  
  323.                         <div className="w-full flex flex-col sm:flex-row justify-between gap-y-6 sm:gap-y-0 gap-x-10 py-6 sm:py-8 border-b border-b-zinc-300 border-dashed box-border">
  324.                             <div className="flex flex-col shrink-0 sm:py-6 sm:w-[30%]">
  325.                                 <label htmlFor="logo" className='font-semibold text-lg'>{t("Date")}</label>
  326.                                 <div className="-mt-1">{t("Add Date from here")}</div>
  327.                             </div>
  328.                             <div className="w-full flex flex-col gap-y-3 bg-white rounded-md drop-shadow p-5 sm:p-7">
  329.                                 <div className='flex flex-row items-center w-full gap-2'>
  330.                                     <Checkbox
  331.                                         id='currently_working'
  332.                                         name='currently_working'
  333.                                         checked={form.currently_working}
  334.                                         onChange={handleCheckbox}
  335.                                         disabled={isLoading}
  336.                                     />
  337.                                     <div className='font-semibold'>
  338.                                         {t('Currently Working')}
  339.                                     </div>
  340.                                 </div>
  341.  
  342.                                 <div>
  343.                                     <label htmlFor="Start">{t('Start date')}</label>
  344.                                     <div className='border border-dashed p-4 rounded-md'>
  345.                                         <div className='flex flex-col w-full gap-1'>
  346.                                             <label htmlFor="start_month" className='font-semibold'>{t('Month')}</label>
  347.                                             <InputDropdown3
  348.                                                 register={register}
  349.                                                 errors={errors}
  350.                                                 name='start_month'
  351.                                                 placeholder=''
  352.                                                 option={monthsOptions}
  353.                                                 form={select?.start_month}
  354.                                                 onChange={handleChangeSelect}
  355.                                             />
  356.                                         </div>
  357.  
  358.                                         <div className='flex flex-col w-full gap-1'>
  359.                                             <label htmlFor="start_year" className='font-semibold'>{t('Year')}</label>
  360.                                             <InputDropdown3
  361.                                                 register={register}
  362.                                                 errors={errors}
  363.                                                 name='start_year'
  364.                                                 placeholder=''
  365.                                                 option={yearOption()}
  366.                                                 form={select?.start_year}
  367.                                                 onChange={handleChangeSelect}
  368.                                             />
  369.                                         </div>
  370.                                     </div>
  371.                                 </div>
  372.                                 <div className={`mt-4 ${form?.currently_working ? "opacity-50 cursor-not-allowed " : ""}`}>
  373.                                     <label htmlFor="Start">{t('End date')}</label>
  374.                                     <div className='border border-dashed p-4 rounded-md'>
  375.                                         <div className='flex flex-col w-full gap-1'>
  376.                                             <label htmlFor="end_month" className='font-semibold'>{t('Month')}</label>
  377.                                             <InputDropdown3
  378.                                                 register={register}
  379.                                                 errors={errors}
  380.                                                 name='end_month'
  381.                                                 placeholder=''
  382.                                                 option={monthsOptions}
  383.                                                 form={select?.end_month}
  384.                                                 onChange={handleChangeSelect}
  385.                                             />
  386.                                         </div>
  387.  
  388.                                         <div className='flex flex-col w-full gap-1'>
  389.                                             <label htmlFor="end_year" className='font-semibold'>{t('Year')}</label>
  390.                                             <InputDropdown3
  391.                                                 register={register}
  392.                                                 errors={errors}
  393.                                                 name='end_year'
  394.                                                 placeholder=''
  395.                                                 option={endYearOptions}
  396.                                                 form={select?.end_year}
  397.                                                 onChange={handleChangeSelect}
  398.                                             />
  399.                                         </div>
  400.                                     </div>
  401.                                 </div>
  402.                             </div>
  403.                         </div>
  404.                     </div>
  405.  
  406.                     <div className="flex gap-3 w-full justify-end mt-7 font-semibold py-5 sticky bottom-0 backdrop-blur-sm bg-white/30">
  407.                         <button type="button" className="cursor-pointer border text-primary hover:opacity-70 border-primary px-5 py-4 rounded-md"
  408.                         onClick={() => router.push('./')}>
  409.                         {t("Back")}</button>
  410.                        
  411.                         {
  412.                         // !form?.icon ||
  413.                         !form?.company ||
  414.                         !form?.company_position ||
  415.                         !form?.address ||
  416.                         !form?.position ||
  417.                         !form?.description ? (
  418.                             <button type="button" className="border border-zinc-200 cursor-not-allowed text-white bg-[#e2e8f0] px-5 py-4 rounded-md"
  419.                             >{t("Save")}</button>
  420.                         ) : (
  421.                             <button type='submit' className={`${!isLoading ? 'bg-primary cursor-pointer' : 'bg-[#e2e8f0] cursor-not-allowed'} cursor-pointer border  hover:saturate-50 text-white px-5 py-4 rounded-md`}
  422.                             disabled={isLoading}>
  423.                             {!isLoading ? t("Save") : (
  424.                                 <Spinner />
  425.                             )}
  426.                             </button>
  427.                         )}
  428.                     </div>
  429.                 </form>
  430.             </section>
  431.         </>
  432.     )
  433. }
  434.  
  435. export default WithAuth(InputExperience)
  436.  
  437. export async function getServerSideProps({req, query}: GetServerSidePropsContext) {
  438.     const {id} = query
  439.  
  440.     if(id){
  441.         try {
  442.             const {data} = await getData(`/experience/${id}`, '', '', req)
  443.             return {
  444.                 props: {
  445.                     experience: data.experience
  446.                 }
  447.             }
  448.         } catch (error: any) {
  449.             return error
  450.         }
  451.     }
  452.  
  453.     return {
  454.         props: {}
  455.     }
  456. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement