[offers][feat] Add currency detection in forms (#542)

* [offers][feat] Tweak OEA text

* [offers][feat] Add currency detection in forms
pull/544/head
Ai Ling 2 years ago committed by GitHub
parent 247a60efab
commit fd97f25de1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -58,9 +58,9 @@ function OfferAnalysisContent({
tab={tab} tab={tab}
/> />
<p className="mt-5"> <p className="mt-5">
{isSubmission {tab === OVERALL_TAB
? 'Here are some of the top offers relevant to you:' ? 'Here are some of the highest offers with the same job title and YOE(±1):'
: 'Relevant top offers:'} : 'Here are some of the highest offers with the same company, job title and YOE(±1):'}
</p> </p>
{analysis.topPercentileOffers.map((topPercentileOffer) => ( {analysis.topPercentileOffers.map((topPercentileOffer) => (
<OfferProfileCard <OfferProfileCard

@ -18,7 +18,10 @@ import type {
} from '~/components/offers/types'; } from '~/components/offers/types';
import type { Month } from '~/components/shared/MonthYearPicker'; import type { Month } from '~/components/shared/MonthYearPicker';
import { Currency } from '~/utils/offers/currency/CurrencyEnum'; import {
Currency,
getCurrencyForCountry,
} from '~/utils/offers/currency/CurrencyEnum';
import { import {
cleanObject, cleanObject,
removeEmptyObjects, removeEmptyObjects,
@ -85,6 +88,7 @@ const defaultOfferProfileValues: OffersProfileFormData = {
}; };
type Props = Readonly<{ type Props = Readonly<{
country: string | null;
initialOfferProfileValues?: OffersProfileFormData; initialOfferProfileValues?: OffersProfileFormData;
profileId?: string; profileId?: string;
token?: string; token?: string;
@ -94,6 +98,7 @@ export default function OffersSubmissionForm({
initialOfferProfileValues = defaultOfferProfileValues, initialOfferProfileValues = defaultOfferProfileValues,
profileId: editProfileId = '', profileId: editProfileId = '',
token: editToken = '', token: editToken = '',
country,
}: Props) { }: Props) {
const [step, setStep] = useState(0); const [step, setStep] = useState(0);
const [params, setParams] = useState({ const [params, setParams] = useState({
@ -137,7 +142,12 @@ export default function OffersSubmissionForm({
}, },
); );
const steps = [<OfferDetailsForm key={0} />, <BackgroundForm key={1} />]; const defaultCurrency = getCurrencyForCountry(country).toString();
const steps = [
<OfferDetailsForm key={0} defaultCurrency={defaultCurrency} />,
<BackgroundForm key={1} defaultCurrency={defaultCurrency} />,
];
const breadcrumbSteps: Array<BreadcrumbStep> = [ const breadcrumbSteps: Array<BreadcrumbStep> = [
{ {

@ -5,10 +5,7 @@ import { Collapsible, RadioList } from '@tih/ui';
import { FieldError } from '~/components/offers/constants'; import { FieldError } from '~/components/offers/constants';
import type { BackgroundPostData } from '~/components/offers/types'; import type { BackgroundPostData } from '~/components/offers/types';
import { import { CURRENCY_OPTIONS } from '~/utils/offers/currency/CurrencyEnum';
Currency,
CURRENCY_OPTIONS,
} from '~/utils/offers/currency/CurrencyEnum';
import { EducationFieldOptions } from '../../EducationFields'; import { EducationFieldOptions } from '../../EducationFields';
import { EducationLevelOptions } from '../../EducationLevels'; import { EducationLevelOptions } from '../../EducationLevels';
@ -82,7 +79,11 @@ function YoeSection() {
); );
} }
function FullTimeJobFields() { type FullTimeJobFieldsProps = Readonly<{
defaultCurrency: string;
}>;
function FullTimeJobFields({ defaultCurrency }: FullTimeJobFieldsProps) {
const { register, formState } = useFormContext<{ const { register, formState } = useFormContext<{
background: BackgroundPostData; background: BackgroundPostData;
}>(); }>();
@ -104,7 +105,7 @@ function FullTimeJobFields() {
endAddOn={ endAddOn={
<FormSelect <FormSelect
borderStyle="borderless" borderStyle="borderless"
defaultValue={Currency.SGD} defaultValue={defaultCurrency}
isLabelHidden={true} isLabelHidden={true}
label="Currency" label="Currency"
options={CURRENCY_OPTIONS} options={CURRENCY_OPTIONS}
@ -154,7 +155,11 @@ function FullTimeJobFields() {
); );
} }
function InternshipJobFields() { type InternshipJobFieldsProps = Readonly<{
defaultCurrency: string;
}>;
function InternshipJobFields({ defaultCurrency }: InternshipJobFieldsProps) {
const { register, formState } = useFormContext<{ const { register, formState } = useFormContext<{
background: BackgroundPostData; background: BackgroundPostData;
}>(); }>();
@ -175,7 +180,7 @@ function InternshipJobFields() {
endAddOn={ endAddOn={
<FormSelect <FormSelect
borderStyle="borderless" borderStyle="borderless"
defaultValue={Currency.SGD} defaultValue={defaultCurrency}
isLabelHidden={true} isLabelHidden={true}
label="Currency" label="Currency"
options={CURRENCY_OPTIONS} options={CURRENCY_OPTIONS}
@ -217,7 +222,11 @@ function InternshipJobFields() {
); );
} }
function CurrentJobSection() { type CurrentJobSectionProps = Readonly<{
defaultCurrency: string;
}>;
function CurrentJobSection({ defaultCurrency }: CurrentJobSectionProps) {
const { register } = useFormContext(); const { register } = useFormContext();
const watchJobType = useWatch({ const watchJobType = useWatch({
name: 'background.experiences.0.jobType', name: 'background.experiences.0.jobType',
@ -243,9 +252,9 @@ function CurrentJobSection() {
/> />
</FormRadioList> </FormRadioList>
{watchJobType === JobType.FULLTIME ? ( {watchJobType === JobType.FULLTIME ? (
<FullTimeJobFields /> <FullTimeJobFields defaultCurrency={defaultCurrency} />
) : ( ) : (
<InternshipJobFields /> <InternshipJobFields defaultCurrency={defaultCurrency} />
)} )}
</FormSection> </FormSection>
); );
@ -280,7 +289,13 @@ function EducationSection() {
); );
} }
export default function BackgroundForm() { type BackgroundFormProps = Readonly<{
defaultCurrency: string;
}>;
export default function BackgroundForm({
defaultCurrency,
}: BackgroundFormProps) {
return ( return (
<div className="space-y-6"> <div className="space-y-6">
<h2 className="mb-8 text-2xl font-bold text-slate-900 sm:text-center sm:text-4xl"> <h2 className="mb-8 text-2xl font-bold text-slate-900 sm:text-center sm:text-4xl">
@ -288,7 +303,7 @@ export default function BackgroundForm() {
</h2> </h2>
<div className="space-y-8 rounded-lg border border-slate-200 p-6 sm:space-y-16 sm:p-8"> <div className="space-y-8 rounded-lg border border-slate-200 p-6 sm:space-y-16 sm:p-8">
<YoeSection /> <YoeSection />
<CurrentJobSection /> <CurrentJobSection defaultCurrency={defaultCurrency} />
<EducationSection /> <EducationSection />
</div> </div>
</div> </div>

@ -30,12 +30,10 @@ import { InternshipCycleOptions } from '../../InternshipCycles';
import JobTypeTabs from '../../JobTypeTabs'; import JobTypeTabs from '../../JobTypeTabs';
import type { OfferFormData } from '../../types'; import type { OfferFormData } from '../../types';
import { FutureYearsOptions } from '../../Years'; import { FutureYearsOptions } from '../../Years';
import { import { CURRENCY_OPTIONS } from '../../../../utils/offers/currency/CurrencyEnum';
Currency,
CURRENCY_OPTIONS,
} from '../../../../utils/offers/currency/CurrencyEnum';
type FullTimeOfferDetailsFormProps = Readonly<{ type FullTimeOfferDetailsFormProps = Readonly<{
defaultCurrency: string;
index: number; index: number;
remove: UseFieldArrayRemove; remove: UseFieldArrayRemove;
}>; }>;
@ -43,6 +41,7 @@ type FullTimeOfferDetailsFormProps = Readonly<{
function FullTimeOfferDetailsForm({ function FullTimeOfferDetailsForm({
index, index,
remove, remove,
defaultCurrency,
}: FullTimeOfferDetailsFormProps) { }: FullTimeOfferDetailsFormProps) {
const { register, formState, setValue, control } = useFormContext<{ const { register, formState, setValue, control } = useFormContext<{
offers: Array<OfferFormData>; offers: Array<OfferFormData>;
@ -135,7 +134,7 @@ function FullTimeOfferDetailsForm({
endAddOn={ endAddOn={
<FormSelect <FormSelect
borderStyle="borderless" borderStyle="borderless"
defaultValue={Currency.SGD} defaultValue={defaultCurrency}
isLabelHidden={true} isLabelHidden={true}
label="Currency" label="Currency"
options={CURRENCY_OPTIONS} options={CURRENCY_OPTIONS}
@ -172,7 +171,7 @@ function FullTimeOfferDetailsForm({
endAddOn={ endAddOn={
<FormSelect <FormSelect
borderStyle="borderless" borderStyle="borderless"
defaultValue={Currency.SGD} defaultValue={defaultCurrency}
isLabelHidden={true} isLabelHidden={true}
label="Currency" label="Currency"
options={CURRENCY_OPTIONS} options={CURRENCY_OPTIONS}
@ -199,7 +198,7 @@ function FullTimeOfferDetailsForm({
endAddOn={ endAddOn={
<FormSelect <FormSelect
borderStyle="borderless" borderStyle="borderless"
defaultValue={Currency.SGD} defaultValue={defaultCurrency}
isLabelHidden={true} isLabelHidden={true}
label="Currency" label="Currency"
options={CURRENCY_OPTIONS} options={CURRENCY_OPTIONS}
@ -222,7 +221,7 @@ function FullTimeOfferDetailsForm({
endAddOn={ endAddOn={
<FormSelect <FormSelect
borderStyle="borderless" borderStyle="borderless"
defaultValue={Currency.SGD} defaultValue={defaultCurrency}
isLabelHidden={true} isLabelHidden={true}
label="Currency" label="Currency"
options={CURRENCY_OPTIONS} options={CURRENCY_OPTIONS}
@ -275,6 +274,7 @@ function FullTimeOfferDetailsForm({
} }
type InternshipOfferDetailsFormProps = Readonly<{ type InternshipOfferDetailsFormProps = Readonly<{
defaultCurrency: string;
index: number; index: number;
remove: UseFieldArrayRemove; remove: UseFieldArrayRemove;
}>; }>;
@ -282,6 +282,7 @@ type InternshipOfferDetailsFormProps = Readonly<{
function InternshipOfferDetailsForm({ function InternshipOfferDetailsForm({
index, index,
remove, remove,
defaultCurrency,
}: InternshipOfferDetailsFormProps) { }: InternshipOfferDetailsFormProps) {
const { register, formState, control } = useFormContext<{ const { register, formState, control } = useFormContext<{
offers: Array<OfferFormData>; offers: Array<OfferFormData>;
@ -373,7 +374,7 @@ function InternshipOfferDetailsForm({
endAddOn={ endAddOn={
<FormSelect <FormSelect
borderStyle="borderless" borderStyle="borderless"
defaultValue={Currency.SGD} defaultValue={defaultCurrency}
isLabelHidden={true} isLabelHidden={true}
label="Currency" label="Currency"
options={CURRENCY_OPTIONS} options={CURRENCY_OPTIONS}
@ -435,6 +436,7 @@ function InternshipOfferDetailsForm({
} }
type OfferDetailsFormArrayProps = Readonly<{ type OfferDetailsFormArrayProps = Readonly<{
defaultCurrency: string;
fieldArrayValues: UseFieldArrayReturn<FieldValues, 'offers', 'id'>; fieldArrayValues: UseFieldArrayReturn<FieldValues, 'offers', 'id'>;
jobType: JobType; jobType: JobType;
}>; }>;
@ -442,6 +444,7 @@ type OfferDetailsFormArrayProps = Readonly<{
function OfferDetailsFormArray({ function OfferDetailsFormArray({
fieldArrayValues, fieldArrayValues,
jobType, jobType,
defaultCurrency,
}: OfferDetailsFormArrayProps) { }: OfferDetailsFormArrayProps) {
const { append, remove, fields } = fieldArrayValues; const { append, remove, fields } = fieldArrayValues;
@ -451,9 +454,17 @@ function OfferDetailsFormArray({
return ( return (
<div key={item.id}> <div key={item.id}>
{jobType === JobType.FULLTIME ? ( {jobType === JobType.FULLTIME ? (
<FullTimeOfferDetailsForm index={index} remove={remove} /> <FullTimeOfferDetailsForm
defaultCurrency={defaultCurrency}
index={index}
remove={remove}
/>
) : ( ) : (
<InternshipOfferDetailsForm index={index} remove={remove} /> <InternshipOfferDetailsForm
defaultCurrency={defaultCurrency}
index={index}
remove={remove}
/>
)} )}
</div> </div>
); );
@ -476,7 +487,13 @@ function OfferDetailsFormArray({
); );
} }
export default function OfferDetailsForm() { type OfferDetailsFormProps = Readonly<{
defaultCurrency: string;
}>;
export default function OfferDetailsForm({
defaultCurrency,
}: OfferDetailsFormProps) {
const watchJobType = useWatch({ const watchJobType = useWatch({
name: `offers.0.jobType`, name: `offers.0.jobType`,
}); });
@ -515,6 +532,7 @@ export default function OfferDetailsForm() {
}} }}
/> />
<OfferDetailsFormArray <OfferDetailsFormArray
defaultCurrency={defaultCurrency}
fieldArrayValues={fieldArrayValues} fieldArrayValues={fieldArrayValues}
jobType={jobType} jobType={jobType}
/> />

@ -1,3 +1,4 @@
import type { GetServerSideProps, InferGetServerSidePropsType } from 'next';
import Error from 'next/error'; import Error from 'next/error';
import Head from 'next/head'; import Head from 'next/head';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
@ -14,7 +15,17 @@ import { getProfilePath } from '~/utils/offers/link';
import { convertToMonthYear } from '~/utils/offers/time'; import { convertToMonthYear } from '~/utils/offers/time';
import { trpc } from '~/utils/trpc'; import { trpc } from '~/utils/trpc';
export default function OffersEditPage() { export const getServerSideProps: GetServerSideProps = async ({ req }) => {
return {
props: {
country: req.cookies.country ?? null,
},
};
};
export default function OffersEditPage({
country,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
const [initialData, setInitialData] = useState<OffersProfileFormData>(); const [initialData, setInitialData] = useState<OffersProfileFormData>();
const router = useRouter(); const router = useRouter();
const { offerProfileId, token = '' } = router.query; const { offerProfileId, token = '' } = router.query;
@ -104,6 +115,7 @@ export default function OffersEditPage() {
)} )}
{!getProfileResult.isLoading && initialData && ( {!getProfileResult.isLoading && initialData && (
<OffersSubmissionForm <OffersSubmissionForm
country={country}
initialOfferProfileValues={initialData} initialOfferProfileValues={initialData}
profileId={profile?.id} profileId={profile?.id}
token={profile?.editToken || undefined} token={profile?.editToken || undefined}

@ -1,14 +0,0 @@
import Head from 'next/head';
import OffersSubmissionForm from '~/components/offers/offersSubmission/OffersSubmissionForm';
export default function OffersSubmissionPage() {
return (
<>
<Head>
<title>Analyze your offers</title>
</Head>
<OffersSubmissionForm />
</>
);
}

@ -1,14 +1,25 @@
import type { GetServerSideProps, InferGetServerSidePropsType } from 'next';
import Head from 'next/head'; import Head from 'next/head';
import OffersSubmissionForm from '~/components/offers/offersSubmission/OffersSubmissionForm'; import OffersSubmissionForm from '~/components/offers/offersSubmission/OffersSubmissionForm';
export default function OffersSubmissionPage() { export const getServerSideProps: GetServerSideProps = async ({ req }) => {
return {
props: {
country: req.cookies.country ?? null,
},
};
};
export default function OffersSubmissionPage({
country,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return ( return (
<> <>
<Head> <Head>
<title>Analyze your offers</title> <title>Analyze your offers</title>
</Head> </Head>
<OffersSubmissionForm /> <OffersSubmissionForm country={country} />
</> </>
); );
} }

Loading…
Cancel
Save