This commit is contained in:
2023-03-16 15:32:14 +00:00
parent 53128a92de
commit b76d5599d8
10 changed files with 3827 additions and 4061 deletions

View File

@@ -1,6 +1,6 @@
import { ActionIcon, createStyles, Group, Header, rem, TextInput } from "@mantine/core"; import { ActionIcon, createStyles, Group, Header, rem, Text, TextInput } from "@mantine/core";
import { useForm } from "@mantine/form"; import { useForm } from "@mantine/form";
import { IconSearch } from "@tabler/icons"; import { Icon123, IconHome, IconSearch } from "@tabler/icons";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
const useStyles = createStyles((theme) => ({ const useStyles = createStyles((theme) => ({
@@ -16,18 +16,6 @@ const useStyles = createStyles((theme) => ({
alignItems: "center", alignItems: "center",
}, },
links: {
[theme.fn.smallerThan("md")]: {
display: "none",
},
},
search: {
[theme.fn.smallerThan("xs")]: {
display: "none",
},
},
link: { link: {
display: "block", display: "block",
lineHeight: 1, lineHeight: 1,
@@ -42,13 +30,14 @@ const useStyles = createStyles((theme) => ({
backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[0], backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[0],
}, },
}, },
linkText: {
[theme.fn.smallerThan("sm")]: {
display: "none",
},
},
})); }));
interface HeaderSearchProps { export function HeaderSearch() {
links: { link: string; label: string }[];
}
export function HeaderSearch({ links }: HeaderSearchProps) {
const { classes } = useStyles(); const { classes } = useStyles();
const router = useRouter(); const router = useRouter();
@@ -58,9 +47,23 @@ export function HeaderSearch({ links }: HeaderSearchProps) {
}, },
}); });
const items = links.map((link) => ( const items = [
{
link: "/",
label: "Home",
icon: <IconHome />,
},
{
link: "/statistic",
label: "Statistic",
icon: <Icon123 />,
},
].map((link) => (
<a key={link.label} href={link.link} className={classes.link}> <a key={link.label} href={link.link} className={classes.link}>
{link.label} <Group>
{link.icon}
<Text className={classes.linkText}>{link.label}</Text>
</Group>
</a> </a>
)); ));
@@ -72,17 +75,12 @@ export function HeaderSearch({ links }: HeaderSearchProps) {
} }
return ( return (
<Header height={56} className={classes.header} mb={120}> <Header height={56} className={classes.header}>
<div className={classes.inner}> <div className={classes.inner}>
<Group spacing={5}>{items}</Group> <Group spacing={5}>{items}</Group>
<form onSubmit={form.onSubmit(submit)}> <form onSubmit={form.onSubmit(submit)}>
<Group> <Group>
<TextInput <TextInput placeholder="Search" required {...form.getInputProps("search")} />
className={classes.search}
placeholder="Search"
required
{...form.getInputProps("search")}
/>
<ActionIcon type="submit"> <ActionIcon type="submit">
<IconSearch /> <IconSearch />
</ActionIcon> </ActionIcon>

View File

@@ -1,4 +1,4 @@
import { Button, Container, Grid, Group, Pagination, Title } from "@mantine/core"; import { Button, Container, Grid, Group, Pagination, ScrollArea, Title } from "@mantine/core";
import { useDocumentTitle } from "@mantine/hooks"; import { useDocumentTitle } from "@mantine/hooks";
import { Paragraph } from "@prisma/client"; import { Paragraph } from "@prisma/client";
import { IconArrowBack } from "@tabler/icons"; import { IconArrowBack } from "@tabler/icons";
@@ -39,33 +39,35 @@ export default function ParagraphGrid({
} }
return ( return (
<Container my="8rem"> <ScrollArea h="calc( 100vh - 56px )">
<Title> <Container my="2rem">
{title} Page {page} <Title>
</Title> {title} Page {page}
<Group position="apart" my="2rem"> </Title>
<Group>{titleAction}</Group> <Group position="apart">
<Button variant="subtle" onClick={() => router.back()} rightIcon={<IconArrowBack />}> <Group>{titleAction}</Group>
Back <Button variant="subtle" onClick={() => router.back()} rightIcon={<IconArrowBack />}>
</Button> Back
</Group> </Button>
<Grid my="md"> </Group>
{paragraphs.map((paragraph) => { <Grid my="md">
return ( {paragraphs.map((paragraph) => {
<Grid.Col xs={12} sm={4} lg={3} key={paragraph.id}> return (
<ParagraphCard <Grid.Col xs={12} sm={4} lg={3} key={paragraph.id}>
title={paragraph.title} <ParagraphCard
id={paragraph.id} title={paragraph.title}
author={paragraph.author} id={paragraph.id}
time={paragraph.time} author={paragraph.author}
/> time={paragraph.time}
</Grid.Col> />
); </Grid.Col>
})} );
</Grid> })}
<Group position="center"> </Grid>
<Pagination total={totalPage} value={page} onChange={toPage} withControls withEdges /> <Group position="center">
</Group> <Pagination total={totalPage} value={page} onChange={toPage} withControls withEdges />
</Container> </Group>
</Container>
</ScrollArea>
); );
} }

