diff --git a/apps/portal/package.json b/apps/portal/package.json index f1bdb9e7..208b1940 100644 --- a/apps/portal/package.json +++ b/apps/portal/package.json @@ -15,6 +15,7 @@ "@headlessui/react": "^1.7.3", "@heroicons/react": "^2.0.11", "@next-auth/prisma-adapter": "^1.0.4", + "@popperjs/core": "^2.11.6", "@prisma/client": "^4.4.0", "@supabase/supabase-js": "^1.35.7", "@tih/ui": "*", @@ -33,6 +34,8 @@ "react-dropzone": "^14.2.3", "react-hook-form": "^7.36.1", "react-pdf": "^5.7.2", + "react-popper": "^2.3.0", + "react-popper-tooltip": "^4.4.2", "react-query": "^3.39.2", "superjson": "^1.10.0", "zod": "^3.18.0" diff --git a/apps/portal/src/components/offers/constants.ts b/apps/portal/src/components/offers/constants.ts index 63a57d0e..10e3b0b1 100644 --- a/apps/portal/src/components/offers/constants.ts +++ b/apps/portal/src/components/offers/constants.ts @@ -110,9 +110,30 @@ export const educationFieldOptions = [ ]; export enum FieldError { - NonNegativeNumber = 'Please fill in a non-negative number in this field.', - Number = 'Please fill in a number in this field.', - Required = 'Please fill in this field.', + NON_NEGATIVE_NUMBER = 'Please fill in a non-negative number in this field.', + NUMBER = 'Please fill in a number in this field.', + REQUIRED = 'Please fill in this field.', } export const OVERALL_TAB = 'Overall'; + +export enum ProfileDetailTab { + ANALYSIS = 'Offer Engine Analysis', + BACKGROUND = 'Background', + OFFERS = 'Offers', +} + +export const profileDetailTabs = [ + { + label: ProfileDetailTab.OFFERS, + value: ProfileDetailTab.OFFERS, + }, + { + label: ProfileDetailTab.BACKGROUND, + value: ProfileDetailTab.BACKGROUND, + }, + { + label: ProfileDetailTab.ANALYSIS, + value: ProfileDetailTab.ANALYSIS, + }, +]; diff --git a/apps/portal/src/components/offers/offersSubmission/analysis/OfferAnalysis.tsx b/apps/portal/src/components/offers/offerAnalysis/OfferAnalysis.tsx similarity index 67% rename from apps/portal/src/components/offers/offersSubmission/analysis/OfferAnalysis.tsx rename to apps/portal/src/components/offers/offerAnalysis/OfferAnalysis.tsx index 4b45b3f2..67c9c9e1 100644 --- a/apps/portal/src/components/offers/offersSubmission/analysis/OfferAnalysis.tsx +++ b/apps/portal/src/components/offers/offerAnalysis/OfferAnalysis.tsx @@ -2,11 +2,9 @@ import { useEffect } from 'react'; import { useState } from 'react'; import { HorizontalDivider, Spinner, Tabs } from '@tih/ui'; -import { trpc } from '~/utils/trpc'; - -import OfferPercentileAnalysis from './OfferPercentileAnalysis'; +import OfferPercentileAnalysisText from './OfferPercentileAnalysisText'; import OfferProfileCard from './OfferProfileCard'; -import { OVERALL_TAB } from '../../constants'; +import { OVERALL_TAB } from '../constants'; import type { Analysis, @@ -29,20 +27,29 @@ function OfferAnalysisContent({ tab, }: OfferAnalysisContentProps) { if (!offerAnalysis || !offer || offerAnalysis.noOfOffers === 0) { + if (tab === OVERALL_TAB) { + return ( +
+ You are the first to submit an offer for your job title and YOE! Check + back later when there are more submissions. +
+ ); + } return (- You are the first to submit an offer for these companies! Check back - later when there are more submissions. + You are the first to submit an offer for this company, job title and + YOE! Check back later when there are more submissions.
); } return ( <> -Here are some of the top offers relevant to you:
{offerAnalysis.topPercentileOffers.map((topPercentileOffer) => (An error occurred while generating profile analysis.
)} - {getAnalysisResult.isLoading && ( -+ Your highest offer is from {companyName}, which is{' '} + {percentile.toFixed(1)} percentile out of {noOfOffers}{' '} + offers received for the same job title and YOE(±1) in the last year. +
+ ) : ( ++ Your offer from {companyName} is {percentile.toFixed(1)}{' '} + percentile out of {noOfOffers} offers received in {companyName} for + the same job title and YOE(±1) in the last year. +
+ ); +} diff --git a/apps/portal/src/components/offers/offerAnalysis/OfferProfileCard.tsx b/apps/portal/src/components/offers/offerAnalysis/OfferProfileCard.tsx new file mode 100644 index 00000000..af786c4b --- /dev/null +++ b/apps/portal/src/components/offers/offerAnalysis/OfferProfileCard.tsx @@ -0,0 +1,74 @@ +import { + BuildingOffice2Icon, + CalendarDaysIcon, +} from '@heroicons/react/24/outline'; +import { JobType } from '@prisma/client'; + +import { HorizontalDivider } from '~/../../../packages/ui/dist'; +import { convertMoneyToString } from '~/utils/offers/currency'; +import { formatDate } from '~/utils/offers/time'; + +import ProfilePhotoHolder from '../profile/ProfilePhotoHolder'; + +import type { AnalysisOffer } from '~/types/offers'; + +type OfferProfileCardProps = Readonly<{ + offerProfile: AnalysisOffer; +}>; + +export default function OfferProfileCard({ + offerProfile: { + company, + income, + profileName, + totalYoe, + level, + monthYearReceived, + jobType, + location, + title, + previousCompanies, + }, +}: OfferProfileCardProps) { + return ( +{profileName}
+{title}
++ Company: {company.name}, {location} +
+Level: {level}
+{formatDate(monthYearReceived)}
++ {jobType === JobType.FULLTIME + ? `${convertMoneyToString(income)} / year` + : `${convertMoneyToString(income)} / month`} +
+{`${startDate ? startDate : 'N/A'} - ${ - endDate ? endDate : 'N/A' - }`}
+{`${startDate || 'N/A'} - ${endDate || 'N/A'}`}
- {totalCompensation - ? `TC: ${totalCompensation}` - : `Monthly Salary: ${monthlySalary}`} -
+ <> ++ {totalCompensation && `TC: ${totalCompensation}`} + {monthlySalary && `Monthly Salary: ${monthlySalary}`} +
++ Base / year: {base} ⋅ Stocks / year: {stocks} ⋅ Bonus / year:{' '} + {bonus} +
+- Base / year: {base} ⋅ Stocks / year: {stocks} ⋅ Bonus / year:{' '} - {bonus} -
+ {negotiationStrategy && ( +No background information available.
+