mirror of
https://github.com/pheralb/svgl.git
synced 2025-02-06 15:17:58 +08:00
⚒️ Improvements & new features.
This commit is contained in:
parent
6e31f5d88e
commit
23c85cb8ed
@ -15,9 +15,11 @@ export interface CustomIconBtnProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SVGCardProps {
|
export interface SVGCardProps {
|
||||||
title: string;
|
id: number;
|
||||||
svg: string;
|
svg: string;
|
||||||
url: string;
|
title: string;
|
||||||
|
href?: string;
|
||||||
|
url?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SidebarContentProps {
|
export interface SidebarContentProps {
|
||||||
@ -26,3 +28,12 @@ export interface SidebarContentProps {
|
|||||||
borderRight?: string;
|
borderRight?: string;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LoadingProps {
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ErrorProps {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
@ -7,8 +7,11 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Container,
|
Container,
|
||||||
Heading,
|
Heading,
|
||||||
|
Center,
|
||||||
|
Icon,
|
||||||
|
Input,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { Sticker } from "phosphor-react";
|
import { ArrowSquareOut, Sticker } from "phosphor-react";
|
||||||
import Theme from "./theme";
|
import Theme from "./theme";
|
||||||
import Tap from "@/animations/tap";
|
import Tap from "@/animations/tap";
|
||||||
import Mobile from "./mobile";
|
import Mobile from "./mobile";
|
||||||
@ -51,7 +54,12 @@ const Header = () => {
|
|||||||
href={link.slug}
|
href={link.slug}
|
||||||
external={link.external}
|
external={link.external}
|
||||||
>
|
>
|
||||||
<Button variant="ghost">{link.title}</Button>
|
<Button variant="ghost" fontFamily="Inter-Semibold">
|
||||||
|
{link.title}
|
||||||
|
{link.external ? (
|
||||||
|
<Icon as={ArrowSquareOut} ml="2" />
|
||||||
|
) : null}
|
||||||
|
</Button>
|
||||||
</CustomLink>
|
</CustomLink>
|
||||||
))}
|
))}
|
||||||
<Theme />
|
<Theme />
|
||||||
@ -63,7 +71,14 @@ const Header = () => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</Container>
|
</Container>
|
||||||
</Box>
|
</Box>
|
||||||
<HStack p="4" spacing={4} overflowY="hidden" bg={bg} borderBottomWidth="1px">
|
<HStack
|
||||||
|
justifyContent="center"
|
||||||
|
p="4"
|
||||||
|
spacing={4}
|
||||||
|
overflowY="hidden"
|
||||||
|
bg={bg}
|
||||||
|
borderBottomWidth="1px"
|
||||||
|
>
|
||||||
<Categories />
|
<Categories />
|
||||||
</HStack>
|
</HStack>
|
||||||
</>
|
</>
|
||||||
|
@ -7,7 +7,7 @@ const Index = ({ children }: LayoutProps) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header />
|
<Header />
|
||||||
<Container maxW="70%">{children}</Container>
|
<Container maxW="70%" mt="5">{children}</Container>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -18,6 +18,9 @@ import { motion } from "framer-motion";
|
|||||||
import { SWRConfig } from "swr";
|
import { SWRConfig } from "swr";
|
||||||
import { fetcher } from "@/services/fetcher";
|
import { fetcher } from "@/services/fetcher";
|
||||||
|
|
||||||
|
// React Hot Toast ->
|
||||||
|
import { Toaster } from "react-hot-toast";
|
||||||
|
|
||||||
function MyApp({ Component, pageProps, router }: AppProps) {
|
function MyApp({ Component, pageProps, router }: AppProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -25,7 +28,7 @@ function MyApp({ Component, pageProps, router }: AppProps) {
|
|||||||
color="#4343E5"
|
color="#4343E5"
|
||||||
startPosition={0.3}
|
startPosition={0.3}
|
||||||
stopDelayMs={200}
|
stopDelayMs={200}
|
||||||
height={3}
|
height={2}
|
||||||
showOnShallow={true}
|
showOnShallow={true}
|
||||||
/>
|
/>
|
||||||
<ChakraProvider theme={theme}>
|
<ChakraProvider theme={theme}>
|
||||||
@ -49,6 +52,7 @@ function MyApp({ Component, pageProps, router }: AppProps) {
|
|||||||
</Layout>
|
</Layout>
|
||||||
</SWRConfig>
|
</SWRConfig>
|
||||||
</ChakraProvider>
|
</ChakraProvider>
|
||||||
|
<Toaster position="bottom-center" reverseOrder={false} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
33
src/pages/api/search.ts
Normal file
33
src/pages/api/search.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import db from "data/svgs";
|
||||||
|
import { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
|
export default function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
const { id, q, c } = req.query;
|
||||||
|
|
||||||
|
// 🔎 Search by id (ex: ?id=1) ->
|
||||||
|
if (id) {
|
||||||
|
const item = db.find((item) => item.id === +id);
|
||||||
|
return res.status(200).json(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔎 Search by query (ex: ?q=d) ->
|
||||||
|
if (q) {
|
||||||
|
const results = db.filter((product) => {
|
||||||
|
const { title } = product;
|
||||||
|
return title;
|
||||||
|
});
|
||||||
|
return res.status(200).json(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔎 Search by category (ex: ?c=library) ->
|
||||||
|
if (c) {
|
||||||
|
const results = db.filter((product) => {
|
||||||
|
const { category } = product;
|
||||||
|
return category;
|
||||||
|
});
|
||||||
|
return res.status(200).json(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✖ Error ->
|
||||||
|
res.status(400).json({ info: "Error: api query not found." });
|
||||||
|
}
|
@ -1,21 +1,25 @@
|
|||||||
import type { NextPage } from "next";
|
import type { NextPage } from "next";
|
||||||
import { Center, Container, Heading } from "@chakra-ui/react";
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { getAllSvgs } from "@/services";
|
import { getAllSvgs } from "@/services";
|
||||||
import { SvgData } from "@/interfaces/svgData";
|
import { SvgData } from "@/interfaces/svgData";
|
||||||
import SVGCard from "@/components/svgCard";
|
import SVGCard from "@/components/svgCard";
|
||||||
import Grid from "@/common/grid";
|
import Grid from "@/common/grid";
|
||||||
|
import Loading from "@/components/loading";
|
||||||
|
import Error from "@/components/error";
|
||||||
|
|
||||||
const Home: NextPage = () => {
|
const Home: NextPage = () => {
|
||||||
const { data, error } = useSWR(getAllSvgs);
|
const { data, error } = useSWR(getAllSvgs);
|
||||||
|
|
||||||
if (error) return <div>failed to load</div>;
|
if (error)
|
||||||
if (!data) return <div>loading...</div>;
|
return (
|
||||||
|
<Error title="Error" description="An unexpected error has occurred" />
|
||||||
|
);
|
||||||
|
if (!data) return <Loading text="Loading..." />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid>
|
<Grid>
|
||||||
{data.map((svg: SvgData) => (
|
{data.map((svg: SvgData) => (
|
||||||
<SVGCard key={svg.id} title={svg.title} url={svg.href} svg={svg.href} />
|
<SVGCard key={svg.id} id={svg.id} svg={svg.href} title={svg.title} />
|
||||||
))}
|
))}
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
|
30
src/pages/svg/[id].tsx
Normal file
30
src/pages/svg/[id].tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import Head from "next/head";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import useSWR from "swr";
|
||||||
|
import { Box, SimpleGrid } from "@chakra-ui/react";
|
||||||
|
|
||||||
|
import Show from "@/animations/show";
|
||||||
|
import { getSvgById } from "@/services";
|
||||||
|
import Loading from "@/components/loading";
|
||||||
|
import SVGInfo from "@/components/svgInfo";
|
||||||
|
|
||||||
|
export default function Icon() {
|
||||||
|
const router = useRouter();
|
||||||
|
const { data, error } = useSWR(
|
||||||
|
() => router.query.id && `${getSvgById}${router.query.id}`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) router.push("/404");
|
||||||
|
if (!data) return <Loading text="Loading..." />;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>{data.title} - svgl</title>
|
||||||
|
</Head>
|
||||||
|
<Show>
|
||||||
|
<SVGInfo {...data} />
|
||||||
|
</Show>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
export const githubVersionPackage = 'https://api.github.com/repos/pheralb/svgl/releases/latest';
|
export const githubVersionPackage = 'https://api.github.com/repos/pheralb/svgl/releases/latest';
|
||||||
export const getAllSvgs = "/api/all";
|
export const getAllSvgs = "/api/all";
|
||||||
export const getCategorySvgs = "/api/categories";
|
export const getCategorySvgs = "/api/categories";
|
||||||
|
export const getSvgById = "/api/search?id=";
|
@ -14,3 +14,7 @@
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.highlight {
|
||||||
|
max-height: 200px;
|
||||||
|
}
|
||||||
|
@ -3,6 +3,42 @@ const baseStyle = {
|
|||||||
fontWeight: "light",
|
fontWeight: "light",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function variantPrimary() {
|
||||||
|
const disabled = {
|
||||||
|
bg: "purple.900",
|
||||||
|
color: "white",
|
||||||
|
};
|
||||||
|
|
||||||
|
const loading = {
|
||||||
|
bg: "purple.800",
|
||||||
|
color: "white",
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
bg: "brand.purple",
|
||||||
|
color: "white",
|
||||||
|
_hover: {
|
||||||
|
bg: "purple.900",
|
||||||
|
_disabled: {
|
||||||
|
...disabled,
|
||||||
|
_loading: loading,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
_active: {
|
||||||
|
bg: "purple.700",
|
||||||
|
},
|
||||||
|
_disabled: {
|
||||||
|
...disabled,
|
||||||
|
_loading: loading,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const variants = {
|
||||||
|
primary: variantPrimary,
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
baseStyle,
|
baseStyle,
|
||||||
|
variants,
|
||||||
};
|
};
|
||||||
|
@ -14,7 +14,7 @@ const theme = extendTheme(
|
|||||||
colors: {
|
colors: {
|
||||||
bg: {
|
bg: {
|
||||||
light: "#F2F2F2",
|
light: "#F2F2F2",
|
||||||
dark: "#050505",
|
dark: "#1F2023",
|
||||||
},
|
},
|
||||||
full: {
|
full: {
|
||||||
light: "#ffffff",
|
light: "#ffffff",
|
||||||
@ -33,11 +33,7 @@ const theme = extendTheme(
|
|||||||
"html, body": {
|
"html, body": {
|
||||||
height: "100%",
|
height: "100%",
|
||||||
maxHeight: "100vh",
|
maxHeight: "100vh",
|
||||||
bgGradient: mode(
|
bg: mode("bg.light", "bg.dark")(props),
|
||||||
"radial(circle at 1px 1px, #C5C5C5 1px, bg.light 0)",
|
|
||||||
"radial(circle at 1px 1px, #212121 1px, bg.dark 0)"
|
|
||||||
)(props),
|
|
||||||
backgroundSize: "40px 40px",
|
|
||||||
fontSize: "14px",
|
fontSize: "14px",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
8
src/theme/toast.ts
Normal file
8
src/theme/toast.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export const ToastTheme = {
|
||||||
|
icon: "🔔",
|
||||||
|
style: {
|
||||||
|
borderRadius: "10px",
|
||||||
|
background: "#1F2023",
|
||||||
|
color: "#fff",
|
||||||
|
},
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user