added book details, update, delete. fixes

This commit is contained in:
lnn0q 2025-06-01 19:37:13 +03:00
parent d1da980501
commit b5738c610d
12 changed files with 290 additions and 16 deletions

View file

@ -0,0 +1,151 @@
import { gql, useQuery } from '@apollo/client';
import { BookOverviewTabs } from '@app/client/components/BookOverviewTabs';
import { bookListQuery } from '@app/client/components/BookSearchList';
import { bookFragment } from '@app/client/fragments';
import { useIdentity } from '@app/client/hooks/identity';
import { useToastMutation } from '@app/client/hooks/useToastMutation';
import { Button, Input, NativeSelect, Skeleton, Stack, Textarea } from '@chakra-ui/react';
import { BookDetailsQuery, WorkingProgressStatus } from '@generated/types';
import { useNavigate } from '@tanstack/react-router';
import { createFileRoute } from '@tanstack/react-router';
import { useState } from 'react';
export const Route = createFileRoute('/work/book/$bookId/overview/details')({
component: RouteComponent
});
function RouteComponent() {
const { bookId: id } = Route.useParams();
const identity = useIdentity();
const navigate = useNavigate();
const { data } = useQuery<BookDetailsQuery>(bookQuery, {
variables: { id }
});
const { update: bookUpdate } = useToastMutation({
mutation: bookUpdateMutation,
successMsg: 'Book updated successfully'
});
const { update: bookDelete } = useToastMutation({
mutation: bookDeleteMutation,
successMsg: 'Book deleted successfully',
refetchQueries: [bookListQuery]
});
const [title, setTitle] = useState<string | undefined>(data?.bookOne.title);
const [description, setDescription] = useState<string | undefined>(data?.bookOne.description);
const [progress, setProgress] = useState<WorkingProgressStatus | undefined>(
data?.bookOne.progressStatus
);
if (data == null) return <Skeleton />;
return (
<>
<BookOverviewTabs
isAuthor={data.bookOne.author.id === identity?.data.id}
bookId={id}
currentTab="details"
/>
<Stack justifyContent="center" alignItems="center">
<Stack width="70%">
<Input
value={title}
onChange={event => setTitle(event.currentTarget.value)}
placeholder="title"
maxLength={60}
/>
<NativeSelect.Root>
<NativeSelect.Field
value={progress}
onChange={event => {
const updatedStatus = event.currentTarget.value;
ensureProgressStatus(updatedStatus);
setProgress(updatedStatus);
}}
>
<option value={WorkingProgressStatus.InProgress}>In progress</option>
<option value={WorkingProgressStatus.Frozen}>Frozen</option>
<option value={WorkingProgressStatus.Complete}>Complete</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
<Textarea
value={description}
onChange={event => setDescription(event.currentTarget.value)}
placeholder="description"
maxLength={500}
autoresize
/>
<Button
width="100%"
onClick={async () => {
await bookUpdate({
variables: {
input: {
id,
title,
description,
progressStatus: progress
}
}
});
}}
>
Update
</Button>
<Button
width="100%"
backgroundColor="red.500"
onClick={async () => {
await bookDelete({ variables: { id } });
navigate({ to: '/' });
}}
>
Delete
</Button>
</Stack>
</Stack>
</>
);
}
function ensureProgressStatus(value: string): asserts value is WorkingProgressStatus {
if (value === WorkingProgressStatus.Complete) return;
if (value === WorkingProgressStatus.InProgress) return;
if (value === WorkingProgressStatus.Frozen) return;
throw new Error('Invalid WorkingPrgoressStatus');
}
const bookQuery = gql`
query BookDetails($id: ID!) {
bookOne(id: $id) {
...Book
}
}
${bookFragment}
`;
const bookUpdateMutation = gql`
mutation BookDetailsUpdate($input: BookUpdateInput!) {
bookUpdate(input: $input) {
...Book
}
}
${bookFragment}
`;
const bookDeleteMutation = gql`
mutation BookDetailsDelete($id: ID!) {
bookDelete(id: $id)
}
`;