parent
ef9877a312
commit
3377801fcd
@ -1,29 +1,33 @@
|
||||
@import '@unocss/reset/tailwind.css';
|
||||
@unocss all;
|
||||
|
||||
:root {
|
||||
--body-bg-color: #fff;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
}
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--body-bg-color);
|
||||
font-family: 'PingFang SC-Regular', Helvetica;
|
||||
/* padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom); */
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.text-balance {
|
||||
text-wrap: balance;
|
||||
}
|
||||
}
|
||||
@import '@unocss/reset/tailwind.css';
|
||||
@unocss all;
|
||||
|
||||
:root {
|
||||
--body-bg-color: #fff;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
}
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--body-bg-color);
|
||||
font-family: 'PingFang SC-Regular', Helvetica;
|
||||
/* padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom); */
|
||||
}
|
||||
|
||||
input {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.text-balance {
|
||||
text-wrap: balance;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
import Image from 'next/image';
|
||||
|
||||
const Avatar = ({ src, alt, size }: { src: string; alt: string; size: number }) => {
|
||||
return (
|
||||
<div className={`rounded-[50%] bg-[#fff] overflow-hidden`} style={{ width: size, height: size }}>
|
||||
<Image className="w-full h-full object-cover" width={size} height={size} src={src} alt={alt} unoptimized />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Avatar;
|
@ -1,51 +1,63 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
import { Logo, LoginCard } from '@/components';
|
||||
|
||||
export default function Header() {
|
||||
const pathName = usePathname();
|
||||
|
||||
const menuList = [
|
||||
{
|
||||
name: '首页',
|
||||
path: '/',
|
||||
},
|
||||
{
|
||||
name: 'APP下载',
|
||||
path: '/download',
|
||||
},
|
||||
{
|
||||
name: '关于我们',
|
||||
path: '/about',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<header className="absolute top-0 w-full h-[80px]">
|
||||
<div className="w-[1200px] h-full mx-auto flex items-center justify-between">
|
||||
<Logo />
|
||||
|
||||
<div className="h-full flex flex-row items-center">
|
||||
<ul className="mr-[40px] flex flex-row items-center space-x-[40px]">
|
||||
{menuList.map(({ name, path }) => (
|
||||
<li
|
||||
key={path}
|
||||
className={`text-[18px] leading-[25.2px] hover:text-[rgba(0,0,0,0.95)] ${pathName === path ? 'text-[rgba(0,0,0,0.95)]' : 'text-[rgba(0,0,0,0.4)]'}`}
|
||||
>
|
||||
<Link href={path}>{name}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<button className="w-[74px] h-[36px] border-[#000] border-[1.5px] rounded-[60px] text-[17px]">登录</button>
|
||||
</div>
|
||||
|
||||
{/* 登录框 */}
|
||||
{/* <LoginCard /> */}
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
'use client';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
import { Logo, LoginModal } from '@/components';
|
||||
|
||||
export default function Header() {
|
||||
const pathName = usePathname();
|
||||
|
||||
const menuList = [
|
||||
{
|
||||
name: '首页',
|
||||
path: '/',
|
||||
},
|
||||
{
|
||||
name: 'APP下载',
|
||||
path: '/download',
|
||||
},
|
||||
{
|
||||
name: '关于我们',
|
||||
path: '/about',
|
||||
},
|
||||
];
|
||||
|
||||
const [showLoginModal, setShowLoginModal] = useState(false);
|
||||
|
||||
const handleLoginModalToggle = () => {
|
||||
setShowLoginModal(!showLoginModal);
|
||||
};
|
||||
|
||||
return (
|
||||
<header className="absolute top-0 w-full h-[80px]">
|
||||
<div className="w-[1200px] h-full mx-auto flex items-center justify-between">
|
||||
<Logo />
|
||||
|
||||
<div className="h-full flex flex-row items-center">
|
||||
<ul className="mr-[40px] flex flex-row items-center space-x-[40px]">
|
||||
{menuList.map(({ name, path }) => (
|
||||
<li
|
||||
key={path}
|
||||
className={`text-[18px] leading-[25.2px] hover:text-[rgba(0,0,0,0.95)] ${pathName === path ? 'text-[rgba(0,0,0,0.95)]' : 'text-[rgba(0,0,0,0.4)]'}`}
|
||||
>
|
||||
<Link href={path}>{name}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<button
|
||||
className="w-[74px] h-[36px] border-[#000] border-[1.5px] rounded-[60px] text-[17px]"
|
||||
onClick={handleLoginModalToggle}
|
||||
>
|
||||
登录
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 登录框 */}
|
||||
{showLoginModal && <LoginModal onClose={handleLoginModalToggle} />}
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import Input from '@/components/common/Input';
|
||||
|
||||
export default function LoginForm({ onClose }: { onClose: () => void }) {
|
||||
const [phone, setPhone] = useState('');
|
||||
const [authCode, seAuthCode] = useState('');
|
||||
|
||||
const handleLogin = () => {
|
||||
event.preventDefault();
|
||||
console.log(phone, authCode);
|
||||
onClose();
|
||||
};
|
||||
|
||||
const handleGetAuthCode = () => {
|
||||
event.preventDefault();
|
||||
console.log('获取验证码');
|
||||
};
|
||||
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>, fn: (text: string) => void) => {
|
||||
const inputValue = e.target.value;
|
||||
const regex = /^[0-9]*$/; // 只允许输入数字
|
||||
|
||||
if (regex.test(inputValue) || inputValue === '') {
|
||||
fn(e.target.value);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
// <form className="space-y-4" onSubmit={handleSubmit(onSubmit)} autoComplete="off">
|
||||
<form autoComplete="off">
|
||||
<div className="w-full flex flex-col">
|
||||
<Input
|
||||
type="text"
|
||||
value={phone}
|
||||
maxLength={11}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleInputChange(e, setPhone)}
|
||||
placeholder="输入手机号"
|
||||
/>
|
||||
|
||||
<div className="relative w-full mt-[20px]">
|
||||
<Input
|
||||
className="w-full"
|
||||
type="text"
|
||||
value={authCode}
|
||||
maxLength={4}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleInputChange(e, seAuthCode)}
|
||||
placeholder="输入验证码"
|
||||
/>
|
||||
<button
|
||||
className="absolute top-[6px] right-[6px] w-[123px] h-[44px] rounded-[100px] bg-[#000] color-[#fff] font-size-[14px] leading-[20px]"
|
||||
onClick={handleGetAuthCode}
|
||||
>
|
||||
获取验证码
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button className="w-full h-[56px] mt-[30px] rounded-[100px] bg-[#B44343] color-[#fff]" onClick={handleLogin}>
|
||||
确定登录
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
import Input from '@/components/common/Input';
|
||||
|
||||
export default function LoginForm(props: any) {
|
||||
//? Focus On Mount
|
||||
// useEffect(() => {
|
||||
// setFocus('email');
|
||||
// }, []);
|
||||
|
||||
return (
|
||||
// <form className="space-y-4" onSubmit={handleSubmit(onSubmit)} autoComplete="off">
|
||||
<form autoComplete="off">
|
||||
<div className="w-full flex flex-col">
|
||||
<Input type="number" value="" onChange={() => {}} placeholder="输入手机号" />
|
||||
|
||||
<div className="relative w-full mt-[20px]">
|
||||
<Input className="w-full" type="number" value="" onChange={() => {}} placeholder="输入验证码" />
|
||||
<button className="absolute top-[6px] right-[6px] w-[123px] h-[44px] rounded-[100px] bg-[#000] color-[#fff] font-size-[14px] leading-[20px]">
|
||||
获取验证码
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button className="w-full h-[56px] mt-[30px] rounded-[100px] bg-[#B44343] color-[#fff]">确定登录</button>
|
||||
</form>
|
||||
);
|
||||
}
|
@ -1,13 +1,28 @@
|
||||
const Input = ({ type, value, onChange, placeholder, className = '' }) => {
|
||||
return (
|
||||
<input
|
||||
className={`w-full h-[56px] py-[18px] pl-[39px] rounded-[100px] px-[14px] bg-[#F2F3F7] leading-[20px] ${className}`}
|
||||
type={type}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Input;
|
||||
const Input = ({
|
||||
type,
|
||||
value,
|
||||
placeholder,
|
||||
maxLength = undefined,
|
||||
className = '',
|
||||
onChange,
|
||||
}: {
|
||||
type: string;
|
||||
value: string | number;
|
||||
placeholder?: string;
|
||||
maxLength?: number;
|
||||
className?: string;
|
||||
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
}) => {
|
||||
return (
|
||||
<input
|
||||
className={`w-full h-[56px] py-[18px] pl-[39px] rounded-[100px] px-[14px] bg-[#F2F3F7] leading-[20px] ${className}`}
|
||||
type={type}
|
||||
value={value}
|
||||
placeholder={placeholder}
|
||||
maxLength={maxLength || undefined}
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Input;
|
||||
|
@ -1,9 +1,9 @@
|
||||
export { default as Logo } from './Logo';
|
||||
export { default as Header } from './Header';
|
||||
export { default as Footer } from './Footer';
|
||||
|
||||
export { default as LoginCard } from './LoginCard';
|
||||
export { default as LoginForm } from './LoginForm';
|
||||
|
||||
// Common
|
||||
export { default as Input } from './common/Input';
|
||||
export { default as Logo } from './Logo';
|
||||
export { default as Header } from './Header';
|
||||
export { default as Footer } from './Footer';
|
||||
|
||||
export { default as LoginModal } from './Login/LoginModal';
|
||||
export { default as LoginForm } from './Login/LoginForm';
|
||||
|
||||
// Common
|
||||
export { default as Input } from './common/Input';
|
||||
|
Loading…
Reference in new issue