管理员后台UI

0603
pan 5 years ago
parent b2eca24120
commit b6b381c119
  1. 67
      src/Active.tsx
  2. 75
      src/App.tsx
  3. 17
      src/InputGroup.tsx
  4. 33
      src/Login.tsx
  5. 12
      src/LoginForm.ts
  6. 70
      src/Main.tsx
  7. 166
      src/Manager.tsx
  8. 139
      src/User.tsx
  9. 0
      src/account/Login.css
  10. 38
      src/account/Login.tsx
  11. 15
      src/account/LoginForm.ts
  12. 10
      src/account/PropCookie.ts
  13. 39
      src/account/Register.tsx
  14. 11
      src/account/RegisterForm.tsx
  15. 45
      src/bootstrap/InputGroup.tsx
  16. 23
      src/bootstrap/LoginFormDesc.ts
  17. 25
      src/entity.ts
  18. 5
      src/index.css
  19. 3
      src/index.tsx

@ -0,0 +1,67 @@
import React from "react";
import {Tabs,Tab,Table,Button} from "react-bootstrap";
import {ActiveForm} from "./entity";
/**
*
*/
export class Active extends React.Component<any, any>{
constructor(props: Readonly<any>) {
super(props);
this.state={
activeList:[]
}
}
//加载活动信息
loadActive(){
this.setState({
activeList:[
{
title:"fuck",
content:"fuck"
}
]
})
}
componentDidMount() {
this.loadActive()
}
render() {
//构建活动信息
const activeTr=this.state.activeList.map((active:ActiveForm,index:number)=>
<tr key={"tr"+index}>
<td>{index+1}</td>
<td>{active.title}</td>
<td>{active.content}</td>
<td><Button variant="danger"></Button></td>
</tr>
)
return (
<Tabs defaultActiveKey="info" id="uncontrolled-tab-example">
<Tab eventKey="info" title="活动管理">
<Table striped bordered hover className="mt-3">
<thead>
<tr>
<th>#</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{activeTr}
</tbody>
</Table>
</Tab>
</Tabs>
);
}
}

@ -1,19 +1,82 @@
import React from 'react'; import React from 'react';
import './App.css'; import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
import {Login} from "./Login"; import {Login} from './account/Login';
import { instanceOf } from 'prop-types';
import { withCookies, Cookies } from 'react-cookie';
import {Main} from "./Main";
import {Register} from "./account/Register";
import {manager_cookie} from "./account/PropCookie";
class App extends React.Component<any, any>{ class App extends React.Component<any, any> {
render() { static propTypes = {
cookies: instanceOf(Cookies).isRequired
};
constructor(props: Readonly<any>) {
super(props);
this.state={}
}
componentDidMount() {
const { cookies } = this.props
if((cookies.get(manager_cookie)||"").length>0){
this.setState({
page:<Main manager={cookies.get(manager_cookie)} logout={this.logout()}/>
})
}else{
this.toLogin()
}
}
//注销登录
logout(){
const { cookies } = this.props
cookies.remove(manager_cookie)
this.toLogin()
}
/**
*
*/
toRegister(){
this.setState({
page:<Register toLogin={()=>this.toLogin()}/>
})
}
//登录
login(manager:string,password:string){
const { cookies } = this.props
console.debug("manager_cookie="+manager)
cookies.set(manager_cookie,manager)
const login=<Login username="" password=""/> this.setState({
page:<Main manager={manager} logout={()=>this.logout()}/>
})
}
/**
*
*/
toLogin(){
this.setState({
page:<Login cookies={this.props.cookies} toRegister={()=>this.toRegister()} login={(manager:string,password:string)=>this.login(manager,password)}/>
})
}
render() {
return ( return (
<div className="App"> <div className="App">
{login} {this.state.page}
</div> </div>
); );
} }
} }
export default App; export default withCookies(App);

