119 lines
3.4 KiB
TypeScript
119 lines
3.4 KiB
TypeScript
import { gql } from '@apollo/client';
|
|
import { BookOverviewTabs } from '@app/client/components/BookOverviewTabs';
|
|
import { Pagination } from '@app/client/components/Pagination';
|
|
import { reviewFragment } from '@app/client/fragments';
|
|
import { useIdentity } from '@app/client/hooks/identity';
|
|
import { usePaginatedQuery } from '@app/client/hooks/usePaginatedQuery';
|
|
import { useToastMutation } from '@app/client/hooks/useToastMutation';
|
|
import { Skeleton, Stack, Text } from '@chakra-ui/react';
|
|
import { BookReviewCreateMutation, BookReviewsQuery } from '@generated/types';
|
|
import { createFileRoute } from '@tanstack/react-router';
|
|
import { useState } from 'react';
|
|
import { bookQuery } from '../overview';
|
|
import { ReviewInput } from '@app/client/components/ReviewInput';
|
|
import { ReviewCard } from '@app/client/components/ReviewCard';
|
|
|
|
export const Route = createFileRoute('/work/book/$bookId/overview/reviews')({
|
|
component: RouteComponent
|
|
});
|
|
|
|
function RouteComponent() {
|
|
const { bookId: id } = Route.useParams();
|
|
const identity = useIdentity();
|
|
|
|
const [reviewsPage, setChaptersListPage] = useState<number>(1);
|
|
const [reviewsPageSize, setChaptersListPageSize] = useState<number>(10);
|
|
const startIndex = (reviewsPage - 1) * reviewsPageSize;
|
|
|
|
const { data } = usePaginatedQuery<BookReviewsQuery>({
|
|
query: bookReviewsQuery,
|
|
input: {
|
|
bookId: id,
|
|
filter: {
|
|
offset: startIndex,
|
|
size: reviewsPageSize
|
|
}
|
|
}
|
|
});
|
|
|
|
const { update: reviewCreate } = useToastMutation<BookReviewCreateMutation>({
|
|
mutation: bookReviewCreateMutation,
|
|
successMsg: 'Review posted!',
|
|
refetchQueries: [bookReviewsQuery, bookQuery]
|
|
});
|
|
|
|
if (data == null) return <Skeleton />;
|
|
|
|
return (
|
|
<>
|
|
<BookOverviewTabs bookId={id} currentTab="reviews" />
|
|
|
|
{identity != null && reviewsPage === 1 && (
|
|
<ReviewInput
|
|
username={identity?.data.user.username}
|
|
onReviewSubmit={async text => {
|
|
await reviewCreate({
|
|
variables: {
|
|
input: {
|
|
bookId: id,
|
|
text
|
|
}
|
|
}
|
|
});
|
|
}}
|
|
/>
|
|
)}
|
|
|
|
{data.reviewMany.items.length === 0 ? (
|
|
<Stack justifyContent="center" alignItems="center" pt={8}>
|
|
<Text>No reviews here yet!</Text>
|
|
</Stack>
|
|
) : (
|
|
data.reviewMany.items.map(item => (
|
|
<ReviewCard
|
|
key={`bookReview#${item.id}`}
|
|
review={{
|
|
id: item.id,
|
|
username: item.author.username,
|
|
text: item.text,
|
|
createdAt: item.createdAt
|
|
}}
|
|
/>
|
|
))
|
|
)}
|
|
|
|
{data.reviewMany.total > reviewsPageSize && (
|
|
<Stack justifyContent="center" alignItems="center">
|
|
<Pagination
|
|
total={data.reviewMany.total}
|
|
page={reviewsPage}
|
|
setPage={setChaptersListPage}
|
|
pageSize={reviewsPageSize}
|
|
setPageSize={setChaptersListPageSize}
|
|
/>
|
|
</Stack>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
const bookReviewsQuery = gql`
|
|
query BookReviews($input: ReviewManyInput!) {
|
|
reviewMany(input: $input) {
|
|
items {
|
|
...Review
|
|
}
|
|
total
|
|
}
|
|
}
|
|
${reviewFragment}
|
|
`;
|
|
|
|
const bookReviewCreateMutation = gql`
|
|
mutation BookReviewCreate($input: ReviewCreateInput!) {
|
|
reviewCreate(input: $input) {
|
|
...Review
|
|
}
|
|
}
|
|
${reviewFragment}
|
|
`;
|