View File

@@ -27,18 +27,7 @@ export default function App(props: AppProps & { colorScheme: ColorScheme }) {
<ColorSchemeProvider colorScheme={colorScheme} toggleColorScheme={toggleColorScheme}> <ColorSchemeProvider colorScheme={colorScheme} toggleColorScheme={toggleColorScheme}>
<MantineProvider theme={{ colorScheme }} withGlobalStyles withNormalizeCSS> <MantineProvider theme={{ colorScheme }} withGlobalStyles withNormalizeCSS>
<HeaderSearch <HeaderSearch />
links={[
{
link: "/",
label: "Home",
},
{
link: "/statistic",
label: "Statistic",
},
]}
/>
<Component {...pageProps} /> <Component {...pageProps} />
<Notifications /> <Notifications />
</MantineProvider> </MantineProvider>

View File

@@ -24,8 +24,8 @@ export default function ParagraphPage({ paragraph }: { paragraph: Paragraph }) {
const router = useRouter(); const router = useRouter();
return ( return (
<ScrollArea h="100vh"> <ScrollArea h="calc( 100vh - 56px )">
<Container my="7rem"> <Container my="2rem">
<Title mb="xl">{paragraph.title}</Title> <Title mb="xl">{paragraph.title}</Title>
<Group position="apart"> <Group position="apart">
<Group> <Group>

View File

@@ -100,9 +100,9 @@ export default function StatisticPage({ data }: StatsGroupProps) {
</div> </div>
)); ));
return ( return (
<Container my="7rem"> <Container my="2rem">
<Title>Statistic</Title> <Title>Statistic</Title>
<Group position="apart" my="2rem"> <Group position="apart" mb="1rem">
<div></div> <div></div>
<Button variant="subtle" onClick={() => router.back()} rightIcon={<IconArrowBack />}> <Button variant="subtle" onClick={() => router.back()} rightIcon={<IconArrowBack />}>
Back Back

View File

@@ -1,61 +0,0 @@
import { Paragraph } from "@prisma/client";
import { GetServerSidePropsContext, GetServerSidePropsResult } from "next";
import ParagraphGrid from "../../components/ParagraphGrid/ParagraphGrid";
import { prismaClient } from "../../lib/db";
interface ListProps {
paragraphs: Omit<Paragraph, "content" | "markdown">[];
skip: number;
take: number;
total: number;
tag: string;
}
export default function TagPage(props: ListProps) {
return <ParagraphGrid title={`DS-Next | Tag ${props.tag}`} {...props} />;
}
export async function getServerSideProps(
ctx: GetServerSidePropsContext
): Promise<GetServerSidePropsResult<ListProps>> {
const skip = Number(ctx.query.skip ?? 0);
const take = Number(ctx.query.take ?? 12);
const tag = ctx.params?.name;
if (!tag || typeof tag !== "string") {
return { notFound: true };
}
const condition = {
tags: {
contains: tag,
},
};
const [total, paragraphs] = await Promise.all([
prismaClient.paragraph.count({
where: condition,
}),
await prismaClient.paragraph.findMany({
where: condition,
skip: Number(skip),
take: Number(take),
orderBy: {
time: "desc",
},
select: {
id: true,
title: true,
tags: true,
time: true,
author: true,
cover: true,
},
}),
]);
paragraphs.forEach((paragraph) => {
paragraph.time = paragraph.time.getTime() as any;
});
return { props: { tag, paragraphs, skip, take, total } };
}

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE `Paragraph` MODIFY `time` DATETIME NOT NULL;

View File

@@ -0,0 +1,8 @@
/*
Warnings:
- You are about to alter the column `time` on the `Paragraph` table. The data in that column could be lost. The data in that column will be cast from `DateTime(0)` to `DateTime`.
*/
-- AlterTable
ALTER TABLE `Paragraph` MODIFY `time` DATETIME NOT NULL;

View File

@@ -15,11 +15,11 @@ model Paragraph {
cover String? cover String?
markdown Boolean? markdown Boolean?
tags String tags String
time DateTime @db.Date time DateTime @db.DateTime
title String title String
@@index([author]) @@index([author])
@@index([time]) @@index([time(order: desc)])
@@index([title]) @@index([title])
@@fulltext([content, author, title, tags]) @@fulltext([content, author, title, tags])
} }

7678
yarn.lock

File diff suppressed because it is too large Load Diff