diff --git a/.eslintrc.json b/.eslintrc.json index 80045cf..90ad9b4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,6 +15,7 @@ "plugin:react/jsx-runtime" ], "rules": { + "@typescript-eslint/no-non-null-assertion": "off", "no-nested-ternary": "off", "react/jsx-props-no-spreading": "off", "no-underscore-dangle": "off", diff --git a/src/components/addLibrary.tsx b/src/components/addLibrary.tsx index bb15a14..b685a13 100644 --- a/src/components/addLibrary.tsx +++ b/src/components/addLibrary.tsx @@ -96,14 +96,21 @@ function Form({ onClose }: { onClose: () => void }) { ); } -export function AddLibrary() { +export function AddLibrary({ onCreate }: { onCreate: () => void }) { const modals = useModals(); const openCreateModal = () => { const id = modals.openModal({ title: 'Create a Library', centered: true, - children:
modals.closeModal(id)} />, + children: ( + { + modals.closeModal(id); + onCreate(); + }} + /> + ), }); }; diff --git a/src/components/emptyPrompt.tsx b/src/components/emptyPrompt.tsx index b6f6993..9c86ba2 100644 --- a/src/components/emptyPrompt.tsx +++ b/src/components/emptyPrompt.tsx @@ -11,7 +11,7 @@ const useStyles = createStyles((theme) => ({ }, })); -export function EmptyPrompt() { +export function EmptyPrompt({ onCreate }: { onCreate: () => void }) { const { classes } = useStyles(); return ( @@ -22,7 +22,7 @@ export function EmptyPrompt() { To be able to add new manga, you need to create a library - + ); diff --git a/src/components/header.tsx b/src/components/header.tsx index 27e9138..c485781 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -8,7 +8,7 @@ const useStyles = createStyles((theme) => ({ header: { backgroundColor: theme.colors.red[8], borderBottom: 0, - boxShadow: theme.shadows.xl, + boxShadow: theme.shadows.md, }, inner: { diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index 71e6b53..9a6fc09 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -1,20 +1,22 @@ import { - ActionIcon, Badge, - Code, createStyles, + Divider, + Grid, Group, + LoadingOverlay, Navbar, Text, - TextInput, Tooltip, UnstyledButton, } from '@mantine/core'; -import { AiOutlineBulb, AiOutlineCheckSquare, AiOutlinePlus, AiOutlineSearch, AiOutlineUser } from 'react-icons/ai'; +import { IconActivity, IconAlertTriangle, IconClock } from '@tabler/icons'; +import { trpc } from '../utils/trpc'; const useStyles = createStyles((theme) => ({ navbar: { paddingTop: 0, + boxShadow: theme.shadows.md, }, section: { @@ -68,9 +70,8 @@ const useStyles = createStyles((theme) => ({ }, mainLinkBadge: { - padding: 0, - width: 20, - height: 20, + padding: 5, + minWidth: 20, pointerEvents: 'none', }, @@ -104,29 +105,31 @@ const useStyles = createStyles((theme) => ({ })); const links = [ - { icon: AiOutlineBulb, label: 'Activity', notifications: 3 }, - { icon: AiOutlineCheckSquare, label: 'Tasks', notifications: 4 }, - { icon: AiOutlineUser, label: 'Contacts' }, + { icon: IconActivity, label: 'Activity', notifications: 862, color: 'teal' }, + { icon: IconClock, label: 'Queue', notifications: 38, color: 'indigo' }, + { icon: IconAlertTriangle, label: 'Failed', notifications: 4, color: 'red' }, ]; const collections = [ - { emoji: '👍', label: 'Sales' }, - { - emoji: '🚚', - label: - 'DeliveriesDeliveriesDeliveriesDeliveriesDeliveriesDeliveriesDeliveriesDeliveriesDeliveriesDeliveriesDeliveries', - }, - { emoji: '💸', label: 'Discounts' }, - { emoji: '💰', label: 'Profits' }, - { emoji: '✨', label: 'Reports' }, - { emoji: '🛒', label: 'Orders' }, - { emoji: '📅', label: 'Events' }, - { emoji: '🙈', label: 'Debts' }, - { emoji: '💁‍♀️', label: 'Customers' }, + { chapter: 123, label: 'Jujutsu Kaisen' }, + { chapter: 2, label: 'One Piece' }, + { chapter: 42, label: 'Bleach' }, + { chapter: 36, label: 'Naruto' }, + { chapter: 98, label: 'Black Clover' }, + { chapter: 610, label: 'Fairy Tail' }, + { chapter: 133, label: 'Hunter x Hunter' }, + { chapter: 51, label: 'Noblesse' }, + { chapter: 24, label: 'Berserk' }, + { chapter: 23, label: 'Berserk' }, ]; export function KaizokuNavbar() { const { classes } = useStyles(); + const libraryQuery = trpc.library.query.useQuery(undefined, { + staleTime: Infinity, + refetchOnWindowFocus: false, + refetchInterval: Infinity, + }); const mainLinks = links.map((link) => ( @@ -135,7 +138,7 @@ export function KaizokuNavbar() { {link.label} {link.notifications && ( - + {link.notifications} )} @@ -151,39 +154,43 @@ export function KaizokuNavbar() { className={classes.collectionLink} style={{ width: 'inherit', overflowX: 'hidden' }} > - - {collection.emoji} - {' '} - {collection.label} + + + + {collection.label} + + + + + + + + #{collection.chapter} + + + )); + if (libraryQuery.isLoading) { + return ; + } + + if (!libraryQuery.data) { + return null; + } + return ( - } - rightSectionWidth={70} - rightSection={Ctrl + K} - styles={{ rightSection: { pointerEvents: 'none' } }} - mb="sm" - /> -
{mainLinks}
- - Collections + + Latest Downloads - - - - -
{collectionLinks}
diff --git a/src/components/newMangaCard.tsx b/src/components/newMangaCard.tsx index 443f9df..4c7178b 100644 --- a/src/components/newMangaCard.tsx +++ b/src/components/newMangaCard.tsx @@ -22,7 +22,7 @@ import { useForm, UseFormReturnType, zodResolver } from '@mantine/form'; import { getHotkeyHandler } from '@mantine/hooks'; import { useModals } from '@mantine/modals'; import { showNotification } from '@mantine/notifications'; -import { IconArrowRight, IconBook, IconCheck, IconSearch, IconX } from '@tabler/icons'; +import { IconArrowRight, IconCheck, IconPlus, IconSearch, IconX } from '@tabler/icons'; import { useState } from 'react'; import { z } from 'zod'; import { trpc } from '../utils/trpc'; @@ -33,11 +33,10 @@ const useStyles = createStyles((theme) => ({ height: 350, width: 210, display: 'flex', - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'flex-end', - backgroundSize: 'cover', - backgroundPosition: 'center', + justifyContent: 'center', + alignItems: 'center', + backgroundColor: theme.colors.gray[4], + cursor: 'pointer', transition: 'transform 150ms ease, box-shadow 150ms ease', @@ -326,6 +325,11 @@ function Form({ onClose }: { onClose: () => void }) { }; const prevStep = () => { + if (active === 0) { + setVisible(false); + onClose(); + form.reset(); + } if (active === 1) { form.setFieldValue('query', ''); form.setFieldValue('source', ''); @@ -419,7 +423,7 @@ function Form({ onClose }: { onClose: () => void }) { - + + + + + ); } diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index bb6de5b..ca03811 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -4,6 +4,7 @@ import { NotificationsProvider } from '@mantine/notifications'; import type { AppProps } from 'next/app'; import Head from 'next/head'; import { KaizokuHeader, KaizokuLinks } from '../components/header'; +import { KaizokuNavbar } from '../components/navbar'; import '../styles/globals.css'; import { trpc } from '../utils/trpc'; @@ -27,6 +28,7 @@ function MyApp({ Component, pageProps }: AppProps) { } header={} styles={(theme) => ({ main: { backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0] }, diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 8d59906..1ad9173 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,21 +1,56 @@ -import { LoadingOverlay } from '@mantine/core'; -import { useRouter } from 'next/router'; +import { Grid, LoadingOverlay } from '@mantine/core'; import { EmptyPrompt } from '../components/emptyPrompt'; +import { MangaCard } from '../components/mangaCard'; +import { NewMangaCard } from '../components/newMangaCard'; import { trpc } from '../utils/trpc'; export default function IndexPage() { const libraryQuery = trpc.library.query.useQuery(); - const router = useRouter(); + + const libraryId = libraryQuery.data?.id; + + const mangaQuery = trpc.manga.query.useQuery( + { + library: libraryId!, + }, + { + staleTime: Infinity, + enabled: libraryId !== undefined, + }, + ); if (libraryQuery.isLoading) { return ; } - if (libraryQuery.data) { - router.push(`/library/${libraryQuery.data.id}`); - return ; + if (!libraryQuery.data) { + return ( + { + libraryQuery.refetch(); + }} + /> + ); } - return ; + return ( + + + { + mangaQuery.refetch(); + }} + /> + + {mangaQuery.data && + mangaQuery.data.map((manga) => { + return ( + + + + ); + })} + + ); } diff --git a/src/pages/library/[id].tsx b/src/pages/library/[id].tsx deleted file mode 100644 index 79c99c5..0000000 --- a/src/pages/library/[id].tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { Grid, LoadingOverlay } from '@mantine/core'; -import { useRouter } from 'next/router'; -import { MangaCard } from '../../components/mangaCard'; -import { NewMangaCard } from '../../components/newMangaCard'; -import { trpc } from '../../utils/trpc'; - -export default function LibraryPage() { - const router = useRouter(); - const { id } = router.query; - const mangaQuery = trpc.manga.query.useQuery( - { - library: parseInt(id as string, 10), - }, - { - staleTime: Infinity, - enabled: id !== undefined, - }, - ); - - if (mangaQuery.isLoading) { - return ; - } - - return ( - - - { - mangaQuery.refetch(); - }} - /> - - {mangaQuery.data && - mangaQuery.data.map((manga) => { - return ( - - - - ); - })} - - ); -} diff --git a/tsconfig.json b/tsconfig.json index 880925d..a4988fb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,6 @@ "allowJs": true, "skipLibCheck": true, "strict": true, - "strictNullChecks": true, "downlevelIteration": true, "forceConsistentCasingInFileNames": true, "noEmit": true,