init
This commit is contained in:
135
app/components/ClientLayout.tsx
Normal file
135
app/components/ClientLayout.tsx
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import AppBar from "@mui/material/AppBar";
|
||||||
|
import Box from "@mui/material/Box";
|
||||||
|
import Toolbar from "@mui/material/Toolbar";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
import Button from "@mui/material/Button";
|
||||||
|
import Menu from "@mui/material/Menu";
|
||||||
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
|
import { ThemeProvider, createTheme } from "@mui/material/styles";
|
||||||
|
import CssBaseline from "@mui/material/CssBaseline";
|
||||||
|
import { styled } from "@mui/material/styles";
|
||||||
|
import ListSubheader from "@mui/material/ListSubheader";
|
||||||
|
import useScrollTrigger from "@mui/material/useScrollTrigger";
|
||||||
|
|
||||||
|
// 自定义内容标题样式
|
||||||
|
const StyledListHeader = styled(ListSubheader)({
|
||||||
|
backgroundImage: "var(--Paper-overlay)",
|
||||||
|
});
|
||||||
|
|
||||||
|
// 创建MUI主题
|
||||||
|
const theme = createTheme({
|
||||||
|
typography: {
|
||||||
|
fontFamily: "inherit",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
interface ClientLayoutProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 客户端组件负责MUI主题和UI组件
|
||||||
|
const ClientLayout: React.FC<ClientLayoutProps> = ({ children }) => {
|
||||||
|
// 将hooks移到组件内部
|
||||||
|
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||||
|
|
||||||
|
const handleMenu = (event: React.MouseEvent<HTMLElement>) => {
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
};
|
||||||
|
interface Props {
|
||||||
|
/**
|
||||||
|
* Injected by the documentation to work in an iframe.
|
||||||
|
* You won't need it on your project.
|
||||||
|
*/
|
||||||
|
window?: () => Window;
|
||||||
|
children?: React.ReactElement<{ elevation?: number }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// function ElevationScroll(props: Props) {
|
||||||
|
// const { children, window } = props;
|
||||||
|
// // Note that you normally won't need to set the window ref as useScrollTrigger
|
||||||
|
// // will default to window.
|
||||||
|
// // This is only being set here because the demo is in an iframe.
|
||||||
|
// const trigger = useScrollTrigger({
|
||||||
|
// disableHysteresis: true,
|
||||||
|
// threshold: 0,
|
||||||
|
// target: window ? window() : undefined,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return children
|
||||||
|
// ? React.cloneElement(children, {
|
||||||
|
// elevation: trigger ? 4 : 0,
|
||||||
|
// })
|
||||||
|
// : null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ThemeProvider theme={theme}>
|
||||||
|
<CssBaseline />
|
||||||
|
<Box sx={{ flexGrow: 1 }}>
|
||||||
|
<AppBar position="static">
|
||||||
|
<Toolbar>
|
||||||
|
{/* 左侧区域:Logo和项目按钮 */}
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
component="div"
|
||||||
|
sx={{ mr: 2, cursor: 'pointer' }}
|
||||||
|
onClick={() => (window.location.href = "/")}
|
||||||
|
>
|
||||||
|
LeonCloud
|
||||||
|
</Typography>
|
||||||
|
<Button
|
||||||
|
id="menu-appbar"
|
||||||
|
aria-controls="menu-appbar"
|
||||||
|
aria-haspopup="true"
|
||||||
|
onClick={handleMenu}
|
||||||
|
color="inherit"
|
||||||
|
>
|
||||||
|
<Typography variant="body1" component="span">
|
||||||
|
项目
|
||||||
|
</Typography>
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 右侧区域留空,让左侧内容靠左 */}
|
||||||
|
<Box sx={{ flexGrow: 1 }} />
|
||||||
|
|
||||||
|
<Menu
|
||||||
|
id="menu-appbar"
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
// anchorOrigin={{
|
||||||
|
// vertical: 'top',
|
||||||
|
// horizontal: 'left',
|
||||||
|
// }}
|
||||||
|
keepMounted
|
||||||
|
// transformOrigin={{
|
||||||
|
// vertical: 'top',
|
||||||
|
// horizontal: 'left',
|
||||||
|
// }}
|
||||||
|
open={Boolean(anchorEl)}
|
||||||
|
onClose={handleClose}
|
||||||
|
>
|
||||||
|
<StyledListHeader>Web</StyledListHeader>
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => (window.location.href = "/project/leonpan")}
|
||||||
|
>
|
||||||
|
LeonPan
|
||||||
|
</MenuItem>
|
||||||
|
{/* <MenuItem onClick={handleClose}>My account</MenuItem> */}
|
||||||
|
</Menu>
|
||||||
|
</Toolbar>
|
||||||
|
</AppBar>
|
||||||
|
</Box>
|
||||||
|
{children}
|
||||||
|
</ThemeProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ClientLayout;
|
||||||
@@ -1,33 +1,28 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Geist, Geist_Mono } from "next/font/google";
|
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
|
||||||
const geistSans = Geist({
|
// 禁用Google字体加载,避免构建错误
|
||||||
variable: "--font-geist-sans",
|
|
||||||
subsets: ["latin"],
|
|
||||||
});
|
|
||||||
|
|
||||||
const geistMono = Geist_Mono({
|
|
||||||
variable: "--font-geist-mono",
|
|
||||||
subsets: ["latin"],
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// 导出元数据
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Create Next App",
|
title: "LeonCloud官网",
|
||||||
description: "Generated by create next app",
|
description: "LeonCloud(原LeonWeb)官网",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 导入客户端组件
|
||||||
|
import ClientLayout from './components/ClientLayout';
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}>) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html>
|
||||||
<body
|
<body>
|
||||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
<ClientLayout>
|
||||||
>
|
{children}
|
||||||
{children}
|
</ClientLayout>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|||||||
457
app/page.tsx
457
app/page.tsx
@@ -1,65 +1,404 @@
|
|||||||
import Image from "next/image";
|
|
||||||
|
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import { Box, Container, Typography, Card, CardContent, CardMedia, Button, useMediaQuery, useTheme } from '@mui/material';
|
||||||
|
import AttachFileIcon from '@mui/icons-material/AttachFile';
|
||||||
|
import PublicIcon from '@mui/icons-material/Public';
|
||||||
|
import WindowIcon from '@mui/icons-material/Window';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
const isTablet = useMediaQuery(theme.breakpoints.down('md'));
|
||||||
|
|
||||||
|
// 功能数据
|
||||||
|
const features = [
|
||||||
|
{
|
||||||
|
icon: <PublicIcon fontSize="large" color="primary" style={{ fontSize: isMobile ? 32 : 48 }} />,
|
||||||
|
title: "云端访问",
|
||||||
|
description: "随时随地访问您的项目和文件,无需担心设备限制"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <WindowIcon fontSize="large" color="primary" style={{ fontSize: isMobile ? 32 : 48 }} />,
|
||||||
|
title: "响应式设计",
|
||||||
|
description: "完美适配各种设备,从手机到桌面电脑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <AttachFileIcon fontSize="large" color="primary" style={{ fontSize: isMobile ? 32 : 48 }} />,
|
||||||
|
title: "文件管理",
|
||||||
|
description: "高效管理您的所有项目文件,支持多种格式"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// 项目数据
|
||||||
|
const projects = [
|
||||||
|
{
|
||||||
|
name: "LeonPan",
|
||||||
|
description: "个人项目展示平台",
|
||||||
|
image: "/projects/leonpan/logo.png",
|
||||||
|
href: "/project/leonpan"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// 扩展服务类别数据
|
||||||
|
const services = [
|
||||||
|
{
|
||||||
|
name: "云盘服务",
|
||||||
|
description: "安全可靠的云存储解决方案",
|
||||||
|
icon: <AttachFileIcon />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "社区论坛",
|
||||||
|
description: "用户交流与分享的平台",
|
||||||
|
icon: <PublicIcon />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "编程语言",
|
||||||
|
description: "创新的编程语言开发",
|
||||||
|
icon: <WindowIcon />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "操作系统",
|
||||||
|
description: "轻量级操作系统解决方案",
|
||||||
|
icon: <WindowIcon />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "我的世界服务器",
|
||||||
|
description: "稳定高效的游戏服务器",
|
||||||
|
icon: <PublicIcon />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "加密语言",
|
||||||
|
description: "安全通信解决方案",
|
||||||
|
icon: <AttachFileIcon />
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen items-center justify-center bg-zinc-50 font-sans dark:bg-black">
|
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default' }}>
|
||||||
<main className="flex min-h-screen w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
|
{/* 英雄区域 */}
|
||||||
<Image
|
<Box sx={{
|
||||||
className="dark:invert"
|
bgcolor: 'primary.main',
|
||||||
src="/next.svg"
|
color: 'white',
|
||||||
alt="Next.js logo"
|
py: isMobile ? 10 : 16,
|
||||||
width={100}
|
px: 2,
|
||||||
height={20}
|
textAlign: 'center',
|
||||||
priority
|
position: 'relative',
|
||||||
/>
|
overflow: 'hidden',
|
||||||
<div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
|
'&::before': {
|
||||||
<h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
|
content: '""',
|
||||||
To get started, edit the page.tsx file.
|
position: 'absolute',
|
||||||
</h1>
|
top: 0,
|
||||||
<p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
|
left: 0,
|
||||||
Looking for a starting point or more instructions? Head over to{" "}
|
right: 0,
|
||||||
<a
|
bottom: 0,
|
||||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
background: 'radial-gradient(circle at 50% 50%, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 70%)',
|
||||||
className="font-medium text-zinc-950 dark:text-zinc-50"
|
zIndex: 1
|
||||||
>
|
}
|
||||||
Templates
|
}}>
|
||||||
</a>{" "}
|
<Container maxWidth="md" sx={{ position: 'relative', zIndex: 2 }}>
|
||||||
or the{" "}
|
<Typography
|
||||||
<a
|
variant={isMobile ? "h3" : "h2"}
|
||||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
component="h1"
|
||||||
className="font-medium text-zinc-950 dark:text-zinc-50"
|
gutterBottom
|
||||||
>
|
fontWeight="bold"
|
||||||
Learning
|
sx={{ mb: 3 }}
|
||||||
</a>{" "}
|
|
||||||
center.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
|
|
||||||
<a
|
|
||||||
className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
|
|
||||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
>
|
||||||
<Image
|
LeonCloud
|
||||||
className="dark:invert"
|
</Typography>
|
||||||
src="/vercel.svg"
|
<Typography
|
||||||
alt="Vercel logomark"
|
variant={isMobile ? "h6" : "h5"}
|
||||||
width={16}
|
paragraph
|
||||||
height={16}
|
sx={{ mb: 6, opacity: 0.9 }}
|
||||||
/>
|
|
||||||
Deploy Now
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]"
|
|
||||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
>
|
||||||
Documentation
|
LeonMMcoset的所有产品的运营商
|
||||||
</a>
|
</Typography>
|
||||||
</div>
|
<Typography
|
||||||
</main>
|
variant="body1"
|
||||||
</div>
|
paragraph
|
||||||
|
sx={{
|
||||||
|
maxWidth: 600,
|
||||||
|
mx: 'auto',
|
||||||
|
opacity: 0.8,
|
||||||
|
mb: 8,
|
||||||
|
fontSize: isMobile ? '1rem' : '1.1rem'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
覆盖云盘、论坛、编程语言、操作系统、我的世界服务器、加密语言等各种服务
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
paragraph
|
||||||
|
sx={{
|
||||||
|
fontWeight: 'bold',
|
||||||
|
fontSize: isMobile ? '1rem' : '1.1rem',
|
||||||
|
backgroundColor: 'rgba(255,255,255,0.1)',
|
||||||
|
py: 2,
|
||||||
|
px: 4,
|
||||||
|
borderRadius: 2,
|
||||||
|
display: 'inline-block'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
我们的宗旨是给用户提供简单、安全、高效、全方面的服务
|
||||||
|
</Typography>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 服务介绍区域 */}
|
||||||
|
<Box sx={{ py: isMobile ? 8 : 12, px: 2 }}>
|
||||||
|
<Container maxWidth="lg">
|
||||||
|
<Typography
|
||||||
|
variant={isMobile ? "h4" : "h3"}
|
||||||
|
component="h2"
|
||||||
|
align="center"
|
||||||
|
gutterBottom
|
||||||
|
fontWeight="bold"
|
||||||
|
sx={{ mb: 6 }}
|
||||||
|
>
|
||||||
|
我们的服务
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: { xs: 3, md: 4 }
|
||||||
|
}}>
|
||||||
|
{services.map((service, index) => (
|
||||||
|
<Box
|
||||||
|
key={index}
|
||||||
|
sx={{
|
||||||
|
width: { xs: '100%', sm: 'calc(50% - 16px)', md: 'calc(33.333% - 16px)' },
|
||||||
|
maxWidth: { xs: '100%', sm: 400, md: 350 },
|
||||||
|
bgcolor: 'background.paper',
|
||||||
|
borderRadius: 3,
|
||||||
|
boxShadow: 2,
|
||||||
|
p: 4,
|
||||||
|
transition: 'all 0.3s ease',
|
||||||
|
'&:hover': {
|
||||||
|
transform: 'translateY(-5px)',
|
||||||
|
boxShadow: 4,
|
||||||
|
},
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
textAlign: 'center'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box sx={{
|
||||||
|
mb: 3,
|
||||||
|
color: 'primary.main',
|
||||||
|
fontSize: isMobile ? 2.5 : 3
|
||||||
|
}}>
|
||||||
|
{service.icon}
|
||||||
|
</Box>
|
||||||
|
<Typography variant="h6" gutterBottom fontWeight="bold">
|
||||||
|
{service.name}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="text.secondary">
|
||||||
|
{service.description}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 项目展示区域 */}
|
||||||
|
<Box sx={{
|
||||||
|
py: isMobile ? 8 : 12,
|
||||||
|
px: 2,
|
||||||
|
bgcolor: 'grey.50'
|
||||||
|
}}>
|
||||||
|
<Container maxWidth="lg">
|
||||||
|
<Typography
|
||||||
|
variant={isMobile ? "h4" : "h3"}
|
||||||
|
component="h2"
|
||||||
|
align="center"
|
||||||
|
gutterBottom
|
||||||
|
fontWeight="bold"
|
||||||
|
sx={{ mb: 6 }}
|
||||||
|
>
|
||||||
|
精选项目
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: 4
|
||||||
|
}}>
|
||||||
|
{projects.map((project, index) => (
|
||||||
|
<Card
|
||||||
|
key={index}
|
||||||
|
sx={{
|
||||||
|
width: { xs: '100%', sm: 400, md: 500 },
|
||||||
|
maxWidth: '100%',
|
||||||
|
borderRadius: 3,
|
||||||
|
boxShadow: 3,
|
||||||
|
transition: 'all 0.3s ease',
|
||||||
|
'&:hover': {
|
||||||
|
transform: 'translateY(-5px)',
|
||||||
|
boxShadow: 6,
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CardMedia
|
||||||
|
component="img"
|
||||||
|
height={200}
|
||||||
|
image={project.image}
|
||||||
|
alt={project.name}
|
||||||
|
sx={{ objectFit: 'contain', padding: 3, bgcolor: 'background.paper' }}
|
||||||
|
/>
|
||||||
|
<CardContent sx={{ textAlign: 'center' }}>
|
||||||
|
<Typography variant="h5" component="h3" gutterBottom fontWeight="bold">
|
||||||
|
{project.name}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" color="text.secondary" paragraph sx={{ mb: 3 }}>
|
||||||
|
{project.description}
|
||||||
|
</Typography>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
size="large"
|
||||||
|
href={project.href}
|
||||||
|
fullWidth
|
||||||
|
sx={{ py: 1.2 }}
|
||||||
|
>
|
||||||
|
查看详情
|
||||||
|
</Button>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 优势亮点 */}
|
||||||
|
<Box sx={{ py: isMobile ? 8 : 12, px: 2 }}>
|
||||||
|
<Container maxWidth="lg">
|
||||||
|
<Typography
|
||||||
|
variant={isMobile ? "h4" : "h3"}
|
||||||
|
component="h2"
|
||||||
|
align="center"
|
||||||
|
gutterBottom
|
||||||
|
fontWeight="bold"
|
||||||
|
sx={{ mb: 6 }}
|
||||||
|
>
|
||||||
|
我们的优势
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: { xs: 4, md: 6 }
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
width: { xs: '100%', md: '45%' },
|
||||||
|
maxWidth: 500,
|
||||||
|
textAlign: isMobile ? 'center' : 'left',
|
||||||
|
mb: { xs: 4, md: 0 }
|
||||||
|
}}>
|
||||||
|
{features.map((feature, index) => (
|
||||||
|
<Box
|
||||||
|
key={index}
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: isMobile ? 'column' : 'row',
|
||||||
|
alignItems: isMobile ? 'center' : 'flex-start',
|
||||||
|
mb: 4,
|
||||||
|
gap: 3
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box sx={{ color: 'primary.main' }}>
|
||||||
|
{feature.icon}
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Typography variant="h6" gutterBottom fontWeight="bold">
|
||||||
|
{feature.title}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="text.secondary">
|
||||||
|
{feature.description}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box sx={{
|
||||||
|
width: { xs: '100%', md: '45%' },
|
||||||
|
maxWidth: 500,
|
||||||
|
bgcolor: 'primary.main',
|
||||||
|
color: 'white',
|
||||||
|
p: 6,
|
||||||
|
borderRadius: 3,
|
||||||
|
boxShadow: 4,
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center'
|
||||||
|
}}>
|
||||||
|
<Typography variant={isMobile ? "h5" : "h4"} gutterBottom fontWeight="bold">
|
||||||
|
我们的承诺
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{ height: 2, bgcolor: 'white', opacity: 0.3, mb: 4 }}></Box>
|
||||||
|
<ul style={{ paddingLeft: isMobile ? 0 : 20, margin: 0, listStyleType: isMobile ? 'none' : 'disc' }}>
|
||||||
|
<li style={{ marginBottom: 16, fontSize: isMobile ? '0.9rem' : '1rem' }}>
|
||||||
|
简单易用的界面设计
|
||||||
|
</li>
|
||||||
|
<li style={{ marginBottom: 16, fontSize: isMobile ? '0.9rem' : '1rem' }}>
|
||||||
|
企业级安全保障
|
||||||
|
</li>
|
||||||
|
<li style={{ marginBottom: 16, fontSize: isMobile ? '0.9rem' : '1rem' }}>
|
||||||
|
高效稳定的系统性能
|
||||||
|
</li>
|
||||||
|
<li style={{ marginBottom: 16, fontSize: isMobile ? '0.9rem' : '1rem' }}>
|
||||||
|
全方面的服务支持
|
||||||
|
</li>
|
||||||
|
<li style={{ fontSize: isMobile ? '0.9rem' : '1rem' }}>
|
||||||
|
持续创新的技术研发
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 页脚区域 */}
|
||||||
|
<Box sx={{ bgcolor: 'primary.dark', color: 'white', py: 8, px: 2 }}>
|
||||||
|
<Container maxWidth="lg">
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: isMobile ? 'column' : 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
mb: 6
|
||||||
|
}}>
|
||||||
|
<Typography variant="h5" gutterBottom fontWeight="bold">
|
||||||
|
LeonCloud
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" sx={{ opacity: 0.8 }}>
|
||||||
|
LeonMMcoset的所有产品的运营商
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box sx={{
|
||||||
|
height: 1,
|
||||||
|
bgcolor: 'white',
|
||||||
|
opacity: 0.1,
|
||||||
|
mb: 6
|
||||||
|
}}></Box>
|
||||||
|
|
||||||
|
<Typography variant="body2" align="center" paragraph>
|
||||||
|
© {new Date().getFullYear()} LeonCloud. 保留所有权利。
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="caption" align="center" color="rgba(255,255,255,0.7)">
|
||||||
|
我们的宗旨是给用户提供简单、安全、高效、全方面的服务
|
||||||
|
</Typography>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
357
app/project/leonpan/page.tsx
Normal file
357
app/project/leonpan/page.tsx
Normal file
@@ -0,0 +1,357 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { Box, Container, Typography, Card, CardContent, CardMedia, Button, useMediaQuery, useTheme, Tabs, Tab } from '@mui/material';
|
||||||
|
import { Code, Star, Download, GitHub, Link, Monitor, Smartphone, Storage } from '@mui/icons-material';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
export default function LeonPan() {
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
const isTablet = useMediaQuery(theme.breakpoints.down('md'));
|
||||||
|
const [currentTab, setCurrentTab] = useState(0);
|
||||||
|
|
||||||
|
// 项目截图
|
||||||
|
const screenshots = [
|
||||||
|
'/projects/leonpan/img1.png',
|
||||||
|
'/projects/leonpan/img2.png',
|
||||||
|
'/projects/leonpan/img3.png'
|
||||||
|
];
|
||||||
|
|
||||||
|
// 功能特点
|
||||||
|
const features = [
|
||||||
|
{
|
||||||
|
icon: <Monitor color="primary" style={{ fontSize: isMobile ? 24 : 32 }} />,
|
||||||
|
title: "Web支持",
|
||||||
|
description: "无需安装任何客户端就可以快速使用"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Smartphone color="primary" style={{ fontSize: isMobile ? 24 : 32 }} />,
|
||||||
|
title: "PC客户端",
|
||||||
|
description: "完美适配Windows 10以上的系统"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Storage color="primary" style={{ fontSize: isMobile ? 24 : 32 }} />,
|
||||||
|
title: "精美设计",
|
||||||
|
description: "提供简洁而专业的用户界面,操作方便"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Code color="primary" style={{ fontSize: isMobile ? 24 : 32 }} />,
|
||||||
|
title: "开源可定制",
|
||||||
|
description: "基于GPLv3协议开源,可自由修改和定制"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// 技术栈
|
||||||
|
// const techStack = [
|
||||||
|
// { name: "Go", level: 90 },
|
||||||
|
// { name: "Vue.js", level: 85 },
|
||||||
|
// { name: "Element UI", level: 80 },
|
||||||
|
// { name: "MySQL", level: 75 },
|
||||||
|
// { name: "Redis", level: 70 }
|
||||||
|
// ];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ minHeight: '100vh', bgcolor: 'background.default' }}>
|
||||||
|
{/* 项目头部 */}
|
||||||
|
<Box sx={{
|
||||||
|
bgcolor: 'primary.main',
|
||||||
|
color: 'white',
|
||||||
|
py: isMobile ? 8 : 12,
|
||||||
|
px: 2,
|
||||||
|
textAlign: 'center',
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
'&::after': {
|
||||||
|
content: '""',
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: -50,
|
||||||
|
right: -50,
|
||||||
|
width: 200,
|
||||||
|
height: 200,
|
||||||
|
borderRadius: '50%',
|
||||||
|
bgcolor: 'rgba(255,255,255,0.1)',
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<Container maxWidth="md" sx={{ position: 'relative', zIndex: 1 }}>
|
||||||
|
<Typography variant={isMobile ? "h3" : "h2"} component="h1" gutterBottom fontWeight="bold">
|
||||||
|
LeonPan
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" paragraph sx={{ maxWidth: 600, mx: 'auto', opacity: 0.9 }}>
|
||||||
|
LeonPan是一个开源项目,改编自Cloudreve开源项目,使用GPLv3协议开源。提供强大的文件管理功能。
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{ mt: 4, display: 'flex', flexWrap: 'wrap', gap: 2, justifyContent: 'center' }}>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
size={isMobile ? "small" : "medium"}
|
||||||
|
startIcon={<GitHub />}
|
||||||
|
sx={{ px: 3 }}
|
||||||
|
onClick={() => window.open('http://leonmmcoset.jjxmm.win:2000/leonmmcoset/leonpan', '_blank')}
|
||||||
|
>
|
||||||
|
Git仓库
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
color="inherit"
|
||||||
|
size={isMobile ? "small" : "medium"}
|
||||||
|
startIcon={<Download />}
|
||||||
|
sx={{ px: 3, borderColor: 'white', color: 'white', '&:hover': { borderColor: 'rgba(255,255,255,0.8)' } }}
|
||||||
|
onClick={() => window.open('http://leonmmcoset.jjxmm.win:5212/', '_blank')}
|
||||||
|
>
|
||||||
|
进入LeonAPP
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 项目概述 */}
|
||||||
|
<Box sx={{ py: isMobile ? 6 : 10, px: 2 }}>
|
||||||
|
<Container maxWidth="lg">
|
||||||
|
<Box sx={{ display: 'flex', flexDirection: isMobile ? 'column' : 'row', gap: isMobile ? 4 : 6, alignItems: 'center', width: '100%' }}>
|
||||||
|
<Box sx={{ width: '100%' }}>
|
||||||
|
<Typography variant={isMobile ? "h4" : "h3"} component="h2" gutterBottom fontWeight="bold">
|
||||||
|
项目概述
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" paragraph sx={{ mb: 3, color: 'text.secondary' }}>
|
||||||
|
LeonPan是基于Cloudreve开发的文件管理系统,提供了丰富的功能和友好的用户界面。
|
||||||
|
它支持多种存储方式,包括本地存储、对象存储等,可以满足不同用户的需求。
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" paragraph sx={{ mb: 3, color: 'text.secondary' }}>
|
||||||
|
项目致力于提供安全、稳定、高效的文件管理解决方案,适用于个人用户和团队协作场景。
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2, mt: 4 }}>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
|
<Star color="secondary" fontSize="small" style={{ fontSize: 16 }} />
|
||||||
|
<Typography variant="body2">开源免费</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
|
<Code color="primary" fontSize="small" style={{ fontSize: 16 }} />
|
||||||
|
<Typography variant="body2">GPLv3协议</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ width: '100%' }}>
|
||||||
|
<Card sx={{ boxShadow: 4, borderRadius: 2, overflow: 'hidden' }}>
|
||||||
|
<CardMedia
|
||||||
|
component="img"
|
||||||
|
height={isMobile ? 200 : 300}
|
||||||
|
image={screenshots[0]}
|
||||||
|
alt="LeonPan 截图"
|
||||||
|
sx={{ objectFit: 'cover' }}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 功能特点 */}
|
||||||
|
<Box sx={{ py: isMobile ? 6 : 10, px: 2, bgcolor: 'grey.50' }}>
|
||||||
|
<Container maxWidth="lg">
|
||||||
|
<Typography variant={isMobile ? "h4" : "h3"} component="h2" align="center" gutterBottom fontWeight="bold">
|
||||||
|
功能特点
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" align="center" paragraph sx={{ mb: 8, maxWidth: 600, mx: 'auto', color: 'text.secondary' }}>
|
||||||
|
LeonPan提供丰富的功能,满足您的文件管理需求
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box sx={{ display: 'flex', flexDirection: 'row', flexWrap: 'wrap', gap: isMobile ? 3 : 4, width: '100%' }}>
|
||||||
|
{features.map((feature, index) => (
|
||||||
|
<Box sx={{ width: isMobile ? '100%' : 'calc(50% - 16px)', key: index }}>
|
||||||
|
<Card sx={{
|
||||||
|
height: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
padding: 3,
|
||||||
|
boxShadow: 2,
|
||||||
|
borderRadius: 2,
|
||||||
|
transition: 'transform 0.3s, box-shadow 0.3s',
|
||||||
|
'&:hover': {
|
||||||
|
transform: 'translateY(-3px)',
|
||||||
|
boxShadow: 4,
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<Box sx={{ mr: 3, display: 'flex', alignItems: 'center', justifyContent: 'center', minWidth: 60 }}>
|
||||||
|
{feature.icon}
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Typography variant="h6" component="h3" gutterBottom fontWeight="bold">
|
||||||
|
{feature.title}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="text.secondary">
|
||||||
|
{feature.description}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Card>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 截图展示 */}
|
||||||
|
<Box sx={{ py: isMobile ? 6 : 10, px: 2 }}>
|
||||||
|
<Container maxWidth="lg">
|
||||||
|
<Typography variant={isMobile ? "h4" : "h3"} component="h2" align="center" gutterBottom fontWeight="bold">
|
||||||
|
界面展示
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" align="center" paragraph sx={{ mb: 8, maxWidth: 600, mx: 'auto', color: 'text.secondary' }}>
|
||||||
|
查看LeonPan的精美界面
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
{/* 截图切换标签 */}
|
||||||
|
{!isMobile && (
|
||||||
|
<Box sx={{ mb: 4, display: 'flex', justifyContent: 'center' }}>
|
||||||
|
<Tabs
|
||||||
|
value={currentTab}
|
||||||
|
onChange={(_, newValue) => setCurrentTab(newValue)}
|
||||||
|
variant="scrollable"
|
||||||
|
scrollButtons="auto"
|
||||||
|
indicatorColor="primary"
|
||||||
|
textColor="primary"
|
||||||
|
>
|
||||||
|
{screenshots.map((_, index) => (
|
||||||
|
<Tab key={index} label={`截图 ${index + 1}`} />
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 主要截图展示 */}
|
||||||
|
<Box sx={{ textAlign: 'center' }}>
|
||||||
|
<Card sx={{ display: 'inline-block', boxShadow: 5, borderRadius: 2, overflow: 'hidden', maxWidth: '100%' }}>
|
||||||
|
<CardMedia
|
||||||
|
component="img"
|
||||||
|
height={isMobile ? 250 : 400}
|
||||||
|
image={screenshots[currentTab]}
|
||||||
|
alt={`LeonPan 截图 ${currentTab + 1}`}
|
||||||
|
sx={{ objectFit: 'contain', maxWidth: '100%' }}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 移动端缩略图导航 */}
|
||||||
|
{isMobile && (
|
||||||
|
<Box sx={{ mt: 4, display: 'flex', gap: 2, justifyContent: 'center', overflowX: 'auto', pb: 2 }}>
|
||||||
|
{screenshots.map((screenshot, index) => (
|
||||||
|
<Button
|
||||||
|
key={index}
|
||||||
|
variant={currentTab === index ? "contained" : "outlined"}
|
||||||
|
size="small"
|
||||||
|
onClick={() => setCurrentTab(index)}
|
||||||
|
sx={{
|
||||||
|
minWidth: 60,
|
||||||
|
height: 60,
|
||||||
|
p: 1,
|
||||||
|
border: currentTab === index ? 0 : 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={screenshot}
|
||||||
|
alt={`缩略图 ${index + 1}`}
|
||||||
|
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 技术栈 */}
|
||||||
|
{/* <Box sx={{ py: isMobile ? 6 : 10, px: 2, bgcolor: 'grey.50' }}>
|
||||||
|
<Container maxWidth="lg">
|
||||||
|
<Typography variant={isMobile ? "h4" : "h3"} component="h2" align="center" gutterBottom fontWeight="bold">
|
||||||
|
技术栈
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" align="center" paragraph sx={{ mb: 8, maxWidth: 600, mx: 'auto', color: 'text.secondary' }}>
|
||||||
|
LeonPan基于现代技术栈开发,保证系统的高性能和稳定性
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box sx={{ display: 'flex', flexDirection: 'row', flexWrap: 'wrap', gap: isMobile ? 3 : 4, width: '100%' }}>
|
||||||
|
{techStack.map((tech, index) => (
|
||||||
|
<Box sx={{ width: isMobile ? '100%' : isTablet ? 'calc(50% - 16px)' : 'calc(33.333% - 20px)', key: index }}>
|
||||||
|
<Card sx={{
|
||||||
|
height: '100%',
|
||||||
|
boxShadow: 2,
|
||||||
|
borderRadius: 2,
|
||||||
|
transition: 'transform 0.3s, box-shadow 0.3s',
|
||||||
|
'&:hover': {
|
||||||
|
transform: 'translateY(-3px)',
|
||||||
|
boxShadow: 4,
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<CardContent>
|
||||||
|
<Typography variant="h6" component="h3" gutterBottom fontWeight="bold">
|
||||||
|
{tech.name}
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{ mt: 2 }}>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>
|
||||||
|
<Typography variant="caption" color="text.secondary" sx={{ minWidth: 40 }}>
|
||||||
|
熟练度
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="caption" color="text.secondary">
|
||||||
|
{tech.level}%
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
width: '100%',
|
||||||
|
height: 8,
|
||||||
|
bgcolor: 'grey.200',
|
||||||
|
borderRadius: 4,
|
||||||
|
overflow: 'hidden'
|
||||||
|
}}>
|
||||||
|
<Box sx={{
|
||||||
|
width: `${tech.level}%`,
|
||||||
|
height: '100%',
|
||||||
|
bgcolor: 'primary.main',
|
||||||
|
borderRadius: 4,
|
||||||
|
transition: 'width 0.5s ease-in-out'
|
||||||
|
}} />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</Box> */}
|
||||||
|
|
||||||
|
{/* 行动号召 */}
|
||||||
|
<Box sx={{ py: isMobile ? 8 : 12, px: 2, bgcolor: 'primary.main', color: 'white', textAlign: 'center' }}>
|
||||||
|
<Container maxWidth="md">
|
||||||
|
<Typography variant={isMobile ? "h4" : "h3"} component="h2" gutterBottom fontWeight="bold">
|
||||||
|
开始使用 LeonPan
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" paragraph sx={{ mb: 6, opacity: 0.9 }}>
|
||||||
|
立即体验LeonPan带来的高效文件管理体验,开源免费,功能强大
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 3, justifyContent: 'center' }}>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
size={isMobile ? "small" : "large"}
|
||||||
|
startIcon={<GitHub />}
|
||||||
|
sx={{ px: 4, py: 1.5 }}
|
||||||
|
onClick={() => window.open('http://leonmmcoset.jjxmm.win:2000/leonmmcoset/leonpan', '_blank')}
|
||||||
|
>
|
||||||
|
访问Git仓库
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
color="inherit"
|
||||||
|
size={isMobile ? "small" : "large"}
|
||||||
|
startIcon={<Download />}
|
||||||
|
sx={{ px: 4, py: 1.5, borderColor: 'white', color: 'white', '&:hover': { borderColor: 'rgba(255,255,255,0.8)' } }}
|
||||||
|
onClick={() => window.open('http://leonmmcoset.jjxmm.win:5212/', '_blank')}
|
||||||
|
>
|
||||||
|
立即访问LeonAPP
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
857
package-lock.json
generated
857
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,11 @@
|
|||||||
"lint": "eslint"
|
"lint": "eslint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@emotion/react": "^11.14.0",
|
||||||
|
"@emotion/styled": "^11.14.1",
|
||||||
|
"@mui/base": "^5.0.0-beta.70",
|
||||||
|
"@mui/icons-material": "^7.3.5",
|
||||||
|
"@mui/material": "^7.3.5",
|
||||||
"next": "16.0.3",
|
"next": "16.0.3",
|
||||||
"react": "19.2.0",
|
"react": "19.2.0",
|
||||||
"react-dom": "19.2.0"
|
"react-dom": "19.2.0"
|
||||||
|
|||||||
BIN
public/projects/leonpan/img1.png
Normal file
BIN
public/projects/leonpan/img1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
BIN
public/projects/leonpan/img2.png
Normal file
BIN
public/projects/leonpan/img2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 359 KiB |
BIN
public/projects/leonpan/img3.png
Normal file
BIN
public/projects/leonpan/img3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 251 KiB |
BIN
public/projects/leonpan/logo.png
Normal file
BIN
public/projects/leonpan/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 219 KiB |
Reference in New Issue
Block a user