@ -1,17 +0,0 @@
import React from "react";
import {InputGroup,FormControl} from 'react-bootstrap'
import {LoginFormDesc} from "./LoginForm";
export class Input extends React.Component<LoginFormDesc, any>{
render() {
return (
<InputGroup className="col-7 ml-auto mr-auto mt-3">
<InputGroup.Prepend>
<InputGroup.Text id={this.props.name}>{this.props.desc}</InputGroup.Text>
</InputGroup.Prepend>
<FormControl placeholder={'请输入'+this.props.desc} aria-describedby={this.props.name} value={this.props.value}
onChange={(e)=>this.props.onChange(e.target.value)}/>
</InputGroup>
);
}
}

@ -1,33 +0,0 @@
import React from "react";
import {Button} from 'react-bootstrap'
import {LoginForm} from "./LoginForm";
import "./login_form.css"
import {Input} from "./InputGroup";
export class Login extends React.Component<LoginForm, LoginForm>{
constructor(props: Readonly<LoginForm>) {
super(props)
this.state={
username:props.username,
password:props.password
}
}
login(){
alert("您输入的用户名是"+this.state.username+",您输入的密码是:"+this.state.password);
}
render() {
return (
<div className="login-form d-flex align-items-center">
<div className="container">
<Input name="username" desc="用户名" value={this.state.username} onChange={(value: string)=>{this.setState({username:value})}}/>
<Input name="password" desc="密码" value={this.state.password} onChange={(value: string)=>{this.setState({password:value})}}/>
<Button variant="success" className="mt-3 col-4" onClick={()=>this.login()}></Button>
</div>
</div>
);
}
}

@ -1,12 +0,0 @@
export interface LoginForm {
username:string;
password:string;
}
export interface LoginFormDesc {
name:string
desc:string
value:string
onChange:Function
}

@ -1,10 +1,78 @@
import React from "react"; import React from "react";
import {Navbar,Nav,Button} from "react-bootstrap";
import {Manager} from "./Manager";
import {User} from "./User";
import {Active} from "./Active";
/**
*
*/
enum Menu {
manager,
user,
active
}
/**
*
*/
export class Main extends React.Component<any, any>{ export class Main extends React.Component<any, any>{
constructor(props: Readonly<any>) {
super(props);
//默认菜单
this.state={
menu:Menu.manager,
subMenu:<Manager/>
}
}
//获取菜单名颜色
getMenuColor(menu:Menu){
return this.state.menu===menu?"black":"blue"
}
//切换菜单
changeMenu(menu:Menu){
this.setState({
menu:menu
})
switch (menu) {
case Menu.manager:
this.setState({
subMenu:<Manager/>
});break;
case Menu.user:
this.setState({
subMenu:<User/>
});break;
case Menu.active:
this.setState({
subMenu:<Active/>
});break;
}
}
render() { render() {
return ( return (
<h1>fff</h1> <div>
<Navbar bg="light">
<Nav className="mr-auto">
<Nav.Link style={{color:this.getMenuColor(Menu.manager)}} onClick={()=>this.changeMenu(Menu.manager)}></Nav.Link>
<Nav.Link style={{color:this.getMenuColor(Menu.user)}} onClick={()=>this.changeMenu(Menu.user)}></Nav.Link>
<Nav.Link style={{color:this.getMenuColor(Menu.active)}} onClick={()=>this.changeMenu(Menu.active)}></Nav.Link>
</Nav>
<Navbar.Text>
{this.props.manager}
</Navbar.Text>
<Button variant="outline-primary" className="ml-3" onClick={()=>this.props.logout()}></Button>
</Navbar>
{this.state.subMenu}
</div>
) )
} }
} }

