feat: 登录
This commit is contained in:
parent
166986e31f
commit
e8da3e4c5a
|
@ -17,11 +17,6 @@ body {
|
|||
|
||||
#bs-app {
|
||||
position: relative;
|
||||
> main {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes gradient {
|
||||
|
|
|
@ -64,3 +64,10 @@ header {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sms-group {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
column-gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,60 @@
|
|||
import "./index.less";
|
||||
import { Input, Space } from "@arco-design/web-react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { routerList } from "../../router";
|
||||
import {
|
||||
Input,
|
||||
Modal,
|
||||
Form,
|
||||
Message,
|
||||
Button,
|
||||
Space,
|
||||
Radio,
|
||||
Tooltip,
|
||||
} from "@arco-design/web-react";
|
||||
import FormItem from "@arco-design/web-react/es/Form/form-item";
|
||||
const InputSearch = Input.Search;
|
||||
const RadioGroup = Radio.Group;
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import Row from "@arco-design/web-react/es/Table/summary/row";
|
||||
import Col from "@arco-design/web-react/es/Grid/col";
|
||||
|
||||
type TLoginMethod = "usePass" | "useSms";
|
||||
|
||||
const DURATION = 120; // 验证码倒计时
|
||||
|
||||
function Nav() {
|
||||
const navigate = useNavigate();
|
||||
const [loginForm] = Form.useForm();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [confirmLoading, setConfirmLoading] = useState(false);
|
||||
const [loginMethod, setLoginMethod] = useState<TLoginMethod>("useSms");
|
||||
let [countdown, setCountdown] = useState(DURATION);
|
||||
const timer = useRef<any>();
|
||||
|
||||
const onOk = () => {
|
||||
loginForm.validate().then((res) => {
|
||||
setConfirmLoading(true);
|
||||
setTimeout(() => {
|
||||
Message.success("Success !");
|
||||
setVisible(false);
|
||||
setConfirmLoading(false);
|
||||
}, 1500);
|
||||
});
|
||||
};
|
||||
|
||||
const onClickSmsBtn = () => {
|
||||
setTimeout(() => {
|
||||
Message.success("验证码已发送");
|
||||
timer.current = setInterval(() => setCountdown(countdown--), 1000);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (countdown === 0) {
|
||||
clearInterval(timer.current);
|
||||
setCountdown(DURATION);
|
||||
}
|
||||
}, [countdown]);
|
||||
|
||||
return (
|
||||
<header>
|
||||
|
@ -34,8 +83,57 @@ function Nav() {
|
|||
<InputSearch allowClear placeholder="搜索" style={{ width: 150 }} />
|
||||
</div>
|
||||
<div className="end">
|
||||
<span>注册</span>
|
||||
<span>登录</span>
|
||||
<span onClick={() => setVisible(true)}>登录</span>
|
||||
<Modal
|
||||
title={
|
||||
<RadioGroup
|
||||
type="button"
|
||||
defaultValue="useSms"
|
||||
onChange={(e) => setLoginMethod(e)}
|
||||
>
|
||||
<Radio value="useSms">验证码</Radio>
|
||||
<Radio value="usePass">密码</Radio>
|
||||
</RadioGroup>
|
||||
}
|
||||
style={{ width: "360px" }}
|
||||
visible={visible}
|
||||
onOk={onOk}
|
||||
okText="登录"
|
||||
cancelText="取消"
|
||||
closeIcon={false}
|
||||
confirmLoading={confirmLoading}
|
||||
onCancel={() => setVisible(false)}
|
||||
>
|
||||
<Form form={loginForm} layout="vertical">
|
||||
<FormItem field="用户名" rules={[{ required: true }]} label="">
|
||||
<Input size="large" placeholder="用户名/手机号" />
|
||||
</FormItem>
|
||||
{loginMethod === "useSms" ? (
|
||||
<FormItem required style={{ marginBottom: 0 }}>
|
||||
<div className="sms-group">
|
||||
<Input size="large" placeholder="验证码" type="text" />
|
||||
<Button
|
||||
size="large"
|
||||
type="primary"
|
||||
onClick={onClickSmsBtn}
|
||||
disabled={countdown !== DURATION}
|
||||
>
|
||||
{countdown === DURATION ? "获取验证码" : `${countdown}s`}
|
||||
</Button>
|
||||
</div>
|
||||
</FormItem>
|
||||
) : (
|
||||
<FormItem
|
||||
field="密码"
|
||||
rules={[{ required: true }]}
|
||||
style={{ marginBottom: 0 }}
|
||||
label=""
|
||||
>
|
||||
<Input size="large" type="password" placeholder="密码" />
|
||||
</FormItem>
|
||||
)}
|
||||
</Form>
|
||||
</Modal>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
|
50
apps/web-main/src/components/Nav/loginModal.tsx
Normal file
50
apps/web-main/src/components/Nav/loginModal.tsx
Normal file
|
@ -0,0 +1,50 @@
|
|||
import { Form, Input, Message, Modal } from "@arco-design/web-react";
|
||||
import FormItem from "@arco-design/web-react/es/Form/form-item";
|
||||
import { useState } from "react";
|
||||
|
||||
function LoginModal() {
|
||||
const [loginForm] = Form.useForm();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [confirmLoading, setConfirmLoading] = useState(false);
|
||||
|
||||
const onOk = () => {
|
||||
loginForm.validate().then((res) => {
|
||||
setConfirmLoading(true);
|
||||
setTimeout(() => {
|
||||
Message.success("Success !");
|
||||
setVisible(false);
|
||||
setConfirmLoading(false);
|
||||
}, 1500);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
style={{ width: "400px" }}
|
||||
visible={visible}
|
||||
onOk={onOk}
|
||||
okText="登录"
|
||||
cancelText="取消"
|
||||
closeIcon={false}
|
||||
confirmLoading={confirmLoading}
|
||||
onCancel={() => setVisible(false)}
|
||||
>
|
||||
<Form form={loginForm} layout="vertical">
|
||||
<FormItem field="username" rules={[{ required: true }]} label="">
|
||||
<Input placeholder="用户名/手机号" />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
required
|
||||
field="password"
|
||||
rules={[{ required: true }]}
|
||||
style={{ marginBottom: 0 }}
|
||||
label=""
|
||||
>
|
||||
<Input placeholder="密码" type="password" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default LoginModal;
|
|
@ -1,43 +1,132 @@
|
|||
.subscribe {
|
||||
padding: 100px 0 20px 0;
|
||||
padding-top: 100px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
// background: linear-gradient(
|
||||
// to right bottom,
|
||||
// hsl(0deg 0% 100%),
|
||||
// hsl(222deg 92% 65% / 13%)
|
||||
// );
|
||||
// background: linear-gradient(
|
||||
// to right bottom,
|
||||
// hsl(0, 0%, 100%),
|
||||
// hsl(0deg 0% 0% / 21%)
|
||||
// );
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
background-image: url(https://images.unsplash.com/photo-1483794344563-d27a8d18014e?ixlib=rb-0.3.5&s=62d4e79…&auto=format&fit=crop&w=1950&q=80);
|
||||
h2 {
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
}
|
||||
h4 {
|
||||
text-align: center;
|
||||
font-weight: 400;
|
||||
color: var(--color-text-4);
|
||||
color: var(--color-text-3);
|
||||
}
|
||||
.options {
|
||||
padding-top: 100px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
column-gap: 20px;
|
||||
}
|
||||
.options {
|
||||
margin-top: 100px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
> section {
|
||||
position: relative;
|
||||
width: 30%;
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
&.popular {
|
||||
position: absolute;
|
||||
right: 5%;
|
||||
width: 35%;
|
||||
height: 120%;
|
||||
top: -10%;
|
||||
background: #fff;
|
||||
box-shadow: 0 0.75rem 2rem 0 rgba(0, 0, 0, 0.1);
|
||||
border-radius: 10px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.125);
|
||||
.sell {
|
||||
color: rgb(var(--primary-5));
|
||||
}
|
||||
}
|
||||
|
||||
.original {
|
||||
color: var(--color-text-3);
|
||||
font-size: 16px;
|
||||
text-decoration: line-through;
|
||||
font-weight: 300;
|
||||
letter-spacing: 3px;
|
||||
}
|
||||
.price {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
font-family: DINCondensed-Bold, "Century Gothic", CenturyGothic,
|
||||
AppleGothic, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 48px;
|
||||
color: var(--color-text-2);
|
||||
line-height: 1;
|
||||
margin-top: 16px;
|
||||
letter-spacing: 1px;
|
||||
line-height: 1;
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: "¥";
|
||||
left: -20px;
|
||||
top: 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
h3 {
|
||||
margin: 40px 0 0 0;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: var(--color-text-2);
|
||||
letter-spacing: 5px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
p {
|
||||
margin: 10px 0 30px 0;
|
||||
color: var(--color-text-3);
|
||||
letter-spacing: 1px;
|
||||
line-height: 1.9;
|
||||
}
|
||||
ul {
|
||||
margin-top: 30px;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--color-text-2);
|
||||
margin-bottom: 10px;
|
||||
span {
|
||||
color: var(--color-text-4);
|
||||
}
|
||||
div {
|
||||
padding-left: 10px;
|
||||
span {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.overlay {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
background: rgba(255, 255, 255, 0.375);
|
||||
box-shadow: 0 0.75rem 2rem 0 rgba(0, 0, 0, 0.1);
|
||||
border-radius: 10px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.125);
|
||||
}
|
||||
|
||||
.text-gradient {
|
||||
background-image: linear-gradient(
|
||||
45deg,
|
||||
hsl(357, 95%, 50%) 25%,
|
||||
hsl(417, 95%, 50%)
|
||||
);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
|
|
@ -1,41 +1,103 @@
|
|||
import { Button } from "@arco-design/web-react";
|
||||
import Checkmark12Filled from "@ricons/fluent/Checkmark12Filled";
|
||||
import { Icon } from "@ricons/utils";
|
||||
import "./index.less";
|
||||
|
||||
// 季度:三个月内,在线学习 ninghao.net 上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
||||
|
||||
function Subscribe() {
|
||||
return (
|
||||
<div className="container subscribe">
|
||||
<div className="subscribe">
|
||||
<div className="container">
|
||||
<h2>订阅选项</h2>
|
||||
<h4>我也不知道该如何劝你们花钱点钱?但是学一点可能就少亏一点</h4>
|
||||
<div className="options">
|
||||
<section className="bs-shadow">
|
||||
<h3>季度</h3>
|
||||
<div className="options overlay">
|
||||
<section>
|
||||
<div className="original">¥1,299</div>
|
||||
<div className="price">199</div>
|
||||
<h3>季度</h3>
|
||||
<p>
|
||||
三个月内,在线学习 ninghao.net
|
||||
上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
||||
</p>
|
||||
<Button>订阅</Button>
|
||||
<Button type="outline">订阅</Button>
|
||||
<ul>
|
||||
<li>
|
||||
<Icon size={20}>
|
||||
<Checkmark12Filled />
|
||||
</Icon>
|
||||
<div>
|
||||
全部视频免费<span>看看看看</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<Icon size={20}>
|
||||
<Checkmark12Filled />
|
||||
</Icon>
|
||||
<div>
|
||||
全部视频免费<span>看看看看</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section className="bs-shadow">
|
||||
<h3>季度</h3>
|
||||
<section>
|
||||
<div className="original">¥1,299</div>
|
||||
<div className="price">299</div>
|
||||
<p>
|
||||
三个月内,在线学习 ninghao.net
|
||||
上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
||||
</p>
|
||||
<Button>订阅</Button>
|
||||
</section>
|
||||
<section className="bs-shadow">
|
||||
<h3>季度</h3>
|
||||
<div className="price">399</div>
|
||||
<p>
|
||||
三个月内,在线学习 ninghao.net
|
||||
上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
||||
</p>
|
||||
<Button>订阅</Button>
|
||||
<Button type="outline">订阅</Button>
|
||||
<ul>
|
||||
<li>
|
||||
<Icon size={20}>
|
||||
<Checkmark12Filled />
|
||||
</Icon>
|
||||
<div>
|
||||
全部视频免费<span>看看看看</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<Icon size={20}>
|
||||
<Checkmark12Filled />
|
||||
</Icon>
|
||||
<div>
|
||||
全部视频免费<span>看看看看</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
{/* popular */}
|
||||
<section className="popular">
|
||||
<div className="original">¥1,299</div>
|
||||
<div className="price">399</div>
|
||||
<h3>季度</h3>
|
||||
<p>
|
||||
三个月内,在线学习 ninghao.net
|
||||
上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
||||
</p>
|
||||
<Button type="primary">订阅</Button>
|
||||
<ul>
|
||||
<li>
|
||||
<Icon size={20}>
|
||||
<Checkmark12Filled />
|
||||
</Icon>
|
||||
<div>
|
||||
全部视频免费<span>看看看看</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<Icon size={20}>
|
||||
<Checkmark12Filled />
|
||||
</Icon>
|
||||
<div>
|
||||
全部视频免费<span>看看看看</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue
Block a user