ui
This commit is contained in:
@@ -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 { IconSearch } from "@tabler/icons";
|
||||
import { Icon123, IconHome, IconSearch } from "@tabler/icons";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
const useStyles = createStyles((theme) => ({
|
||||
@@ -16,18 +16,6 @@ const useStyles = createStyles((theme) => ({
|
||||
alignItems: "center",
|
||||
},
|
||||
|
||||
links: {
|
||||
[theme.fn.smallerThan("md")]: {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
|
||||
search: {
|
||||
[theme.fn.smallerThan("xs")]: {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
|
||||
link: {
|
||||
display: "block",
|
||||
lineHeight: 1,
|
||||
@@ -42,13 +30,14 @@ const useStyles = createStyles((theme) => ({
|
||||
backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[0],
|
||||
},
|
||||
},
|
||||
linkText: {
|
||||
[theme.fn.smallerThan("sm")]: {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
interface HeaderSearchProps {
|
||||
links: { link: string; label: string }[];
|
||||
}
|
||||
|
||||
export function HeaderSearch({ links }: HeaderSearchProps) {
|
||||
export function HeaderSearch() {
|
||||
const { classes } = useStyles();
|
||||
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}>
|
||||
{link.label}
|
||||
<Group>
|
||||
{link.icon}
|
||||
<Text className={classes.linkText}>{link.label}</Text>
|
||||
</Group>
|
||||
</a>
|
||||
));
|
||||
|
||||
@@ -72,17 +75,12 @@ export function HeaderSearch({ links }: HeaderSearchProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<Header height={56} className={classes.header} mb={120}>
|
||||
<Header height={56} className={classes.header}>
|
||||
<div className={classes.inner}>
|
||||
<Group spacing={5}>{items}</Group>
|
||||
<form onSubmit={form.onSubmit(submit)}>
|
||||
<Group>
|
||||
<TextInput
|
||||
className={classes.search}
|
||||
placeholder="Search"
|
||||
required
|
||||
{...form.getInputProps("search")}
|
||||
/>
|
||||
<TextInput placeholder="Search" required {...form.getInputProps("search")} />
|
||||
<ActionIcon type="submit">
|
||||
<IconSearch />
|
||||
</ActionIcon>
|
||||
|
||||
@@ -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 { Paragraph } from "@prisma/client";
|
||||
import { IconArrowBack } from "@tabler/icons";
|
||||
@@ -39,11 +39,12 @@ export default function ParagraphGrid({
|
||||
}
|
||||
|
||||
return (
|
||||
<Container my="8rem">
|
||||
<ScrollArea h="calc( 100vh - 56px )">
|
||||
<Container my="2rem">
|
||||
<Title>
|
||||
{title} Page {page}
|
||||
</Title>
|
||||
<Group position="apart" my="2rem">
|
||||
<Group position="apart">
|
||||
<Group>{titleAction}</Group>
|
||||
<Button variant="subtle" onClick={() => router.back()} rightIcon={<IconArrowBack />}>
|
||||
Back
|
||||
@@ -67,5 +68,6 @@ export default function ParagraphGrid({
|
||||
<Pagination total={totalPage} value={page} onChange={toPage} withControls withEdges />
|
||||
</Group>
|
||||
</Container>
|
||||
</ScrollArea>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -27,18 +27,7 @@ export default function App(props: AppProps & { colorScheme: ColorScheme }) {
|
||||
|
||||
<ColorSchemeProvider colorScheme={colorScheme} toggleColorScheme={toggleColorScheme}>
|
||||
<MantineProvider theme={{ colorScheme }} withGlobalStyles withNormalizeCSS>
|
||||
<HeaderSearch
|
||||
links={[
|
||||
{
|
||||
link: "/",
|
||||
label: "Home",
|
||||
},
|
||||
{
|
||||
link: "/statistic",
|
||||
label: "Statistic",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<HeaderSearch />
|
||||
<Component {...pageProps} />
|
||||
<Notifications />
|
||||
</MantineProvider>
|
||||
|
||||
@@ -24,8 +24,8 @@ export default function ParagraphPage({ paragraph }: { paragraph: Paragraph }) {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<ScrollArea h="100vh">
|
||||
<Container my="7rem">
|
||||
<ScrollArea h="calc( 100vh - 56px )">
|
||||
<Container my="2rem">
|
||||
<Title mb="xl">{paragraph.title}</Title>
|
||||
<Group position="apart">
|
||||
<Group>
|
||||
|
||||
@@ -100,9 +100,9 @@ export default function StatisticPage({ data }: StatsGroupProps) {
|
||||
</div>
|
||||
));
|
||||
return (
|
||||
<Container my="7rem">
|
||||
<Container my="2rem">
|
||||
<Title>Statistic</Title>
|
||||
<Group position="apart" my="2rem">
|
||||
<Group position="apart" mb="1rem">
|
||||
<div></div>
|
||||
<Button variant="subtle" onClick={() => router.back()} rightIcon={<IconArrowBack />}>
|
||||
Back
|
||||
|
||||
@@ -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 } };
|
||||
}
|
||||
2
prisma/migrations/20230316150231_dev/migration.sql
Normal file
2
prisma/migrations/20230316150231_dev/migration.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `Paragraph` MODIFY `time` DATETIME NOT NULL;
|
||||
8
prisma/migrations/20230316151242_dev/migration.sql
Normal file
8
prisma/migrations/20230316151242_dev/migration.sql
Normal 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;
|
||||
@@ -15,11 +15,11 @@ model Paragraph {
|
||||
cover String?
|
||||
markdown Boolean?
|
||||
tags String
|
||||
time DateTime @db.Date
|
||||
time DateTime @db.DateTime
|
||||
title String
|
||||
|
||||
@@index([author])
|
||||
@@index([time])
|
||||
@@index([time(order: desc)])
|
||||
@@index([title])
|
||||
@@fulltext([content, author, title, tags])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user