feat: 登录
This commit is contained in:
parent
166986e31f
commit
e8da3e4c5a
|
@ -17,11 +17,6 @@ body {
|
||||||
|
|
||||||
#bs-app {
|
#bs-app {
|
||||||
position: relative;
|
position: relative;
|
||||||
> main {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes gradient {
|
@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 "./index.less";
|
||||||
import { Input, Space } from "@arco-design/web-react";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { routerList } from "../../router";
|
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 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() {
|
function Nav() {
|
||||||
const navigate = useNavigate();
|
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 (
|
return (
|
||||||
<header>
|
<header>
|
||||||
|
@ -34,8 +83,57 @@ function Nav() {
|
||||||
<InputSearch allowClear placeholder="搜索" style={{ width: 150 }} />
|
<InputSearch allowClear placeholder="搜索" style={{ width: 150 }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="end">
|
<div className="end">
|
||||||
<span>注册</span>
|
<span onClick={() => setVisible(true)}>登录</span>
|
||||||
<span>登录</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>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</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 {
|
.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 {
|
h2 {
|
||||||
text-align: center;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
h4 {
|
h4 {
|
||||||
text-align: center;
|
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: var(--color-text-4);
|
color: var(--color-text-3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.options {
|
.options {
|
||||||
padding-top: 100px;
|
margin-top: 100px;
|
||||||
display: grid;
|
position: relative;
|
||||||
grid-template-columns: 1fr 1fr 1fr;
|
display: flex;
|
||||||
column-gap: 20px;
|
|
||||||
> section {
|
> section {
|
||||||
|
position: relative;
|
||||||
|
width: 30%;
|
||||||
padding: 40px;
|
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 {
|
.price {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
font-family: DINCondensed-Bold, "Century Gothic", CenturyGothic,
|
font-family: DINCondensed-Bold, "Century Gothic", CenturyGothic,
|
||||||
AppleGothic, sans-serif;
|
AppleGothic, sans-serif;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
color: var(--color-text-2);
|
color: var(--color-text-2);
|
||||||
line-height: 1;
|
|
||||||
margin-top: 16px;
|
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
|
line-height: 1;
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
content: "¥";
|
||||||
|
left: -20px;
|
||||||
|
top: 0;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
h3 {
|
h3 {
|
||||||
|
margin: 40px 0 0 0;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--color-text-2);
|
color: var(--color-text-2);
|
||||||
letter-spacing: 5px;
|
letter-spacing: 5px;
|
||||||
margin-top: 40px;
|
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
|
margin: 10px 0 30px 0;
|
||||||
color: var(--color-text-3);
|
color: var(--color-text-3);
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
line-height: 1.9;
|
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 { Button } from "@arco-design/web-react";
|
||||||
|
import Checkmark12Filled from "@ricons/fluent/Checkmark12Filled";
|
||||||
|
import { Icon } from "@ricons/utils";
|
||||||
import "./index.less";
|
import "./index.less";
|
||||||
|
|
||||||
// 季度:三个月内,在线学习 ninghao.net 上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
// 季度:三个月内,在线学习 ninghao.net 上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
||||||
|
|
||||||
function Subscribe() {
|
function Subscribe() {
|
||||||
return (
|
return (
|
||||||
<div className="container subscribe">
|
<div className="subscribe">
|
||||||
|
<div className="container">
|
||||||
<h2>订阅选项</h2>
|
<h2>订阅选项</h2>
|
||||||
<h4>我也不知道该如何劝你们花钱点钱?但是学一点可能就少亏一点</h4>
|
<h4>我也不知道该如何劝你们花钱点钱?但是学一点可能就少亏一点</h4>
|
||||||
<div className="options">
|
<div className="options overlay">
|
||||||
<section className="bs-shadow">
|
<section>
|
||||||
<h3>季度</h3>
|
<div className="original">¥1,299</div>
|
||||||
<div className="price">199</div>
|
<div className="price">199</div>
|
||||||
|
<h3>季度</h3>
|
||||||
<p>
|
<p>
|
||||||
三个月内,在线学习 ninghao.net
|
三个月内,在线学习 ninghao.net
|
||||||
上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
||||||
</p>
|
</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>
|
||||||
<section className="bs-shadow">
|
<section>
|
||||||
<h3>季度</h3>
|
<div className="original">¥1,299</div>
|
||||||
<div className="price">299</div>
|
<div className="price">299</div>
|
||||||
<p>
|
|
||||||
三个月内,在线学习 ninghao.net
|
|
||||||
上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
|
||||||
</p>
|
|
||||||
<Button>订阅</Button>
|
|
||||||
</section>
|
|
||||||
<section className="bs-shadow">
|
|
||||||
<h3>季度</h3>
|
<h3>季度</h3>
|
||||||
<div className="price">399</div>
|
|
||||||
<p>
|
<p>
|
||||||
三个月内,在线学习 ninghao.net
|
三个月内,在线学习 ninghao.net
|
||||||
上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
上的所有课程,通过高效的内容,快速掌握各种软件应用开发技术。
|
||||||
</p>
|
</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>
|
||||||
|
{/* 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>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user