update: components

mack-mac
mackt 8 months ago
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,44 +1,46 @@
import Image from 'next/image';
import LoginForm from './LoginForm';
export default function LoginCard() {
return (
<div className="fixed inset-0 flex justify-center pt-[30vh] z-50">
{/* 遮罩层 */}
<div className="fixed inset-0 bg-black opacity-50"></div>
{/* 登录框 */}
<div className="relative flex flex-col w-[420px] h-[470px] pt-[49px] p-[40px] rounded-[24px] bg-[#fff] z-10">
{/* title */}
<div className="mb-[30px]">
<p className="text-[24px] leading-[33px] text-[#000] font-bold"></p>
<p className="mt-[6px] text-[13px] leading-[18px] text-[rgba(0,0,0,0.7)]">
</p>
</div>
{/* close-btn */}
<Image
className="absolute top-[24px] right-[24px] cursor-pointer"
width={24}
height={24}
src="/img/icon/close.svg"
alt="close"
/>
{/* form */}
<LoginForm />
<div className="absolute bottom-[30px] left-0 right-0 text-[13px] leading-[18px] text-[rgba(0,0,0,0.4)] text-center">
{' '}
<a className="text-[#000]" href="">
</a>
<a className="text-[#000]" href="">
</a>
</div>
</div>
</div>
);
}
import Image from 'next/image';
import LoginForm from './LoginForm';
export default function LoginCard({ onClose }: { onClose: () => void }) {
return (
<div className="fixed inset-0 flex justify-center pt-[30vh] z-50">
{/* 遮罩层 */}
<div className="fixed inset-0 bg-black opacity-50"></div>
{/* 登录框 */}
<div className="relative flex flex-col w-[420px] h-[470px] pt-[49px] p-[40px] rounded-[24px] bg-[#fff] z-10">
{/* title */}
<div className="mb-[30px]">
<p className="text-[24px] leading-[33px] text-[#000] font-bold"></p>
<p className="mt-[6px] text-[13px] leading-[18px] text-[rgba(0,0,0,0.7)]">
</p>
</div>
{/* close-btn */}
<Image
className="absolute top-[24px] right-[24px] cursor-pointer"
width={24}
height={24}
src="/img/icon/close.svg"
alt="close"
onClick={onClose}
/>
{/* form */}
<LoginForm onClose={onClose} />
<div className="absolute bottom-[30px] left-0 right-0 text-[13px] leading-[18px] text-[rgba(0,0,0,0.4)] text-center">
{' '}
<a className="text-[#000]" href="">
</a>
<a className="text-[#000]" href="">
</a>
</div>
</div>
</div>
);
}

@ -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…
Cancel
Save