added chapter view, fixes, added ratings, added chapter updates/deletions
This commit is contained in:
parent
029b7e9353
commit
4801cf3a13
34 changed files with 1345 additions and 191 deletions
121
app/client/components/BookChapterForm.tsx
Normal file
121
app/client/components/BookChapterForm.tsx
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
import { Button } from '@app/client/components/ui/button';
|
||||
import { Box, Input, Stack, Textarea } from '@chakra-ui/react';
|
||||
import { valibotResolver } from '@hookform/resolvers/valibot';
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import { useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { Descendant } from 'slate';
|
||||
import * as v from 'valibot';
|
||||
import { EditorSlate } from './EditorSlate';
|
||||
import { Field } from './ui/field';
|
||||
|
||||
interface BookChapterEditInitialValues {
|
||||
readonly title: string;
|
||||
readonly foreword?: string;
|
||||
readonly footnote?: string;
|
||||
readonly content?: Descendant[];
|
||||
}
|
||||
|
||||
interface BookChapterInput {
|
||||
readonly title: string;
|
||||
readonly foreword?: string;
|
||||
readonly footnote?: string;
|
||||
readonly content: Descendant[];
|
||||
}
|
||||
|
||||
interface BookChapterFormValues {
|
||||
readonly title: string;
|
||||
readonly foreword: string;
|
||||
readonly footnote: string;
|
||||
}
|
||||
|
||||
export function BookChapterForm({
|
||||
bookId,
|
||||
initialValues,
|
||||
onChapterSubmit
|
||||
}: {
|
||||
readonly bookId: string;
|
||||
readonly initialValues?: BookChapterEditInitialValues | null;
|
||||
readonly onChapterSubmit: (chapter: BookChapterInput) => Promise<void>;
|
||||
}) {
|
||||
const [content, setContent] = useState<Descendant[]>([]);
|
||||
|
||||
const schema = v.pipe(
|
||||
v.object({
|
||||
title: v.pipe(v.string(), v.nonEmpty('Title is required'), v.maxLength(60)),
|
||||
foreword: v.pipe(v.string()),
|
||||
footnote: v.pipe(v.string())
|
||||
})
|
||||
);
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors }
|
||||
} = useForm<BookChapterFormValues>({
|
||||
defaultValues: {
|
||||
title: initialValues?.title,
|
||||
foreword: initialValues?.foreword,
|
||||
footnote: initialValues?.footnote
|
||||
},
|
||||
resolver: valibotResolver(schema)
|
||||
});
|
||||
|
||||
const onSubmit = handleSubmit(async values =>
|
||||
onChapterSubmit({
|
||||
title: values.title,
|
||||
foreword: values.foreword,
|
||||
footnote: values.footnote,
|
||||
content
|
||||
})
|
||||
);
|
||||
|
||||
return (
|
||||
<form onSubmit={onSubmit}>
|
||||
<Stack justifyContent="center" alignItems="center" minHeight="88vh">
|
||||
<Stack maxWidth="840px" minHeight="80vh" justifyContent="center" alignItems="center">
|
||||
<Stack width="100%" direction="row" justifyContent="space-between" alignItems="start">
|
||||
<Box>
|
||||
<Field invalid={errors.title != null} errorText={errors.title?.message}>
|
||||
<Input {...register('title')} placeholder="Chapter title" />
|
||||
</Field>
|
||||
</Box>
|
||||
<Stack direction="row">
|
||||
<Button onClick={async () => onSubmit()}>Submit</Button>
|
||||
<Link to={`/work/book/${bookId}/overview`}>
|
||||
<Button>Go back</Button>
|
||||
</Link>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Field invalid={errors.foreword != null} errorText={errors.foreword?.message}>
|
||||
<Textarea
|
||||
color="fg.muted"
|
||||
variant="subtle"
|
||||
placeholder="Foreword"
|
||||
resize="none"
|
||||
maxLength={500}
|
||||
{...register('foreword')}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<EditorSlate
|
||||
initialValue={initialValues?.content}
|
||||
onChange={values => setContent(values)}
|
||||
/>
|
||||
|
||||
<Field invalid={errors.footnote != null} errorText={errors.footnote?.message}>
|
||||
<Textarea
|
||||
color="fg.muted"
|
||||
variant="subtle"
|
||||
placeholder="Footnote"
|
||||
resize="none"
|
||||
maxLength={500}
|
||||
{...register('footnote')}
|
||||
/>
|
||||
</Field>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue