mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-07-28 20:52:00 +08:00
[resumes][fix] browse tabs updates on tab shift
This commit is contained in:
@ -41,7 +41,9 @@ export default function ResumeListItem({ href, resumeInfo }: Props) {
|
|||||||
<div className="mt-4 flex justify-start text-xs text-slate-500">
|
<div className="mt-4 flex justify-start text-xs text-slate-500">
|
||||||
<div className="flex gap-2 pr-4">
|
<div className="flex gap-2 pr-4">
|
||||||
<ChatBubbleLeftIcon className="w-4" />
|
<ChatBubbleLeftIcon className="w-4" />
|
||||||
{resumeInfo.numComments} comments
|
{`${resumeInfo.numComments} comment${
|
||||||
|
resumeInfo.numComments > 0 ? 's' : ''
|
||||||
|
}`}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
{resumeInfo.isStarredByUser ? (
|
{resumeInfo.isStarredByUser ? (
|
||||||
|
@ -47,6 +47,9 @@ export default function ResumeCommentsForm({
|
|||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
// New Comment added, invalidate query to trigger refetch
|
// New Comment added, invalidate query to trigger refetch
|
||||||
trpcContext.invalidateQueries(['resumes.comments.list']);
|
trpcContext.invalidateQueries(['resumes.comments.list']);
|
||||||
|
trpcContext.invalidateQueries(['resumes.resume.findAll']);
|
||||||
|
trpcContext.invalidateQueries(['resumes.resume.user.findUserStarred']);
|
||||||
|
trpcContext.invalidateQueries(['resumes.resume.user.findUserCreated']);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -42,11 +42,17 @@ export default function ResumeReviewPage() {
|
|||||||
const starMutation = trpc.useMutation('resumes.resume.star', {
|
const starMutation = trpc.useMutation('resumes.resume.star', {
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
utils.invalidateQueries(['resumes.resume.findOne']);
|
utils.invalidateQueries(['resumes.resume.findOne']);
|
||||||
|
utils.invalidateQueries(['resumes.resume.findAll']);
|
||||||
|
utils.invalidateQueries(['resumes.resume.user.findUserStarred']);
|
||||||
|
utils.invalidateQueries(['resumes.resume.user.findUserCreated']);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const unstarMutation = trpc.useMutation('resumes.resume.unstar', {
|
const unstarMutation = trpc.useMutation('resumes.resume.unstar', {
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
utils.invalidateQueries(['resumes.resume.findOne']);
|
utils.invalidateQueries(['resumes.resume.findOne']);
|
||||||
|
utils.invalidateQueries(['resumes.resume.findAll']);
|
||||||
|
utils.invalidateQueries(['resumes.resume.user.findUserStarred']);
|
||||||
|
utils.invalidateQueries(['resumes.resume.user.findUserCreated']);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const userIsOwner =
|
const userIsOwner =
|
||||||
@ -89,6 +95,9 @@ export default function ResumeReviewPage() {
|
|||||||
}}
|
}}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
utils.invalidateQueries(['resumes.resume.findOne']);
|
utils.invalidateQueries(['resumes.resume.findOne']);
|
||||||
|
utils.invalidateQueries(['resumes.resume.findAll']);
|
||||||
|
utils.invalidateQueries(['resumes.resume.user.findUserStarred']);
|
||||||
|
utils.invalidateQueries(['resumes.resume.user.findUserCreated']);
|
||||||
setIsEditMode(false);
|
setIsEditMode(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -35,8 +35,6 @@ import ResumeSignInButton from '~/components/resumes/shared/ResumeSignInButton';
|
|||||||
|
|
||||||
import { trpc } from '~/utils/trpc';
|
import { trpc } from '~/utils/trpc';
|
||||||
|
|
||||||
import type { Resume } from '~/types/resume';
|
|
||||||
|
|
||||||
const filters: Array<Filter> = [
|
const filters: Array<Filter> = [
|
||||||
{
|
{
|
||||||
id: 'role',
|
id: 'role',
|
||||||
@ -63,11 +61,9 @@ export default function ResumeHomePage() {
|
|||||||
const [searchValue, setSearchValue] = useState('');
|
const [searchValue, setSearchValue] = useState('');
|
||||||
const [userFilters, setUserFilters] = useState(INITIAL_FILTER_STATE);
|
const [userFilters, setUserFilters] = useState(INITIAL_FILTER_STATE);
|
||||||
const [shortcutSelected, setShortcutSelected] = useState('All');
|
const [shortcutSelected, setShortcutSelected] = useState('All');
|
||||||
const [resumes, setResumes] = useState<Array<Resume>>([]);
|
|
||||||
const [renderSignInButton, setRenderSignInButton] = useState(false);
|
const [renderSignInButton, setRenderSignInButton] = useState(false);
|
||||||
const [signInButtonText, setSignInButtonText] = useState('');
|
const [signInButtonText, setSignInButtonText] = useState('');
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [totalPages, setTotalPages] = useState(1);
|
|
||||||
|
|
||||||
const PAGE_LIMIT = 10;
|
const PAGE_LIMIT = 10;
|
||||||
const skip = (currentPage - 1) * PAGE_LIMIT;
|
const skip = (currentPage - 1) * PAGE_LIMIT;
|
||||||
@ -90,13 +86,7 @@ export default function ResumeHomePage() {
|
|||||||
],
|
],
|
||||||
{
|
{
|
||||||
enabled: tabsValue === BROWSE_TABS_VALUES.ALL,
|
enabled: tabsValue === BROWSE_TABS_VALUES.ALL,
|
||||||
onSuccess: (data) => {
|
onSuccess: () => {
|
||||||
setTotalPages(
|
|
||||||
data.totalRecords % PAGE_LIMIT === 0
|
|
||||||
? data.totalRecords / PAGE_LIMIT
|
|
||||||
: Math.floor(data.totalRecords / PAGE_LIMIT) + 1,
|
|
||||||
);
|
|
||||||
setResumes(data.mappedResumeData);
|
|
||||||
setRenderSignInButton(false);
|
setRenderSignInButton(false);
|
||||||
},
|
},
|
||||||
staleTime: 5 * 60 * 1000,
|
staleTime: 5 * 60 * 1000,
|
||||||
@ -117,18 +107,9 @@ export default function ResumeHomePage() {
|
|||||||
{
|
{
|
||||||
enabled: tabsValue === BROWSE_TABS_VALUES.STARRED,
|
enabled: tabsValue === BROWSE_TABS_VALUES.STARRED,
|
||||||
onError: () => {
|
onError: () => {
|
||||||
setResumes([]);
|
|
||||||
setRenderSignInButton(true);
|
setRenderSignInButton(true);
|
||||||
setSignInButtonText('to view starred resumes');
|
setSignInButtonText('to view starred resumes');
|
||||||
},
|
},
|
||||||
onSuccess: (data) => {
|
|
||||||
setTotalPages(
|
|
||||||
data.totalRecords % PAGE_LIMIT === 0
|
|
||||||
? data.totalRecords / PAGE_LIMIT
|
|
||||||
: Math.floor(data.totalRecords / PAGE_LIMIT) + 1,
|
|
||||||
);
|
|
||||||
setResumes(data.mappedResumeData);
|
|
||||||
},
|
|
||||||
retry: false,
|
retry: false,
|
||||||
staleTime: 5 * 60 * 1000,
|
staleTime: 5 * 60 * 1000,
|
||||||
},
|
},
|
||||||
@ -148,18 +129,9 @@ export default function ResumeHomePage() {
|
|||||||
{
|
{
|
||||||
enabled: tabsValue === BROWSE_TABS_VALUES.MY,
|
enabled: tabsValue === BROWSE_TABS_VALUES.MY,
|
||||||
onError: () => {
|
onError: () => {
|
||||||
setResumes([]);
|
|
||||||
setRenderSignInButton(true);
|
setRenderSignInButton(true);
|
||||||
setSignInButtonText('to view your submitted resumes');
|
setSignInButtonText('to view your submitted resumes');
|
||||||
},
|
},
|
||||||
onSuccess: (data) => {
|
|
||||||
setTotalPages(
|
|
||||||
data.totalRecords % PAGE_LIMIT === 0
|
|
||||||
? data.totalRecords / PAGE_LIMIT
|
|
||||||
: Math.floor(data.totalRecords / PAGE_LIMIT) + 1,
|
|
||||||
);
|
|
||||||
setResumes(data.mappedResumeData);
|
|
||||||
},
|
|
||||||
retry: false,
|
retry: false,
|
||||||
staleTime: 5 * 60 * 1000,
|
staleTime: 5 * 60 * 1000,
|
||||||
},
|
},
|
||||||
@ -208,6 +180,30 @@ export default function ResumeHomePage() {
|
|||||||
setCurrentPage(1);
|
setCurrentPage(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTabQueryData = () => {
|
||||||
|
switch (tabsValue) {
|
||||||
|
case BROWSE_TABS_VALUES.ALL:
|
||||||
|
return allResumesQuery.data;
|
||||||
|
case BROWSE_TABS_VALUES.STARRED:
|
||||||
|
return starredResumesQuery.data;
|
||||||
|
case BROWSE_TABS_VALUES.MY:
|
||||||
|
return myResumesQuery.data;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTabResumes = () => {
|
||||||
|
return getTabQueryData()?.mappedResumeData ?? [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTabTotalPages = () => {
|
||||||
|
const numRecords = getTabQueryData()?.totalRecords ?? 0;
|
||||||
|
return numRecords % PAGE_LIMIT === 0
|
||||||
|
? numRecords / PAGE_LIMIT
|
||||||
|
: Math.floor(numRecords / PAGE_LIMIT) + 1;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
@ -277,7 +273,7 @@ export default function ResumeHomePage() {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
className="rounded-md bg-indigo-500 py-1 px-3 text-sm font-medium text-white"
|
className="rounded-md bg-indigo-500 py-2 px-3 text-sm font-medium text-white"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={onSubmitResume}>
|
onClick={onSubmitResume}>
|
||||||
Submit Resume
|
Submit Resume
|
||||||
@ -374,7 +370,7 @@ export default function ResumeHomePage() {
|
|||||||
{renderSignInButton && (
|
{renderSignInButton && (
|
||||||
<ResumeSignInButton text={signInButtonText} />
|
<ResumeSignInButton text={signInButtonText} />
|
||||||
)}
|
)}
|
||||||
{totalPages === 0 && (
|
{getTabResumes().length === 0 && (
|
||||||
<div className="mt-4">Nothing to see here.</div>
|
<div className="mt-4">Nothing to see here.</div>
|
||||||
)}
|
)}
|
||||||
<ResumeListItems
|
<ResumeListItems
|
||||||
@ -383,12 +379,12 @@ export default function ResumeHomePage() {
|
|||||||
starredResumesQuery.isFetching ||
|
starredResumesQuery.isFetching ||
|
||||||
myResumesQuery.isFetching
|
myResumesQuery.isFetching
|
||||||
}
|
}
|
||||||
resumes={resumes}
|
resumes={getTabResumes()}
|
||||||
/>
|
/>
|
||||||
<div className="my-4 flex justify-center">
|
<div className="my-4 flex justify-center">
|
||||||
<Pagination
|
<Pagination
|
||||||
current={currentPage}
|
current={currentPage}
|
||||||
end={totalPages}
|
end={getTabTotalPages()}
|
||||||
label="pagination"
|
label="pagination"
|
||||||
start={1}
|
start={1}
|
||||||
onSelect={(page) => setCurrentPage(page)}
|
onSelect={(page) => setCurrentPage(page)}
|
||||||
|
Reference in New Issue
Block a user