mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-07-29 13:13:54 +08:00
[offers][refactor] tweak submit and analysis steps UI
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { HorizontalDivider, Spinner, Tabs } from '@tih/ui';
|
||||
import { Alert, HorizontalDivider, Spinner, Tabs } from '@tih/ui';
|
||||
|
||||
import OfferPercentileAnalysisText from './OfferPercentileAnalysisText';
|
||||
import OfferProfileCard from './OfferProfileCard';
|
||||
@ -22,17 +22,19 @@ function OfferAnalysisContent({
|
||||
if (!analysis || analysis.noOfOffers === 0) {
|
||||
if (tab === OVERALL_TAB) {
|
||||
return (
|
||||
<p className="m-10">
|
||||
You are the first to submit an offer for your job title and YOE! Check
|
||||
back later when there are more submissions.
|
||||
</p>
|
||||
<Alert title="Insufficient data to compare with" variant="info">
|
||||
You are among the first to submit an offer for your job title and
|
||||
years of experience! Check back later when there are more submissions.
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<p className="m-10">
|
||||
You are the first to submit an offer for this company, job title and
|
||||
YOE! Check back later when there are more submissions.
|
||||
</p>
|
||||
<Alert title="Insufficient data to compare with" variant="info">
|
||||
You are among the first to submit an offer for this company, job title
|
||||
and years of experience! Check back later when there are more
|
||||
submissions.
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
return (
|
||||
|
@ -73,58 +73,67 @@ export default function OffersProfileSave({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex w-full justify-center">
|
||||
<div className="flex w-full justify-center pb-10">
|
||||
<div className="max-w-2xl text-center">
|
||||
<h5 className="mb-6 text-4xl font-bold text-slate-900">
|
||||
<h2 className="block text-center text-3xl font-bold leading-8 tracking-tight text-gray-900 sm:text-4xl">
|
||||
Save for future edits
|
||||
</h5>
|
||||
<p className="mb-2 text-slate-900">We value your privacy.</p>
|
||||
<p className="mb-5 text-slate-900">
|
||||
To keep you offer profile strictly anonymous, only people who have the
|
||||
link below can edit it.
|
||||
</h2>
|
||||
<p className="mt-4 text-xl leading-8 text-slate-500">
|
||||
We value your privacy
|
||||
</p>
|
||||
<div className="mb-20 grid grid-cols-12 gap-4">
|
||||
<div className="col-span-11">
|
||||
<TextInput
|
||||
disabled={true}
|
||||
isLabelHidden={true}
|
||||
label="Edit link"
|
||||
value={getProfileLink(profileId, token)}
|
||||
<div className="mt-6 max-w-md text-slate-500">
|
||||
<div className="bg-info-50 rounded-lg p-6">
|
||||
<p className="sm:tex-base text-sm">
|
||||
To keep your offer profile strictly anonymous, it is not linked to
|
||||
your user account. Only people who have the link below can edit
|
||||
it. If you want to edit the profile in future, store the link
|
||||
somewhere.
|
||||
</p>
|
||||
<div className="mt-4 flex gap-4">
|
||||
<div className="grow">
|
||||
<TextInput
|
||||
disabled={true}
|
||||
isLabelHidden={true}
|
||||
label="Edit link"
|
||||
value={getProfileLink(profileId, token)}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
icon={DocumentDuplicateIcon}
|
||||
isLabelHidden={true}
|
||||
label="Copy"
|
||||
variant="info"
|
||||
onClick={() => {
|
||||
copyProfileLink(profileId, token);
|
||||
showToast({
|
||||
title: `Profile edit link copied to clipboard!`,
|
||||
variant: 'success',
|
||||
});
|
||||
gaEvent({
|
||||
action: 'offers.profile_submission_copy_edit_profile_link',
|
||||
category: 'engagement',
|
||||
label: 'Copy Edit Profile Link in Profile Submission',
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mt-6 text-xs sm:text-sm">
|
||||
If you do not want to manually store the link somewhere else, you
|
||||
can add this offers profile to your user account by clicking the
|
||||
button below. It will still only be editable by you.
|
||||
</p>
|
||||
<div className="mt-6">
|
||||
<Button
|
||||
disabled={isSavedQuery.isLoading || isSaved}
|
||||
icon={isSaved ? CheckIcon : BookmarkSquareIcon}
|
||||
isLoading={saveMutation.isLoading || isSavedQuery.isLoading}
|
||||
label={isSaved ? 'Added to account' : 'Add to your account'}
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
onClick={handleSave}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
icon={DocumentDuplicateIcon}
|
||||
isLabelHidden={true}
|
||||
label="Copy"
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
copyProfileLink(profileId, token);
|
||||
showToast({
|
||||
title: `Profile edit link copied to clipboard!`,
|
||||
variant: 'success',
|
||||
});
|
||||
gaEvent({
|
||||
action: 'offers.profile_submission_copy_edit_profile_link',
|
||||
category: 'engagement',
|
||||
label: 'Copy Edit Profile Link in Profile Submission',
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<p className="mb-5 text-slate-900">
|
||||
If you do not want to keep the edit link, you can opt to save this
|
||||
profile under your account's dashboard. It will still only be editable
|
||||
by you.
|
||||
</p>
|
||||
<div className="mb-20">
|
||||
<Button
|
||||
disabled={isSavedQuery.isLoading || isSaved}
|
||||
icon={isSaved ? CheckIcon : BookmarkSquareIcon}
|
||||
isLoading={saveMutation.isLoading || isSavedQuery.isLoading}
|
||||
label={isSaved ? 'Saved to user profile' : 'Save to user profile'}
|
||||
variant="primary"
|
||||
onClick={handleSave}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -15,10 +15,12 @@ export default function OffersSubmissionAnalysis({
|
||||
return (
|
||||
<div className="mb-8">
|
||||
<h5 className="mb-8 text-center text-4xl font-bold text-slate-900">
|
||||
Result
|
||||
Offer Analysis
|
||||
</h5>
|
||||
{!analysis && (
|
||||
<p className="mb-8 text-center">Error generating analysis.</p>
|
||||
<p className="text-error-500 mb-8 text-center">
|
||||
Error generating analysis.
|
||||
</p>
|
||||
)}
|
||||
{analysis && (
|
||||
<OfferAnalysis
|
||||
|
@ -267,7 +267,7 @@ export default function OffersSubmissionForm({
|
||||
<div ref={pageRef} className="w-full overflow-y-scroll">
|
||||
<div className="flex justify-center">
|
||||
<div className="block w-full max-w-screen-md overflow-hidden rounded-lg sm:shadow-lg md:my-10">
|
||||
<div className="bg-primary-100 flex justify-center px-4 py-4 sm:px-6 lg:px-8">
|
||||
<div className="flex justify-center bg-slate-100 px-4 py-4 sm:px-6 lg:px-8">
|
||||
<Breadcrumbs
|
||||
currentStep={step}
|
||||
setStep={setStep}
|
||||
|
@ -78,48 +78,50 @@ export default function OffersSubmissionResult() {
|
||||
</div>
|
||||
)}
|
||||
{!getAnalysis.isLoading && (
|
||||
<div ref={pageRef} className="fixed h-full w-full overflow-y-scroll">
|
||||
<div className="mb-20 flex justify-center">
|
||||
<div className="my-5 block w-full max-w-screen-md rounded-lg bg-white py-10 px-10 shadow-lg">
|
||||
<div className="mb-4 flex justify-end">
|
||||
<div ref={pageRef} className="w-full overflow-y-scroll">
|
||||
<div className="flex justify-center">
|
||||
<div className="block w-full max-w-screen-md overflow-hidden rounded-lg sm:shadow-lg md:my-10">
|
||||
<div className="flex justify-center bg-slate-100 px-4 py-4 sm:px-6 lg:px-8">
|
||||
<Breadcrumbs
|
||||
currentStep={step}
|
||||
setStep={setStep}
|
||||
steps={breadcrumbSteps}
|
||||
/>
|
||||
</div>
|
||||
{steps[step]}
|
||||
{step === 0 && (
|
||||
<div className="flex justify-end">
|
||||
<Button
|
||||
disabled={false}
|
||||
icon={ArrowRightIcon}
|
||||
label="Next"
|
||||
variant="secondary"
|
||||
onClick={() => setStep(step + 1)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{step === 1 && (
|
||||
<div className="flex items-center justify-between">
|
||||
<Button
|
||||
addonPosition="start"
|
||||
icon={ArrowLeftIcon}
|
||||
label="Previous"
|
||||
variant="secondary"
|
||||
onClick={() => setStep(step - 1)}
|
||||
/>
|
||||
<Button
|
||||
href={getProfilePath(
|
||||
offerProfileId as string,
|
||||
token as string,
|
||||
)}
|
||||
icon={EyeIcon}
|
||||
label="View your profile"
|
||||
variant="primary"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="bg-white p-6 sm:p-10">
|
||||
{steps[step]}
|
||||
{step === 0 && (
|
||||
<div className="flex justify-end">
|
||||
<Button
|
||||
disabled={false}
|
||||
icon={ArrowRightIcon}
|
||||
label="Next"
|
||||
variant="primary"
|
||||
onClick={() => setStep(step + 1)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{step === 1 && (
|
||||
<div className="flex items-center justify-between">
|
||||
<Button
|
||||
addonPosition="start"
|
||||
icon={ArrowLeftIcon}
|
||||
label="Previous"
|
||||
variant="secondary"
|
||||
onClick={() => setStep(step - 1)}
|
||||
/>
|
||||
<Button
|
||||
href={getProfilePath(
|
||||
offerProfileId as string,
|
||||
token as string,
|
||||
)}
|
||||
icon={EyeIcon}
|
||||
label="View your profile"
|
||||
variant="primary"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -12,10 +12,7 @@ import { createValidationRegex } from '~/utils/offers/zodRegex';
|
||||
import { createRouter } from '../context';
|
||||
|
||||
const getOrder = (prefix: string) => {
|
||||
if (prefix === '+') {
|
||||
return 'asc';
|
||||
}
|
||||
return 'desc';
|
||||
return prefix === '+' ? 'asc' : 'desc';
|
||||
};
|
||||
|
||||
const sortingKeysMap = {
|
||||
|
Reference in New Issue
Block a user