@ -0,0 +1,166 @@
import React from "react";
import {Tabs,Tab,Button,Table,Modal} from "react-bootstrap";
import {ManagerForm} from "./entity";
import {Input} from "./bootstrap/InputGroup";
/**
*
*/
export class Manager extends React.Component<any, any>{
constructor(props: Readonly<any>) {
super(props);
this.state={
managerList:[],
//修改密码模态框状态位
showModifyPwd:false,
//修改密码表单
modify:{
password:"",
confirmPwd:""
},
//添加管理员模态框状态位
showAddManager:false,
//添加管理员表单
addManager:{
manager:"",
password:"",
confirmPwd:""
}
}
}
/**
*
*/
loadManager(){
this.setState({
managerList:[
{
manager:"admin123"
}
]
})
}
/**
*
*/
checkPwd(modify:any){
if(modify.password.length>0&&modify.confirmPwd.length>0&&modify.password===modify.confirmPwd){
return {
check:true
}
}else if(modify.confirmPwd.length>0&&modify.confirmPwd.length>0){
return {
check:false,
invalid:'两次密码输入不一致'
}
}else if(modify.password.length>0&&modify.confirmPwd.length===0){
return {
check:false,
invalid: '确认密码为空'
}
}else{
return {
check:undefined
}
}
}
componentDidMount() {
this.loadManager()
}
/**
*
*/
getForm(){
let key: string
let form:any
let manager;
if(this.state.showAddManager){
key='addManager'
form=this.state.addManager
manager=<Input name="manager" type="text" desc="管理员账号" value={form.manager} onChange={(value: string)=>{this.setState({[key]:{
manager:value,
password:form.password,
confirmPwd:form.confirmPwd
}})}}/>
}else{
key='modify'
form=this.state.modify
}
return <Modal.Body>
{manager}
<Input name="password" type="password" desc="密码" value={form.password} onChange={(value: string)=>{this.setState({[key]:{
manager:form.manager,
password:value,
confirmPwd:form.confirmPwd
}})}}/>
<Input name="confirmPwd" type="password" desc="确认密码" value={form.confirmPwd} onChange={(value: string)=>{this.setState({[key]:{
manager:form.manager,
password:form.password,
confirmPwd:value
}})}}
valid={this.checkPwd(form)}
/>
</Modal.Body>
}
render() {
//构造表格行数据
const managerTr=this.state.managerList.map((manager:ManagerForm,index:number)=>
<tr key={"tr"+index}>
<td>{index+1}</td>
<td>{manager.manager}</td>
<td>
<Button variant="info" className="mr-3" onClick={()=>this.setState({showModifyPwd:true})}></Button>
<Button variant="danger"></Button>
</td>
</tr>
)
const modalTitle=this.state.showModifyPwd?'修改密码':'添加管理员'
return (
<Tabs defaultActiveKey="info" id="uncontrolled-tab-example">
<Tab eventKey="info" title="管理员信息">
<Button variant="primary" className="mt-3" onClick={()=>this.setState({showAddManager:true})}></Button>
<Table striped bordered hover className="mt-3">
<thead>
<tr>
<th>#</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{managerTr}
</tbody>
</Table>
<Modal show={this.state.showModifyPwd||this.state.showAddManager} size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
{modalTitle}
</Modal.Title>
</Modal.Header>
{this.getForm()}
<Modal.Footer className="ml-auto mr-auto">
<Button variant="info" onClick={()=>this.setState({showModifyPwd:false,showAddManager:false})}>{modalTitle}</Button>
<Button onClick={()=>this.setState({showModifyPwd:false,showAddManager:false})}></Button>
</Modal.Footer>
</Modal>
</Tab>
</Tabs>
);
}
}

