diff --git a/apps/portal/src/components/resumes/landing/Container.tsx b/apps/portal/src/components/resumes/landing/Container.tsx index 3a975859..94d35463 100644 --- a/apps/portal/src/components/resumes/landing/Container.tsx +++ b/apps/portal/src/components/resumes/landing/Container.tsx @@ -9,7 +9,7 @@ type ContainerProps = { export const Container: FC = ({ className, ...props }) => { return (
); diff --git a/apps/portal/src/components/resumes/landing/PrimaryFeatures.tsx b/apps/portal/src/components/resumes/landing/PrimaryFeatures.tsx index 51b3c5a0..b2fedb17 100644 --- a/apps/portal/src/components/resumes/landing/PrimaryFeatures.tsx +++ b/apps/portal/src/components/resumes/landing/PrimaryFeatures.tsx @@ -4,27 +4,27 @@ import { useEffect, useState } from 'react'; import { Tab } from '@headlessui/react'; import { Container } from './Container'; -import screenshotExpenses from './images/screenshots/expenses.png'; -import screenshotPayroll from './images/screenshots/payroll.png'; -import screenshotVatReturns from './images/screenshots/vat-returns.png'; +import resumeBrowse from './images/screenshots/resumes-browse.png'; +import resumeReview from './images/screenshots/resumes-review.png'; +import resumeSubmit from './images/screenshots/resumes-submit.png'; const features = [ { description: 'Browse the most popular reviewed resumes out there and see what you can learn', - image: screenshotPayroll, + image: resumeBrowse, title: 'Browse', }, { description: 'Upload your own resume easily to get feedback from people in industry.', - image: screenshotExpenses, + image: resumeSubmit, title: 'Submit', }, { description: 'Pass the baton forward by reviewing resumes and bounce off ideas with other engineers out there.', - image: screenshotVatReturns, + image: resumeReview, title: 'Review', }, ]; @@ -49,7 +49,6 @@ export function PrimaryFeatures() { return (
@@ -64,7 +63,7 @@ export function PrimaryFeatures() { vertical={tabOrientation === 'vertical'}> {({ selectedIndex }) => ( <> -
+
{features.map((feature, featureIndex) => (
- + {features.map((feature) => (
diff --git a/apps/portal/src/components/resumes/landing/Testimonials.tsx b/apps/portal/src/components/resumes/landing/Testimonials.tsx index f7db5f1e..ad43f019 100644 --- a/apps/portal/src/components/resumes/landing/Testimonials.tsx +++ b/apps/portal/src/components/resumes/landing/Testimonials.tsx @@ -94,7 +94,6 @@ function QuoteIcon(props: QuoteProps) { export function Testimonials() { return (
diff --git a/apps/portal/src/components/resumes/landing/images/screenshots/contacts.png b/apps/portal/src/components/resumes/landing/images/screenshots/contacts.png deleted file mode 100644 index 5901470b..00000000 Binary files a/apps/portal/src/components/resumes/landing/images/screenshots/contacts.png and /dev/null differ diff --git a/apps/portal/src/components/resumes/landing/images/screenshots/expenses.png b/apps/portal/src/components/resumes/landing/images/screenshots/expenses.png deleted file mode 100644 index ca35472e..00000000 Binary files a/apps/portal/src/components/resumes/landing/images/screenshots/expenses.png and /dev/null differ diff --git a/apps/portal/src/components/resumes/landing/images/screenshots/inventory.png b/apps/portal/src/components/resumes/landing/images/screenshots/inventory.png deleted file mode 100644 index b98721c6..00000000 Binary files a/apps/portal/src/components/resumes/landing/images/screenshots/inventory.png and /dev/null differ diff --git a/apps/portal/src/components/resumes/landing/images/screenshots/payroll.png b/apps/portal/src/components/resumes/landing/images/screenshots/payroll.png deleted file mode 100644 index 16f5b5a7..00000000 Binary files a/apps/portal/src/components/resumes/landing/images/screenshots/payroll.png and /dev/null differ diff --git a/apps/portal/src/components/resumes/landing/images/screenshots/profit-loss.png b/apps/portal/src/components/resumes/landing/images/screenshots/profit-loss.png deleted file mode 100644 index 229df78a..00000000 Binary files a/apps/portal/src/components/resumes/landing/images/screenshots/profit-loss.png and /dev/null differ diff --git a/apps/portal/src/components/resumes/landing/images/screenshots/reporting.png b/apps/portal/src/components/resumes/landing/images/screenshots/reporting.png deleted file mode 100644 index 72b5e8e9..00000000 Binary files a/apps/portal/src/components/resumes/landing/images/screenshots/reporting.png and /dev/null differ diff --git a/apps/portal/src/components/resumes/landing/images/screenshots/resumes-browse.png b/apps/portal/src/components/resumes/landing/images/screenshots/resumes-browse.png new file mode 100644 index 00000000..6bdc81c9 Binary files /dev/null and b/apps/portal/src/components/resumes/landing/images/screenshots/resumes-browse.png differ diff --git a/apps/portal/src/components/resumes/landing/images/screenshots/resumes-review.png b/apps/portal/src/components/resumes/landing/images/screenshots/resumes-review.png new file mode 100644 index 00000000..1a6b466a Binary files /dev/null and b/apps/portal/src/components/resumes/landing/images/screenshots/resumes-review.png differ diff --git a/apps/portal/src/components/resumes/landing/images/screenshots/resumes-submit.png b/apps/portal/src/components/resumes/landing/images/screenshots/resumes-submit.png new file mode 100644 index 00000000..ccfcce1f Binary files /dev/null and b/apps/portal/src/components/resumes/landing/images/screenshots/resumes-submit.png differ diff --git a/apps/portal/src/components/resumes/landing/images/screenshots/vat-returns.png b/apps/portal/src/components/resumes/landing/images/screenshots/vat-returns.png deleted file mode 100644 index 3dd043bd..00000000 Binary files a/apps/portal/src/components/resumes/landing/images/screenshots/vat-returns.png and /dev/null differ diff --git a/apps/portal/src/pages/_app.tsx b/apps/portal/src/pages/_app.tsx index 11606124..9914942e 100644 --- a/apps/portal/src/pages/_app.tsx +++ b/apps/portal/src/pages/_app.tsx @@ -3,6 +3,7 @@ import type { Session } from 'next-auth'; import { SessionProvider } from 'next-auth/react'; import React from 'react'; import superjson from 'superjson'; +import { ToastsProvider } from '@tih/ui'; import { httpBatchLink } from '@trpc/client/links/httpBatchLink'; import { loggerLink } from '@trpc/client/links/loggerLink'; import { withTRPC } from '@trpc/next'; @@ -19,9 +20,11 @@ const MyApp: AppType<{ session: Session | null }> = ({ }) => { return ( - - - + + + + + ); }; diff --git a/apps/portal/src/pages/index.tsx b/apps/portal/src/pages/index.tsx index 360c81e8..51f58469 100644 --- a/apps/portal/src/pages/index.tsx +++ b/apps/portal/src/pages/index.tsx @@ -1,32 +1,11 @@ -import { useState } from 'react'; -import type { TypeaheadOption } from '@tih/ui'; -import { HorizontalDivider } from '@tih/ui'; - -import CompaniesTypeahead from '~/components/shared/CompaniesTypeahead'; -import type { Month, MonthYear } from '~/components/shared/MonthYearPicker'; -import MonthYearPicker from '~/components/shared/MonthYearPicker'; - export default function HomePage() { - const [selectedCompany, setSelectedCompany] = - useState(null); - const [monthYear, setMonthYear] = useState({ - month: (new Date().getMonth() + 1) as Month, - year: new Date().getFullYear(), - }); - return (

- Homepage + Tech Interview Handbook Portal

- setSelectedCompany(option)} - /> -
{JSON.stringify(selectedCompany, null, 2)}
- -
diff --git a/apps/portal/src/pages/resumes/index.tsx b/apps/portal/src/pages/resumes/index.tsx index 4f84c9d1..ae063c0b 100644 --- a/apps/portal/src/pages/resumes/index.tsx +++ b/apps/portal/src/pages/resumes/index.tsx @@ -3,7 +3,6 @@ import Head from 'next/head'; import { CallToAction } from '~/components/resumes/landing/CallToAction'; import { Hero } from '~/components/resumes/landing/Hero'; import { PrimaryFeatures } from '~/components/resumes/landing/PrimaryFeatures'; -import { Testimonials } from '~/components/resumes/landing/Testimonials'; export default function Home() { return ( @@ -16,7 +15,6 @@ export default function Home() { - ); diff --git a/apps/portal/src/pages/test__.tsx b/apps/portal/src/pages/test__.tsx new file mode 100644 index 00000000..26859c56 --- /dev/null +++ b/apps/portal/src/pages/test__.tsx @@ -0,0 +1,51 @@ +import { useState } from 'react'; +import type { TypeaheadOption } from '@tih/ui'; +import { Button } from '@tih/ui'; +import { useToast } from '@tih/ui'; +import { HorizontalDivider } from '@tih/ui'; + +import CompaniesTypeahead from '~/components/shared/CompaniesTypeahead'; +import type { Month, MonthYear } from '~/components/shared/MonthYearPicker'; +import MonthYearPicker from '~/components/shared/MonthYearPicker'; + +export default function HomePage() { + const [selectedCompany, setSelectedCompany] = + useState(null); + const [monthYear, setMonthYear] = useState({ + month: (new Date().getMonth() + 1) as Month, + year: new Date().getFullYear(), + }); + + const { showToast } = useToast(); + + return ( +
+
+
+

+ Test Page +

+ setSelectedCompany(option)} + /> +
{JSON.stringify(selectedCompany, null, 2)}
+ + + +
+
+
+ ); +} diff --git a/apps/portal/src/server/router/offers/offers-profile-router.ts b/apps/portal/src/server/router/offers/offers-profile-router.ts index 104cdf95..9aade630 100644 --- a/apps/portal/src/server/router/offers/offers-profile-router.ts +++ b/apps/portal/src/server/router/offers/offers-profile-router.ts @@ -754,12 +754,76 @@ export const offersProfileRouter = createRouter() } } else if (!exp.id) { // Create new experience - if ( - exp.jobType === JobType.FULLTIME && - exp.totalCompensation?.currency != null && - exp.totalCompensation?.value != null - ) { - if (exp.companyId) { + if (exp.jobType === JobType.FULLTIME) { + if (exp.totalCompensation?.currency != null && + exp.totalCompensation?.value != null) { + if (exp.companyId) { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + company: { + connect: { + id: exp.companyId, + }, + }, + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + level: exp.level, + location: exp.location, + specialization: exp.specialization, + title: exp.title, + totalCompensation: { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + exp.totalCompensation.value, + exp.totalCompensation.currency, + baseCurrencyString, + ), + currency: exp.totalCompensation.currency, + value: exp.totalCompensation.value, + }, + }, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } else { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + level: exp.level, + location: exp.location, + specialization: exp.specialization, + title: exp.title, + totalCompensation: { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + exp.totalCompensation.value, + exp.totalCompensation.currency, + baseCurrencyString, + ), + currency: exp.totalCompensation.currency, + value: exp.totalCompensation.value, + }, + }, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } + } else if (exp.companyId) { await ctx.prisma.offersBackground.update({ data: { experiences: { @@ -775,18 +839,6 @@ export const offersProfileRouter = createRouter() location: exp.location, specialization: exp.specialization, title: exp.title, - totalCompensation: { - create: { - baseCurrency: baseCurrencyString, - baseValue: await convert( - exp.totalCompensation.value, - exp.totalCompensation.currency, - baseCurrencyString, - ), - currency: exp.totalCompensation.currency, - value: exp.totalCompensation.value, - }, - }, }, }, }, @@ -805,18 +857,6 @@ export const offersProfileRouter = createRouter() location: exp.location, specialization: exp.specialization, title: exp.title, - totalCompensation: { - create: { - baseCurrency: baseCurrencyString, - baseValue: await convert( - exp.totalCompensation.value, - exp.totalCompensation.currency, - baseCurrencyString, - ), - currency: exp.totalCompensation.currency, - value: exp.totalCompensation.value, - }, - }, }, }, }, @@ -825,12 +865,74 @@ export const offersProfileRouter = createRouter() }, }); } - } else if ( - exp.jobType === JobType.INTERN && - exp.monthlySalary?.currency != null && - exp.monthlySalary?.value != null - ) { - if (exp.companyId) { + } else if (exp.jobType === JobType.INTERN) { + if (exp.monthlySalary?.currency != null && + exp.monthlySalary?.value != null) { + if (exp.companyId) { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + company: { + connect: { + id: exp.companyId, + }, + }, + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + location: exp.location, + monthlySalary: { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + exp.monthlySalary.value, + exp.monthlySalary.currency, + baseCurrencyString, + ), + currency: exp.monthlySalary.currency, + value: exp.monthlySalary.value, + }, + }, + specialization: exp.specialization, + title: exp.title, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } else { + await ctx.prisma.offersBackground.update({ + data: { + experiences: { + create: { + durationInMonths: exp.durationInMonths, + jobType: exp.jobType, + location: exp.location, + monthlySalary: { + create: { + baseCurrency: baseCurrencyString, + baseValue: await convert( + exp.monthlySalary.value, + exp.monthlySalary.currency, + baseCurrencyString, + ), + currency: exp.monthlySalary.currency, + value: exp.monthlySalary.value, + }, + }, + specialization: exp.specialization, + title: exp.title, + }, + }, + }, + where: { + id: input.background.id, + }, + }); + } + } else if (exp.companyId) { await ctx.prisma.offersBackground.update({ data: { experiences: { @@ -843,18 +945,6 @@ export const offersProfileRouter = createRouter() durationInMonths: exp.durationInMonths, jobType: exp.jobType, location: exp.location, - monthlySalary: { - create: { - baseCurrency: baseCurrencyString, - baseValue: await convert( - exp.monthlySalary.value, - exp.monthlySalary.currency, - baseCurrencyString, - ), - currency: exp.monthlySalary.currency, - value: exp.monthlySalary.value, - }, - }, specialization: exp.specialization, title: exp.title, }, @@ -872,18 +962,6 @@ export const offersProfileRouter = createRouter() durationInMonths: exp.durationInMonths, jobType: exp.jobType, location: exp.location, - monthlySalary: { - create: { - baseCurrency: baseCurrencyString, - baseValue: await convert( - exp.monthlySalary.value, - exp.monthlySalary.currency, - baseCurrencyString, - ), - currency: exp.monthlySalary.currency, - value: exp.monthlySalary.value, - }, - }, specialization: exp.specialization, title: exp.title, }, diff --git a/packages/ui/src/Toast/Toast.tsx b/packages/ui/src/Toast/Toast.tsx new file mode 100644 index 00000000..4d6efe51 --- /dev/null +++ b/packages/ui/src/Toast/Toast.tsx @@ -0,0 +1,108 @@ +import { Fragment, useEffect, useRef } from 'react'; +import { Transition } from '@headlessui/react'; +import { CheckIcon } from '@heroicons/react/24/outline'; +import { XMarkIcon } from '@heroicons/react/24/solid'; + +type ToastVariant = 'failure' | 'success'; + +export type ToastMessage = { + duration?: number; + subtitle?: string; + title: string; + variant: ToastVariant; +}; + +type Props = Readonly<{ + duration?: number; + onClose: () => void; + subtitle?: string; + title: string; + variant: ToastVariant; +}>; + +const DEFAULT_DURATION = 5000; + +function ToastIcon({ variant }: Readonly<{ variant: ToastVariant }>) { + switch (variant) { + case 'success': + return ( +