Compare commits
No commits in common. "f9fcae6c7cf3e54f902465a66d98499e985d1a5e" and "240ed2deaf588bdb48459dddc97f33dcb8cbbff1" have entirely different histories.
f9fcae6c7c
...
240ed2deaf
@ -1,3 +0,0 @@
|
||||
{
|
||||
"extends": "next/core-web-vitals"
|
||||
}
|
44
.gitignore
vendored
44
.gitignore
vendored
@ -1,36 +1,26 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
# build output
|
||||
dist/
|
||||
dist.zip
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
.yarn/install-state.gz
|
||||
node_modules/
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
*.lock
|
||||
|
||||
# Development content
|
||||
public/media
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"tabWidth": 2,
|
||||
"singleQuote": false,
|
||||
"printWidth": 120
|
||||
"printWidth": 120,
|
||||
"singleQuote": false
|
||||
}
|
4
.vscode/extensions.json
vendored
Normal file
4
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"recommendations": ["astro-build.astro-vscode"],
|
||||
"unwantedRecommendations": []
|
||||
}
|
11
.vscode/launch.json
vendored
Normal file
11
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"command": "./node_modules/.bin/astro dev",
|
||||
"name": "Development server",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
}
|
||||
]
|
||||
}
|
36
README.md
36
README.md
@ -1,36 +0,0 @@
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
@ -1,19 +0,0 @@
|
||||
import { ReactNode } from "react";
|
||||
import GitHubIcon from "@mui/icons-material/GitHub";
|
||||
import TwitterIcon from "@mui/icons-material/Twitter";
|
||||
import CoffeeIcon from "@mui/icons-material/Coffee";
|
||||
|
||||
export interface RelatedAccount {
|
||||
icon: ReactNode;
|
||||
platform: string;
|
||||
accountName: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
export const SITE_NAME = "Goatshed";
|
||||
|
||||
export const RELATED_ACCOUNTS: RelatedAccount[] = [
|
||||
{ icon: <GitHubIcon />, platform: "GitHub", accountName: "@smartsheep-hq", link: "https://github.com/smartsheep-hq" },
|
||||
{ icon: <TwitterIcon />, platform: "Twitter", accountName: "@littlesheepovo", link: "https://twitter.com/littlesheepovo" },
|
||||
{ icon: <CoffeeIcon />, platform: "Ko-fi", accountName: "@littlesheep2code", link: "https://ko-fi.com/littlesheep2code" },
|
||||
];
|
@ -1,3 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
@ -1,38 +0,0 @@
|
||||
import type { Metadata } from "next";
|
||||
import { ReactNode } from "react";
|
||||
import { ThemeProvider } from "@mui/material/styles";
|
||||
import { AppRouterCacheProvider } from "@mui/material-nextjs/v13-appRouter";
|
||||
import { CssBaseline } from "@mui/material";
|
||||
import { SITE_NAME } from "@/app/consts";
|
||||
import { theme } from "@/app/theme";
|
||||
|
||||
import "@fontsource/roboto/300.css";
|
||||
import "@fontsource/roboto/400.css";
|
||||
import "@fontsource/roboto/500.css";
|
||||
import "@fontsource/roboto/700.css";
|
||||
|
||||
import "./globals.css";
|
||||
|
||||
import AppShell from "@/components/AppShell";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: SITE_NAME,
|
||||
description: "山羊寒舍,在这里最终智羊工作室的最新动态。"
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }: Readonly<{
|
||||
children: ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>
|
||||
<AppRouterCacheProvider>
|
||||
<CssBaseline />
|
||||
<ThemeProvider theme={theme}>
|
||||
<AppShell>{children}</AppShell>
|
||||
</ThemeProvider>
|
||||
</AppRouterCacheProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
79
app/page.tsx
79
app/page.tsx
@ -1,79 +0,0 @@
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
Button,
|
||||
Card, colors,
|
||||
Container,
|
||||
Grid,
|
||||
List,
|
||||
ListItemAvatar,
|
||||
ListItemButton,
|
||||
ListItemText,
|
||||
Typography
|
||||
} from "@mui/material";
|
||||
import { RELATED_ACCOUNTS } from "@/app/consts";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<Container sx={{ scrollBehavior: "smooth", px: 5 }}>
|
||||
<Grid
|
||||
container
|
||||
id="introduce"
|
||||
alignItems="center"
|
||||
sx={{ height: "calc(100vh - 64px)" }}
|
||||
>
|
||||
<Grid item xs={12} md={6} sx={{ textAlign: { xs: "center", md: "initial" } }}>
|
||||
<Typography variant="h3" component="h1" gutterBottom>你好呀 👋</Typography>
|
||||
<Typography paragraph>
|
||||
欢迎来到 SmartSheep Studio 的官方网站!在这里了解,订阅,跟踪我们的最新消息。
|
||||
接触我们最大的官方社区,并且尝试最新产品,参与各种活动,提供反馈,让我们更好的服务您。
|
||||
</Typography>
|
||||
<Button variant="contained" href="#about-us" size="large">探索更多</Button>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
md={6}
|
||||
sx={{ display: "flex", justifyContent: { xs: "center", lg: "end" }, order: { xs: -100, lg: 0 } }}
|
||||
>
|
||||
<Box>
|
||||
<Image src="/smartsheep.svg" alt="Logo" width={256} height={256} />
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
container
|
||||
id="about-us"
|
||||
alignItems="center"
|
||||
sx={{ height: "calc(100vh - 64px)" }}
|
||||
>
|
||||
<Grid item xs={12} md={6} sx={{ display: "flex", justifyContent: { xs: "center", lg: "end" } }}>
|
||||
<Card sx={{ flexGrow: 1, mr: { xs: 0, md: 8 } }}>
|
||||
<List sx={{ width: "100%", bgcolor: "background.paper" }}>
|
||||
{RELATED_ACCOUNTS.map((item, idx) => (
|
||||
<Link key={idx} href={item.link} target="_blank" passHref>
|
||||
<ListItemButton>
|
||||
<ListItemAvatar>
|
||||
<Avatar sx={{ bgcolor: colors.blueGrey[700] }}>{item.icon}</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={item.platform} secondary={item.accountName} />
|
||||
</ListItemButton>
|
||||
</Link>
|
||||
))}
|
||||
</List>
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6} sx={{ textAlign: { xs: "center", md: "initial" } }}>
|
||||
<Typography variant="h3" component="h1" gutterBottom>关于我们</Typography>
|
||||
<Typography paragraph>
|
||||
我们是一群充满活力、对开源充满热情的开发者。成立于 2019 年。自那年起我们一直在开发让人喜欢的开源软件。
|
||||
在我们这里,“取之于开源,用之于开源” 不仅是原则,更是我们信仰的座右铭。
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Container>
|
||||
);
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
import { Box, Card, CardContent, CardMedia, Divider, Typography } from "@mui/material";
|
||||
import { getSinglePost } from "@/content/posts";
|
||||
import Image from "next/image";
|
||||
import PostContent from "@/components/posts/PostContent";
|
||||
|
||||
export default function PostDetailPage({ params }: { params: { id: string } }) {
|
||||
const post = getSinglePost(params.id);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
{
|
||||
post.thumbnail &&
|
||||
<CardMedia sx={{ height: 360, position: "relative" }} title={post.title}>
|
||||
<Image
|
||||
fill
|
||||
src={post.thumbnail}
|
||||
alt={post.title}
|
||||
style={{ objectFit: "cover" }}
|
||||
/>
|
||||
</CardMedia>
|
||||
}
|
||||
|
||||
<CardContent sx={{ paddingX: 5, paddingY: 3 }}>
|
||||
<Box>
|
||||
<Typography gutterBottom variant="h5" component="h1">
|
||||
{post.title}
|
||||
</Typography>
|
||||
<Typography color="text.secondary" variant="body2">
|
||||
{post.description ?? "No description yet."}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Divider sx={{ my: 5 }} />
|
||||
<Box component="article" sx={{ minWidth: 0 }}>
|
||||
<PostContent content={post.content ?? ""} />
|
||||
</Box>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
import { Box, Container } from "@mui/material";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
export default function PostLayout({children}: Readonly<{
|
||||
children: ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<Container sx={{ display: "flex", justifyContent: "center", gap: 4, py: 4 }}>
|
||||
<Box sx={{ flexGrow: 1, maxWidth: 720 }}>
|
||||
{children}
|
||||
</Box>
|
||||
</Container>
|
||||
)
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
import { Button, Card, CardActions, CardContent, CardMedia, Typography } from "@mui/material";
|
||||
import { getSortedPosts } from "@/content/posts";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function PostList() {
|
||||
const posts = getSortedPosts();
|
||||
|
||||
return (
|
||||
posts.map((post) => (
|
||||
<Card key={post.id} sx={{ width: "100%" }}>
|
||||
{
|
||||
post.thumbnail &&
|
||||
<CardMedia sx={{ height: 160, position: "relative" }} title={post.title}>
|
||||
<Image
|
||||
fill
|
||||
src={post.thumbnail}
|
||||
alt={post.title}
|
||||
style={{ objectFit: "cover" }}
|
||||
/>
|
||||
</CardMedia>
|
||||
}
|
||||
|
||||
<CardContent sx={{ paddingX: 5, paddingY: 3 }}>
|
||||
<Typography gutterBottom variant="h5" component="h2">
|
||||
{post.title}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{post.description ?? "No description yet."}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
<CardActions sx={{ paddingX: 4, paddingBottom: 2 }}>
|
||||
<Link href={`/posts/${post.id}`} passHref>
|
||||
<Button>Read more</Button>
|
||||
</Link>
|
||||
</CardActions>
|
||||
</Card>
|
||||
))
|
||||
);
|
||||
}
|
14
app/theme.ts
14
app/theme.ts
@ -1,14 +0,0 @@
|
||||
"use client"
|
||||
|
||||
import { createTheme } from "@mui/material/styles";
|
||||
|
||||
export const theme = createTheme({
|
||||
palette: {
|
||||
primary: {
|
||||
main: "#49509e"
|
||||
},
|
||||
secondary: {
|
||||
main: "#d43630"
|
||||
}
|
||||
}
|
||||
});
|
17
astro.config.mjs
Normal file
17
astro.config.mjs
Normal file
@ -0,0 +1,17 @@
|
||||
import { defineConfig } from "astro/config";
|
||||
|
||||
import react from "@astrojs/react";
|
||||
import tailwind from "@astrojs/tailwind";
|
||||
import sitemap from "@astrojs/sitemap";
|
||||
import cloudflare from "@astrojs/cloudflare";
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
output: "hybrid",
|
||||
site: "https://smartsheep.studio",
|
||||
integrations: [tailwind(), react(), sitemap()],
|
||||
adapter: cloudflare(),
|
||||
redirects: {
|
||||
"/p/[...slug]": "/posts/[...slug]",
|
||||
},
|
||||
});
|
@ -1,143 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Slide,
|
||||
Toolbar,
|
||||
Typography,
|
||||
AppBar as MuiAppBar,
|
||||
AppBarProps as MuiAppBarProps,
|
||||
useScrollTrigger,
|
||||
IconButton,
|
||||
styled, Box, useMediaQuery
|
||||
} from "@mui/material";
|
||||
import { ReactElement, ReactNode, useEffect, useState } from "react";
|
||||
import { SITE_NAME } from "@/app/consts";
|
||||
import NavigationDrawer, { DRAWER_WIDTH, AppNavigationHeader, isMobileQuery } from "@/components/NavigationDrawer";
|
||||
import MenuIcon from "@mui/icons-material/Menu";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
function HideOnScroll(props: {
|
||||
window?: () => Window;
|
||||
children: ReactElement;
|
||||
}) {
|
||||
const { children, window } = props;
|
||||
const trigger = useScrollTrigger({
|
||||
target: window ? window() : undefined
|
||||
});
|
||||
|
||||
return (
|
||||
<Slide appear={false} direction="down" in={!trigger}>
|
||||
{children}
|
||||
</Slide>
|
||||
);
|
||||
}
|
||||
|
||||
interface AppBarProps extends MuiAppBarProps {
|
||||
open?: boolean;
|
||||
}
|
||||
|
||||
const ShellAppBar = styled(MuiAppBar, {
|
||||
shouldForwardProp: (prop) => prop !== "open"
|
||||
})<AppBarProps>(({ theme, open }) => {
|
||||
const isMobile = useMediaQuery(isMobileQuery);
|
||||
|
||||
return ({
|
||||
transition: theme.transitions.create(["margin", "width"], {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
duration: theme.transitions.duration.leavingScreen
|
||||
}),
|
||||
...(!isMobile && open && {
|
||||
width: `calc(100% - ${DRAWER_WIDTH}px)`,
|
||||
transition: theme.transitions.create(["margin", "width"], {
|
||||
easing: theme.transitions.easing.easeOut,
|
||||
duration: theme.transitions.duration.enteringScreen
|
||||
}),
|
||||
marginRight: DRAWER_WIDTH
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
const AppMain = styled("main", { shouldForwardProp: (prop) => prop !== "open" })<{
|
||||
open?: boolean;
|
||||
}>(({ theme, open }) => {
|
||||
const isMobile = useMediaQuery(isMobileQuery);
|
||||
|
||||
return ({
|
||||
flexGrow: 1,
|
||||
transition: theme.transitions.create("margin", {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
duration: theme.transitions.duration.leavingScreen
|
||||
}),
|
||||
marginRight: -DRAWER_WIDTH,
|
||||
...(!isMobile && open && {
|
||||
transition: theme.transitions.create("margin", {
|
||||
easing: theme.transitions.easing.easeOut,
|
||||
duration: theme.transitions.duration.enteringScreen
|
||||
}),
|
||||
marginRight: 0
|
||||
}),
|
||||
position: "relative"
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
export default function AppShell({ children }: {
|
||||
children: ReactNode,
|
||||
}) {
|
||||
let documentWindow: Window;
|
||||
|
||||
const isMobile = useMediaQuery(isMobileQuery);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
documentWindow = window;
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<HideOnScroll window={() => documentWindow}>
|
||||
<ShellAppBar open={open} position="fixed">
|
||||
<Toolbar sx={{ height: 64 }}>
|
||||
<IconButton
|
||||
size="large"
|
||||
edge="start"
|
||||
color="inherit"
|
||||
aria-label="menu"
|
||||
sx={{ ml: isMobile ? 0.5 : 0, mr: 2 }}
|
||||
>
|
||||
<Image src="/smartsheep.svg" alt="Logo" width={32} height={32} />
|
||||
</IconButton>
|
||||
|
||||
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
|
||||
<Link href="/">
|
||||
{SITE_NAME}
|
||||
</Link>
|
||||
</Typography>
|
||||
|
||||
<IconButton
|
||||
size="large"
|
||||
edge="start"
|
||||
color="inherit"
|
||||
aria-label="menu"
|
||||
onClick={() => setOpen(true)}
|
||||
sx={{ mr: 1, display: !isMobile && open ? "none" : "block" }}
|
||||
>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
</Toolbar>
|
||||
</ShellAppBar>
|
||||
</HideOnScroll>
|
||||
|
||||
<Box sx={{ display: "flex" }}>
|
||||
<AppMain open={open}>
|
||||
<AppNavigationHeader />
|
||||
|
||||
{children}
|
||||
</AppMain>
|
||||
|
||||
<NavigationDrawer open={open} onClose={() => setOpen(false)} />
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
|
||||
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
|
||||
import {
|
||||
Box,
|
||||
Divider,
|
||||
Drawer,
|
||||
IconButton,
|
||||
List,
|
||||
ListItemButton,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
styled,
|
||||
useMediaQuery
|
||||
} from "@mui/material";
|
||||
import { theme } from "@/app/theme";
|
||||
import { ReactNode } from "react";
|
||||
import HomeIcon from "@mui/icons-material/Home";
|
||||
import ArticleIcon from "@mui/icons-material/Article";
|
||||
import Link from "next/link";
|
||||
|
||||
export interface NavigationItem {
|
||||
icon: ReactNode;
|
||||
title: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
export const DRAWER_WIDTH = 320;
|
||||
export const NAVIGATION_ITEMS: NavigationItem[] = [
|
||||
{ icon: <HomeIcon />, title: "首页", link: "/" },
|
||||
{ icon: <ArticleIcon />, title: "新闻", link: "/posts" },
|
||||
];
|
||||
|
||||
export const AppNavigationHeader = styled("div")(({ theme }) => ({
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
padding: theme.spacing(0, 1),
|
||||
justifyContent: "flex-start",
|
||||
height: 64,
|
||||
...theme.mixins.toolbar
|
||||
}));
|
||||
|
||||
export function AppNavigation({ showClose, onClose }: {
|
||||
showClose?: boolean,
|
||||
onClose: () => void
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<AppNavigationHeader>
|
||||
{
|
||||
showClose &&
|
||||
<IconButton onClick={onClose}>
|
||||
{theme.direction === "rtl" ? <ChevronLeftIcon /> : <ChevronRightIcon />}
|
||||
</IconButton>
|
||||
}
|
||||
</AppNavigationHeader>
|
||||
<Divider />
|
||||
<List>
|
||||
{NAVIGATION_ITEMS.map((item, idx) => (
|
||||
<Link key={idx} href={item.link} passHref>
|
||||
<ListItemButton>
|
||||
<ListItemIcon>{item.icon}</ListItemIcon>
|
||||
<ListItemText primary={item.title} />
|
||||
</ListItemButton>
|
||||
</Link>
|
||||
))}
|
||||
</List>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export const isMobileQuery = theme.breakpoints.down("md");
|
||||
|
||||
export default function NavigationDrawer({ open, onClose }: {
|
||||
open: boolean,
|
||||
onClose: () => void,
|
||||
}) {
|
||||
const isMobile = useMediaQuery(isMobileQuery);
|
||||
|
||||
return isMobile ? (
|
||||
<>
|
||||
<Box sx={{ flexShrink: 0, width: DRAWER_WIDTH }} />
|
||||
<Drawer
|
||||
keepMounted
|
||||
anchor="right"
|
||||
variant="temporary"
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
sx={{
|
||||
"& .MuiDrawer-paper": {
|
||||
boxSizing: "border-box",
|
||||
width: DRAWER_WIDTH
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AppNavigation onClose={onClose} />
|
||||
</Drawer>
|
||||
</>
|
||||
) : (
|
||||
<Drawer
|
||||
variant="persistent"
|
||||
anchor="right"
|
||||
open={open}
|
||||
sx={{
|
||||
width: DRAWER_WIDTH,
|
||||
flexShrink: 0,
|
||||
"& .MuiDrawer-paper": {
|
||||
width: DRAWER_WIDTH
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AppNavigation showClose onClose={onClose} />
|
||||
</Drawer>
|
||||
);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import MuiMarkdown from "mui-markdown";
|
||||
|
||||
export default function PostContent({ content }: { content: string }) {
|
||||
return <MuiMarkdown>{content}</MuiMarkdown>;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import matter from "gray-matter";
|
||||
|
||||
const postsDirectory = path.join(process.cwd(), "content", "posts");
|
||||
|
||||
export interface Post {
|
||||
id: string;
|
||||
title: string;
|
||||
thumbnail?: string;
|
||||
description?: string;
|
||||
content?: string;
|
||||
date: Date;
|
||||
}
|
||||
|
||||
export function getSortedPosts() {
|
||||
const fileNames = fs.readdirSync(postsDirectory);
|
||||
const allPostsData: Post[] = fileNames.map((fileName) => {
|
||||
const id = fileName.replace(/\.md$/, "");
|
||||
|
||||
const fullPath = path.join(postsDirectory, fileName);
|
||||
const fileContents = fs.readFileSync(fullPath, "utf8");
|
||||
|
||||
const matterResult = matter(fileContents);
|
||||
|
||||
return {
|
||||
id,
|
||||
...matterResult.data
|
||||
} as Post;
|
||||
});
|
||||
|
||||
return allPostsData.sort((a, b) => {
|
||||
return a.date < b.date ? 1 : -1;
|
||||
});
|
||||
}
|
||||
|
||||
export function getSinglePost(id: string) {
|
||||
const fullPath = path.join(postsDirectory, id + ".md");
|
||||
const fileContents = fs.readFileSync(fullPath, "utf8");
|
||||
const matterResult = matter(fileContents);
|
||||
|
||||
return {
|
||||
id,
|
||||
content: matterResult.content,
|
||||
...matterResult.data,
|
||||
} as Post;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
---
|
||||
thumbnail: 'https://images.unsplash.com/photo-1707344088547-3cf7cea5ca49?q=80&w=2970&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'
|
||||
title: 'Two Forms of Pre-rendering'
|
||||
date: '2020-01-01'
|
||||
---
|
||||
|
||||
# Woah!
|
||||
|
||||
Next.js has two forms of pre-rendering: **Static Generation** and **Server-side Rendering**. The difference is in **when** it generates the HTML for a page.
|
||||
|
||||
- **Static Generation** is the pre-rendering method that generates the HTML at **build time**. The pre-rendered HTML is then _reused_ on each request.
|
||||
- **Server-side Rendering** is the pre-rendering method that generates the HTML on **each request**.
|
||||
|
||||
Importantly, Next.js lets you **choose** which pre-rendering form to use for each page. You can create a "hybrid" Next.js app by using Static Generation for most pages and using Server-side Rendering for others.
|
661
license
Normal file
661
license
Normal file
@ -0,0 +1,661 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
@ -1,14 +0,0 @@
|
||||
/** @type {import("next").NextConfig} */
|
||||
const nextConfig = {
|
||||
pageExtensions: ["js", "jsx", "mdx", "ts", "tsx"],
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "**",
|
||||
},
|
||||
],
|
||||
}
|
||||
};
|
||||
|
||||
export default nextConfig;
|
71
package.json
71
package.json
@ -1,47 +1,46 @@
|
||||
{
|
||||
"name": "capital",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro check && astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/cache": "^11.11.0",
|
||||
"@emotion/react": "^11.11.3",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@fontsource/roboto": "^5.0.8",
|
||||
"@mdx-js/loader": "^3.0.1",
|
||||
"@mdx-js/react": "^3.0.1",
|
||||
"@mui/icons-material": "^5.15.10",
|
||||
"@mui/material": "^5.15.10",
|
||||
"@mui/material-nextjs": "^5.15.11",
|
||||
"@next/mdx": "^14.1.0",
|
||||
"@types/mdx": "^2.0.11",
|
||||
"gray-matter": "^4.0.3",
|
||||
"html-react-parser": "^5.1.7",
|
||||
"@astrojs/check": "^0.4.1",
|
||||
"@astrojs/cloudflare": "^9.0.0",
|
||||
"@astrojs/node": "^8.0.0",
|
||||
"@astrojs/react": "^3.0.9",
|
||||
"@astrojs/sitemap": "^3.0.5",
|
||||
"@astrojs/tailwind": "^5.1.0",
|
||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@types/react": "^18.2.48",
|
||||
"@types/react-dom": "^18.2.18",
|
||||
"aplayer": "^1.10.1",
|
||||
"artplayer": "^5.1.1",
|
||||
"astro": "^4.2.1",
|
||||
"dompurify": "^3.0.8",
|
||||
"html-react-parser": "^5.1.2",
|
||||
"marked": "^12.0.0",
|
||||
"mui-markdown": "^1.1.13",
|
||||
"next": "14.1.0",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
"medium-zoom": "^1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"react": "^17",
|
||||
"react-dom": "^17",
|
||||
"sass": "^1.70.0",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"theme-change": "^2.5.0",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.1.0",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3.3.0",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^17.0.0 || ^18.0.0"
|
||||
"@types/dompurify": "^3.0.5",
|
||||
"@types/node": "^20.11.5",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"daisyui": "^4.6.0",
|
||||
"prettier": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
0
app/icon.svg → public/favicon.svg
Executable file → Normal file
0
app/icon.svg → public/favicon.svg
Executable file → Normal file
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
Before Width: | Height: | Size: 1.3 KiB |
@ -1,21 +0,0 @@
|
||||
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1024" height="1024">
|
||||
<title>SmartSheep Logo</title>
|
||||
<defs>
|
||||
<image width="124" height="198" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHwAAADGCAMAAAAnkRSfAAAAAXNSR0IB2cksfwAAAq9QTFRFAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////J9QBRAAAAOV0Uk5TAA0WEiFfjMLMr40/BRdmtuz//vbQYAQmpfLdQAGovyURj/iOD0r07loDGJfbPDTf/bhd94QLdPrrVQLWcPmtHU31egknzehRg9Ev1xnzbgYHhfzmTMorSOSbFJloKsniReXDKG/7kQ6m8WMw3ue7I4cKNdTZOFTqsR5/Hzra0zZY7al4Ir5SPWHvnpbG4MRrlKJs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"/>
|
||||
<image width="122" height="142" id="img2" href="data:image/png;base64,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"/>
|
||||
</defs>
|
||||
<style>
|
||||
.s0 { fill: #ffffff;stroke: #000000;stroke-miterlimit:100;stroke-width: 56 }
|
||||
.s1 { fill: #4750a3;stroke: #000000;stroke-miterlimit:100;stroke-width: 56 }
|
||||
</style>
|
||||
<path id="Wool" fill-rule="evenodd" class="s0" d="m128 608.4c0 95.9 77.4 173.6 172.8 173.6h441.6c84.8 0 153.6-69.1 153.6-154.3 0-74.6-52.8-136.9-122.9-151.1 4.9-12.9 7.7-27 7.7-41.7 0-63.9-51.6-115.8-115.2-115.8-23.6 0-45.7 7.3-64 19.6-33.2-57.9-95.2-96.7-166.4-96.7-106.1 0-192 86.3-192 192.9 0 3.2 0.1 6.5 0.2 9.7-67.2 23.8-115.4 88.1-115.4 163.8z"/>
|
||||
<g id="Crystal">
|
||||
<path id="Crystal" class="s1" d="m699 224l138.6 80v160l-138.6 80-138.6-80v-160z"/>
|
||||
<use id="Highlight" href="#img1" x="688" y="255"/>
|
||||
</g>
|
||||
<g id="Horn">
|
||||
</g>
|
||||
<g id="Face">
|
||||
<use id="Slime" href="#img2" x="233" y="538"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 8.1 KiB |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>
|
Before Width: | Height: | Size: 629 B |
22
semantic.json
Normal file
22
semantic.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"base": "libs/fomantic",
|
||||
"paths": {
|
||||
"source": {
|
||||
"config": "src/theme.config",
|
||||
"definitions": "src/definitions/",
|
||||
"site": "src/site/",
|
||||
"themes": "src/themes/"
|
||||
},
|
||||
"output": {
|
||||
"packaged": "dist/",
|
||||
"uncompressed": "dist/components/",
|
||||
"compressed": "dist/components/",
|
||||
"themes": "dist/themes/"
|
||||
},
|
||||
"clean": "dist/"
|
||||
},
|
||||
"permission": false,
|
||||
"autoInstall": false,
|
||||
"rtl": false,
|
||||
"version": "2.9.3"
|
||||
}
|
197
src/assets/fonts/fonts.css
Normal file
197
src/assets/fonts/fonts.css
Normal file
@ -0,0 +1,197 @@
|
||||
:root {
|
||||
--bs-body-font-family: "IBM Plex Sans", "Noto Serif SC", sans-serif !important;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
font-family: var(--bs-body-font-family);
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-100 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: normal;
|
||||
font-weight: 100;
|
||||
src: url("./ibm-plex-sans-v19-latin-100.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-100italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: italic;
|
||||
font-weight: 100;
|
||||
src: url("./ibm-plex-sans-v19-latin-100italic.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-200 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: normal;
|
||||
font-weight: 200;
|
||||
src: url("./ibm-plex-sans-v19-latin-200.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-200italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: italic;
|
||||
font-weight: 200;
|
||||
src: url("./ibm-plex-sans-v19-latin-200italic.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-300 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url("./ibm-plex-sans-v19-latin-300.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-300italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: url("./ibm-plex-sans-v19-latin-300italic.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-regular - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url("./ibm-plex-sans-v19-latin-regular.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: url("./ibm-plex-sans-v19-latin-italic.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-500 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url("./ibm-plex-sans-v19-latin-500.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-500italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
src: url("./ibm-plex-sans-v19-latin-500italic.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-600 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: url("./ibm-plex-sans-v19-latin-600.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-600italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: url("./ibm-plex-sans-v19-latin-600italic.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-700 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: url("./ibm-plex-sans-v19-latin-700.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ibm-plex-sans-700italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "IBM Plex Sans";
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url("./ibm-plex-sans-v19-latin-700italic.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* noto-serif-sc-200 - chinese-simplified */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Noto Serif SC";
|
||||
font-style: normal;
|
||||
font-weight: 200;
|
||||
src: url("./noto-serif-sc-v22-chinese-simplified-200.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* noto-serif-sc-300 - chinese-simplified */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Noto Serif SC";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url("./noto-serif-sc-v22-chinese-simplified-300.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* noto-serif-sc-regular - chinese-simplified */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Noto Serif SC";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url("./noto-serif-sc-v22-chinese-simplified-regular.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* noto-serif-sc-500 - chinese-simplified */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Noto Serif SC";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url("./noto-serif-sc-v22-chinese-simplified-500.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* noto-serif-sc-600 - chinese-simplified */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Noto Serif SC";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: url("./noto-serif-sc-v22-chinese-simplified-600.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* noto-serif-sc-700 - chinese-simplified */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Noto Serif SC";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: url("./noto-serif-sc-v22-chinese-simplified-700.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* noto-serif-sc-900 - chinese-simplified */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Noto Serif SC";
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
src: url("./noto-serif-sc-v22-chinese-simplified-900.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-100.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-100.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-100italic.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-100italic.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-200.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-200.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-200italic.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-200italic.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-300.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-300.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-300italic.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-300italic.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-500.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-500.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-500italic.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-500italic.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-600.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-600.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-600italic.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-600italic.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-700.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-700.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-700italic.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-700italic.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-italic.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-italic.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-regular.woff2
Executable file
BIN
src/assets/fonts/ibm-plex-sans-v19-latin-regular.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-200.woff2
Executable file
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-200.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-300.woff2
Executable file
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-300.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-500.woff2
Executable file
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-500.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-600.woff2
Executable file
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-600.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-700.woff2
Executable file
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-700.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-900.woff2
Executable file
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-900.woff2
Executable file
Binary file not shown.
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-regular.woff2
Executable file
BIN
src/assets/fonts/noto-serif-sc-v22-chinese-simplified-regular.woff2
Executable file
Binary file not shown.
51
src/components/Footer.astro
Normal file
51
src/components/Footer.astro
Normal file
@ -0,0 +1,51 @@
|
||||
<footer class="p-10 bg-base-200 text-base-content">
|
||||
<div class="footer container mx-auto">
|
||||
<nav>
|
||||
<h6 class="footer-title">服务</h6>
|
||||
<a class="link link-hover" href="https://id.smartsheep.studio" target="_blank">Goatpass</a>
|
||||
<a class="link link-hover" href="https://feed.smartsheep.studio" target="_blank">Goatplaza</a>
|
||||
<a class="link link-hover" href="https://wiki.smartsheep.studio" target="_blank">Goatpedia</a>
|
||||
<a class="link link-hover" href="https://disk.smartsheep.studio" target="_blank">Goatdisk</a>
|
||||
</nav>
|
||||
<nav>
|
||||
<h6 class="footer-title">工作室</h6>
|
||||
<a class="link link-hover" href="/about/us">关于我们</a>
|
||||
<a class="link link-hover" href="/about/contact">联系方式</a>
|
||||
<a class="link link-hover" href="/recruitment">招才纳贤</a>
|
||||
</nav>
|
||||
<nav>
|
||||
<h6 class="footer-title">法律</h6>
|
||||
<a class="link link-hover" href="/legal/privacy-policy">隐私协议</a>
|
||||
<a class="link link-hover" href="/legal/user-agreement">用户协议</a>
|
||||
<a class="link link-hover" href="/legal/community-guidelines">社区准则</a>
|
||||
</nav>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<footer class="px-10 py-4 border-t bg-base-200 text-base-content border-base-300">
|
||||
<div class="footer container mx-auto">
|
||||
<aside class="items-center grid-flow-col">
|
||||
<img class="me-1" src="/favicon.svg" alt="Logo" width="32" height="32" />
|
||||
<p>
|
||||
SmartSheep Studio<br />
|
||||
Developing open-source software since 2019
|
||||
</p>
|
||||
</aside>
|
||||
<nav class="md:place-self-center md:justify-self-end">
|
||||
<div class="grid grid-flow-col gap-4">
|
||||
<a href="https://github.com/LittleSheep2Code" target="_blank" class="fill-base-content">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 496 512">
|
||||
<path
|
||||
d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3 .3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5 .3-6.2 2.3zm44.2-1.7c-2.9 .7-4.9 2.6-4.6 4.9 .3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3 .7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3 .3 2.9 2.3 3.9 1.6 1 3.6 .7 4.3-.7 .7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3 .7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3 .7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"
|
||||
></path>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="https://twitter.com/littlesheepovo" target="_blank" class="fill-base-content">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512">
|
||||
<path d="M459.4 151.7c.3 4.5 .3 9.1 .3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53 51.7 63.7 129.3 105.3 216.4 109.8-1.6-7.8-2.6-15.9-2.6-24 0-57.8 46.8-104.9 104.9-104.9 30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3z"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</footer>
|
73
src/components/Navbar.astro
Normal file
73
src/components/Navbar.astro
Normal file
@ -0,0 +1,73 @@
|
||||
---
|
||||
interface MenuItem {
|
||||
href?: string;
|
||||
label: string;
|
||||
children?: MenuItem[];
|
||||
}
|
||||
|
||||
const items: MenuItem[] = [
|
||||
{
|
||||
label: "情报", children: [
|
||||
{ href: "/posts", label: "记录" },
|
||||
{ href: "/moments", label: "回忆" }
|
||||
]
|
||||
}
|
||||
];
|
||||
---
|
||||
|
||||
<div class="fixed top-0 navbar shadow-md bg-base-100 lg:px-5 z-10">
|
||||
<div class="navbar-start">
|
||||
<a class="btn btn-ghost text-xl p-2 w-[48px] h-[48px] max-lg:ml-2.5" href="/">
|
||||
<img width="40" height="40" src="/favicon.svg" alt="Logo" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-center flex">
|
||||
<ul class="menu menu-horizontal px-1">
|
||||
{
|
||||
items.map((item) => (
|
||||
<li>
|
||||
{item.children ? (
|
||||
<details>
|
||||
<summary>{item.label}</summary>
|
||||
<ul class="p-2">
|
||||
{item.children?.map((child) => (
|
||||
<li>
|
||||
<a href={child.href}>{child.label}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</details>
|
||||
) : (
|
||||
<a href={item.href}>{item.label}</a>
|
||||
)}
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
<label class="swap swap-rotate px-[16px]" data-toggle-theme="dark,light" data-act-class="swap-active">
|
||||
<svg
|
||||
class="swap-on fill-current w-6 h-6"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z"
|
||||
></path>
|
||||
</svg
|
||||
>
|
||||
|
||||
<svg
|
||||
class="swap-off fill-current w-6 h-6"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z"
|
||||
></path>
|
||||
</svg
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
53
src/components/PostList.astro
Normal file
53
src/components/PostList.astro
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
interface Props {
|
||||
posts: any[];
|
||||
}
|
||||
|
||||
const { posts } = Astro.props;
|
||||
|
||||
function getThumbnail(item: any): string | null {
|
||||
for (const attachment of item?.attachments ?? []) {
|
||||
if (attachment.mimetype.startsWith("image")) {
|
||||
return attachment.external_url
|
||||
? attachment.external_url
|
||||
: `https://feed.smartsheep.studio/api/attachments/o/${attachment.file_id}`;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
---
|
||||
|
||||
<div class="grid justify-items-strench shadow-lg">
|
||||
{
|
||||
posts?.map((item) => (
|
||||
<a href={`/p/${item.alias}`}>
|
||||
<div class="card sm:card-side hover:bg-base-200 transition-colors sm:max-w-none">
|
||||
{getThumbnail(item) && (
|
||||
<figure class="mx-auto w-full object-cover p-6 max-sm:pb-0 sm:max-w-[12rem] sm:pe-0">
|
||||
<img
|
||||
loading="lazy"
|
||||
src={getThumbnail(item)}
|
||||
class="border-base-content bg-base-300 rounded-btn border border-opacity-5"
|
||||
alt={item?.title}
|
||||
/>
|
||||
</figure>
|
||||
)}
|
||||
<div class="card-body">
|
||||
<h2 class="text-xl">{item?.title}</h2>
|
||||
<div class="mx-[-2px] mt-[-4px]">
|
||||
{item?.categories?.map((category: any) => (
|
||||
<span class="badge badge-primary">{category.name}</span>
|
||||
))}
|
||||
{item?.tags?.map((tag: any) => (
|
||||
<span class="badge badge-secondary">{tag.name}</span>
|
||||
))}
|
||||
</div>
|
||||
<div class="text-xs opacity-60 line-clamp-3">
|
||||
{item?.content?.substring(0, 160).replaceAll("#", "").replaceAll("*", "").trim() + "……"}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
15
src/components/posts/Content.tsx
Normal file
15
src/components/posts/Content.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import parse from "html-react-parser";
|
||||
import mediumZoom from "medium-zoom";
|
||||
import DOMPurify from "dompurify";
|
||||
import * as marked from "marked";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export default function Content({ content }: { content: string }) {
|
||||
useEffect(() => {
|
||||
mediumZoom(document.querySelectorAll(".post img"), {
|
||||
background: "var(--fallback-b1,oklch(var(--b1)/1))",
|
||||
});
|
||||
});
|
||||
|
||||
return <article className="prose max-w-none">{parse(DOMPurify.sanitize(marked.parse(content) as string))}</article>;
|
||||
}
|
111
src/components/posts/Media.tsx
Normal file
111
src/components/posts/Media.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
// @ts-ignore
|
||||
import APlayer from "aplayer";
|
||||
import Artplayer from "artplayer";
|
||||
import { useState, Fragment, useRef, useEffect } from "react";
|
||||
|
||||
import "aplayer/dist/APlayer.min.css";
|
||||
|
||||
function Video({ url, mimetype, ...rest }: { url: string; mimetype: string; className?: string }) {
|
||||
const container = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
new Artplayer({
|
||||
container: container.current as HTMLDivElement,
|
||||
url: url,
|
||||
setting: true,
|
||||
flip: true,
|
||||
loop: true,
|
||||
playbackRate: true,
|
||||
aspectRatio: true,
|
||||
subtitleOffset: true,
|
||||
fullscreen: true,
|
||||
fullscreenWeb: true,
|
||||
screenshot: true,
|
||||
autoPlayback: true,
|
||||
airplay: true,
|
||||
theme: "#49509e",
|
||||
});
|
||||
});
|
||||
|
||||
return <div ref={container} {...rest}></div>;
|
||||
}
|
||||
|
||||
function Audio({
|
||||
url,
|
||||
artist,
|
||||
caption,
|
||||
...rest
|
||||
}: {
|
||||
url: string;
|
||||
artist: string;
|
||||
caption: string;
|
||||
className?: string;
|
||||
}) {
|
||||
const container = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
new APlayer({
|
||||
container: container.current,
|
||||
audio: [
|
||||
{
|
||||
name: caption,
|
||||
artist: artist,
|
||||
url: url,
|
||||
theme: "#49509e",
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
return <div ref={container} {...rest}></div>;
|
||||
}
|
||||
|
||||
export default function Media({
|
||||
sources,
|
||||
author,
|
||||
}: {
|
||||
sources: { id: number; filename: string; mimetype: string }[];
|
||||
author?: { name: string };
|
||||
}) {
|
||||
const items = sources.sort((a, b) => (a.id > b.id ? 1 : -1));
|
||||
console.log(items);
|
||||
const [focus, setFocus] = useState<boolean[]>(items.map((_, idx) => idx === 0));
|
||||
|
||||
function changeFocus(idx: number) {
|
||||
setFocus(focus.map((_, i) => i === idx));
|
||||
}
|
||||
|
||||
function getUrl(item: any) {
|
||||
return item.external_url ? item.external_url : `https://feed.smartsheep.studio/api/attachments/o/${item.file_id}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div role="tablist" className="tabs tabs-lifted">
|
||||
{items.map((item, idx) => (
|
||||
<Fragment key={idx}>
|
||||
<input
|
||||
type="radio"
|
||||
name={item.filename}
|
||||
role="tab"
|
||||
className="tab"
|
||||
aria-label={item.filename}
|
||||
checked={focus[idx]}
|
||||
onChange={() => changeFocus(idx)}
|
||||
/>
|
||||
<div role="tabpanel" className="tab-content bg-base-100 border-base-300 rounded-box w-full">
|
||||
{item.mimetype.startsWith("video") && (
|
||||
<div className="w-full h-[460px]">
|
||||
<Video className="w-full h-full" mimetype={item.mimetype} url={getUrl(item)} />
|
||||
</div>
|
||||
)}
|
||||
{item.mimetype.startsWith("audio") && (
|
||||
<div className="w-full">
|
||||
<Audio url={getUrl(item)} artist={author?.name ?? "佚名"} caption={item.filename} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
1
src/env.d.ts
vendored
Normal file
1
src/env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="astro/client" />
|
11
src/layouts/PageLayout.astro
Normal file
11
src/layouts/PageLayout.astro
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
import RootLayout from "./RootLayout.astro";
|
||||
|
||||
const { title } = Astro.props;
|
||||
---
|
||||
|
||||
<RootLayout title={title}>
|
||||
<main class="container mx-auto mt-header px-5">
|
||||
<slot />
|
||||
</main>
|
||||
</RootLayout>
|
96
src/layouts/RootLayout.astro
Normal file
96
src/layouts/RootLayout.astro
Normal file
@ -0,0 +1,96 @@
|
||||
---
|
||||
import "../assets/fonts/fonts.css";
|
||||
|
||||
import "@fortawesome/fontawesome-free/css/all.min.css";
|
||||
import "nprogress/nprogress.css";
|
||||
|
||||
import Navbar from "../components/Navbar.astro";
|
||||
import Footer from "../components/Footer.astro";
|
||||
import { ViewTransitions } from "astro:transitions";
|
||||
|
||||
const { title } = Astro.props;
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
{title && <title>山羊寒舍 | {title}</title>}
|
||||
{!title && <title>山羊寒舍</title>}
|
||||
|
||||
<script is:inline>
|
||||
if (localStorage.getItem("theme") === null) {
|
||||
document.documentElement.setAttribute("data-theme", "light");
|
||||
} else {
|
||||
document.documentElement.setAttribute("data-theme", localStorage.getItem("theme"));
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import NProgress from "nprogress";
|
||||
NProgress.configure({ showSpinner: false, trickleSpeed: 800 });
|
||||
document.addEventListener("astro:before-preparation", function () {
|
||||
NProgress.start();
|
||||
});
|
||||
document.addEventListener("astro:after-preparation", function () {
|
||||
NProgress.done();
|
||||
});
|
||||
</script>
|
||||
|
||||
<ViewTransitions />
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header -->
|
||||
<Navbar />
|
||||
|
||||
<!-- Content -->
|
||||
<main transition:animate="slide">
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<Footer />
|
||||
|
||||
<!-- Styles -->
|
||||
<style>
|
||||
html {
|
||||
overflow-x: hidden !important;
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style is:global>
|
||||
.h-fullpage {
|
||||
height: calc(100vh - 64px);
|
||||
}
|
||||
|
||||
.max-h-fullpage {
|
||||
max-height: calc(100vh - 64px);
|
||||
}
|
||||
|
||||
.mt-header {
|
||||
margin-top: 64px;
|
||||
}
|
||||
|
||||
.top-header {
|
||||
top: 64px;
|
||||
}
|
||||
|
||||
#nprogress .bar {
|
||||
background: #49509e !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import { themeChange } from "theme-change";
|
||||
themeChange();
|
||||
</script>
|
||||
|
||||
<script
|
||||
async
|
||||
src="https://analytics.smartsheep.studio/script.js"
|
||||
data-website-id="bbe87bab-bd5b-416b-8767-b29088c75ab2"></script>
|
||||
</body>
|
||||
</html>
|
17
src/pages/404.astro
Normal file
17
src/pages/404.astro
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
import RootLayout from "../layouts/RootLayout.astro";
|
||||
|
||||
export const prerender = false;
|
||||
---
|
||||
|
||||
<RootLayout>
|
||||
<div class="h-screen w-full flex justify-center items-center">
|
||||
<div class="text-center">
|
||||
<h2 class="text-2xl font-bold">404</h2>
|
||||
<h3 class="text-lg">Not Found</h3>
|
||||
|
||||
<p class="mt-5">哎呀~ 你要找的资源不存在呢~</p>
|
||||
<a class="link" href="/">返回主页</a>
|
||||
</div>
|
||||
</div>
|
||||
</RootLayout>
|
29
src/pages/about/contact.astro
Normal file
29
src/pages/about/contact.astro
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
import PageLayout from "../../layouts/PageLayout.astro";
|
||||
---
|
||||
|
||||
<PageLayout title="联系方式">
|
||||
<article class="prose mx-auto py-28">
|
||||
<h1>联系方式</h1>
|
||||
|
||||
<p>
|
||||
为了防止爬虫找到我们的联系方式,我们借助赛博门神 Cloudflare 实现了面对爬虫时我们的联系方式会被 mask
|
||||
掉。想不到吧小爬虫们~
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
所以如果你看到的也是乱码,换个好点的有独立互联网地址的代理吧。或是关掉吧,Cloudflare 又没被墙。
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
<span>我们主要提供一个方式联系我们,便是我们工作室的电邮地址</span>
|
||||
<i>其实你直接联系小羊也一样的</i>
|
||||
</p>
|
||||
|
||||
<address>alphabot@smartsheep.studio</address>
|
||||
|
||||
<p>そうなんです~ 当スタジオのメールアドレスは、 「アルファボット」のものです☆~</p>
|
||||
|
||||
<p>上記は当社のメールアドレスですので、ご協力、またはカスタマーサービスサポートを受けることを歓迎します。</p>
|
||||
</article>
|
||||
</PageLayout>
|
39
src/pages/about/us.astro
Normal file
39
src/pages/about/us.astro
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
import PageLayout from "../../layouts/PageLayout.astro";
|
||||
---
|
||||
|
||||
<PageLayout title="关于我们">
|
||||
<article class="prose mx-auto py-28">
|
||||
<h1>关于我们</h1>
|
||||
|
||||
<p>我们是一个名义上的工作室,实质上就是个人自娱自乐的名号罢了。我们可以用一段代码来介绍我们。</p>
|
||||
|
||||
<pre>console.log(undefined)</pre>
|
||||
|
||||
<p>按下 F12,把这段代码复制到你的控制台,这便是我们的所有信息了。</p>
|
||||
|
||||
<h2>关于语言</h2>
|
||||
|
||||
<p>
|
||||
不过我们可以补充一点,关于语言的使用问题。由于我们的 Founder 也是我们唯一的成员是土生土长的华人,所以我们根据 50%
|
||||
原则,汉语变成为我们的母语。而跟着国际化的目标,我们的第二母语便不变的成为英语。
|
||||
</p>
|
||||
|
||||
<p>
|
||||
目前,除了我们 Capital 官网项目,其他的产品皆根据我们国际化原则初版使用英语。在未来增加其他多语言的支持,并且
|
||||
Simplified Chinese 简体中文为我们本地化清单上的第一项。
|
||||
</p>
|
||||
|
||||
<h2>成员列表</h2>
|
||||
|
||||
<div role="alert" class="alert alert-error">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<div>
|
||||
<span>Record Not Found</span> <br>
|
||||
<i class="opacity-80">This is a feature, not a bug.</i>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</PageLayout>
|
29
src/pages/categories/[slug].astro
Normal file
29
src/pages/categories/[slug].astro
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
import PageLayout from "../../layouts/PageLayout.astro";
|
||||
import PostList from "../../components/PostList.astro";
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
const { slug } = Astro.params;
|
||||
|
||||
const response = await fetch(
|
||||
`https://feed.smartsheep.studio/api/posts?${new URLSearchParams({
|
||||
offset: (0).toString(),
|
||||
take: (100).toString(),
|
||||
category: slug ?? "none",
|
||||
realmId: process.env.PUBLIC_REALM_ID ?? (0).toString(),
|
||||
})}`,
|
||||
);
|
||||
const posts = (await response.json())["data"];
|
||||
---
|
||||
|
||||
<PageLayout title="分类检索">
|
||||
<div class="max-w-[720px] mx-auto">
|
||||
<div class="pt-16 pb-6 px-6">
|
||||
<h1 class="text-4xl font-bold">分类检索</h1>
|
||||
<p class="pt-3">以下是包含该分类的记录……</p>
|
||||
</div>
|
||||
|
||||
<PostList posts={posts as any[]} />
|
||||
</div>
|
||||
</PageLayout>
|
157
src/pages/events/years/2024.astro
Normal file
157
src/pages/events/years/2024.astro
Normal file
@ -0,0 +1,157 @@
|
||||
---
|
||||
import RootLayout from "../../../layouts/RootLayout.astro";
|
||||
|
||||
export const prerender = false;
|
||||
---
|
||||
|
||||
<RootLayout>
|
||||
<div id="countdown-container" class="w-screen h-screen flex items-center justify-center">
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="text-center">
|
||||
<p>距离</p>
|
||||
<h2 class="text-2xl font-bold">贰〇贰肆 甲辰年</h2>
|
||||
<p id="countdown-notifier">还有</p>
|
||||
</div>
|
||||
|
||||
<!-- Countdown -->
|
||||
<div class="grid grid-flow-col gap-5 text-center auto-cols-max">
|
||||
<div class="flex flex-col">
|
||||
<span class="countdown font-mono text-5xl">
|
||||
<span id="countdown-days" style="--value:0"></span>
|
||||
</span>
|
||||
天
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="countdown font-mono text-5xl">
|
||||
<span id="countdown-hours" style="--value:0"></span>
|
||||
</span>
|
||||
时
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="countdown font-mono text-5xl">
|
||||
<span id="countdown-minutes" style="--value:0"></span>
|
||||
</span>
|
||||
分
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="countdown font-mono text-5xl">
|
||||
<span id="countdown-seconds" style="--value:0"></span>
|
||||
</span>
|
||||
秒
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footnote -->
|
||||
<div class="text-xs text-center opacity-0 hover:opacity-100 transition-opacity duration-300">
|
||||
<p>智羊陪您过大年</p>
|
||||
<a class="link" href="https://smartsheep.studio">smartsheep.studio</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="fireworks" style="left: 15%; top: 5%;"></div>
|
||||
<div class="fireworks" style="right: 30%; top: 13%; animation-delay: -0.4s"></div>
|
||||
<div class="fireworks" style="left: 5%; top: 23%; animation-delay: -1.7s"></div>
|
||||
<div class="fireworks" style="right: 45%; top: 8%; animation-delay: -3.1s"></div>
|
||||
<div class="fireworks" style="left: 21%; top: 9%; animation-delay: -3.8s"></div>
|
||||
<div class="fireworks" style="right: 63%; top: 23%; animation-delay: -4.5s"></div>
|
||||
<div class="fireworks" style="left: 12%; top: 75%; animation-delay: -5.2s"></div>
|
||||
<div class="fireworks" style="right: 86%; top: 12%; animation-delay: -5.9s"></div>
|
||||
<div class="fireworks" style="left: 23%; top: 34%; animation-delay: -6.6s"></div>
|
||||
<div class="fireworks" style="right: 23%; top: 17%; animation-delay: -7.3s;"></div>
|
||||
<div class="fireworks" style="left: 2%; top: 23%; animation-delay: -8s;"></div>
|
||||
<div class="fireworks" style="right: 46%; top: 63%; animation-delay: -8.7s;"></div>
|
||||
</RootLayout>
|
||||
|
||||
<script>
|
||||
const targetDate = new Date("2024-02-10T00:00:00.0000");
|
||||
|
||||
const countdownDays = document.querySelector<HTMLSpanElement>("#countdown-days");
|
||||
const countdownHours = document.querySelector<HTMLSpanElement>("#countdown-hours");
|
||||
const countdownMinutes = document.querySelector<HTMLSpanElement>("#countdown-minutes");
|
||||
const countdownSeconds = document.querySelector<HTMLSpanElement>("#countdown-seconds");
|
||||
const countdownNotifier = document.querySelector<HTMLParagraphElement>("#countdown-notifier");
|
||||
|
||||
function calcDelta() {
|
||||
const delta = Math.abs(targetDate.getTime() - Date.now());
|
||||
|
||||
const days = Math.floor(delta / (1000 * 60 * 60 * 24));
|
||||
const hours = Math.floor((delta % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||
const minutes = Math.floor((delta % (1000 * 60 * 60)) / (1000 * 60));
|
||||
const seconds = Math.floor((delta % (1000 * 60)) / 1000);
|
||||
|
||||
countdownDays?.style.setProperty("--value", days.toString());
|
||||
countdownHours?.style.setProperty("--value", hours.toString());
|
||||
countdownMinutes?.style.setProperty("--value", minutes.toString());
|
||||
countdownSeconds?.style.setProperty("--value", seconds.toString());
|
||||
|
||||
if(targetDate.getTime() <= Date.now() && countdownNotifier != null) {
|
||||
countdownNotifier.innerText = "已过"
|
||||
}
|
||||
}
|
||||
|
||||
setInterval(() => calcDelta(), 100);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body, html, #countdown-container {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
.fireworks {
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
background: #ffefad;
|
||||
-webkit-mask: url("https://imgservices-1252317822.image.myqcloud.com/image/081320210201435/e9951400.png") right top
|
||||
no-repeat;
|
||||
-webkit-mask-size: auto 150px;
|
||||
animation:
|
||||
fireworks 2s steps(24) infinite,
|
||||
random 8s steps(1) infinite,
|
||||
random_color 1s infinite;
|
||||
}
|
||||
@keyframes fireworks {
|
||||
0% {
|
||||
-webkit-mask-position: 0%;
|
||||
}
|
||||
50%,
|
||||
100% {
|
||||
-webkit-mask-position: 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes random {
|
||||
0% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
25% {
|
||||
transform: translate(200%, 50%) scale(0.8);
|
||||
}
|
||||
50% {
|
||||
transform: translate(80%, 80%) scale(1.2);
|
||||
}
|
||||
75% {
|
||||
transform: translate(20%, 60%) scale(0.65);
|
||||
}
|
||||
}
|
||||
@keyframes random_color {
|
||||
0% {
|
||||
background-color: #ffefad;
|
||||
}
|
||||
25% {
|
||||
background-color: #ffadad;
|
||||
}
|
||||
50% {
|
||||
background-color: #aeadff;
|
||||
}
|
||||
75% {
|
||||
background-color: #adffd9;
|
||||
}
|
||||
}
|
||||
@media screen and (prefers-reduced-motion) {
|
||||
/* 禁用不必要的动画 */
|
||||
.fireworks {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
</style>
|
144
src/pages/index.astro
Normal file
144
src/pages/index.astro
Normal file
@ -0,0 +1,144 @@
|
||||
---
|
||||
import RootLayout from "../layouts/RootLayout.astro";
|
||||
|
||||
export const prerender = false;
|
||||
---
|
||||
|
||||
<RootLayout>
|
||||
<div class="mt-header wrapper px-5">
|
||||
<div id="hello" class="hero h-fullpage">
|
||||
<div class="hero-content w-full grid grid-cols-1 md:grid-cols-2 max-md:gap-[60px]">
|
||||
<div class="max-md:text-center">
|
||||
<h1 class="text-5xl font-bold">你好呀 👋</h1>
|
||||
<p class="py-6">
|
||||
欢迎来到 SmartSheep Studio 的官方网站!在这里了解,订阅,跟踪我们的最新消息。
|
||||
接触我们最大的官方社区,并且尝试最新产品,参与各种活动,提供反馈,让我们更好的服务您。
|
||||
</p>
|
||||
<a href="#about" class="btn btn-primary btn-md">了解更多</a>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center md:justify-end max-md:order-first">
|
||||
<div class="spinning p-3 md:p-5 shadow-2xl aspect-square rounded-[30%] w-[192px] md:w-[256px] lg:w-[384px]">
|
||||
<img src="/favicon.svg" alt="logo" loading="lazy" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="about" class="hero h-fullpage">
|
||||
<div class="hero-content w-full grid grid-cols-1 md:grid-cols-2 max-md:gap-[60px]">
|
||||
<div class="flex justify-center md:justify-start">
|
||||
<div class="stats shadow overflow-x-auto">
|
||||
<div class="stat">
|
||||
<div class="stat-figure text-secondary">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
class="inline-block w-8 h-8 stroke-current"
|
||||
><path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg
|
||||
>
|
||||
</div>
|
||||
<div class="stat-title">People</div>
|
||||
<div class="stat-value">1</div>
|
||||
<div class="stat-desc">2019 - {new Date().getFullYear()}</div>
|
||||
</div>
|
||||
|
||||
<div class="stat">
|
||||
<div class="stat-figure text-secondary">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
class="inline-block w-8 h-8 stroke-current"
|
||||
><path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"
|
||||
></path></svg
|
||||
>
|
||||
</div>
|
||||
<div class="stat-title">Clients</div>
|
||||
<div class="stat-value">180</div>
|
||||
<div class="stat-desc">↗︎ 80 (44%)</div>
|
||||
</div>
|
||||
|
||||
<div class="stat">
|
||||
<div class="stat-figure text-secondary">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
class="inline-block w-8 h-8 stroke-current"
|
||||
><path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"></path></svg
|
||||
>
|
||||
</div>
|
||||
<div class="stat-title">Products</div>
|
||||
<div class="stat-value">4</div>
|
||||
<div class="stat-desc">↘︎ 8 (67%)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="max-md:text-center">
|
||||
<h1 class="text-5xl font-bold">关于我们 🔖</h1>
|
||||
<p class="py-6">
|
||||
我们是一群充满活力、对开源充满热情的开发者。成立于 2019
|
||||
年。自那年起我们一直在开发让人喜欢的开源软件。在我们这里,“取之于开源,用之于开源”
|
||||
不仅是原则,更是我们信仰的座右铭。
|
||||
</p>
|
||||
<a href="#history" class="btn btn-primary btn-md pl-[24px]"> 查看「岁月史书」</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</RootLayout>
|
||||
|
||||
<style>
|
||||
.spinning {
|
||||
animation: 5s ease-in-out infinite running spinning;
|
||||
}
|
||||
|
||||
@keyframes spinning {
|
||||
0% {
|
||||
rotate: 0deg;
|
||||
}
|
||||
60% {
|
||||
rotate: 360deg;
|
||||
}
|
||||
100% {
|
||||
rotate: 360deg;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
.wrapper {
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.wrapper::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.history {
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.history::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
</style>
|
98
src/pages/legal/community-guidelines.astro
Normal file
98
src/pages/legal/community-guidelines.astro
Normal file
@ -0,0 +1,98 @@
|
||||
---
|
||||
import PageLayout from "../../layouts/PageLayout.astro";
|
||||
|
||||
const updatedAt = new Date("2024-02-15T07:37:11.631Z");
|
||||
---
|
||||
|
||||
<PageLayout title="Goatworks Community Guidelines">
|
||||
<article class="prose mx-auto py-28">
|
||||
<h1>Goatworks Community Guidelines</h1>
|
||||
|
||||
<p>Last updated at {updatedAt.toLocaleString()}</p>
|
||||
|
||||
<p>
|
||||
Welcome to our community! We are committed to fostering an open, friendly, and respectful environment to
|
||||
facilitate meaningful communication and shared experiences. Please adhere to the following community guidelines to
|
||||
ensure that every member can enjoy a positive and enriching community experience.
|
||||
</p>
|
||||
|
||||
<h2>1. Respect Others</h2>
|
||||
<p>
|
||||
Ensure that your words and actions respect fellow community members. Avoid the use of insulting, discriminatory,
|
||||
or offensive language. Respect others' viewpoints, even if you disagree. Engage in discussions constructively to
|
||||
foster understanding and knowledge sharing.
|
||||
</p>
|
||||
|
||||
<h2>2. Maintain Friendliness and Inclusivity</h2>
|
||||
<p>
|
||||
We welcome members from diverse cultures, backgrounds, and perspectives. Ensure that your interactions are
|
||||
friendly and inclusive. Refrain from posting offensive or discriminatory content. Help us create an environment
|
||||
that accommodates a variety of opinions and ideas.
|
||||
</p>
|
||||
|
||||
<h2>3. Respect Privacy</h2>
|
||||
<p>
|
||||
Respect the privacy of other members. Avoid sharing others' personal information without their consent. If you
|
||||
need to share information related to others, ensure you have obtained their permission.
|
||||
</p>
|
||||
|
||||
<h2>4. Inappropriate Content and Behavior</h2>
|
||||
<p>
|
||||
Refrain from posting any illegal, obscene, threatening, or otherwise inappropriate content. This includes but is
|
||||
not limited to explicit material, hate speech, false information, or any behavior that violates laws and ethical
|
||||
standards.
|
||||
</p>
|
||||
|
||||
<h2>5. Provide Valuable Contributions</h2>
|
||||
<p>
|
||||
Share meaningful and valuable content within the community. Avoid posting unrelated or repetitive information.
|
||||
Maintain the quality of discussions and provide helpful insights and experiences for other members.
|
||||
</p>
|
||||
|
||||
<h2>6. Respect Administrators and Moderators</h2>
|
||||
<p>
|
||||
Follow the guidance and rules provided by administrators and moderators. Their goal is to maintain community order
|
||||
and ensure a pleasant experience for every member. If you have any questions or concerns, feel free to contact
|
||||
them privately.
|
||||
</p>
|
||||
|
||||
<h2>7. Respect Diverse Political Views</h2>
|
||||
<p>
|
||||
We encourage the respectful sharing of diverse political views. However, express your opinions in a way that
|
||||
respects others, avoiding offensive, provocative, or insulting language. Political discussions should be conducted
|
||||
constructively to promote understanding and information sharing.
|
||||
</p>
|
||||
|
||||
<h2>8. Adhere to International Political Standards</h2>
|
||||
<p>
|
||||
Our community consists of members from around the world with different political beliefs. Understand and respect
|
||||
international political viewpoints, avoiding conflicts arising from political stances. Keep an open mind and be
|
||||
willing to listen and learn from diverse cultural and national perspectives.
|
||||
</p>
|
||||
|
||||
<h2>9. Comply with Legal Regulations</h2>
|
||||
<p>
|
||||
Any form of illegal behavior is unacceptable in our community. Ensure that your words and actions comply with
|
||||
local and international laws, especially in matters related to politics. Prohibitions include incitement,
|
||||
advocating violence, or any other unlawful activities.
|
||||
</p>
|
||||
|
||||
<h2>10. Avoid Improper Political Promotion</h2>
|
||||
<p>
|
||||
Avoid engaging in inappropriate political promotion within the community. The community is intended for
|
||||
constructive exchange, not as a platform for political propaganda. Respect the preferences of other members and
|
||||
refrain from forcefully advocating personal or group political stances.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
We believe that by adhering to these guidelines, we can create an inclusive community rich in diverse
|
||||
perspectives. Violations may result in appropriate sanctions, and the specific consequences will depend on the
|
||||
severity and frequency of the violations.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Thank you for your cooperation in maintaining an open and friendly atmosphere in our community, providing an
|
||||
enjoyable communication experience for all members!
|
||||
</p>
|
||||
</article>
|
||||
</PageLayout>
|
81
src/pages/legal/privacy-policy.astro
Normal file
81
src/pages/legal/privacy-policy.astro
Normal file
@ -0,0 +1,81 @@
|
||||
---
|
||||
import PageLayout from "../../layouts/PageLayout.astro";
|
||||
|
||||
const updatedAt = new Date("2024-02-15T07:37:11.631Z");
|
||||
---
|
||||
|
||||
<PageLayout title="Privacy Policy">
|
||||
<article class="prose mx-auto py-28">
|
||||
<h1>Privacy Policy</h1>
|
||||
|
||||
<p>Last updated at {updatedAt.toLocaleString()}</p>
|
||||
|
||||
<p>
|
||||
SmartSheep Studio (referred to as "we," "our," or "the Studio") respects and protects your personal
|
||||
privacy. This Privacy Policy is intended to explain our practices regarding the collection, use, sharing, and
|
||||
protection of your personal information. Please read this Privacy Policy carefully to understand how we handle
|
||||
your personal information.
|
||||
</p>
|
||||
|
||||
<h2>1. Information Collection</h2>
|
||||
|
||||
<p>We may collect various types of information, including but not limited to:</p>
|
||||
|
||||
<ul>
|
||||
<li>Personal identification information (e.g., name, address, email address, phone number, etc.)</li>
|
||||
<li>Device information (e.g., IP address, operating system, browser type, etc.)</li>
|
||||
<li>Usage data (e.g., access times, browsing history, clickstream data, etc.)</li>
|
||||
</ul>
|
||||
|
||||
<p>We may collect information through various methods, including:</p>
|
||||
|
||||
<ul>
|
||||
<li>Information you provide (e.g., account registration, form submissions, etc.)</li>
|
||||
<li>Automatically collected information (e.g., through Cookies, Web Beacons, etc.)</li>
|
||||
</ul>
|
||||
|
||||
<h2>2. Information Use</h2>
|
||||
|
||||
<p>We may use your personal information for various purposes, including:</p>
|
||||
|
||||
<ul>
|
||||
<li>Providing requested products or services</li>
|
||||
<li>Processing transactions and payments</li>
|
||||
<li>Sending relevant notifications</li>
|
||||
<li>Providing customer support and services</li>
|
||||
<li>Improving our products and services</li>
|
||||
</ul>
|
||||
|
||||
<h2>3. Information Sharing</h2>
|
||||
|
||||
<p>We may share your personal information with third parties, including but not limited to:</p>
|
||||
|
||||
<ul>
|
||||
<li>Business partners</li>
|
||||
<li>Third-party service providers</li>
|
||||
<li>When required by law or government agencies</li>
|
||||
</ul>
|
||||
|
||||
<h2>4. Information Security</h2>
|
||||
|
||||
<p>
|
||||
We will take reasonable security measures to protect your personal information from unauthorized access, use, or
|
||||
disclosure. However, please note that no method of transmission over the internet is 100% secure.
|
||||
</p>
|
||||
|
||||
<h2>5. Changes to Privacy Policy</h2>
|
||||
|
||||
<p>
|
||||
We reserve the right to modify this Privacy Policy at any time. The updated policy will be posted on our website
|
||||
and will become effective upon posting. Please check our Privacy Policy regularly for updates.
|
||||
</p>
|
||||
|
||||
<h2>6. Contact Us</h2>
|
||||
|
||||
<p>If you have any questions or concerns about our Privacy Policy, please contact us at:</p>
|
||||
|
||||
<address>alphabot@smartsheep.studio</address>
|
||||
|
||||
<p>Thank you for reading our Privacy Policy.</p>
|
||||
</article>
|
||||
</PageLayout>
|
94
src/pages/legal/user-agreement.astro
Normal file
94
src/pages/legal/user-agreement.astro
Normal file
@ -0,0 +1,94 @@
|
||||
---
|
||||
import PageLayout from "../../layouts/PageLayout.astro";
|
||||
|
||||
const updatedAt = new Date("2024-02-15T07:37:11.631Z");
|
||||
---
|
||||
|
||||
<PageLayout title="User Agreement">
|
||||
<article class="prose mx-auto py-28">
|
||||
<h1>User Agreement</h1>
|
||||
|
||||
<p>Last updated at {updatedAt.toLocaleString()}</p>
|
||||
|
||||
<p>
|
||||
Please read this user agreement carefully before using our product/service. By using our product/service, you
|
||||
agree to comply with the following terms and conditions:
|
||||
</p>
|
||||
|
||||
<h2>1. User Content</h2>
|
||||
|
||||
<p>
|
||||
1.1 You are solely responsible for any text, images, audio, video, or other materials (collectively referred to as
|
||||
"User Content") you upload, publish, or share through our product/service.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
1.2 You warrant that you are the lawful owner of all User Content you upload, or you have obtained all necessary
|
||||
authorizations and licenses to use and share such User Content on our product/service.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
1.3 You agree not to upload, publish, or share any User Content that is illegal, infringing, obscene, threatening,
|
||||
defamatory, or otherwise violates applicable laws.
|
||||
</p>
|
||||
|
||||
<h2>2. Community Guidelines and Service Termination</h2>
|
||||
|
||||
<p>
|
||||
2.1 You must adhere to our community guidelines, which include but are not limited to
|
||||
<a href="/legal/community-guidelines">Goatworks Community Guidelines</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
2.2 Violation of the community guidelines may result in our sole discretion to delete, modify, or refuse
|
||||
acceptance of any User Content and may lead to termination or suspension of your access to our product/service.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
2.3 We reserve the right to modify the community guidelines at any time, and you agree to comply with the latest
|
||||
community guidelines.
|
||||
</p>
|
||||
|
||||
<h2>3. Legal Responsibility</h2>
|
||||
|
||||
<p>3.1 We do not assume any responsibility for the legality, accuracy, completeness, or quality of User Content.</p>
|
||||
|
||||
<p>
|
||||
3.2 You agree to bear all legal responsibilities arising from your User Content, including but not limited to
|
||||
claims, lawsuits, losses, and expenses incurred by third parties.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
3.3 We are not liable for any losses or damages caused by User Content, including but not limited to direct or
|
||||
indirect special, incidental, consequential, or punitive damages.
|
||||
</p>
|
||||
|
||||
<h2>4. User Responsibilities</h2>
|
||||
|
||||
<p>
|
||||
4.1 You agree to maintain the confidentiality of your account and password and assume full responsibility for all
|
||||
activities conducted through your account.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
4.2 You agree to promptly notify us of any unauthorized use of your account or other security vulnerabilities.
|
||||
</p>
|
||||
|
||||
<h2>5. Termination</h2>
|
||||
|
||||
<p>
|
||||
We reserve the right to terminate or suspend your access to our product/service at any time without prior notice
|
||||
if we believe you have violated any provisions of this user agreement or community guidelines.
|
||||
</p>
|
||||
|
||||
<h2>6. Contact Us</h2>
|
||||
|
||||
<p>If you have any questions about this user agreement, please contact us at:</p>
|
||||
|
||||
<address>
|
||||
alphabot@smartsheep.studio
|
||||
</address>
|
||||
|
||||
<p>Thank you for reading and complying with our user agreement.</p>
|
||||
</article>
|
||||
</PageLayout>
|
17
src/pages/moments.astro
Normal file
17
src/pages/moments.astro
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
import RootLayout from "../layouts/RootLayout.astro";
|
||||
---
|
||||
|
||||
<RootLayout>
|
||||
<iframe class="moments-frame" src="https://feed.smartsheep.studio/realms/1?embedded=yes"></iframe>
|
||||
</RootLayout>
|
||||
|
||||
<style>
|
||||
.moments-frame {
|
||||
margin-top: 64px;
|
||||
display: block;
|
||||
border: 0;
|
||||
width: 100vw;
|
||||
height: calc(100vh - 64px);
|
||||
}
|
||||
</style>
|
156
src/pages/posts/[slug].astro
Normal file
156
src/pages/posts/[slug].astro
Normal file
@ -0,0 +1,156 @@
|
||||
---
|
||||
import PageLayout from "../../layouts/PageLayout.astro";
|
||||
// @ts-ignore
|
||||
import Media from "../../components/posts/Media";
|
||||
import Content from "../../components/posts/Content";
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
const { slug } = Astro.params;
|
||||
|
||||
const response = await fetch(`https://feed.smartsheep.studio/api/posts/${slug}`);
|
||||
|
||||
if (response.status !== 200) {
|
||||
return Astro.redirect("/404");
|
||||
}
|
||||
|
||||
const post = (await response.json())["data"];
|
||||
|
||||
if (post.realm_id != parseInt(process.env.PUBLIC_REALM_ID ?? "0")) {
|
||||
return Astro.redirect(`https://feed.smartsheep.studio/posts/${post.id}`);
|
||||
}
|
||||
|
||||
function getThumbnail(item: any): string | null {
|
||||
for (const attachment of item?.attachments ?? []) {
|
||||
if (attachment.mimetype.startsWith("image")) {
|
||||
return attachment.external_url
|
||||
? attachment.external_url
|
||||
: `https://feed.smartsheep.studio/api/attachments/o/${attachment.file_id}`;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getAttachments(item: any): any[] {
|
||||
let filtered = false;
|
||||
return item.attachments.filter((item: any) => {
|
||||
if(item.mimetype.startsWith("image") && !filtered) {
|
||||
filtered = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
}
|
||||
|
||||
function getAuthorLink(user: any): string {
|
||||
return `https://feed.smartsheep.studio/accounts/${user.name}`;
|
||||
}
|
||||
|
||||
const embedOptions = new URLSearchParams({
|
||||
embedded: "yes",
|
||||
title: "讨论",
|
||||
noContent: "yes",
|
||||
noAuthor: "yes",
|
||||
}).toString();
|
||||
---
|
||||
|
||||
<PageLayout title={post?.title}>
|
||||
<div class="wrapper">
|
||||
<div class="card w-full shadow-xl post h-fit">
|
||||
{
|
||||
getThumbnail(post) && (
|
||||
<figure>
|
||||
<img src={getThumbnail(post)} alt={post?.title} />
|
||||
</figure>
|
||||
)
|
||||
}
|
||||
<div class="card-body">
|
||||
<div class="mx-1 mb-5">
|
||||
<h2 class="card-title">{post?.title}</h2>
|
||||
<div class="text-sm flex max-lg:flex-col gap-x-4">
|
||||
<span>
|
||||
<i class="fa-solid fa-user me-1"></i>
|
||||
作者
|
||||
<a class="link" target="_blank" href={getAuthorLink(post?.author)}>{post?.author?.nick ?? "佚名"}</a>
|
||||
</span>
|
||||
<span>
|
||||
<i class="fa-solid fa-calendar me-1"></i>
|
||||
发布于 {new Date(post?.created_at).toLocaleString()}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{
|
||||
getAttachments(post)?.length > 0 && (
|
||||
<div class="my-5 w-full">
|
||||
<Media client:only sources={getAttachments(post)} author={post?.author} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
<Content content={post?.content} client:only />
|
||||
|
||||
<div class="mt-5 flex gap-1">
|
||||
{
|
||||
post?.categories?.map((category: any) => (
|
||||
<a href={`/categories/${category?.alias}`} class="badge badge-primary">
|
||||
<i class="fa-solid fa-layer-group me-1.5" />
|
||||
{category?.name}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
{
|
||||
post?.tags?.map((tag: any) => (
|
||||
<a href={`/tags/${tag?.alias}`} class="badge badge-accent">
|
||||
<i class="fa-regular fa-tag me-1.5" />
|
||||
{tag?.name}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h-fit sticky top-header">
|
||||
<div class="card shadow-xl">
|
||||
<iframe id="interactive-iframe" src={`https://feed.smartsheep.studio/posts/${slug}?${embedOptions}`}> </iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageLayout>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: oklch(var(--bc) / 0.8);
|
||||
}
|
||||
|
||||
.metadata {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
transition: color 0.3s;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.wrapper {
|
||||
grid-template-columns: 2fr 1fr;
|
||||
}
|
||||
|
||||
#interactive-iframe {
|
||||
height: calc(100vh - 64px);
|
||||
}
|
||||
}
|
||||
|
||||
#interactive-iframe {
|
||||
display: block;
|
||||
border: 0;
|
||||
width: 100%;
|
||||
min-height: 480px;
|
||||
}
|
||||
</style>
|
28
src/pages/posts/index.astro
Normal file
28
src/pages/posts/index.astro
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
import PageLayout from "../../layouts/PageLayout.astro";
|
||||
import PostList from "../../components/PostList.astro";
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
const response = await fetch(
|
||||
`https://feed.smartsheep.studio/api/posts?${new URLSearchParams({
|
||||
offset: (0).toString(),
|
||||
take: (100).toString(),
|
||||
realmId: process.env.PUBLIC_REALM_ID ?? (0).toString(),
|
||||
})}`,
|
||||
);
|
||||
const posts = (await response.json())["data"];
|
||||
---
|
||||
|
||||
<PageLayout title="记录">
|
||||
<div class="max-w-[720px] mx-auto">
|
||||
<div class="pt-16 pb-6 px-6">
|
||||
<h1 class="text-4xl font-bold">记录</h1>
|
||||
<p class="pt-2">记录生活,记录理想,记录记录……</p>
|
||||
</div>
|
||||
|
||||
<div class="pb-12">
|
||||
<PostList posts={posts} />
|
||||
</div>
|
||||
</div>
|
||||
</PageLayout>
|
37
src/pages/recruitment.astro
Normal file
37
src/pages/recruitment.astro
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
import PageLayout from "../layouts/PageLayout.astro";
|
||||
---
|
||||
|
||||
<PageLayout title="招贤纳士">
|
||||
<article class="prose mx-auto py-28">
|
||||
<h1>招贤纳士</h1>
|
||||
|
||||
<p>現在、弊社では新規メンバーの募集は行っておりませんし、採用の予定もございません。</p>
|
||||
|
||||
<p>
|
||||
Si desea unirse a nuestro estudio y contribuir a la industria del código abierto, le recomendamos que envíe una
|
||||
solicitud de extracción directamente a nuestro proyecto.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Unser Mie Repo ermöglicht es jedem Benutzer mit Goatpass, das Repository zu forken und Commits und Pull Requests
|
||||
zu erstellen.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Однако, если вы действительно хотите стать частью нас, вы можете попытаться получить наш флаг набора, выполнив
|
||||
следующие испытания.
|
||||
</p>
|
||||
|
||||
<pre>RG9pIHNlIG5hyJl0ZSwgZG9pIHNlIG5hyJl0ZSB0cmVpLCB0cmVpIHNlIG5hyJl0ZSB0b2F0ZSBsdWNydXJpbGU</pre>
|
||||
|
||||
<p>
|
||||
ಮೇಲಿನ ಸ್ಪಷ್ಟ ಪಠ್ಯವನ್ನು ಯಾವುದೇ ವಿಧಾನದಿಂದ ಪಡೆಯಿರಿ ಮತ್ತು ಅದನ್ನು ಮತ್ತು ನಿಮ್ಮ ರೆಸ್ಯೂಮ್ ಅನ್ನು ನಮ್ಮ ಆಲ್ಫಾಬಾಟ್ ಇಮೇಲ್ಗೆ
|
||||
ಕಳುಹಿಸಿ.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Bientôt, un de nos spécialistes vous contactera!
|
||||
</p>
|
||||
</article>
|
||||
</PageLayout>
|
29
src/pages/tags/[slug].astro
Normal file
29
src/pages/tags/[slug].astro
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
import PageLayout from "../../layouts/PageLayout.astro";
|
||||
import PostList from "../../components/PostList.astro";
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
const { slug } = Astro.params;
|
||||
|
||||
const response = await fetch(
|
||||
`https://feed.smartsheep.studio/api/posts?${new URLSearchParams({
|
||||
offset: (0).toString(),
|
||||
take: (100).toString(),
|
||||
tag: slug ?? "none",
|
||||
realmId: process.env.PUBLIC_REALM_ID ?? (0).toString(),
|
||||
})}`,
|
||||
);
|
||||
const posts = (await response.json())["data"];
|
||||
---
|
||||
|
||||
<PageLayout title="标签检索">
|
||||
<div class="max-w-[720px] mx-auto">
|
||||
<div class="pt-16 pb-6 px-6">
|
||||
<h1 class="text-4xl font-bold">标签检索</h1>
|
||||
<p class="pt-3">以下是包含该标签的记录……</p>
|
||||
</div>
|
||||
|
||||
<PostList posts={posts as any[]} />
|
||||
</div>
|
||||
</PageLayout>
|
41
tailwind.config.mjs
Normal file
41
tailwind.config.mjs
Normal file
@ -0,0 +1,41 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
|
||||
daisyui: {
|
||||
themes: [
|
||||
{
|
||||
light: {
|
||||
...require("daisyui/src/theming/themes")["light"],
|
||||
primary: "#4750a3",
|
||||
secondary: "#93c5fd",
|
||||
accent: "#0f766e",
|
||||
info: "#67e8f9",
|
||||
success: "#15803d",
|
||||
warning: "#f97316",
|
||||
error: "#dc2626",
|
||||
"--rounded-box": "0",
|
||||
"--rounded-btn": "0",
|
||||
"--rounded-badge": "0",
|
||||
"--tab-radius": "0",
|
||||
},
|
||||
},
|
||||
{
|
||||
dark: {
|
||||
...require("daisyui/src/theming/themes")["dark"],
|
||||
primary: "#4750a3",
|
||||
secondary: "#93c5fd",
|
||||
accent: "#0f766e",
|
||||
info: "#67e8f9",
|
||||
success: "#15803d",
|
||||
warning: "#f97316",
|
||||
error: "#dc2626",
|
||||
"--rounded-box": "0",
|
||||
"--rounded-btn": "0",
|
||||
"--rounded-badge": "0",
|
||||
"--tab-radius": "0",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [require("daisyui"), require("@tailwindcss/typography")],
|
||||
};
|
@ -1,11 +0,0 @@
|
||||
import type { Config } from "tailwindcss";
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
plugins: [require("@tailwindcss/typography")],
|
||||
};
|
||||
export default config;
|
@ -1,26 +1,10 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"exclude": ["./content", "./dist"],
|
||||
"compilerOptions": {
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
"target": "es5",
|
||||
"lib": ["esnext", "es2021"],
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "react"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user