added resolvers, updated model, updated navbar

This commit is contained in:
lnn0q 2025-05-17 21:41:07 +03:00
parent a8375b99c2
commit 1d40d7e15f
23 changed files with 439 additions and 301 deletions

View file

@ -0,0 +1,84 @@
import { gql } from '@apollo/client';
import { Skeleton, 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 { usePaginatedQuery } from '../hooks/usePaginatedQuery';
export function BookSearchList() {
const [workingSearchValue, setWorkingSearchValue] = useState<string>('');
const [workingsListPage, setWorkingsListPage] = useState<number>(1);
const [workingsListPageSize, setWorkingsListPageSize] = useState<number>(2);
const startIndex = (workingsListPage - 1) * workingsListPageSize;
const { data } = usePaginatedQuery<BooksListQuery>({
query,
input: {
filter: {
terms: workingSearchValue,
offset: startIndex,
size: workingsListPageSize
}
}
});
return (
<>
{data != null ? (
<>
<WorkingListSearch
onSubmit={value => {
setWorkingSearchValue(value);
}}
/>
<WorkingList workingsList={[...data.bookMany.items]} />
{data.bookMany.items.length != 0 && (
<Pagination
total={data.bookMany.total}
page={workingsListPage}
setPage={setWorkingsListPage}
pageSize={workingsListPageSize}
/>
)}
</>
) : (
<>
<Stack direction="row" justifyContent="center" alignItems="center" gap={2}>
<Skeleton height={10} width="80%" />
<Skeleton height={10} width="calc(20% - 6px)" />
</Stack>
<Skeleton height={20} />
<Skeleton height={20} />
<Skeleton height={20} />
</>
)}
</>
);
}
const query = gql`
query BooksList($input: BookManyInput!) {
bookMany(input: $input) {
items {
id
title
description
author {
id
username
}
updatedAt
progressStatus
ratingTotal
reviewsTotal
wordsTotal
chaptersTotal
}
total
}
}
`;

View file

@ -0,0 +1,27 @@
import { Badge, BadgeProps, Box, Icon, Stack } from '@chakra-ui/react';
import { ReactNode } from 'react';
export function IconBadge({
children,
iconClass,
backgroundColor,
size = 'lg'
}: {
children?: ReactNode;
iconClass: string;
backgroundColor?: BadgeProps['backgroundColor'];
size?: 'sm' | 'md' | 'lg' | 'xs';
}) {
return (
<Box flex={1} direction="row" justifyContent="center" alignItems="center">
<Badge variant="solid" size={size} backgroundColor={backgroundColor}>
<Stack direction="row">
<Icon fontSize="xl">
<i className={iconClass} />
</Icon>
{children}
</Stack>
</Badge>
</Box>
);
}

View file

@ -1,14 +1,28 @@
import { List } from '@chakra-ui/react';
import { Card, List, Text } from '@chakra-ui/react';
import { WorkingCardProps, WorkingListCard } from './WorkingListCard';
export function WorkingList({ workingsList }: { workingsList: WorkingCardProps[] }) {
return (
<List.Root variant="plain" gap={4}>
{workingsList.map(workingData => (
<List.Item key={workingData.id}>
<WorkingListCard {...workingData} />
{workingsList.length != 0 ? (
workingsList.map(workingData => (
<List.Item key={workingData.id}>
<WorkingListCard {...workingData} />
</List.Item>
))
) : (
<List.Item>
<Card.Root
variant="outline"
width="100%"
padding={4}
justifyContent="center"
alignItems={'center'}
>
<Text fontSize="md">Nothing is here yet!</Text>
</Card.Root>
</List.Item>
))}
)}
</List.Root>
);
}

View file

@ -1,6 +1,6 @@
import { Badge, BadgeProps, Box, Card, Heading, Icon, Link, Stack, Text } from '@chakra-ui/react';
import { Badge, Box, Card, Heading, Link, Stack, Text } from '@chakra-ui/react';
import { WorkingProgressStatus } from '@generated/types';
import { ReactNode } from 'react';
import { IconBadge } from './IconBadge';
import { WorkingProgressStatusBadge } from './WorkingProgressStatusBadge';
import { WorkingRatingBadge } from './WorkingRatingBadge';
@ -88,28 +88,3 @@ export function WorkingListCard({
</Card.Root>
);
}
export function IconBadge({
children,
iconClass,
backgroundColor,
size = 'lg'
}: {
children?: ReactNode;
iconClass: string;
backgroundColor?: BadgeProps['backgroundColor'];
size?: 'sm' | 'md' | 'lg' | 'xs';
}) {
return (
<Box flex={1} direction="row" justifyContent="center" alignItems="center">
<Badge variant="solid" size={size} backgroundColor={backgroundColor}>
<Stack direction="row">
<Icon fontSize="xl">
<i className={iconClass} />
</Icon>
{children}
</Stack>
</Badge>
</Box>
);
}

View file

@ -1,19 +1,13 @@
import { Button, Icon, Input, InputGroup, Stack } from '@chakra-ui/react';
import { useState } from 'react';
export function WorkingListSearch({
value,
onChange,
onSubmit
}: {
value: string;
onChange: (value: string) => void;
onSubmit: (value: string) => void;
}) {
export function WorkingListSearch({ onSubmit }: { onSubmit: (value: string) => void }) {
const [searchValue, setSearchValue] = useState<string>('');
return (
<form
onSubmit={event => {
event.preventDefault();
onSubmit(value);
onSubmit(searchValue);
}}
>
<Stack direction="row">
@ -26,8 +20,8 @@ export function WorkingListSearch({
}
>
<Input
value={value}
onChange={event => onChange(event.currentTarget.value)}
value={searchValue}
onChange={event => setSearchValue(event.currentTarget.value)}
placeholder="Search works..."
/>
</InputGroup>

View file

@ -32,6 +32,6 @@ export function WorkingProgressStatusBadge({
function toWorkingProgressStatusIcon(value: WorkingProgressStatus): string {
if (value === WorkingProgressStatus.InProgress) return 'nf nf-fa-clock';
if (value === WorkingProgressStatus.Frozen) return 'nf nf-fa-snowflake';
if (value === WorkingProgressStatus.Finished) return 'nf nf-fa-circle_check';
if (value === WorkingProgressStatus.Complete) return 'nf nf-fa-circle_check';
assertUnreachable(value);
}

View file

@ -1,5 +1,5 @@
import { BadgeProps, Text } from '@chakra-ui/react';
import { IconBadge } from './WorkingListCard';
import { IconBadge } from './IconBadge';
interface WorkingRatingParams {
rating: string;