Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { GetServerSidePropsContext } from 'next';
- import { useRouter } from 'next/navigation';
- import { useEffect, useState } from 'react';
- import { useDispatch } from 'react-redux';
- //* store
- import { setPageTitle } from '@/store/themeConfigSlice';
- //* utils
- import { config } from '@/configs';
- import { getData, postData, postFile, putData } from '@/utils/fetch';
- import { notValidMsg, requiredMsg } from '@/utils/regex';
- //* middleware
- import WithAuth from '@/middlewares/WithAuth';
- //* component
- import InputMessage from '@/components/core/Alert/InputMessage';
- import { showMessage } from '@/components/core/Alert/ShowMessage';
- import Button from '@/components/core/Button';
- import TextInput from '@/components/core/TextInput';
- //* hook form
- import CKEditorComp from '@/components/core/InputTextEditor/CKEditor';
- import { yupResolver } from '@hookform/resolvers/yup';
- import { useForm } from 'react-hook-form';
- import * as yup from 'yup';
- import TextArea from '@/components/core/TextArea/TextArea';
- import Spinner from '@/components/core/spinner';
- import { CloseIcon } from '@/components/icon/close-icon';
- import SelectInput from '@/components/core/SelectInput';
- import { useTranslation } from 'react-i18next';
- import { EyeIcon } from '@/components/icon/eyes';
- import { EyeOff } from '@/components/icon/eye-off-icon';
- import { yearOption, monthsOptions } from '@/data/fullDate';
- import { regexAllCharacter, regexAlphanumeric, regexAlphabetsNumbers } from '@/utils/regex-message';
- import InputDropdown3 from '@/components/core/InputDropdown3';
- import { FormExperienceType } from '@/types/profile';
- import Checkbox from '@/components/core/Checkbox';
- interface IInputExperience {
- experience: FormExperienceType
- }
- const schema = yup.object().shape({
- company: yup.string().required().matches(regexAlphanumeric.regex, regexAlphabetsNumbers.msg),
- company_position: yup.string().required().matches(regexAlphanumeric.regex, regexAlphanumeric.msg),
- address: yup.string().required().matches(regexAllCharacter.regex, regexAllCharacter.msg),
- position: yup.number().required(),
- start_date: yup.string(),
- end_date: yup.string(),
- description: yup.string().required().matches(regexAllCharacter.regex, regexAllCharacter.msg),
- // start_month: yup.string().required(requiredMsg('Bulan Masuk')),
- // start_year: yup.string().required(requiredMsg('Tahun Masuk')),
- // end_month: yup.string().required(requiredMsg('Bulan Keluar')),
- // end_year: yup.string().required(requiredMsg('Tahun Keluar')),
- })
- function InputExperience({experience}: IInputExperience) {
- const { t } = useTranslation();
- const router = useRouter()
- const dispatch = useDispatch()
- const [form, setForm] = useState({
- company: '' || experience?.company,
- company_position: '' || experience?.company_position,
- address: '' || experience?.address,
- position: '' || experience?.position,
- start_date: '' || experience?.start_date,
- end_date: experience?.end_date || '',
- description: '' || experience?.description,
- currently_working: experience?.currently_working || false
- })
- const [select, setSelect] = useState({
- start_year: '',
- end_year: '',
- start_month: '',
- end_month: '',
- })
- // schema
- const {
- register,
- handleSubmit,
- formState: {errors},
- trigger,
- setValue
- } = useForm({
- resolver: yupResolver(schema)
- })
- const [isLoading, setIsLoading] = useState<boolean>(false)
- const [autoField, setAutoField] = useState<any[]>([])
- const [endYearOptions, setEndYearOptions] = useState(yearOption())
- // const { end_date, ...withoutEndDate } = form
- const handleChangeInput = (e: any) => {
- const {name, value} = e.target
- if(!autoField.includes(name)){
- setForm({...form, [name]: value})
- trigger(name)
- }else{
- setForm({...form, [name]: value})
- }
- }
- const handleAutoField = (e: any) => {
- const {name, value} = e.target
- setAutoField([...autoField, name])
- setValue(name, value)
- if(value != ''){
- trigger(name)
- }
- }
- const handleChangeSelect = (e: any) => {
- const {name, value} = e.target
- setSelect({ ...select ,[name]: value})
- if(name == 'start_year'){
- updateEndYear(value)
- }
- if(name == 'end_year' && parseInt(value) <= parseInt(select.start_year)){
- setSelect({...select, end_year: ''})
- }
- }
- const updateEndYear = (startYear: string) => {
- const updatedEndYearOptions = yearOption().filter(option => parseInt(option.value) >= parseInt(startYear));
- setEndYearOptions(updatedEndYearOptions);
- // Reset end_year if it is before the start_year
- if (select.end_year && parseInt(select.end_year) <= parseInt(startYear)) {
- setSelect(prevSelect => ({ ...prevSelect, end_year: '' }));
- // setValue('end_year', '');
- }
- }
- const handleCheckbox = (e: any) => {
- const {name, checked} = e.target
- setForm({...form, [name]: checked})
- }
- const convertDate = (date: string) => {
- const month = date?.split("-")[1]
- const year = date?.split("-")[0]
- return `${month} ${year}`
- }
- useEffect(() => {
- setSelect({
- start_month: convertDate(form.start_date).split(" ")[0],
- start_year: convertDate(form.start_date).split(" ")[1],
- end_month: form.currently_working
- ? ""
- : convertDate(form.end_date).split(" ")[0],
- end_year: form.currently_working
- ? ""
- : convertDate(form.end_date).split(" ")[1],
- })
- },[])
- useEffect(() => {
- const startDate = `${select.start_year}-${select.start_month}`
- const endDate = form.currently_working ? null :`${select.end_year}-${select.end_month}`
- setForm((prevForm: any) => ({
- ...prevForm,
- start_date: startDate,
- end_date: endDate,
- }))
- },[select])
- const handleSaveAction = async () => {
- const { company, company_position, position, address, description } = form
- if(company && company_position && position && address && description){
- const postForm = {
- ...form,
- end_date: form.currently_working ? null : form.end_date
- }
- if(experience){
- try {
- setIsLoading(true);
- await putData(`/experience/${experience.id}`, postForm);
- showMessage(`${t("Successfully updated")}`);
- router.push('./');
- setIsLoading(false);
- } catch (error: any) {
- showMessage(`${t("Failed to update")}`, 'error');
- setIsLoading(false);
- }
- } else {
- //* ADD ACTION
- try {
- setIsLoading(true);
- const data = await postData('/experience', postForm);
- showMessage(`${t("Successfully added")}`);
- router.push('./');
- console.log(data)
- setIsLoading(false);
- } catch (error: any) {
- showMessage(`${t("Failed to add")}`, 'error');
- setIsLoading(false);
- }
- }
- }
- }
- return (
- <>
- <section className="">
- <form
- onSubmit={handleSubmit(handleSaveAction)}
- >
- <div className="mb-5 flex flex-col gap-5 md:flex-row md:items-center">
- <h5 className="sm:pb-2 text-lg font-semibold dark:text-white-light">{experience ? 'Edit' : t("Create")} {t("Experience")}</h5>
- </div>
- <div className="w-full border-b border-b-zinc-300 border-dashed"></div>
- <div className="w-full flex flex-col">
- {/* Basic Input */}
- <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">
- <div className="flex flex-col shrink-0 sm:py-6 sm:w-[30%]">
- <label htmlFor="logo" className='font-semibold text-lg'>{t("Basic Info")}</label>
- <div className="-mt-1">{t("Add some basic info about your Experience from here")}</div>
- </div>
- <div className="w-full flex flex-col gap-y-3 bg-white rounded-md drop-shadow p-5 sm:p-7">
- {/* input company */}
- <div className="flex flex-col w-full gap-1">
- <label htmlFor="company" className='font-semibold'>{t("Company")}</label>
- <TextInput
- register={register}
- errors={errors}
- id="company"
- name="company"
- type="text"
- placeholder=""
- value={form.company}
- className="w-full cursor-auto overflow-hidden rounded-md focus:outline-primary bg-white text-black"
- onChange={handleChangeInput}
- onInput={handleAutoField}
- />
- </div>
- {/* input company_position */}
- <div className="flex flex-col w-full gap-1">
- <label htmlFor="company_position" className='font-semibold'>{t("Company Position")}</label>
- <TextInput
- register={register}
- errors={errors}
- id="company_position"
- name="company_position"
- type="text"
- placeholder=""
- value={form.company_position}
- className="w-full cursor-auto overflow-hidden rounded-md focus:outline-primary bg-white text-black"
- onChange={handleChangeInput}
- onInput={handleAutoField}
- />
- </div>
- {/* input company */}
- <div className="flex flex-col w-full gap-1">
- <label htmlFor="position" className='font-semibold'>{t("Position")}</label>
- <TextInput
- register={register}
- errors={errors}
- id="position"
- name="position"
- type="number"
- placeholder=""
- value={form.position}
- className="w-full cursor-auto overflow-hidden rounded-md focus:outline-primary bg-white text-black"
- onChange={handleChangeInput}
- onInput={handleAutoField}
- />
- </div>
- {/* input company */}
- <div className="flex flex-col w-full gap-1">
- <label htmlFor="address" className='font-semibold'>{t("Address")}</label>
- <TextArea
- register={register}
- errors={errors}
- id="address"
- name="address"
- type="text"
- placeholder=""
- value={form.address}
- className="w-full cursor-auto overflow-hidden rounded-md focus:outline-primary bg-white text-black"
- onChange={handleChangeInput}
- onInput={handleAutoField}
- />
- </div>
- <div className="flex flex-col w-full gap-1">
- <label htmlFor="position" className='font-semibold'>{t("Description")}</label>
- <TextArea
- register={register}
- errors={errors}
- id="description"
- name="description"
- type="text"
- placeholder=""
- value={form.description}
- className="w-full cursor-auto overflow-hidden rounded-md focus:outline-primary bg-white text-black"
- onChange={handleChangeInput}
- onInput={handleAutoField}
- />
- </div>
- </div>
- </div>
- <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">
- <div className="flex flex-col shrink-0 sm:py-6 sm:w-[30%]">
- <label htmlFor="logo" className='font-semibold text-lg'>{t("Date")}</label>
- <div className="-mt-1">{t("Add Date from here")}</div>
- </div>
- <div className="w-full flex flex-col gap-y-3 bg-white rounded-md drop-shadow p-5 sm:p-7">
- <div className='flex flex-row items-center w-full gap-2'>
- <Checkbox
- id='currently_working'
- name='currently_working'
- checked={form.currently_working}
- onChange={handleCheckbox}
- disabled={isLoading}
- />
- <div className='font-semibold'>
- {t('Currently Working')}
- </div>
- </div>
- <div>
- <label htmlFor="Start">{t('Start date')}</label>
- <div className='border border-dashed p-4 rounded-md'>
- <div className='flex flex-col w-full gap-1'>
- <label htmlFor="start_month" className='font-semibold'>{t('Month')}</label>
- <InputDropdown3
- register={register}
- errors={errors}
- name='start_month'
- placeholder=''
- option={monthsOptions}
- form={select?.start_month}
- onChange={handleChangeSelect}
- />
- </div>
- <div className='flex flex-col w-full gap-1'>
- <label htmlFor="start_year" className='font-semibold'>{t('Year')}</label>
- <InputDropdown3
- register={register}
- errors={errors}
- name='start_year'
- placeholder=''
- option={yearOption()}
- form={select?.start_year}
- onChange={handleChangeSelect}
- />
- </div>
- </div>
- </div>
- <div className={`mt-4 ${form?.currently_working ? "opacity-50 cursor-not-allowed " : ""}`}>
- <label htmlFor="Start">{t('End date')}</label>
- <div className='border border-dashed p-4 rounded-md'>
- <div className='flex flex-col w-full gap-1'>
- <label htmlFor="end_month" className='font-semibold'>{t('Month')}</label>
- <InputDropdown3
- register={register}
- errors={errors}
- name='end_month'
- placeholder=''
- option={monthsOptions}
- form={select?.end_month}
- onChange={handleChangeSelect}
- />
- </div>
- <div className='flex flex-col w-full gap-1'>
- <label htmlFor="end_year" className='font-semibold'>{t('Year')}</label>
- <InputDropdown3
- register={register}
- errors={errors}
- name='end_year'
- placeholder=''
- option={endYearOptions}
- form={select?.end_year}
- onChange={handleChangeSelect}
- />
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div className="flex gap-3 w-full justify-end mt-7 font-semibold py-5 sticky bottom-0 backdrop-blur-sm bg-white/30">
- <button type="button" className="cursor-pointer border text-primary hover:opacity-70 border-primary px-5 py-4 rounded-md"
- onClick={() => router.push('./')}>
- {t("Back")}</button>
- {
- // !form?.icon ||
- !form?.company ||
- !form?.company_position ||
- !form?.address ||
- !form?.position ||
- !form?.description ? (
- <button type="button" className="border border-zinc-200 cursor-not-allowed text-white bg-[#e2e8f0] px-5 py-4 rounded-md"
- >{t("Save")}</button>
- ) : (
- <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`}
- disabled={isLoading}>
- {!isLoading ? t("Save") : (
- <Spinner />
- )}
- </button>
- )}
- </div>
- </form>
- </section>
- </>
- )
- }
- export default WithAuth(InputExperience)
- export async function getServerSideProps({req, query}: GetServerSidePropsContext) {
- const {id} = query
- if(id){
- try {
- const {data} = await getData(`/experience/${id}`, '', '', req)
- return {
- props: {
- experience: data.experience
- }
- }
- } catch (error: any) {
- return error
- }
- }
- return {
- props: {}
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement