✨ adding login page.

This commit is contained in:
zuiidea
2021-04-05 16:54:22 +08:00
parent b0cb27712d
commit a0000d7371
16 changed files with 163 additions and 133 deletions
+1 -1
View File
@@ -56,7 +56,7 @@
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-react": "^7.23.1",
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "^4.2.0",
"husky": "^6.0.0",
"less-vars-to-js": "^1.3.0",
"lint-staged": "^10.0.0",
"mockjs": "^1.1.0",
-14
View File
@@ -1,14 +0,0 @@
import React from 'react';
export interface GlobalFooterProps {
links?: Array<{
key?: string;
title: React.ReactNode;
href: string;
blankTarget?: boolean;
}>;
copyright?: React.ReactNode;
style?: React.CSSProperties;
className?: string;
}
export default class GlobalFooter extends React.Component<GlobalFooterProps, any> {}
-28
View File
@@ -1,28 +0,0 @@
import React from 'react';
import classNames from 'classnames';
import styles from './index.less';
const GlobalFooter = ({ className, links, copyright }) => {
const clsString = classNames(styles.globalFooter, className);
return (
<footer className={clsString}>
{links && (
<div className={styles.links}>
{links.map(link => (
<a
key={link.key}
title={link.key}
target={link.blankTarget ? '_blank' : '_self'}
href={link.href}
>
{link.title}
</a>
))}
</div>
)}
{copyright && <div className={styles.copyright}>{copyright}</div>}
</footer>
);
};
export default GlobalFooter;
+1 -1
View File
@@ -13,7 +13,7 @@
transition: all 0.3s;
&:not(:last-child) {
margin-right: 40px;
margin-right: 16px;
}
&:hover {
-15
View File
@@ -1,15 +0,0 @@
---
title: GlobalFooter
subtitle: 全局页脚
cols: 1
order: 7
---
页脚属于全局导航的一部分,作为对顶部导航的补充,通过传递数据控制展示内容。
## API
| 参数 | 说明 | 类型 | 默认值 |
| --------- | -------- | ---------------------------------------------------------------- | ------ |
| links | 链接数据 | array<{ title: ReactNode, href: string, blankTarget?: boolean }> | - |
| copyright | 版权信息 | ReactNode | - |
+39
View File
@@ -0,0 +1,39 @@
import React from 'react'
import styles from './index.less'
interface LinkItem {
key: string
title: React.ReactNode
href?: string
blankTarget?: boolean
}
interface GlobalFooterProps {
links?: LinkItem[]
copyright?: React.ReactNode
}
const GlobalFooter: React.FC<GlobalFooterProps> = ({
links = [],
copyright,
}) => {
return (
<footer className={styles.globalFooter}>
<div className={styles.links}>
{links.map((link) => (
<a
key={link.key}
title={link.key}
target={link.blankTarget ? '_blank' : '_self'}
href={link.href}
>
{link.title}
</a>
))}
</div>
{copyright && <div className={styles.copyright}>{copyright}</div>}
</footer>
)
}
export default GlobalFooter
+2 -10
View File
@@ -1,20 +1,12 @@
import React, { PureComponent, Fragment } from 'react'
import PropTypes from 'prop-types'
<<<<<<< HEAD
import { Breadcrumb, Icon } from 'antd'
import { Link } from 'umi'
import withRouter from 'umi/withRouter'
import { withI18n } from '@lingui/react'
import { pathMatchRegexp, queryAncestors } from 'utils'
=======
import { Breadcrumb } from 'antd'
import { Link, withRouter } from 'umi'
import { t } from "@lingui/macro"
import { t } from '@lingui/macro'
import iconMap from 'utils/iconMap'
const { pathToRegexp } = require('path-to-regexp')
import { queryAncestors } from 'utils'
>>>>>>> master
import styles from './Bread.less'
const { pathToRegexp } = require('path-to-regexp')
@withRouter
class Bread extends PureComponent {
+9 -19
View File
@@ -1,22 +1,10 @@
import React, { PureComponent, Fragment } from 'react'
import PropTypes from 'prop-types'
<<<<<<< HEAD
import { Menu, Icon } from 'antd'
import { Link, Navlink } from 'umi'
import withRouter from 'umi/withRouter'
import {
arrayToTree,
queryAncestors,
pathMatchRegexp,
addLangPrefix,
} from 'utils'
=======
import { Menu } from 'antd'
import { NavLink, withRouter } from 'umi'
import { pathToRegexp } from 'path-to-regexp'
import { arrayToTree, queryAncestors } from 'utils'
import iconMap from 'utils/iconMap'
>>>>>>> master
import store from 'store'
const { SubMenu } = Menu
@@ -27,12 +15,14 @@ class SiderMenu extends PureComponent {
openKeys: store.get('openKeys') || [],
}
onOpenChange = openKeys => {
onOpenChange = (openKeys) => {
const { menus } = this.props
const rootSubmenuKeys = menus.filter(_ => !_.menuParentId).map(_ => _.id)
const rootSubmenuKeys = menus
.filter((_) => !_.menuParentId)
.map((_) => _.id)
const latestOpenKey = openKeys.find(
key => this.state.openKeys.indexOf(key) === -1
(key) => this.state.openKeys.indexOf(key) === -1
)
let newOpenKeys = openKeys
@@ -46,8 +36,8 @@ class SiderMenu extends PureComponent {
store.set('openKeys', newOpenKeys)
}
generateMenus = data => {
return data.map(item => {
generateMenus = (data) => {
return data.map((item) => {
if (item.children) {
return (
<SubMenu
@@ -89,12 +79,12 @@ class SiderMenu extends PureComponent {
// Find a menu that matches the pathname.
const currentMenu = menus.find(
_ => _.route && pathToRegexp(_.route).exec(location.pathname)
(_) => _.route && pathToRegexp(_.route).exec(location.pathname)
)
// Find the key that should be selected according to the current menu.
const selectedKeys = currentMenu
? queryAncestors(menus, currentMenu, 'menuParentId').map(_ => _.id)
? queryAncestors(menus, currentMenu, 'menuParentId').map((_) => _.id)
: []
const menuProps = collapsed
+1 -12
View File
@@ -4,16 +4,5 @@ import Loader from './Loader'
import ScrollBar from './ScrollBar'
import GlobalFooter from './GlobalFooter'
import Ellipsis from './Ellipsis'
import * as MyLayout from './Layout/index.js'
import Page from './Page'
export {
MyLayout,
GlobalFooter,
Ellipsis,
FilterItem,
DropOption,
Loader,
Page,
ScrollBar,
}
export { GlobalFooter, Ellipsis, FilterItem, DropOption, Loader, ScrollBar }
+3 -3
View File
@@ -12,13 +12,13 @@ const language = detect(
checkLanguage(fromUrl('lang')),
checkLanguage(fromStorage(LOCALE_LANGUAGE)),
checkLanguage(fromNavigator()),
'zh'
'en'
)
export const config: IConfig = {
title: 'React Seed',
title: 'Antd Admin',
logo: 'logo.svg',
copyright: 'Ant Design Admin © 2018 zuiidea',
copyright: 'Ant Design Admin © 2021 zuiidea',
language: language as ISupportedLocales,
/* Layout configuration, specify which layout to use for route. */
+15 -5
View File
@@ -1,5 +1,8 @@
import { ILanguage, IAntdI18nMap } from '@/typings'
import { ILanguage, ILanguages, IAntdI18nMap } from '@/typings'
/**
* Countrys flags: https://www.flaticon.com/packs/countrys-flags
*/
export const language: ILanguage = {
en: {
flag: '/america.svg',
@@ -9,14 +12,21 @@ export const language: ILanguage = {
flag: '/china.svg',
value: '简体中文',
},
'pt-br': {
flag: '/portugal.svg',
value: 'Português',
},
}
export const languages = Object.entries(language).map(([key, value]: any) => ({
key,
...value,
}))
export const languages: ILanguages[] = Object.entries(language).map(
([key, value]: any) => ({
key,
...value,
})
)
export const antdI18nMap: IAntdI18nMap = {
zh: 'zh_CN',
en: 'en_US',
'pt-br': 'pt_PT',
}
+20
View File
@@ -0,0 +1,20 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2021-04-05 15:59+0800\n"
"Mime-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: pt-br\n"
#: src/pages/login/index.tsx:14
msgid "Sign in"
msgstr ""
#: src/pages/login/index.tsx:18
msgid "Username"
msgstr ""
#: src/pages/login/index.tsx:22
msgid "Password"
msgstr ""
+5
View File
@@ -0,0 +1,5 @@
import { Redirect } from 'umi'
const Index = () => <Redirect to="/dashboard" />
export default Index
+15 -15
View File
@@ -4,9 +4,9 @@
position: absolute;
top: 45%;
left: 50%;
margin: -160px 0 0 -160px;
width: 320px;
height: 320px;
margin: -160px 0 0 -160px;
padding: 36px;
box-shadow: 0 0 100px rgba(0, 0, 0, 0.08);
@@ -15,22 +15,22 @@
}
p {
color: rgb(204, 204, 204);
text-align: center;
margin-top: 16px;
font-size: 12px;
display: flex;
justify-content: space-between;
margin-top: 16px;
color: rgb(204, 204, 204);
font-size: 12px;
text-align: center;
}
}
.logo {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 24px;
text-align: center;
cursor: pointer;
margin-bottom: 24px;
display: flex;
justify-content: center;
align-items: center;
img {
width: 40px;
@@ -38,13 +38,13 @@
}
span {
display: inline-block;
color: @primary-color;
font-weight: 700;
vertical-align: text-bottom;
font-size: 16px;
text-transform: uppercase;
vertical-align: text-bottom;
@text-gradient .text-gradient();
display: inline-block;
font-weight: 700;
color: @primary-color;
.text-gradient();
}
}
@@ -55,6 +55,6 @@
.footer {
position: absolute;
bottom: 0;
width: 100%;
bottom: 0;
}
+46 -10
View File
@@ -1,26 +1,59 @@
import React from 'react'
import { Button, Row } from 'antd'
import { Trans } from '@lingui/macro'
import { config } from '@/configs'
import { Button, Row, Input, Form } from 'antd'
import { GithubOutlined } from '@ant-design/icons'
import { GlobalFooter } from '@/components'
import { Trans, t } from '@lingui/macro'
import { config, languages } from '@/configs'
import styles from './index.less'
const FormItem = Form.Item
const Login: React.FC = () => {
const footerLinks = [
{
key: 'github',
title: <GithubOutlined />,
href: 'https://github.com/zuiidea/antd-admin',
blankTarget: true,
},
...languages.map((item) => ({
key: item.key,
title: <span>{item.value}</span>,
})),
]
const handleFinish = (values) => {
console.log(values)
}
return (
<>
<div className={styles.form}>
<div className={styles.logo}>
<img alt="logo" src={config.logo} />
<span>{config.title}</span>
</div>
<Form onFinish={handleFinish}>
<FormItem
name="username"
rules={[{ required: true, message: 'Please input your username!' }]}
hasFeedback
>
<Input placeholder={t`Username`} />
</FormItem>
<FormItem
name="password"
rules={[{ required: true, message: 'Please input your password!' }]}
hasFeedback
>
<Input.Password placeholder={t`Password`} />
</FormItem>
<Row>
<Button
type="primary"
// onClick={this.handleOk}
// loading={loading.effects.login}
>
<Button type="primary" htmlType="submit">
<Trans>Sign in</Trans>
</Button>
<p>
<span>
<span className="margin-right">
<Trans>Username</Trans>
:guest
</span>
@@ -30,7 +63,10 @@ const Login: React.FC = () => {
</span>
</p>
</Row>
</div>
</Form>
</div>
<div className={styles.footer}>
<GlobalFooter links={footerLinks} copyright={config.copyright} />
</div>
</>
)
+6
View File
@@ -14,6 +14,12 @@ export interface ILanguage {
[key: string]: ILanguageItem
}
export interface ILanguages {
key: string
flag: string
value: string
}
export interface IAntdI18nMap {
[key: string]: string
}