implemented ratings, fixes

This commit is contained in:
lnn0q 2025-06-01 17:54:57 +03:00
parent 4801cf3a13
commit d1da980501
31 changed files with 775 additions and 236 deletions

View file

@ -51,7 +51,7 @@ function RouteComponent() {
}
});
navigate({ to: `/work/book/${bookId}/overview` });
navigate({ to: `/work/book/${bookId}/overview/contents` });
}}
/>
);

View file

@ -1,10 +1,9 @@
import { gql, useQuery } from '@apollo/client';
import { EditorSlate } from '@app/client/components/EditorSlate';
import { bookChapterFragment } from '@app/client/fragments';
import { Button, Heading, Icon, Skeleton, Stack, Text } from '@chakra-ui/react';
import { BookChapterViewQuery, BookChapterViewNavigationQuery } from '@generated/types';
import { Button, Heading, Icon, Separator, Skeleton, Stack, Text } from '@chakra-ui/react';
import { BookChapterViewNavigationQuery, BookChapterViewQuery } from '@generated/types';
import { createFileRoute, Link } from '@tanstack/react-router';
import { Descendant } from 'slate';
export const Route = createFileRoute('/work/book/$bookId/chapter/$chapterId/view')({
component: RouteComponent
@ -13,53 +12,35 @@ export const Route = createFileRoute('/work/book/$bookId/chapter/$chapterId/view
function RouteComponent() {
const { bookId, chapterId } = Route.useParams();
return (
<Stack justifyContent="center" alignItems="center">
<BookChapterView bookId={bookId} chapterId={chapterId} />
</Stack>
);
}
function BookChapterView({
bookId,
chapterId
}: {
readonly bookId: string;
readonly chapterId: string;
}) {
const { data } = useQuery<BookChapterViewQuery>(bookChapterQuery, {
variables: { id: chapterId }
variables: { id: chapterId },
fetchPolicy: 'cache-and-network'
});
const { data: navigationData } = useQuery<BookChapterViewNavigationQuery>(
bookChapterNavigationQuery,
{
variables: { id: chapterId }
variables: { id: chapterId },
fetchPolicy: 'no-cache'
}
);
if (data == null || navigationData == null) return <Skeleton />;
if (data == null) return <Skeleton />;
return (
<Stack justifyContent="center" alignItems="center">
<BookChapterView
bookId={bookId}
chapter={{ ...data.bookChapterOne, ...navigationData.bookChapterOne }}
/>
</Stack>
);
}
interface BookChapterViewChapter {
readonly id: string;
readonly title: string;
readonly createdAt: string;
readonly updatedAt: string;
readonly foreword?: string | null;
readonly footnote?: string | null;
readonly content: Descendant[];
readonly sequenceNumber: number;
readonly reviewsTotal: number;
readonly previousChapterId?: string | null;
readonly nextChapterId?: string | null;
readonly book: {
readonly title: string;
};
}
function BookChapterView({
bookId,
chapter
}: {
readonly bookId: string;
readonly chapter: BookChapterViewChapter;
}) {
return (
<Stack
maxWidth="840px"
@ -70,18 +51,38 @@ function BookChapterView({
>
<Heading as="div" maxWidth="100%">
<Text textAlign="center" minWidth={0}>
{chapter.book.title}
{data.bookChapterOne.book.title}
</Text>
<Text textAlign="center">-</Text>
<Text textAlign="center" minWidth={0}>
{chapter.title}
{data.bookChapterOne.title}
</Text>
</Heading>
<EditorSlate initialValue={chapter.content} readOnly />
{data.bookChapterOne.foreword && (
<>
<Stack width="91%" justifyContent="left" alignItems="start" paddingY={2}>
<Text fontWeight="bold">Foreword:</Text>
<Text color="fg.muted">{data.bookChapterOne.foreword}</Text>
</Stack>
<Separator width="91%" />
</>
)}
<EditorSlate initialValue={data.bookChapterOne.content} readOnly />
{data.bookChapterOne.footnote && (
<>
<Separator width="91%" />
<Stack width="91%" justifyContent="left" alignItems="start" paddingY={2}>
<Text fontWeight="bold">Footnote:</Text>
<Text color="fg.muted">{data.bookChapterOne.foreword}</Text>
</Stack>
</>
)}
<Text>{data.bookChapterOne.footnote}</Text>
<ChapterNavigation
bookId={bookId}
previousChapterId={chapter.previousChapterId}
nextChapterId={chapter.nextChapterId}
previousChapterId={navigationData?.bookChapterOne.previousChapterId}
nextChapterId={navigationData?.bookChapterOne.nextChapterId}
/>
</Stack>
);
@ -108,7 +109,7 @@ function ChapterNavigation({
</Button>
</Link>
)}
<Link to={`/work/book/${bookId}/overview`}>
<Link to={`/work/book/${bookId}/overview/contents`}>
<Button
variant="ghost"
borderLeftRadius={previousChapterId ? 0 : undefined}
@ -134,7 +135,7 @@ function ChapterNavigation({
);
}
const bookChapterQuery = gql`
export const bookChapterQuery = gql`
query BookChapterView($id: ID!) {
bookChapterOne(id: $id) {
id
@ -149,7 +150,7 @@ const bookChapterQuery = gql`
${bookChapterFragment}
`;
export const bookChapterNavigationQuery = gql`
const bookChapterNavigationQuery = gql`
query BookChapterViewNavigation($id: ID!) {
bookChapterOne(id: $id) {
id

View file

@ -5,8 +5,7 @@ import { useToastMutation } from '@app/client/hooks/useToastMutation';
import { Skeleton } from '@chakra-ui/react';
import { BookChapterNewCreateMutation, BookChapterNewQuery } from '@generated/types';
import { createFileRoute, redirect, useNavigate } from '@tanstack/react-router';
import { bookChapterListQuery } from '../overview';
import { bookChapterNavigationQuery } from './$chapterId/view';
import { bookChapterListQuery } from '../overview/contents';
export const Route = createFileRoute('/work/book/$bookId/chapter/new')({
component: RouteComponent,
@ -28,12 +27,12 @@ function RouteComponent() {
const { update: chapterCreate } = useToastMutation<BookChapterNewCreateMutation>({
mutation,
successMsg: 'Chapter created successfully',
refetchQueries: [bookChapterListQuery, bookChapterNavigationQuery]
refetchQueries: [bookChapterListQuery]
});
if (data == null) return <Skeleton />;
if (identity?.data.user.id !== data.bookOne.author.id)
throw redirect({ to: `/work/book/${id}/overview` });
throw redirect({ to: `/work/book/${id}/overview/contents` });
return (
<BookChapterForm
@ -48,7 +47,7 @@ function RouteComponent() {
}
});
navigate({ to: `/work/book/${id}/overview` });
navigate({ to: `/work/book/${id}/overview/contents` });
}}
/>
);