-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
355 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
55 changes: 55 additions & 0 deletions
55
5.react/8.ecommerce/ecommerce-front/src/components/admin/AddCategory.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { Button, Form, Input, message } from "antd"; | ||
import React, { useState } from "react"; | ||
import Layout from "../core/Layout"; | ||
import axios from "axios"; | ||
import { API } from "../../config"; | ||
import { isAuth } from "../../helpers/auth"; | ||
import { Link } from "react-router-dom"; | ||
import { Jwt } from "../../types/auth"; | ||
|
||
const AddCategory = () => { | ||
const { user, token } = isAuth() as Jwt; | ||
|
||
async function addCategory(name: string) { | ||
try { | ||
let response = await axios.post<{ name: string }>( | ||
`${API}/category/create/${user._id}`, | ||
{ | ||
name: name, | ||
}, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
}, | ||
} | ||
); | ||
message.success(`[${response.data.name}] 分类添加成功`); | ||
} catch (error: any) { | ||
message.error(error.response.data.error); | ||
} | ||
} | ||
|
||
const onFinish = (value: { name: string }) => { | ||
const { name } = value; | ||
if (name) addCategory(name); | ||
}; | ||
return ( | ||
<Layout title="添加分类" subTitle=""> | ||
<Form onFinish={onFinish}> | ||
<Form.Item name="name" label="分类名称"> | ||
<Input /> | ||
</Form.Item> | ||
<Form.Item> | ||
<Button type="primary" htmlType="submit"> | ||
添加分类 | ||
</Button> | ||
</Form.Item> | ||
</Form> | ||
<Button> | ||
<Link to="/admin/dashboard">返回 Dashboard</Link> | ||
</Button> | ||
</Layout> | ||
); | ||
}; | ||
|
||
export default AddCategory; |
113 changes: 113 additions & 0 deletions
113
5.react/8.ecommerce/ecommerce-front/src/components/admin/AddProduct.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import { Button, Form, Input, message, Select, Upload } from "antd"; | ||
import { UploadOutlined } from "@ant-design/icons"; | ||
import React, { useEffect, useState } from "react"; | ||
import { useShallow } from "zustand/react/shallow"; | ||
import Layout from "../core/Layout"; | ||
// import { useDispatch, useSelector } from "react-redux" | ||
// import { getCategory } from "../../store/actions/category.actions" | ||
// import { AppState } from "../../store/reducers/index" | ||
// import { CategoryState } from "../../store/reducers/category.reducer" | ||
import { RcFile } from "antd/lib/upload"; | ||
import axios from "axios"; | ||
import { API } from "../../config"; | ||
import { isAuth } from "../../helpers/auth"; | ||
import { Jwt } from "../../types/auth"; | ||
import { useCategoryStore } from "../../store/category"; | ||
|
||
const AddProduct = () => { | ||
const [file, setFile] = useState<RcFile>(); | ||
|
||
const getCategories = useCategoryStore((state) => state.getCategories); | ||
const categories = useCategoryStore((state) => state.result); | ||
|
||
useEffect(() => { | ||
getCategories(); | ||
}, [getCategories]); | ||
|
||
const { user, token } = isAuth() as Jwt; | ||
|
||
const onFinish = (product: any) => { | ||
const formData = new FormData(); | ||
for (let attr in product) { | ||
formData.set(attr, product[attr]); | ||
} | ||
if (typeof file !== "undefined") { | ||
formData.set("photo", file); | ||
} | ||
|
||
axios | ||
.post(`${API}/product/create/${user._id}`, formData, { | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
}, | ||
}) | ||
.then( | ||
() => { | ||
message.success("商品添加成功"); | ||
}, | ||
() => { | ||
message.error("商品添加失败"); | ||
} | ||
); | ||
}; | ||
|
||
const addProductForm = () => { | ||
const props = { | ||
accept: "image/*", | ||
beforeUpload: function (file: RcFile) { | ||
setFile(file); | ||
return false; | ||
}, | ||
}; | ||
return ( | ||
<Form onFinish={onFinish} initialValues={{ category: "" }}> | ||
<Form.Item> | ||
<Upload {...props}> | ||
<Button icon={<UploadOutlined />}>上传商品封面</Button> | ||
</Upload> | ||
</Form.Item> | ||
<Form.Item name="name" label="商品名称"> | ||
<Input /> | ||
</Form.Item> | ||
<Form.Item name="description" label="商品描述"> | ||
<Input /> | ||
</Form.Item> | ||
<Form.Item name="price" label="商品价格"> | ||
<Input /> | ||
</Form.Item> | ||
<Form.Item name="category" label="所属分类"> | ||
<Select> | ||
<Select.Option value="">请选择分类</Select.Option> | ||
{categories.map(item => ( | ||
<Select.Option key={item._id} value={item._id}> | ||
{item.name} | ||
</Select.Option> | ||
))} | ||
</Select> | ||
</Form.Item> | ||
<Form.Item name="quantity" label="商品数量"> | ||
<Input /> | ||
</Form.Item> | ||
<Form.Item name="shipping" label="是否需要运输"> | ||
<Select> | ||
<Select.Option value="1">是</Select.Option> | ||
<Select.Option value="0">否</Select.Option> | ||
</Select> | ||
</Form.Item> | ||
<Form.Item> | ||
<Button type="primary" htmlType="submit"> | ||
添加商品 | ||
</Button> | ||
</Form.Item> | ||
</Form> | ||
); | ||
}; | ||
|
||
return ( | ||
<Layout title="添加商品" subTitle=""> | ||
{addProductForm()} | ||
</Layout> | ||
); | ||
}; | ||
|
||
export default AddProduct; |
69 changes: 69 additions & 0 deletions
69
5.react/8.ecommerce/ecommerce-front/src/components/admin/AdminDashboard.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import React, { useState } from "react"; | ||
import Layout from "../core/Layout"; | ||
import { Jwt } from "../../types/auth"; | ||
import { isAuth } from "../../helpers/auth"; | ||
import { Col, Descriptions, Menu, MenuProps, Row, Typography } from "antd"; | ||
import { Link, useNavigate } from "react-router-dom"; | ||
import { | ||
ShoppingCartOutlined, | ||
UserOutlined, | ||
OrderedListOutlined, | ||
} from "@ant-design/icons"; | ||
|
||
const items: MenuProps["items"] = [ | ||
{ | ||
label: "添加分类", | ||
key: "/create/category", | ||
icon: <ShoppingCartOutlined />, | ||
}, | ||
{ | ||
label: "添加产品", | ||
key: "/create/product", | ||
icon: <UserOutlined />, | ||
}, | ||
{ | ||
label: "订单列表", | ||
key: "/admin/orders", | ||
icon: <OrderedListOutlined />, | ||
}, | ||
]; | ||
const AdminDashboard = () => { | ||
const { | ||
user: { name, email }, | ||
} = isAuth() as Jwt; | ||
|
||
const navigate = useNavigate(); | ||
|
||
const [current, setCurrent] = useState(""); | ||
const onClick: MenuProps["onClick"] = (e) => { | ||
setCurrent(e.key); | ||
navigate(e.key); | ||
}; | ||
|
||
const adminLinks = () => ( | ||
<> | ||
<Typography.Title level={5}>管理员链接</Typography.Title> | ||
<Menu items={items} onClick={onClick} selectedKeys={[current]}></Menu> | ||
</> | ||
); | ||
|
||
const adminInfo = () => ( | ||
<Descriptions title="管理员信息" bordered> | ||
<Descriptions.Item label="昵称">{name}</Descriptions.Item> | ||
<Descriptions.Item label="邮件">{email}</Descriptions.Item> | ||
<Descriptions.Item label="角色">管理员</Descriptions.Item> | ||
</Descriptions> | ||
); | ||
|
||
return ( | ||
<Layout title="管理员 Dashboard" subTitle=""> | ||
<Row> | ||
<Col span="4">{adminLinks()}</Col> | ||
<Col span="1"></Col> | ||
<Col span="19">{adminInfo()}</Col> | ||
</Row> | ||
</Layout> | ||
); | ||
}; | ||
|
||
export default AdminDashboard; |
18 changes: 18 additions & 0 deletions
18
5.react/8.ecommerce/ecommerce-front/src/components/admin/AdminRoute.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import React, { FC } from "react"; | ||
import { Navigate } from "react-router-dom"; | ||
import { isAuth } from "../../helpers/auth"; | ||
import { Jwt } from "../../types/auth"; | ||
|
||
const AdminRoute: FC<any> = ({ component: Component, ...rest }) => { | ||
const auth = isAuth(); | ||
if (auth) { | ||
const { | ||
user: { role }, | ||
} = auth as Jwt; | ||
if (role === 1) return <Component {...rest} />; | ||
} | ||
|
||
return <Navigate replace to="/signin" />; | ||
}; | ||
|
||
export default AdminRoute; |
12 changes: 12 additions & 0 deletions
12
5.react/8.ecommerce/ecommerce-front/src/components/admin/Dashboard.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import React from "react" | ||
import Layout from "../core/Layout" | ||
|
||
const Dashboard = () => { | ||
return ( | ||
<Layout title="用户 Dashboard" subTitle=""> | ||
Dashboard | ||
</Layout> | ||
) | ||
} | ||
|
||
export default Dashboard |
14 changes: 14 additions & 0 deletions
14
5.react/8.ecommerce/ecommerce-front/src/components/admin/PrivateRoute.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import React, { FC } from "react"; | ||
import { Navigate } from "react-router-dom"; | ||
import { isAuth } from "../../helpers/auth"; | ||
|
||
const PrivateRoute: FC<any> = ({ component: Component, ...rest }) => { | ||
const auth = isAuth(); | ||
if (auth) { | ||
return <Component {...rest} />; | ||
} | ||
|
||
return <Navigate replace to="/signin" />; | ||
}; | ||
|
||
export default PrivateRoute; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.