feat: 🎸 complete layout for home, login and register pages

- 完成首页整体布局:顶栏(标题、主题切换、头像)、主区(侧边栏与内容区域)、底部  - 完成登录页与注册页的界面搭建  -
本次仅实现界面,功能逻辑尚未接入
This commit is contained in:
2025-11-21 23:12:21 +08:00
parent fde23217a6
commit 3302421371
14 changed files with 276 additions and 12 deletions

View File

@@ -1,2 +1,20 @@
@import "tailwindcss";
@plugin "daisyui";
@import 'tailwindcss';
@plugin 'daisyui';
html,
body,
#root {
padding: 0;
margin: 0;
width: 100vw;
height: 100vh;
justify-items: center;
box-sizing: border-box;
overflow: hidden;
}
*,
*::before,
*::after {
box-sizing: inherit;
}

View File

@@ -1,12 +1,8 @@
import "./App.css";
import './App.css';
import { Home } from '~/pages';
function App() {
return (
<main class='container'>
</main>
);
return <Home />;
}
export default App;

BIN
src/assets/avatar.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -0,0 +1,14 @@
const Footer = () => {
return (
<footer class="flex h-10 w-full items-center justify-between border-t border-gray-400 bg-gray-300 px-5">
<span>Copyright &copy 2025 Zhilv</span>
<span class="text-blue-400 dark:text-blue-600">
<a href="https://www.kmux.cn" target="_blank">
</a>
</span>
</footer>
);
};
export default Footer;

View File

@@ -0,0 +1,68 @@
import { Component, Show } from 'solid-js';
import avatarSvg from '~/assets/avatar.jpg';
interface HeaderProps {
isAvatar?: boolean;
}
const Header: Component<HeaderProps> = ({ isAvatar = true }) => {
return (
<header class="flex h-16 w-screen flex-row items-center justify-center space-x-5 border-b border-gray-500 bg-pink-100 px-5">
<span class="flex flex-1 justify-center text-4xl"></span>
<label class="toggle text-base-content toggle-xl rounded-full">
<input type="checkbox" value="synthwave" class="theme-controller" />
<svg
aria-label="sun"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<g
stroke-linejoin="round"
stroke-linecap="round"
stroke-width="2"
fill="none"
stroke="currentColor"
>
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="m4.93 4.93 1.41 1.41"></path>
<path d="m17.66 17.66 1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="m6.34 17.66-1.41 1.41"></path>
<path d="m19.07 4.93-1.41 1.41"></path>
</g>
</svg>
<svg
aria-label="moon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<g
stroke-linejoin="round"
stroke-linecap="round"
stroke-width="2"
fill="none"
stroke="currentColor"
>
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path>
</g>
</svg>
</label>
<Show when={isAvatar}>
<details class="dropdown dropdown-end">
<summary class="avatar">
<img src={avatarSvg} alt="" class="w-13 rounded-xl" />
</summary>
<ul class="menu dropdown-content bg-base-100 rounded-box z-1 w-16 space-y-1 p-2 text-center">
<li></li>
<li>退</li>
</ul>
</details>
</Show>
</header>
);
};
export default Header;

View File

@@ -0,0 +1,17 @@
import { A } from '@solidjs/router';
const Main = () => {
return (
<main class="flex w-full flex-1 items-center bg-red-100">
<nav class="menu h-full w-25 space-y-2 border-r border-gray-300 bg-red-200/30 text-center text-lg shadow-lg shadow-gray-400">
<span class="text-2xl"></span>
<div class="divider"></div>
<A href="/"></A>
<A href="/auth/login"></A>
<A href="/auth/register"></A>
</nav>
</main>
);
};
export default Main;

View File

@@ -0,0 +1,5 @@
import Header from './Header';
import Main from './Main';
import Footer from './Footer';
export { Header, Main, Footer };

View File

@@ -0,0 +1,19 @@
import { Component, JSX } from 'solid-js';
interface CardProps {
title: string;
children?: JSX.Element;
}
const Card: Component<CardProps> = ({ title, children }) => {
return (
<div class="card h-100 w-150 items-center justify-center rounded-xl border border-pink-300 bg-red-200/30 shadow-xl shadow-red-300/50">
<span class="card-title text-3xl">{title}</span>
<div class="mt-10 flex-col justify-center space-y-5 text-center">
{children}
</div>
</div>
);
};
export default Card;

View File

@@ -0,0 +1,3 @@
import Card from './Card';
export { Card };

View File

@@ -1,5 +1,32 @@
/* @refresh reload */
import { render } from "solid-js/web";
import App from "./App";
import { render } from 'solid-js/web';
import { Router } from '@solidjs/router';
import { children, lazy } from 'solid-js';
render(() => <App />, document.getElementById("root") as HTMLElement);
const wrapper = document.getElementById('root');
if (!wrapper) {
throw new Error('Wrapper div not found');
}
const routes = [
{
path: '/',
component: lazy(() => import('~/App')),
},
{
path: '/auth',
children: [
{
path: '/login',
component: lazy(() => import('~/pages/Login')),
},
{
path: '/register',
component: lazy(() => import('~/pages/Register')),
},
],
},
];
render(() => <Router>{routes}</Router>, wrapper);

13
src/pages/Home.tsx Normal file
View File

@@ -0,0 +1,13 @@
import { Header, Main, Footer } from '~/components/layout';
const Home = () => {
return (
<div class="flex h-full w-full flex-col rounded-lg bg-gray-100">
<Header />
<Main />
<Footer />
</div>
);
};
export default Home;

40
src/pages/Login.tsx Normal file
View File

@@ -0,0 +1,40 @@
import { A } from '@solidjs/router';
import { Header, Footer } from '~/components/layout';
import { Card } from '~/components/ui';
const Login = () => {
return (
<div class="flex h-full w-full flex-col">
<Header isAvatar={false} />
<div class="flex w-full flex-1 items-center justify-center rounded-xl bg-red-100">
<Card title="登录界面">
<input
type="text"
class="input w-full rounded-xl"
placeholder="请输入用户名"
/>
<input
type="password"
class="input w-full"
placeholder="请输入密码"
/>
<div class="flex justify-center">
<button class="btn w-full"></button>
</div>
<div class="mt-10 flex-col justify-center space-y-5"></div>
<div class="m-2">
<span class="text-sm font-bold">
<A href="/auth/register" class="text-blue-400">
</A>
</span>
</div>
</Card>
</div>
<Footer />
</div>
);
};
export default Login;

39
src/pages/Register.tsx Normal file
View File

@@ -0,0 +1,39 @@
import { A } from '@solidjs/router';
import { Header, Footer } from '~/components/layout';
import { Card } from '~/components/ui';
const Register = () => {
return (
<div class="flex h-full w-full flex-col">
<Header isAvatar={false} />
<div class="flex w-full flex-1 items-center justify-center rounded-xl bg-red-100">
<Card title="注册界面">
<input
type="text"
class="input w-full rounded-xl"
placeholder="请输入用户名"
/>
<input
type="password"
class="input w-full"
placeholder="请输入密码"
/>
<div class="flex justify-center">
<button class="btn w-full"></button>
</div>
<div class="m-2">
<span class="text-sm font-bold">
<A href="/auth/login" class="text-blue-400">
</A>
</span>
</div>
</Card>
</div>
<Footer />
</div>
);
};
export default Register;

5
src/pages/index.ts Normal file
View File

@@ -0,0 +1,5 @@
import Home from './Home';
import Login from './Login';
import Register from './Register';
export { Home, Login, Register };