diff --git a/app/client/components/BookSearchList.tsx b/app/client/components/BookSearchList.tsx
index 0f6d881..ab67d40 100644
--- a/app/client/components/BookSearchList.tsx
+++ b/app/client/components/BookSearchList.tsx
@@ -1,16 +1,18 @@
import { gql } from '@apollo/client';
-import { Skeleton, Stack } from '@chakra-ui/react';
+import { Stack } from '@chakra-ui/react';
import { BooksListQuery } from '@generated/types';
import { useState } from 'react';
import { Pagination } from '../components/Pagination';
import { WorkingList } from '../components/WorkingList';
-import { WorkingListSearch } from '../components/WorkingListSearch';
+import { ListSearch } from '../components/ListSearch';
+import { bookFragment } from '../fragments';
import { usePaginatedQuery } from '../hooks/usePaginatedQuery';
+import { PaginatedListSkeleton } from './PaginatedListSkeleton';
export function BookSearchList() {
const [workingSearchValue, setWorkingSearchValue] = useState('');
const [workingsListPage, setWorkingsListPage] = useState(1);
- const [workingsListPageSize, setWorkingsListPageSize] = useState(2);
+ const [workingsListPageSize, setWorkingsListPageSize] = useState(10);
const startIndex = (workingsListPage - 1) * workingsListPageSize;
const { data } = usePaginatedQuery({
@@ -26,35 +28,24 @@ export function BookSearchList() {
return (
<>
+ setWorkingSearchValue(value)} />
{data != null ? (
<>
- {
- setWorkingSearchValue(value);
- }}
- />
-
-
- {data.bookMany.items.length !== 0 && (
-
+ {data.bookMany.total > workingsListPageSize && (
+
+
+
)}
>
) : (
- <>
-
-
-
-
-
-
-
- >
+
)}
>
);
@@ -64,21 +55,10 @@ const query = gql`
query BooksList($input: BookManyInput!) {
bookMany(input: $input) {
items {
- id
- title
- description
- author {
- id
- username
- }
- updatedAt
- progressStatus
- ratingTotal
- reviewsTotal
- wordsTotal
- chaptersTotal
+ ...Book
}
total
}
}
+ ${bookFragment}
`;
diff --git a/app/client/components/EditorSlate.tsx b/app/client/components/EditorSlate.tsx
index 01a6e00..2a0a14a 100644
--- a/app/client/components/EditorSlate.tsx
+++ b/app/client/components/EditorSlate.tsx
@@ -1,6 +1,6 @@
import { Button, Card, Stack, Text, Wrap } from '@chakra-ui/react';
import isHotkey from 'is-hotkey';
-import React, { KeyboardEvent, MouseEvent, useCallback, useMemo, useState } from 'react';
+import React, { KeyboardEvent, MouseEvent, useCallback, useMemo } from 'react';
import { createEditor, Descendant, Editor, Element as SlateElement, Transforms } from 'slate';
import { withHistory } from 'slate-history';
import {
@@ -44,7 +44,7 @@ export function EditorSlate() {
}
}}
>
-
+
>
@@ -65,7 +65,7 @@ type AlignType = (typeof TEXT_ALIGN_TYPES)[number];
type ListType = (typeof LIST_TYPES)[number];
type CustomElementFormat = CustomElementType | AlignType | ListType;
-const RichTextExample = () => {
+function EditorViewport() {
const renderElement = useCallback((props: RenderElementProps) => , []);
const renderLeaf = useCallback((props: RenderLeafProps) => , []);
const editor = useMemo(() => withHistory(withReact(createEditor())), []);
@@ -123,12 +123,17 @@ const RichTextExample = () => {
-
+
{
className="slate-editor"
style={{
outline: 'none',
- minWidth: '100%'
+ minWidth: '100%',
+ maxWidth: 'unset',
+ maxHeight: '75vh',
+ padding: 0,
+ overflowY: 'auto'
}}
renderElement={renderElement}
renderLeaf={renderLeaf}
@@ -158,9 +167,9 @@ const RichTextExample = () => {
);
-};
+}
-const toggleBlock = (editor: CustomEditor, format: CustomElementFormat) => {
+function toggleBlock(editor: CustomEditor, format: CustomElementFormat) {
const isActive = isBlockActive(editor, format, isAlignType(format) ? 'align' : 'type');
const isList = isListType(format);
@@ -188,9 +197,9 @@ const toggleBlock = (editor: CustomEditor, format: CustomElementFormat) => {
const block = { type: format, children: [] };
Transforms.wrapNodes(editor, block);
}
-};
+}
-const toggleMark = (editor: CustomEditor, format: CustomTextKey) => {
+function toggleMark(editor: CustomEditor, format: CustomTextKey) {
const isActive = isMarkActive(editor, format);
if (isActive) {
@@ -198,13 +207,13 @@ const toggleMark = (editor: CustomEditor, format: CustomTextKey) => {
} else {
Editor.addMark(editor, format, true);
}
-};
+}
-const isBlockActive = (
+function isBlockActive(
editor: CustomEditor,
format: CustomElementFormat,
blockType: 'type' | 'align' = 'type'
-) => {
+) {
const { selection } = editor;
if (!selection) return false;
@@ -223,15 +232,15 @@ const isBlockActive = (
})
);
- return !!match;
-};
+ return Boolean(match);
+}
-const isMarkActive = (editor: CustomEditor, format: CustomTextKey) => {
+function isMarkActive(editor: CustomEditor, format: CustomTextKey) {
const marks = Editor.marks(editor);
return marks ? marks[format] === true : false;
-};
+}
-const Element = ({ attributes, children, element }: RenderElementProps) => {
+function Element({ attributes, children, element }: RenderElementProps) {
const style: React.CSSProperties = {};
if (isAlignElement(element)) {
style.textAlign = element.align as AlignType;
@@ -280,9 +289,9 @@ const Element = ({ attributes, children, element }: RenderElementProps) => {
);
}
-};
+}
-const Leaf = ({ attributes, children, leaf }: RenderLeafProps) => {
+function Leaf({ attributes, children, leaf }: RenderLeafProps) {
if (leaf.bold) {
children = {children};
}
@@ -300,7 +309,7 @@ const Leaf = ({ attributes, children, leaf }: RenderLeafProps) => {
}
return {children};
-};
+}
interface BlockButtonProps {
format: CustomElementFormat;
@@ -308,7 +317,7 @@ interface BlockButtonProps {
text?: string;
}
-const BlockButton = ({ format, icon, text }: BlockButtonProps) => {
+function BlockButton({ format, icon, text }: BlockButtonProps) {
const editor = useSlate();
return (
);
-};
+}
interface MarkButtonProps {
format: CustomTextKey;
@@ -333,7 +342,7 @@ interface MarkButtonProps {
text?: string;
}
-const MarkButton = ({ format, icon, text }: MarkButtonProps) => {
+function MarkButton({ format, icon, text }: MarkButtonProps) {
const editor = useSlate();
return (
);
-};
+}
-const isAlignType = (format: CustomElementFormat): format is AlignType => {
+function isAlignType(format: CustomElementFormat): format is AlignType {
return TEXT_ALIGN_TYPES.includes(format as AlignType);
-};
+}
-const isListType = (format: CustomElementFormat): format is ListType => {
+function isListType(format: CustomElementFormat): format is ListType {
return LIST_TYPES.includes(format as ListType);
-};
+}
-const isAlignElement = (element: CustomElement): element is CustomElementWithAlign => {
+function isAlignElement(element: CustomElement): element is CustomElementWithAlign {
return 'align' in element;
-};
+}
diff --git a/app/client/components/EditorTestSlate.tsx b/app/client/components/EditorTestSlate.tsx
deleted file mode 100644
index 3129685..0000000
--- a/app/client/components/EditorTestSlate.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Card, Heading } from '@chakra-ui/react';
-import { useState } from 'react';
-import { BaseEditor, createEditor, Descendant } from 'slate';
-import { Editable, ReactEditor, Slate, withReact } from 'slate-react';
-
-type CustomElement = { type: 'paragraph'; children: CustomText[] };
-type CustomText = { text: string };
-
-declare module 'slate' {
- interface CustomTypes {
- Editor: BaseEditor & ReactEditor;
- Element: CustomElement;
- Text: CustomText;
- }
-}
-
-export function EditorSlate() {
- const initialValue: Descendant[] = [
- {
- type: 'paragraph',
- children: [{ text: 'A line of text in a paragraph.' }]
- }
- ];
-
- const [editor] = useState(() => withReact(createEditor()));
- return (
- // Add the editable component inside the context.
- <>
-
-
- Editor
-
-
-
-
-
-
-
- >
- );
-}
diff --git a/app/client/components/Link.tsx b/app/client/components/Link.tsx
new file mode 100644
index 0000000..5f262f1
--- /dev/null
+++ b/app/client/components/Link.tsx
@@ -0,0 +1,25 @@
+import { Text } from '@chakra-ui/react';
+import { LinkProps as LinkExtended, Link as TanstackLink } from '@tanstack/react-router';
+import { ReactNode } from 'react';
+
+interface LinkProps {
+ children: ReactNode;
+ to: LinkExtended['to'];
+ link?: LinkExtended;
+}
+
+export function Link(props: LinkProps) {
+ return (
+
+
+ {props.children}
+
+
+ );
+}
diff --git a/app/client/components/WorkingListSearch.tsx b/app/client/components/ListSearch.tsx
similarity index 77%
rename from app/client/components/WorkingListSearch.tsx
rename to app/client/components/ListSearch.tsx
index 4a85652..5442397 100644
--- a/app/client/components/WorkingListSearch.tsx
+++ b/app/client/components/ListSearch.tsx
@@ -1,7 +1,13 @@
import { Button, Icon, Input, InputGroup, Stack } from '@chakra-ui/react';
import { useState } from 'react';
-export function WorkingListSearch({ onSubmit }: { onSubmit: (value: string) => void }) {
+export function ListSearch({
+ placeholder,
+ onSubmit
+}: {
+ readonly placeholder?: string;
+ readonly onSubmit: (value: string) => void;
+}) {
const [searchValue, setSearchValue] = useState('');
return (