普通使用者 Dashboard 頁面
// src\components\admin\Dashboard.tsx
import { Col, Descriptions, List, Menu, message, Row, Typography } from 'antd'
import { Link } from 'react-router-dom'
import Layout from '../core/Layout'
import { ShoppingCartOutlined, UserOutlined } from '@ant-design/icons'
import { isAuth } from '../../helpers/auth'
import { Jwt } from '../../store/models/auth'
import { useEffect, useState } from 'react'
import axios from 'axios'
import { API } from '../../config'
import { Order, OrderProduct } from '../../store/models/order'
const { Title } = Typography
const Dashboard = () => {
const {
token,
user: { name, email, _id: userId }
} = isAuth() as Jwt
const links = () => (
<>
<Title level={5}>使用者導航</Title>
<Menu style={{ borderRight: 0 }}>
<Menu.Item>
<ShoppingCartOutlined style={{ marginRight: '5px' }} />
<Link to="/cart">購物車</Link>
</Menu.Item>
<Menu.Item>
<UserOutlined style={{ marginRight: '5px' }} />
<Link to="/user/profile">資料更新</Link>
</Menu.Item>
</Menu>
</>
)
const info = () => (
<Descriptions title="使用者資訊" bordered>
<Descriptions.Item label="昵稱">{name}</Descriptions.Item>
<Descriptions.Item label="郵箱">{email}</Descriptions.Item>
<Descriptions.Item label="角色">普通使用者</Descriptions.Item>
</Descriptions>
)
const [orders, setOrders] = useState([])
async function getOrders() {
try {
const response = await axios.get(`${API}/user/orders/${userId}`, {
headers: {
Authorization: `Bearer ${token}`
}
})
setOrders(response.data)
} catch (error) {
message.error(error.response.data.errors[0])
}
}
useEffect(() => {
getOrders()
}, [])
const historyOrder = () => (
<>
<Title level={5} style={{ marginTop: '20px' }}>
購買曆史
</Title>
<List
dataSource={orders}
renderItem={(item: Order) => (
<List.Item>
<Col span="18">{item.products.map(({ snapshot }: OrderProduct) => snapshot.name).join('、')}</Col>
<Col span="6">{item.amount}</Col>
</List.Item>
)}
/>
</>
)
return (
<Layout title="使用者 dashboard" subTitle="">
<Row>
<Col span="4">{links()}</Col>
<Col span="20">
{info()}
{historyOrder()}
</Col>
</Row>
</Layout>
)
}
export default Dashboard
資料更新頁面
頁面布局
// src\components\admin\Profile.tsx
import { Button, Form, Input } from 'antd'
import Layout from '../core/Layout'
const Profile = () => {
return (
<Layout title="資料更新" subTitle="">
<Form>
<Form.Item name="email" label="郵箱">
<Input disabled />
</Form.Item>
<Form.Item name="name" label="昵稱">
<Input />
</Form.Item>
<Form.Item name="password" label="密碼">
<Input.Password />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
修改
</Button>
</Form.Item>
</Form>
</Layout>
)
}
export default Profile
路由配置
// src\Routes.tsx
import Profile from './components/admin/Profile'
<PrivateRoute path="/user/profile" component={Profile} />
修改方法
// src\helpers\auth.ts
import { message } from 'antd'
import axios from 'axios'
import { API } from '../config'
import { SignupPayload } from '../store/actions/auth.action'
import { Jwt } from '../store/models/auth'
// 是否登入
export function isAuth(): boolean | Jwt {
const jwt = localStorage.getItem('jwt')
if (jwt) {
return JSON.parse(jwt)
}
return false
}
// 修改
export function update(value: SignupPayload) {
const auth = isAuth() as Jwt
axios
.put(`${API}/user/${auth.user._id}`, value, {
headers: {
Authorization: `Bearer ${auth.token}`
}
})
.then(({ data }) => {
auth.user.email = data.email
auth.user.name = data.name
localStorage.setItem('jwt', JSON.stringify(auth))
message.success('修改成功')
})
.catch(error => {
message.error(error.response.data.errors[0])
})
}
修改操作
// src\components\admin\Profile.tsx
import { Button, Form, Input } from 'antd'
import { isAuth, update } from '../../helpers/auth'
import { SignupPayload } from '../../store/actions/auth.action'
import { Jwt } from '../../store/models/auth'
import Layout from '../core/Layout'
const Profile = () => {
const {
user: { name, email }
} = isAuth() as Jwt
const onFinish = (value: SignupPayload) => {
update(value)
}
return (
<Layout title="資料更新" subTitle="">
<Form onFinish={onFinish} initialValues={{ name, email }}>
<Form.Item name="email" label="郵箱">
<Input disabled />
</Form.Item>
<Form.Item name="name" label="昵稱">
<Input />
</Form.Item>
<Form.Item name="password" label="密碼">
<Input.Password />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
修改
</Button>
</Form.Item>
</Form>
</Layout>
)
}
export default Profile