@ -0,0 +1,139 @@
import React from "react";
import {Tabs,Tab,Table,Button,Modal} from "react-bootstrap";
import {UserForm} from "./entity";
import {Input} from "./bootstrap/InputGroup";
/**
*
*/
export class User extends React.Component<any, any>{
constructor(props: Readonly<any>) {
super(props);
this.state={
userList:[],
showUser:false
}
}
/**
*
*/
loadUser(){
this.setState({userList:[
{
username:"ffff",
name:"ffff",
sex:"男",
age:12,
headImg:"https://www.baidu.com/img/baidu_85beaf5496f291521eb75ba38eacbd87.svg",
phone:1234567890,
mail:"abc@qq.com",
address:"广州",
timeMoney:22,
desc:"自我介绍"
},
{
username:"ffff",
name:"草",
sex:"男",
age:12,
headImg:"https://www.baidu.com/img/baidu_85beaf5496f291521eb75ba38eacbd87.svg",
phone:1234567890,
mail:"abc@qq.com",
address:"广州",
timeMoney:22,
desc:"自我介绍"
}
]})
}
//修改个人信息
modifyUser(){
alert("您修改的用户是"+this.state.user.name)
this.setState({showUser:false})
}
componentDidMount() {
this.loadUser()
}
render() {
//构造表格行数据
const userTr=this.state.userList.map((user:UserForm,index:number)=>
<tr key={"tr"+index}>
<td className="align-middle">{index+1}</td>
<td className="align-middle">{user.username}</td>
<td className="align-middle">{user.name}</td>
<td className="align-middle">{user.sex}</td>
<td className="align-middle">{user.age}</td>
<td className="align-middle"><img className="head-img" src={user.headImg} alt="头像" onClick={()=>this.setState({headImg:user.headImg})}/></td>
<td className="align-middle">{user.phone}</td>
<td className="align-middle">{user.mail}</td>
<td className="align-middle">{user.address}</td>
<td className="align-middle">{user.timeMoney}</td>
<td className="align-middle">{user.desc}</td>
<td className="align-middle">
<Button variant="info" className="mr-3" onClick={()=>this.setState({showUser:true,user:user})}></Button>
<Button variant="danger" className="mr-3"></Button>
<Button variant="primary"></Button>
</td>
</tr>
)
return (
<Tabs defaultActiveKey="info" id="uncontrolled-tab-example">
<Tab eventKey="info" title="用户信息">
<Table striped bordered hover className="mt-3">
<thead>
<tr>
<th>#</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{userTr}
</tbody>
</Table>
<Modal show={(this.state.headImg||"").length>0} centered onClick={()=>this.setState({headImg:""})} onHide={()=>{}}>
<Modal.Header closeButton/>
<Modal.Body>
<img alt="头像" src={this.state.headImg} style={{width:"100%",height:"100%"}}/>
</Modal.Body>
</Modal>
<Modal show={this.state.showUser} centered onHide={()=>{}}>
<Modal.Header closeButton onClick={()=>this.setState({showUser:false})}>
<Modal.Title id="contained-modal-title-vcenter">
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Input name="name" desc="姓名" value={{...{user:{}},...this.state.user}.name} onChange={(value:string)=>this.setState({
user:{
name:value
}
})}/>
</Modal.Body>
<Modal.Footer className="ml-auto mr-auto">
<Button variant="info" onClick={()=>this.modifyUser()}></Button>
</Modal.Footer>
</Modal>
</Tab>
</Tabs>
);
}
}

@ -0,0 +1,38 @@
import React from "react";
import {Button} from 'react-bootstrap'
import {LoginForm} from "./LoginForm";
import {Input} from "../bootstrap/InputGroup";
/**
*
*/
export class Login extends React.Component<LoginForm, LoginForm>{
constructor(props: Readonly<LoginForm>) {
super(props)
this.state={
manager:"",
password:"",
toRegister:props.toRegister,
cookies:props.cookies,
login:props.login
}
}
render() {
return (
<div className="d-flex align-items-center" style={{height:window.screen.availHeight+'px'}}>
<div className="container">
<Input name="manager" type="text" desc="管理员账号" value={this.state.manager} onChange={(value: string)=>{this.setState({manager:value})}}/>
<Input name="password" type="password" desc="管理员密码" value={this.state.password} onChange={(value: string)=>{this.setState({password:value})}}/>
<Button variant="success" className="mt-3 col-2 mr-3" onClick={()=>this.state.login(this.state.manager,this.state.password)}></Button>
<Button variant="info" className="mt-3 col-2" onClick={()=>this.props.toRegister()}></Button>
</div>
</div>
);
}
}

@ -0,0 +1,15 @@
/**
*
*/
import {PropCookie} from "./PropCookie";
export interface LoginForm extends PropCookie{
//管理员名
manager?:string;
//密码
password?:string;
//跳转注册
toRegister:Function;
//登录
login:Function;
}

@ -0,0 +1,10 @@
import {Cookies } from 'react-cookie';
/**
* cookie信息
*/
export interface PropCookie {
cookies:Cookies;
}
export const manager_cookie="manager_cookie"

