From 2f50694016755ea4bec134205ac1f85bab2926f7 Mon Sep 17 00:00:00 2001 From: Su Yin <53945359+tnsyn@users.noreply.github.com> Date: Sat, 8 Oct 2022 20:57:04 +0800 Subject: [PATCH] [resumes][feat] Fetch resumes for browse tabs (#326) * [resumes][fix] Change browse list item styling * [resumes][feat] Add protected tabs router for browse page * [resumes][feat] Fetch all, starred and my resumes in browse page * [resumes][fix] Fix overflow y scrolling * [resumes][fix] Use date-fns to format upload time text --- .../resumes/browse/BrowseListItem.tsx | 13 +-- .../components/resumes/browse/constants.ts | 6 ++ apps/portal/src/pages/resumes/index.tsx | 58 ++++++++++-- apps/portal/src/server/router/index.ts | 2 + .../resumes-resume-protected-tabs-router.ts | 93 +++++++++++++++++++ apps/portal/src/server/router/resumes.ts | 2 +- 6 files changed, 158 insertions(+), 16 deletions(-) create mode 100644 apps/portal/src/server/router/resumes-resume-protected-tabs-router.ts diff --git a/apps/portal/src/components/resumes/browse/BrowseListItem.tsx b/apps/portal/src/components/resumes/browse/BrowseListItem.tsx index 3588f0c0..3c10a463 100644 --- a/apps/portal/src/components/resumes/browse/BrowseListItem.tsx +++ b/apps/portal/src/components/resumes/browse/BrowseListItem.tsx @@ -1,3 +1,4 @@ +import { formatDistanceToNow } from 'date-fns'; import Link from 'next/link'; import type { UrlObject } from 'url'; import { ChevronRightIcon } from '@heroicons/react/20/solid'; @@ -13,8 +14,8 @@ type Props = Readonly<{ export default function BrowseListItem({ href, resumeInfo }: Props) { return ( -
-
+
+
{resumeInfo.title}
{resumeInfo.role} @@ -33,11 +34,11 @@ export default function BrowseListItem({ href, resumeInfo }: Props) {
-
- {/* TODO: Replace hardcoded days ago with calculated days ago*/} - Uploaded 2 days ago by {resumeInfo.user} +
+ Uploaded {formatDistanceToNow(resumeInfo.createdAt)} ago by{' '} + {resumeInfo.user}
- +
); diff --git a/apps/portal/src/components/resumes/browse/constants.ts b/apps/portal/src/components/resumes/browse/constants.ts index 6a52fc7f..af98c36d 100644 --- a/apps/portal/src/components/resumes/browse/constants.ts +++ b/apps/portal/src/components/resumes/browse/constants.ts @@ -1,3 +1,9 @@ +export const BROWSE_TABS_VALUES = { + ALL: 'all', + MY: 'my', + STARRED: 'starred', +}; + export const SORT_OPTIONS = [ { current: true, href: '#', name: 'Latest' }, { current: false, href: '#', name: 'Popular' }, diff --git a/apps/portal/src/pages/resumes/index.tsx b/apps/portal/src/pages/resumes/index.tsx index fb0ca8b0..84515f81 100644 --- a/apps/portal/src/pages/resumes/index.tsx +++ b/apps/portal/src/pages/resumes/index.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import { Fragment, useState } from 'react'; +import { Fragment, useEffect, useState } from 'react'; import { Disclosure, Menu, Transition } from '@headlessui/react'; import { ChevronDownIcon, @@ -11,6 +11,7 @@ import { Tabs, TextInput } from '@tih/ui'; import BrowseListItem from '~/components/resumes/browse/BrowseListItem'; import { + BROWSE_TABS_VALUES, EXPERIENCE, LOCATION, ROLES, @@ -19,6 +20,8 @@ import { } from '~/components/resumes/browse/constants'; import FilterPill from '~/components/resumes/browse/FilterPill'; +import type { Resume } from '~/types/resume'; + const filters = [ { id: 'roles', @@ -41,12 +44,47 @@ import ResumeReviewsTitle from '~/components/resumes/ResumeReviewsTitle'; import { trpc } from '~/utils/trpc'; export default function ResumeHomePage() { - const [tabsValue, setTabsValue] = useState('all'); + const [tabsValue, setTabsValue] = useState(BROWSE_TABS_VALUES.ALL); const [searchValue, setSearchValue] = useState(''); - const resumesQuery = trpc.useQuery(['resumes.resume.list']); + const [resumes, setResumes] = useState(Array()); + + const allResumesQuery = trpc.useQuery(['resumes.resume.all'], { + enabled: tabsValue === BROWSE_TABS_VALUES.ALL, + }); + const starredResumesQuery = trpc.useQuery(['resumes.resume.browse.stars'], { + enabled: tabsValue === BROWSE_TABS_VALUES.STARRED, + }); + const myResumesQuery = trpc.useQuery(['resumes.resume.browse.my'], { + enabled: tabsValue === BROWSE_TABS_VALUES.MY, + }); + + useEffect(() => { + switch (tabsValue) { + case BROWSE_TABS_VALUES.ALL: { + setResumes(allResumesQuery.data ?? Array()); + break; + } + case BROWSE_TABS_VALUES.STARRED: { + setResumes(starredResumesQuery.data ?? Array()); + break; + } + case BROWSE_TABS_VALUES.MY: { + setResumes(myResumesQuery.data ?? Array()); + break; + } + default: { + setResumes(Array()); + } + } + }, [ + allResumesQuery.data, + starredResumesQuery.data, + myResumesQuery.data, + tabsValue, + ]); return ( -
+
@@ -64,15 +102,15 @@ export default function ResumeHomePage() { tabs={[ { label: 'All Resumes', - value: 'all', + value: BROWSE_TABS_VALUES.ALL, }, { label: 'Starred Resumes', - value: 'starred', + value: BROWSE_TABS_VALUES.STARRED, }, { label: 'My Resumes', - value: 'my', + value: BROWSE_TABS_VALUES.MY, }, ]} value={tabsValue} @@ -223,12 +261,14 @@ export default function ResumeHomePage() {
- {resumesQuery.isLoading ? ( + {allResumesQuery.isLoading || + starredResumesQuery.isLoading || + myResumesQuery.isLoading ? (
Loading...
) : (