Skip to content

Commit

Permalink
feat: add dark mode
Browse files Browse the repository at this point in the history
  • Loading branch information
oae committed Nov 3, 2022
1 parent f423b48 commit 22f6689
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 86 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@trpc/server": "^10.0.0-proxy-beta.23",
"bullmq": "^2.3.2",
"contrast-color": "^1.0.1",
"cookies-next": "^2.1.1",
"cron-parser": "^4.6.0",
"cronstrue": "^2.14.0",
"dayjs": "^1.11.5",
Expand Down
18 changes: 18 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/components/addManga/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const useStyles = createStyles((theme) => ({
right: '55px',
width: 'calc(100% - 55px)',
height: '50px',
background: 'white',
background: theme.colorScheme === 'dark' ? theme.colors.dark[7] : theme.white,
},
}));

Expand Down
8 changes: 6 additions & 2 deletions src/components/addManga/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const useStyles = createStyles((theme) => ({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: theme.colors.gray[4],
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[4],
cursor: 'pointer',

transition: 'transform 150ms ease, box-shadow 150ms ease',
Expand All @@ -21,6 +21,10 @@ const useStyles = createStyles((theme) => ({
boxShadow: theme.shadows.md,
},
},

plusIcon: {
color: theme.colorScheme === 'light' ? theme.colors.dark[4] : theme.colors.gray[4],
},
}));

export const useAddMangaModal = () => {
Expand Down Expand Up @@ -58,7 +62,7 @@ export function AddManga({ onAdd }: { onAdd: () => void }) {
return (
<Tooltip label="Add a new manga" position="bottom">
<Paper shadow="lg" p="md" radius="md" className={classes.card} onClick={() => addMangaModal(onAdd)}>
<IconPlus color="darkblue" opacity={0.5} size={96} />
<IconPlus className={classes.plusIcon} opacity={0.5} size={96} />
</Paper>
</Tooltip>
);
Expand Down
114 changes: 61 additions & 53 deletions src/components/addManga/mangaSearchResult.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,40 @@
import { createStyles, Image, SimpleGrid, Text, UnstyledButton } from '@mantine/core';
import { createStyles, Image, ScrollArea, SimpleGrid, Text, UnstyledButton } from '@mantine/core';
import { useUncontrolled } from '@mantine/hooks';
import { useEffect, useState } from 'react';

const useStyles = createStyles((theme, { checked, disabled }: { checked: boolean; disabled: boolean }) => ({
button: {
display: 'flex',
alignItems: 'center',
width: '100%',
transition: 'background-color 150ms ease, border-color 150ms ease',
border: `1px solid ${
checked
? theme.fn.variant({ variant: 'outline', color: theme.primaryColor }).border
: theme.colorScheme === 'dark'
? theme.colors.dark[8]
: theme.colors.gray[3]
}`,
borderRadius: theme.radius.sm,
padding: theme.spacing.sm,
backgroundColor: checked
? theme.fn.variant({ variant: 'light', color: theme.primaryColor }).background
: disabled
? theme.colors.gray[3]
: theme.white,
},
const useStyles = createStyles((theme, { checked, disabled }: { checked: boolean; disabled: boolean }) => {
let backgroundColor = 'light';
if (disabled) {
backgroundColor = theme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[4];
}
if (checked) {
backgroundColor = theme.fn.variant({ variant: 'light', color: theme.primaryColor }).background!;
}
return {
button: {
display: 'flex',
alignItems: 'center',
width: '100%',
transition: 'background-color 150ms ease, border-color 150ms ease',
border: `1px solid ${
checked
? theme.fn.variant({ variant: 'outline', color: theme.primaryColor }).border
: theme.colorScheme === 'dark'
? theme.colors.dark[8]
: theme.colors.gray[3]
}`,
borderRadius: theme.radius.sm,
padding: theme.spacing.sm,
backgroundColor,
outline: 'none !important',
},

body: {
flex: 1,
marginLeft: theme.spacing.md,
},
}));
body: {
flex: 1,
marginLeft: theme.spacing.md,
},
};
});

interface ImageCheckboxProps {
checked?: boolean;
Expand Down Expand Up @@ -115,31 +121,33 @@ export function MangaSearchResult({
}, [items]);

return (
<SimpleGrid
cols={2}
breakpoints={[
{ maxWidth: 'md', cols: 2 },
{ maxWidth: 'sm', cols: 1 },
]}
>
{items.map((m) => (
<ImageCheckbox
key={m.title}
image={m.cover || '/cover-not-found.jpg'}
title={m.title}
disabled={selected && m.title !== selected.title}
description={m.status}
onChange={(checked) => {
if (checked) {
setSelected(m);
onSelect(m);
} else {
setSelected(undefined);
onSelect(undefined);
}
}}
/>
))}
</SimpleGrid>
<ScrollArea sx={{ height: 350 }}>
<SimpleGrid
cols={2}
breakpoints={[
{ maxWidth: 'md', cols: 2 },
{ maxWidth: 'sm', cols: 1 },
]}
>
{items.map((m) => (
<ImageCheckbox
key={m.title}
image={m.cover || '/cover-not-found.jpg'}
title={m.title}
disabled={selected && m.title !== selected.title}
description={m.status}
onChange={(checked) => {
if (checked) {
setSelected(m);
onSelect(m);
} else {
setSelected(undefined);
onSelect(undefined);
}
}}
/>
))}
</SimpleGrid>
</ScrollArea>
);
}
18 changes: 17 additions & 1 deletion src/components/headerSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ const useStyles = createStyles((theme) => ({
backgroundColor: theme.white,
cursor: 'pointer',
outline: '0 !important',

'&:hover': {
backgroundColor: theme.colors.gray[0],
},
},

kbd: {
backgroundColor: theme.colors.gray[4],
borderColor: theme.colors.gray[4],
color: theme.black,
},
}));

Expand Down Expand Up @@ -87,7 +97,13 @@ export function SearchControl() {
</Grid.Col>
<Grid.Col span="content">
<Group spacing={5}>
<Kbd py={0}>Ctrl</Kbd>+<Kbd py={0}>P</Kbd>
<Kbd className={classes.kbd} py={0}>
Ctrl
</Kbd>
+
<Kbd className={classes.kbd} py={0}>
P
</Kbd>
</Group>
</Grid.Col>
</Grid>
Expand Down
2 changes: 1 addition & 1 deletion src/components/madeWith.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function MadeWith({ minimized }: { minimized: boolean }): JSX.Element {
{hearth}
</Box>
in{' '}
<b style={{ marginLeft: '4px', color: '#051D49' }}>
<b style={{ marginLeft: '4px' }}>
<Tooltip withArrow label={<Text weight="lighter">a.k.a. Turkey</Text>} inline position="top-start">
<Text component="span">Isekai</Text>
</Tooltip>
Expand Down
4 changes: 3 additions & 1 deletion src/components/mangaCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@ const useStyles = createStyles((theme, _params, getRef) => ({
},
editButton: {
ref: getRef('editButton'),
backgroundColor: theme.white,
color: theme.colors.blue[6],
position: 'absolute',
right: 10,
bottom: 10,
display: 'none',
'&:hover': {
backgroundColor: theme.white,
backgroundColor: theme.colors.gray[0],
},
},
title: {
Expand Down
4 changes: 2 additions & 2 deletions src/components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ const useStyles = createStyles((theme) => ({
paddingTop: theme.spacing.xs,
paddingBottom: theme.spacing.xs,
borderRadius: theme.radius.sm,
color: theme.colors.gray[7],
color: theme.colorScheme === 'dark' ? theme.colors.gray[5] : theme.colors.gray[8],

'&:hover': {
backgroundColor: theme.colors.gray[0],
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.gray[9] : theme.colors.gray[0],
},
},
}));
Expand Down
78 changes: 53 additions & 25 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,72 @@
import { AppShell, MantineProvider } from '@mantine/core';
import { AppShell, ColorScheme, ColorSchemeProvider, MantineProvider } from '@mantine/core';
import { useColorScheme, useHotkeys } from '@mantine/hooks';
import { ModalsProvider } from '@mantine/modals';
import { NotificationsProvider } from '@mantine/notifications';
import { getCookie, setCookie } from 'cookies-next';
import type { AppProps } from 'next/app';
import Head from 'next/head';
import { useEffect, useState } from 'react';
import { KaizokuHeader } from '../components/header';
import { KaizokuNavbar } from '../components/navbar';
import '../styles/globals.css';
import { trpc } from '../utils/trpc';

function MyApp({ Component, pageProps }: AppProps) {
function MyApp(props: AppProps) {
const { Component, pageProps } = props;
const preferredColorScheme = useColorScheme();
const [colorScheme, setColorScheme] = useState<ColorScheme>('light');
useEffect(() => {
let followSystem = getCookie('follow-system');
if (followSystem === undefined) {
followSystem = true;
setCookie('follow-system', '1');
}
if (followSystem === '1') {
setColorScheme(preferredColorScheme);
} else {
setColorScheme((getCookie('mantine-color-scheme') as ColorScheme) || preferredColorScheme);
}
}, [preferredColorScheme]);
const toggleColorScheme = (value?: ColorScheme) => {
const nextColorScheme = value || (colorScheme === 'dark' ? 'light' : 'dark');
setColorScheme(nextColorScheme);
setCookie('mantine-color-scheme', nextColorScheme, { maxAge: 60 * 60 * 24 * 30 });
};

useHotkeys([['shift+t', () => toggleColorScheme()]]);

return (
<>
<Head>
<title>Kaizoku</title>
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
</Head>

<MantineProvider
withGlobalStyles
withNormalizeCSS
theme={{
fontFamily: 'Inter',
colorScheme: 'light',
}}
>
<ModalsProvider>
<NotificationsProvider position="top-center" limit={5}>
<AppShell
padding="md"
navbar={<KaizokuNavbar />}
header={<KaizokuHeader />}
styles={(theme) => ({
main: { backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0] },
})}
>
<Component {...pageProps} />
</AppShell>
</NotificationsProvider>
</ModalsProvider>
</MantineProvider>
<ColorSchemeProvider colorScheme={colorScheme} toggleColorScheme={toggleColorScheme}>
<MantineProvider
withGlobalStyles
withNormalizeCSS
theme={{
fontFamily: 'Inter',
colorScheme,
}}
>
<ModalsProvider>
<NotificationsProvider position="top-center" limit={5}>
<AppShell
padding="md"
navbar={<KaizokuNavbar />}
header={<KaizokuHeader />}
styles={(theme) => ({
main: { backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0] },
})}
>
<Component {...pageProps} />
</AppShell>
</NotificationsProvider>
</ModalsProvider>
</MantineProvider>
</ColorSchemeProvider>
</>
);
}
Expand Down

0 comments on commit 22f6689

Please sign in to comment.