@ -0,0 +1,39 @@
import React from "react";
import {RegisterForm} from "./RegisterForm";
import {Input} from "../bootstrap/InputGroup";
import {Button} from 'react-bootstrap'
/**
*
*/
export class Register extends React.Component<RegisterForm, RegisterForm>{
constructor(props: Readonly<RegisterForm>) {
super(props)
this.state={
manager:"",
password:"",
toLogin:props.toLogin
}
}
//注册
register(){
alert("您输入的用户名是"+this.state.manager+",您输入的密码是:"+this.state.password);
}
render() {
return (
<div className="d-flex align-items-center" style={{height:window.screen.availHeight+'px'}}>
<div className="container">
<Input name="manager" type="text" desc="管理员名" value={this.state.manager} onChange={(value: string)=>{this.setState({manager:value})}}/>
<Input name="password" type="password" desc="密码" value={this.state.password} onChange={(value: string)=>{this.setState({password:value})}}/>
<Button variant="success" className="mt-3 col-2 mr-3" onClick={()=>this.register()}></Button>
<Button variant="info" className="mt-3 col-2" onClick={()=>this.props.toLogin()}></Button>
</div>
</div>
);
}
}

@ -0,0 +1,11 @@
/**
*
*/
export interface RegisterForm {
//管理员名
manager?:string;
//密码
password?:string;
//跳转登录
toLogin:Function;
}

@ -0,0 +1,45 @@
import React from "react";
import {InputGroup,FormControl} from 'react-bootstrap'
import {InputFormDesc} from "./LoginFormDesc";
const defaultValid={
check:false,
valid:'验证成功',
invalid:'验证失败'
}
/**
* bootstrap InputGroup组件封装
*/
export class Input extends React.Component<InputFormDesc, any>{
merge(){
return {...defaultValid,...this.props.valid}
}
valid(){
if(this.props.valid===undefined||this.props.valid.check===undefined){
return ""
}else{
return this.props.valid.check?'is-valid':'is-invalid'
}
}
render() {
return (
<InputGroup className="col-7 ml-auto mr-auto mt-3">
<InputGroup.Prepend>
<InputGroup.Text id={this.props.name}>{this.props.desc}</InputGroup.Text>
</InputGroup.Prepend>
<FormControl className={this.valid()} type={this.props.type} placeholder={'请输入'+this.props.desc} aria-describedby={this.props.name} value={this.props.value}
onChange={(e)=>this.props.onChange(e.target.value)}/>
<div className="valid-feedback text-center">
{this.merge().valid}
</div>
<div className="invalid-feedback text-center">
{this.merge().invalid}
</div>
</InputGroup>
);
}
}

@ -0,0 +1,23 @@
/**
*
*/
export interface InputFormDesc {
//表单名
name: string
//描述信息
desc: string
//表单值
value?: string
//数据类型
type?:
|"text"
|"password"
//值改变事件
onChange: Function
//验证信息
valid?:{
check?:Boolean;
valid?:String;
invalid?:String;
}
}

@ -0,0 +1,25 @@
//管理员
export interface ManagerForm {
manager:string;
}
//用户
export interface UserForm {
username:string;
name:string;
sex:string;
age:number;
headImg:string;
phone:number;
mail:string;
address:string;
timeMoney:string;
desc:string;
}
//活动
export interface ActiveForm {
title:string;
content:string;
}

@ -12,4 +12,7 @@ code {
monospace; monospace;
} }
.head-img{
width: 100px;
height: 100px;
}

@ -3,10 +3,13 @@ import ReactDOM from 'react-dom';
import './index.css'; import './index.css';
import App from './App'; import App from './App';
import * as serviceWorker from './serviceWorker'; import * as serviceWorker from './serviceWorker';
import { CookiesProvider } from 'react-cookie';
ReactDOM.render( ReactDOM.render(
<React.StrictMode> <React.StrictMode>
<CookiesProvider>
<App /> <App />
</CookiesProvider>
</React.StrictMode>, </React.StrictMode>,
document.getElementById('root') document.getElementById('root')
); );

Loading…
Cancel
Save