[offers][fix] Fix offer analysis and save

pull/403/head
Ai Ling 3 years ago
parent 0adec461d0
commit fc06de187c

@ -1,12 +1,11 @@
import Error from 'next/error';
import { useEffect } from 'react';
import { useState } from 'react';
import { HorizontalDivider, Spinner, Tabs } from '@tih/ui';
import { trpc } from '~/utils/trpc';
import OfferPercentileAnalysis from '../analysis/OfferPercentileAnalysis';
import OfferProfileCard from '../analysis/OfferProfileCard';
import OfferPercentileAnalysis from './analysis/OfferPercentileAnalysis';
import OfferProfileCard from './analysis/OfferProfileCard';
import { OVERALL_TAB } from '../constants';
import type {
@ -105,34 +104,32 @@ export default function OfferAnalysis({ profileId }: OfferAnalysisProps) {
];
return (
<>
{getAnalysisResult.isError && (
<Error
statusCode={404}
title="An error occurred while generating profile analysis."
/>
)}
{!getAnalysisResult.isError && analysis && (
<div>
<h5 className="mb-2 text-center text-4xl font-bold text-gray-900">
Result
</h5>
{getAnalysisResult.isLoading ? (
<Spinner className="m-10" display="block" size="lg" />
) : (
<div>
<Tabs
label="Result Navigation"
tabs={tabOptions}
value={tab}
onChange={setTab}
/>
<HorizontalDivider className="mb-5" />
<OfferAnalysisContent analysis={analysis} tab={tab} />
</div>
)}
</div>
)}
</>
analysis && (
<div>
<h5 className="mb-2 text-center text-4xl font-bold text-gray-900">
Result
</h5>
{getAnalysisResult.isError && (
<p className="m-10 text-center">
An error occurred while generating profile analysis.
</p>
)}
{getAnalysisResult.isLoading && (
<Spinner className="m-10" display="block" size="lg" />
)}
{!getAnalysisResult.isError && !getAnalysisResult.isLoading && (
<div>
<Tabs
label="Result Navigation"
tabs={tabOptions}
value={tab}
onChange={setTab}
/>
<HorizontalDivider className="mb-5" />
<OfferAnalysisContent analysis={analysis} tab={tab} />
</div>
)}
</div>
)
);
}

