Skip to content

Commit

Permalink
refactor: cleanup library page
Browse files Browse the repository at this point in the history
  • Loading branch information
oae committed Oct 10, 2022
1 parent 0152736 commit 22d5346
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 128 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
11 changes: 9 additions & 2 deletions src/components/addLibrary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: <Form onClose={() => modals.closeModal(id)} />,
children: (
<Form
onClose={() => {
modals.closeModal(id);
onCreate();
}}
/>
),
});
};

Expand Down
4 changes: 2 additions & 2 deletions src/components/emptyPrompt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const useStyles = createStyles((theme) => ({
},
}));

export function EmptyPrompt() {
export function EmptyPrompt({ onCreate }: { onCreate: () => void }) {
const { classes } = useStyles();

return (
Expand All @@ -22,7 +22,7 @@ export function EmptyPrompt() {
<Text size="sm" className={classes.description}>
To be able to add new manga, you need to create a library
</Text>
<AddLibrary />
<AddLibrary onCreate={onCreate} />
</Stack>
</Center>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
97 changes: 52 additions & 45 deletions src/components/navbar.tsx
Original file line number Diff line number Diff line change
@@ -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: {
Expand Down Expand Up @@ -68,9 +70,8 @@ const useStyles = createStyles((theme) => ({
},

mainLinkBadge: {
padding: 0,
width: 20,
height: 20,
padding: 5,
minWidth: 20,
pointerEvents: 'none',
},

Expand Down Expand Up @@ -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) => (
<UnstyledButton key={link.label} className={classes.mainLink}>
Expand All @@ -135,7 +138,7 @@ export function KaizokuNavbar() {
<span>{link.label}</span>
</div>
{link.notifications && (
<Badge size="sm" variant="filled" className={classes.mainLinkBadge}>
<Badge size="md" variant="dot" color={link.color} className={classes.mainLinkBadge}>
{link.notifications}
</Badge>
)}
Expand All @@ -151,39 +154,43 @@ export function KaizokuNavbar() {
className={classes.collectionLink}
style={{ width: 'inherit', overflowX: 'hidden' }}
>
<span style={{ marginRight: 9, fontSize: 16, overflowX: 'hidden', textOverflow: 'ellipsis', width: 'inherit' }}>
{collection.emoji}
</span>{' '}
{collection.label}
<Grid gutter={5}>
<Grid.Col span="content" style={{ maxWidth: 180, whiteSpace: 'nowrap', overflow: 'hidden' }}>
<Tooltip label={collection.label}>
<Text weight={600}>{collection.label}</Text>
</Tooltip>
</Grid.Col>
<Grid.Col span="auto">
<Divider mt="xs" variant="dotted" />
</Grid.Col>
<Grid.Col span="content">
<Badge size="sm" variant="light" color="indigo" className={classes.mainLinkBadge}>
#{collection.chapter}
</Badge>
</Grid.Col>
</Grid>
</a>
));

if (libraryQuery.isLoading) {
return <LoadingOverlay visible overlayBlur={2} />;
}

if (!libraryQuery.data) {
return null;
}

return (
<Navbar width={{ sm: 300 }} p="md" className={classes.navbar} fixed>
<TextInput
placeholder="Search"
size="xs"
icon={<AiOutlineSearch size={12} strokeWidth={1.5} />}
rightSectionWidth={70}
rightSection={<Code className={classes.searchCode}>Ctrl + K</Code>}
styles={{ rightSection: { pointerEvents: 'none' } }}
mb="sm"
/>

<Navbar.Section className={classes.section}>
<div className={classes.mainLinks}>{mainLinks}</div>
</Navbar.Section>

<Navbar.Section className={classes.section}>
<Group className={classes.collectionsHeader} position="apart">
<Text size="xs" weight={500} color="dimmed">
Collections
<Text size="md" weight={500} color="dimmed">
Latest Downloads
</Text>
<Tooltip label="Create collection" withArrow position="right">
<ActionIcon variant="default" size={18}>
<AiOutlinePlus size={12} strokeWidth={1.5} />
</ActionIcon>
</Tooltip>
</Group>
<div className={classes.collections}>{collectionLinks}</div>
</Navbar.Section>
Expand Down
44 changes: 17 additions & 27 deletions src/components/newMangaCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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',

Expand Down Expand Up @@ -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', '');
Expand Down Expand Up @@ -419,7 +423,7 @@ function Form({ onClose }: { onClose: () => void }) {

<Group position="right" className={classes.buttonGroup}>
<Button variant="default" onClick={prevStep}>
Back
{active === 0 ? 'Cancel' : 'Back'}
</Button>
<Button hidden={active !== 2} type="submit">
Add
Expand All @@ -441,6 +445,7 @@ export function NewMangaCard({ onAdd }: { onAdd: () => void }) {
overflow: 'inside',
trapFocus: true,
size: 'xl',
closeOnClickOutside: false,
title: 'Add a new manga',
centered: true,
children: (
Expand All @@ -455,25 +460,10 @@ export function NewMangaCard({ onAdd }: { onAdd: () => void }) {
};

return (
<Paper
shadow="lg"
p="md"
radius="md"
sx={{
backgroundImage: `linear-gradient(rgba(0, 0, 0, 0.9), rgba(0, 0, 0, 0.9)), url('https://s4.anilist.co/file/anilistcdn/media/manga/cover/large/bx53390-1RsuABC34P9D.jpg')`,
}}
className={classes.card}
>
<Button
variant="filled"
leftIcon={<IconBook size={18} />}
onClick={openCreateModal}
fullWidth
color="indigo"
size="xs"
>
Add new
</Button>
</Paper>
<Tooltip label="Add a new manga" position="bottom">
<Paper shadow="lg" p="md" radius="md" className={classes.card} onClick={openCreateModal}>
<IconPlus color="darkblue" opacity={0.5} size={96} />
</Paper>
</Tooltip>
);
}
2 changes: 2 additions & 0 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -27,6 +28,7 @@ function MyApp({ Component, pageProps }: AppProps) {
<NotificationsProvider position="top-center" limit={5}>
<AppShell
padding="md"
navbar={<KaizokuNavbar />}
header={<KaizokuHeader links={KaizokuLinks} />}
styles={(theme) => ({
main: { backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0] },
Expand Down
49 changes: 42 additions & 7 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -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 <LoadingOverlay visible overlayBlur={2} />;
}

if (libraryQuery.data) {
router.push(`/library/${libraryQuery.data.id}`);
return <LoadingOverlay visible overlayBlur={2} />;
if (!libraryQuery.data) {
return (
<EmptyPrompt
onCreate={() => {
libraryQuery.refetch();
}}
/>
);
}

return <EmptyPrompt />;
return (
<Grid justify="flex-start">
<Grid.Col span="content">
<NewMangaCard
onAdd={() => {
mangaQuery.refetch();
}}
/>
</Grid.Col>
{mangaQuery.data &&
mangaQuery.data.map((manga) => {
return (
<Grid.Col span="content" key={manga.id}>
<MangaCard category={manga.interval} title={manga.title} image={manga.cover} />
</Grid.Col>
);
})}
</Grid>
);
}
Loading

0 comments on commit 22d5346

Please sign in to comment.