[resumes][feat] Change review page to dynamic routing

pull/322/head
Wu Peirong 3 years ago
parent 6cbb305f91
commit 902f07601e

@ -22,6 +22,7 @@
"@trpc/react": "^9.27.2",
"@trpc/server": "^9.27.2",
"clsx": "^1.2.1",
"date-fns": "^2.29.3",
"next": "12.3.1",
"next-auth": "~4.10.3",
"react": "18.2.0",

@ -6,7 +6,11 @@ import { Button, Spinner } from '@tih/ui';
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js`;
export default function ResumePdf() {
type Props = Readonly<{
url: string;
}>;
export default function ResumePdf({ url }: Props) {
const [numPages, setNumPages] = useState(0);
const [pageNumber] = useState(1);
@ -18,7 +22,7 @@ export default function ResumePdf() {
<div>
<Document
className="h-[calc(100vh-17rem)] overflow-scroll"
file="/test_resume.pdf"
file={url}
loading={<Spinner display="block" label="" size="lg" />}
onLoadSuccess={onPdfLoadSuccess}>
<Page pageNumber={pageNumber} />

@ -0,0 +1,111 @@
import formatDistanceToNow from 'date-fns/formatDistanceToNow';
import Error from 'next/error';
import { useRouter } from 'next/router';
import {
AcademicCapIcon,
BriefcaseIcon,
CalendarIcon,
InformationCircleIcon,
MapPinIcon,
StarIcon,
} from '@heroicons/react/20/solid';
import { Spinner } from '@tih/ui';
import CommentsSection from '~/components/resumes/comments/CommentsSection';
import ResumePdf from '~/components/resumes/ResumePdf';
import { trpc } from '~/utils/trpc';
export default function ResumeReviewPage() {
const ErrorPage = (
<Error statusCode={404} title="Requested resume does not exist." />
);
const router = useRouter();
const { resumeId } = router.query;
// Safe to assert resumeId type as string because query is only sent if so
const detailsQuery = trpc.useQuery(
['resumes.details.find', { resumeId: resumeId as string }],
{ enabled: typeof resumeId === 'string' },
);
return (
<>
{detailsQuery.isError && ErrorPage}
{detailsQuery.isLoading && <Spinner display="block" label="" size="lg" />}
{detailsQuery.isFetched && detailsQuery.data && (
<main className="flex-1 p-4">
<div className="flex flex-row md:space-x-8">
<h1 className="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl sm:tracking-tight">
{detailsQuery.data.title}
</h1>
<button
className="isolate inline-flex max-h-10 items-center space-x-4 rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
type="button">
<span className="relative inline-flex">
<StarIcon
aria-hidden="true"
className="-ml-1 mr-2 h-5 w-5 text-gray-400"
/>
Star
</span>
<span className="relative -ml-px inline-flex">
{detailsQuery.data._count.stars}
</span>
</button>
</div>
<div className="flex flex-col pt-1 sm:mt-0 sm:flex-row sm:flex-wrap sm:space-x-8">
<div className="mt-2 flex items-center text-sm text-gray-500">
<BriefcaseIcon
aria-hidden="true"
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
/>
{detailsQuery.data.role}
</div>
<div className="flex items-center pt-2 text-sm text-gray-500">
<MapPinIcon
aria-hidden="true"
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
/>
{detailsQuery.data.location}
</div>
<div className="flex items-center pt-2 text-sm text-gray-500">
<AcademicCapIcon
aria-hidden="true"
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
/>
{detailsQuery.data.experience}
</div>
<div className="flex items-center pt-2 text-sm text-gray-500">
<CalendarIcon
aria-hidden="true"
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
/>
{`Uploaded ${formatDistanceToNow(
new Date(detailsQuery.data.createdAt),
{ addSuffix: true },
)} by ${detailsQuery.data.resumesProfile.user.name}`}
</div>
</div>
{detailsQuery.data.additionalInfo && (
<div className="flex items-center pt-2 text-sm text-gray-500">
<InformationCircleIcon
aria-hidden="true"
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
/>
{detailsQuery.data.additionalInfo}
</div>
)}
<div className="flex h-full w-full flex-row py-4">
<div className="w-1/2">
<ResumePdf url={detailsQuery.data.url} />
</div>
<div className="mx-8 w-1/2">
{/* TODO: Update resumeId */}
<CommentsSection resumeId="cl8y6gtez0009yedbne9qp5zi" />
</div>
</div>
</main>
)}
</>
);
}

@ -1,82 +0,0 @@
import {
AcademicCapIcon,
BriefcaseIcon,
CalendarIcon,
InformationCircleIcon,
MapPinIcon,
StarIcon,
} from '@heroicons/react/20/solid';
import CommentsSection from '~/components/resumes/comments/CommentsSection';
import ResumePdf from '~/components/resumes/ResumePdf';
export default function ResumeReviewPage() {
return (
<main className="flex-1 p-4">
<div className="flex flex-row md:space-x-8">
<h1 className="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl sm:tracking-tight">
Please help moi, applying for medtech startups in Singapore
</h1>
<button
className="isolate inline-flex max-h-10 items-center space-x-4 rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
type="button">
<span className="relative inline-flex">
<StarIcon
aria-hidden="true"
className="-ml-1 mr-2 h-5 w-5 text-gray-400"
/>
Star
</span>
<span className="relative -ml-px inline-flex">12k</span>
</button>
</div>
<div className="flex flex-col pt-1 sm:mt-0 sm:flex-row sm:flex-wrap sm:space-x-8">
<div className="mt-2 flex items-center text-sm text-gray-500">
<BriefcaseIcon
aria-hidden="true"
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
/>
Software Engineer (Backend)
</div>
<div className="flex items-center pt-2 text-sm text-gray-500">
<MapPinIcon
aria-hidden="true"
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
/>
Singapore
</div>
<div className="flex items-center pt-2 text-sm text-gray-500">
<AcademicCapIcon
aria-hidden="true"
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
/>
Fresh Grad
</div>
<div className="flex items-center pt-2 text-sm text-gray-500">
<CalendarIcon
aria-hidden="true"
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
/>
Uploaded 2 days ago by Git Ji Ra
</div>
</div>
<div className="flex items-center pt-2 text-sm text-gray-500">
<InformationCircleIcon
aria-hidden="true"
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
/>
Looking to break into SWE roles after doing engineering for the past 2
years
</div>
<div className="flex h-full w-full flex-row py-4">
<div className="w-1/2">
<ResumePdf />
</div>
<div className="mx-8 w-1/2">
{/* TODO: Update resumeId */}
<CommentsSection resumeId="cl8y6gtez0009yedbne9qp5zi" />
</div>
</div>
</main>
);
}

@ -18,6 +18,15 @@ export const resumesDetailsRouter = createRouter().query('find', {
stars: true,
},
},
resumesProfile: {
select: {
user: {
select: {
name: true,
},
},
},
},
},
where: {
id: resumeId,

@ -6049,7 +6049,7 @@ damerau-levenshtein@^1.0.8:
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==
date-fns@^2.29.1:
date-fns@^2.29.1, date-fns@^2.29.3:
version "2.29.3"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8"
integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==

Loading…
Cancel
Save