@ -1,13 +1,30 @@
import { useRouter } from 'next/router';
import { useState } from 'react';
import { setTimeout } from 'timers';
import { CheckIcon, DocumentDuplicateIcon } from '@heroicons/react/20/solid';
import { BookmarkSquareIcon, EyeIcon } from '@heroicons/react/24/outline';
import { Button, TextInput } from '@tih/ui';
export default function OfferProfileSave() {
import {
copyProfileLink,
getProfileLink,
getProfilePath,
} from '~/utils/offers/link';
type OfferProfileSaveProps = Readonly<{
profileId: string;
token?: string;
}>;
export default function OfferProfileSave({
profileId,
token,
}: OfferProfileSaveProps) {
const [linkCopied, setLinkCopied] = useState(false);
const [isSaving, setSaving] = useState(false);
const [isSaved, setSaved] = useState(false);
const router = useRouter();
const saveProfile = () => {
setSaving(true);
setTimeout(() => {
@ -27,13 +44,13 @@ export default function OfferProfileSave() {
To keep you offer profile strictly anonymous, only people who have the
link below can edit it.
</p>
<div className="mb-20 grid grid-cols-12 gap-4">
<div className="mb-5 grid grid-cols-12 gap-4">
<div className="col-span-11">
<TextInput
disabled={true}
isLabelHidden={true}
label="Edit link"
value="link.myprofile-auto-generate..."
value={getProfileLink(profileId, token)}
/>
</div>
<Button
@ -41,10 +58,12 @@ export default function OfferProfileSave() {
isLabelHidden={true}
label="Copy"
variant="primary"
onClick={() => setLinkCopied(true)}
onClick={() => {
copyProfileLink(profileId, token), setLinkCopied(true);
}}
/>
</div>
<div className="mb-5">
<div className="mb-20">
{linkCopied && (
<p className="text-purple-700">Link copied to clipboard!</p>
)}
@ -60,13 +79,18 @@ export default function OfferProfileSave() {
disabled={isSaved}
icon={isSaved ? CheckIcon : BookmarkSquareIcon}
isLoading={isSaving}
label="Save to user profile"
label={isSaved ? 'Saved to user profile' : 'Save to user profile'}
variant="primary"
onClick={saveProfile}
/>
</div>
<div className="mb-10">
<Button icon={EyeIcon} label="View your profile" variant="special" />
<Button
icon={EyeIcon}
label="View your profile"
variant="special"
onClick={() => router.push(getProfilePath(profileId, token))}
/>
</div>
</div>
</div>

@ -3,7 +3,7 @@ import { UserCircleIcon } from '@heroicons/react/24/outline';
import { HorizontalDivider } from '~/../../../packages/ui/dist';
import { formatDate } from '~/utils/offers/time';
import { JobType } from '../types';
import { JobType } from '../../types';
import type { AnalysisOffer } from '~/types/offers';

@ -5,6 +5,7 @@ import { Button, HorizontalDivider, Spinner, TextArea } from '@tih/ui';
import ExpandableCommentCard from '~/components/offers/profile/comments/ExpandableCommentCard';
import { copyProfileLink } from '~/utils/offers/link';
import { trpc } from '~/utils/trpc';
import type { OffersDiscussion, Reply } from '~/types/offers';
@ -84,19 +85,6 @@ export default function ProfileComments({
}
}
function handleCopyEditLink() {
// TODO: Add notification
navigator.clipboard.writeText(
`${window.location.origin}/offers/profile/${profileId}?token=${token}`,
);
}
function handleCopyPublicLink() {
navigator.clipboard.writeText(
`${window.location.origin}/offers/profile/${profileId}`,
);
}
if (isLoading) {
return (
<div className="col-span-10 pt-4">
@ -116,7 +104,7 @@ export default function ProfileComments({
label="Copy profile edit link"
size="sm"
variant="secondary"
onClick={handleCopyEditLink}
onClick={() => copyProfileLink(profileId, token)}
/>
)}
<Button
@ -127,7 +115,7 @@ export default function ProfileComments({
label="Copy public link"
size="sm"
variant="secondary"
onClick={handleCopyPublicLink}
onClick={() => copyProfileLink(profileId)}
/>
</div>
<h2 className="mt-2 mb-6 text-2xl font-bold">Discussions</h2>

@ -8,6 +8,7 @@ import ProfileHeader from '~/components/offers/profile/ProfileHeader';
import type { BackgroundCard, OfferEntity } from '~/components/offers/types';
import { convertCurrencyToString } from '~/utils/offers/currency';
import { getProfilePath } from '~/utils/offers/link';
import { formatDate } from '~/utils/offers/time';
import { trpc } from '~/utils/trpc';
@ -38,7 +39,7 @@ export default function OfferProfile() {
}
// If the profile is not editable with a wrong token, redirect to the profile page
if (!data?.isEditable && token !== '') {
router.push(`/offers/profile/${offerProfileId}`);
router.push(getProfilePath(offerProfileId as string));
}
setIsEditable(data?.isEditable ?? false);

@ -96,7 +96,13 @@ export default function OffersSubmissionPage() {
label: 'Analysis',
},
{
component: <OfferProfileSave key={3} />,
component: (
<OfferProfileSave
key={3}
profileId={createProfileResponse?.id || ''}
token={createProfileResponse?.token}
/>
),
hasNext: false,
hasPrevious: false,
label: 'Save',

@ -216,7 +216,7 @@ export const offersAnalysisRouter = createRouter()
// TODO: Shift yoe out of background to make it mandatory
if (
!overallHighestOffer.profile.background ||
!overallHighestOffer.profile.background.totalYoe
overallHighestOffer.profile.background.totalYoe === undefined
) {
throw new TRPCError({
code: 'BAD_REQUEST',

@ -0,0 +1,15 @@
export function getProfileLink(profileId: string, token?: string) {
return `${window.location.origin}${getProfilePath(profileId, token)}`;
}
export function copyProfileLink(profileId: string, token?: string) {
// TODO: Add notification
navigator.clipboard.writeText(getProfileLink(profileId, token));
}
export function getProfilePath(profileId: string, token?: string) {
if (token) {
return `/offers/profile/${profileId}?token=${token}`;
}
return `/offers/profile/${profileId}`;
}
Loading…
Cancel
Save