[resumes][refactor] Change Tabs to List view (#387)

Co-authored-by: Terence Ho <>
pull/391/head
Terence 2 years ago committed by GitHub
parent 5913a52f2b
commit 612bef14ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -16,7 +16,7 @@ import type { ResumeComment } from '~/types/resume-comments';
type ResumeCommentListItemProps = { type ResumeCommentListItemProps = {
comment: ResumeComment; comment: ResumeComment;
userId?: string; userId: string | undefined;
}; };
type ICommentInput = { type ICommentInput = {
@ -78,8 +78,8 @@ export default function ResumeCommentListItem({
}; };
return ( return (
<div className="border-primary-300 w-3/4 rounded-md border-2 bg-white p-2 drop-shadow-md"> <div className="border-primary-300 w-11/12 min-w-fit rounded-md border-2 bg-white p-2 drop-shadow-md">
<div className="flex w-full flex-row space-x-2 p-1 align-top"> <div className="flex flex-row space-x-2 p-1 align-top">
{comment.user.image ? ( {comment.user.image ? (
<img <img
alt={comment.user.name ?? 'Reviewer'} alt={comment.user.name ?? 'Reviewer'}
@ -103,7 +103,7 @@ export default function ResumeCommentListItem({
</div> </div>
</div> </div>
<div className="text-xs text-gray-600"> <div className="px-2 text-xs text-gray-600">
{comment.createdAt.toLocaleString('en-US', { {comment.createdAt.toLocaleString('en-US', {
dateStyle: 'medium', dateStyle: 'medium',
timeStyle: 'short', timeStyle: 'short',
@ -123,7 +123,7 @@ export default function ResumeCommentListItem({
defaultValue={comment.description} defaultValue={comment.description}
disabled={commentUpdateMutation.isLoading} disabled={commentUpdateMutation.isLoading}
errorMessage={errors.description?.message} errorMessage={errors.description?.message}
label="Edit comment" label=""
placeholder="Leave your comment here" placeholder="Leave your comment here"
onChange={setFormValue} onChange={setFormValue}
/> />

@ -1,6 +1,14 @@
import { useSession } from 'next-auth/react'; import { useSession } from 'next-auth/react';
import { useState } from 'react'; import {
import { Spinner, Tabs } from '@tih/ui'; BookOpenIcon,
BriefcaseIcon,
CodeBracketSquareIcon,
FaceSmileIcon,
IdentificationIcon,
SparklesIcon,
} from '@heroicons/react/24/outline';
import { ResumesSection } from '@prisma/client';
import { Spinner } from '@tih/ui';
import { Button } from '@tih/ui'; import { Button } from '@tih/ui';
import { trpc } from '~/utils/trpc'; import { trpc } from '~/utils/trpc';
@ -21,23 +29,26 @@ export default function ResumeCommentsList({
setShowCommentsForm, setShowCommentsForm,
}: ResumeCommentsListProps) { }: ResumeCommentsListProps) {
const { data: sessionData } = useSession(); const { data: sessionData } = useSession();
const [tab, setTab] = useState(RESUME_COMMENTS_SECTIONS[0].value);
const [tabs, setTabs] = useState(RESUME_COMMENTS_SECTIONS);
const commentsQuery = trpc.useQuery(['resumes.comments.list', { resumeId }], { const commentsQuery = trpc.useQuery(['resumes.comments.list', { resumeId }]);
onSuccess: (data: Array<ResumeComment>) => {
const updatedTabs = RESUME_COMMENTS_SECTIONS.map(({ label, value }) => {
const count = data.filter(({ section }) => section === value).length;
const updatedLabel = count > 0 ? `${label} (${count})` : label;
return {
label: updatedLabel,
value,
};
});
setTabs(updatedTabs); const renderIcon = (section: ResumesSection) => {
}, const className = 'h-8 w-8';
}); switch (section) {
case ResumesSection.GENERAL:
return <IdentificationIcon className={className} />;
case ResumesSection.EDUCATION:
return <BookOpenIcon className={className} />;
case ResumesSection.EXPERIENCE:
return <BriefcaseIcon className={className} />;
case ResumesSection.PROJECTS:
return <CodeBracketSquareIcon className={className} />;
case ResumesSection.SKILLS:
return <SparklesIcon className={className} />;
default:
return <FaceSmileIcon className={className} />;
}
};
const renderButton = () => { const renderButton = () => {
if (sessionData === null) { if (sessionData === null) {
@ -57,29 +68,45 @@ export default function ResumeCommentsList({
<div className="space-y-3"> <div className="space-y-3">
{renderButton()} {renderButton()}
<Tabs
label="comments"
tabs={tabs}
value={tab}
onChange={(value) => setTab(value)}
/>
{commentsQuery.isFetching ? ( {commentsQuery.isFetching ? (
<div className="col-span-10 pt-4"> <div className="col-span-10 pt-4">
<Spinner display="block" size="lg" /> <Spinner display="block" size="lg" />
</div> </div>
) : ( ) : (
<div className="m-2 flow-root h-[calc(100vh-20rem)] w-full flex-col space-y-3 overflow-y-auto"> <div className="m-2 flow-root h-[calc(100vh-20rem)] w-full flex-col space-y-4 overflow-y-auto">
{(commentsQuery.data?.filter((c) => c.section === tab) ?? []).map( {RESUME_COMMENTS_SECTIONS.map(({ label, value }) => {
(comment) => ( const comments = commentsQuery.data
? commentsQuery.data.filter((comment: ResumeComment) => {
return (comment.section as string) === value;
})
: [];
const commentCount = comments.length;
return (
<div key={value} className="mb-4 space-y-3">
<div className="flex flex-row items-center space-x-2 text-indigo-800">
{renderIcon(value)}
<div className="w-fit text-xl font-medium">{label}</div>
</div>
{commentCount > 0 ? (
comments.map((comment) => {
return (
<ResumeCommentListItem <ResumeCommentListItem
key={comment.id} key={comment.id}
comment={comment} comment={comment}
userId={sessionData?.user?.id} userId={sessionData?.user?.id}
/> />
), );
})
) : (
<div>There are no comments for this section yet!</div>
)} )}
</div> </div>
);
})}
</div>
)} )}
</div> </div>
); );

Loading…
Cancel
Save