173 lines
6.7 KiB
TypeScript
173 lines
6.7 KiB
TypeScript
import {EmploymentStatus, EMPLOYMENT_STATUS, Gender, User} from "@/interfaces/user";
|
|
import {FormEvent, useState} from "react";
|
|
import countryCodes from "country-codes-list";
|
|
import {RadioGroup} from "@headlessui/react";
|
|
import Input from "./Low/Input";
|
|
import clsx from "clsx";
|
|
import Button from "./Low/Button";
|
|
import {BsArrowRepeat} from "react-icons/bs";
|
|
import axios from "axios";
|
|
import {toast} from "react-toastify";
|
|
import {KeyedMutator} from "swr";
|
|
import CountrySelect from "./Low/CountrySelect";
|
|
|
|
interface Props {
|
|
user: User;
|
|
mutateUser: KeyedMutator<User>;
|
|
}
|
|
|
|
export default function DemographicInformationInput({user, mutateUser}: Props) {
|
|
const [country, setCountry] = useState<string>();
|
|
const [phone, setPhone] = useState<string>();
|
|
const [gender, setGender] = useState<Gender>();
|
|
const [employment, setEmployment] = useState<EmploymentStatus>();
|
|
const [position, setPosition] = useState<string>();
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
|
const [companyName, setCompanyName] = useState<string>();
|
|
const [commercialRegistration, setCommercialRegistration] = useState<string>();
|
|
|
|
const save = (e?: FormEvent) => {
|
|
if (e) e.preventDefault();
|
|
setIsLoading(true);
|
|
|
|
axios
|
|
.patch("/api/users/update", {
|
|
demographicInformation: {
|
|
country,
|
|
phone: `+${countryCodes.findOne("countryCode" as any, country!).countryCallingCode}${phone}`,
|
|
gender,
|
|
employment: user.type === "corporate" ? undefined : employment,
|
|
position: user.type === "corporate" ? position : undefined,
|
|
},
|
|
agentInformation: user.type === "agent" ? {companyName, commercialRegistration} : undefined,
|
|
})
|
|
.then((response) => mutateUser((response.data as {user: User}).user))
|
|
.catch(() => {
|
|
toast.error("Something went wrong, please try again later!", {toastId: "user-update-error"});
|
|
})
|
|
.finally(() => setIsLoading(false));
|
|
};
|
|
|
|
return (
|
|
<div className="flex flex-col items-center justify-center gap-12 w-full">
|
|
<h2 className="font-semibold text-center text-xl max-w-[800px]">
|
|
Welcome to EnCoach, the ultimate platform dedicated to helping you master the IELTS ! We are thrilled that you have chosen us as your
|
|
learning companion on this journey towards achieving your desired IELTS score.
|
|
<br />
|
|
<br />
|
|
To make the most of your learning experience, we kindly request you to complete your profile. By providing some essential information
|
|
about yourself.
|
|
</h2>
|
|
<form className="flex flex-col items-center justify-items-center gap-6 w-full h-full -md:px-4 lg:w-1/2 mb-32" onSubmit={save}>
|
|
{user.type === "agent" && (
|
|
<div className="w-full flex gap-8">
|
|
<Input type="text" onChange={setCompanyName} name="companyName" label="Corporate Name" required />
|
|
<Input
|
|
type="text"
|
|
onChange={setCommercialRegistration}
|
|
name="commercialRegistration"
|
|
label="Commercial Registration"
|
|
required
|
|
/>
|
|
</div>
|
|
)}
|
|
<div className="relative flex flex-col gap-3 w-full">
|
|
<label className="font-normal text-base text-mti-gray-dim">Country *</label>
|
|
<CountrySelect value={country} onChange={setCountry} />
|
|
</div>
|
|
<Input type="tel" name="phone" label="Phone number" onChange={(e) => setPhone(e)} placeholder="Enter phone number" required />
|
|
<div className="relative flex flex-col gap-3 w-full">
|
|
<label className="font-normal text-base text-mti-gray-dim">Gender *</label>
|
|
<RadioGroup value={gender} onChange={setGender} className="flex flex-row justify-between">
|
|
<RadioGroup.Option value="male">
|
|
{({checked}) => (
|
|
<span
|
|
className={clsx(
|
|
"px-6 py-4 w-28 flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
|
|
"transition duration-300 ease-in-out",
|
|
!checked ? "bg-white border-mti-gray-platinum" : "bg-mti-purple-light border-mti-purple-dark text-white",
|
|
)}>
|
|
Male
|
|
</span>
|
|
)}
|
|
</RadioGroup.Option>
|
|
<RadioGroup.Option value="female">
|
|
{({checked}) => (
|
|
<span
|
|
className={clsx(
|
|
"px-6 py-4 w-28 flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
|
|
"transition duration-300 ease-in-out",
|
|
!checked ? "bg-white border-mti-gray-platinum" : "bg-mti-purple-light border-mti-purple-dark text-white",
|
|
)}>
|
|
Female
|
|
</span>
|
|
)}
|
|
</RadioGroup.Option>
|
|
<RadioGroup.Option value="other">
|
|
{({checked}) => (
|
|
<span
|
|
className={clsx(
|
|
"px-6 py-4 w-28 flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
|
|
"transition duration-300 ease-in-out",
|
|
!checked ? "bg-white border-mti-gray-platinum" : "bg-mti-purple-light border-mti-purple-dark text-white",
|
|
)}>
|
|
Other
|
|
</span>
|
|
)}
|
|
</RadioGroup.Option>
|
|
</RadioGroup>
|
|
</div>
|
|
{user.type === "corporate" && (
|
|
<Input name="position" onChange={setPosition} type="text" label="Position" placeholder="CEO, Head of Marketing..." required />
|
|
)}
|
|
{user.type !== "corporate" && (
|
|
<div className="relative flex flex-col gap-3 w-full">
|
|
<label className="font-normal text-base text-mti-gray-dim">Employment Status *</label>
|
|
<RadioGroup value={employment} onChange={setEmployment} className="grid grid-cols-2 items-center gap-4 place-items-center">
|
|
{EMPLOYMENT_STATUS.map(({status, label}) => (
|
|
<RadioGroup.Option value={status} key={status}>
|
|
{({checked}) => (
|
|
<span
|
|
className={clsx(
|
|
"px-6 py-4 w-44 md:w-48 flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
|
|
"transition duration-300 ease-in-out",
|
|
!checked
|
|
? "bg-white border-mti-gray-platinum"
|
|
: "bg-mti-purple-light border-mti-purple-dark text-white",
|
|
)}>
|
|
{label}
|
|
</span>
|
|
)}
|
|
</RadioGroup.Option>
|
|
))}
|
|
</RadioGroup>
|
|
</div>
|
|
)}
|
|
</form>
|
|
|
|
<div className="self-end flex justify-end w-full gap-8 absolute bottom-8 left-0 px-8">
|
|
<Button
|
|
className="lg:mt-8 max-w-[400px] w-full self-end"
|
|
color="purple"
|
|
onClick={save}
|
|
disabled={
|
|
isLoading ||
|
|
!country ||
|
|
!phone ||
|
|
!gender ||
|
|
(user.type === "corporate" ? !position : !employment) ||
|
|
(user.type === "agent" ? !companyName || !commercialRegistration : false)
|
|
}>
|
|
{!isLoading && "Save information"}
|
|
{isLoading && (
|
|
<div className="flex items-center justify-center">
|
|
<BsArrowRepeat className="text-white animate-spin" size={25} />
|
|
</div>
|
|
)}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|