Commit 44042d09 authored by chaiwat's avatar chaiwat

7/3/2565

parent 3120dd73
This diff is collapsed.
......@@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@ant-design/charts": "^1.3.5",
"@craco/craco": "^6.4.3",
"@line/liff": "^2.17.0",
"@testing-library/jest-dom": "^5.11.4",
......
......@@ -7,6 +7,7 @@ import {
ToolOutlined,
TeamOutlined,
// SettingOutlined,
CommentOutlined,
LogoutOutlined,
// DollarOutlined,
} from "@ant-design/icons";
......@@ -15,7 +16,7 @@ import {
import { sendLogout, FetchGarage } from "../../services";
const { Sider } = Layout;
const { SubMenu } = Menu;
// const { SubMenu } = Menu;
const { Title } = Typography;
export default function App() {
......@@ -49,7 +50,7 @@ export default function App() {
});
}
// console.log("data", countNoti.length);
// console.log("data", countNoti.length);
const onCollapse = (collapsed) => {
setCollapsed(collapsed);
......@@ -106,7 +107,6 @@ export default function App() {
<Link to={"/admin/dashboard"}>หน้าแรก</Link>
</Menu.Item>
<SubMenu key="sub1" icon={<ToolOutlined />} title="สมาชิก">
<Menu.Item key="3" icon={<ToolOutlined />}>
<Link to={"/admin/all-garage"}>ร้านซ่อม</Link>
</Menu.Item>
......@@ -114,9 +114,8 @@ export default function App() {
<Menu.Item key="4" icon={<TeamOutlined />}>
<Link to={"/admin/all-member"}>ลูกค้าสมาชิก</Link>
</Menu.Item>
</SubMenu>
<Menu.Item key="6" icon={<SolutionOutlined />}>
<Menu.Item key="5" icon={<SolutionOutlined />}>
<Badge count={countNoti.length}>
<Link
to={"/admin/approve"}
......@@ -127,6 +126,10 @@ export default function App() {
</Badge>
</Menu.Item>
<Menu.Item key="6" icon={<CommentOutlined />}>
<Link to={"/admin/reported"}>การแจ้งปัญหา</Link>
</Menu.Item>
{/*
<Menu.Item key="10" icon={<DollarOutlined />}>
<Link to={"/dashboard/payment"}>การชำระเงิน</Link>
......
......@@ -6,8 +6,8 @@ import {
AppstoreAddOutlined,
ToolOutlined,
OrderedListOutlined,
UserAddOutlined,
TeamOutlined,
// UserAddOutlined,
// TeamOutlined,
FileSearchOutlined,
CommentOutlined,
// SettingOutlined,
......@@ -60,14 +60,18 @@ export default function App() {
>
<Row className="display-flex-center">
<Col>
<Title level={5} style={{color: "#ffbf00"}}>
<Title level={5} style={{ color: "#ffbf00" }}>
<Avatar
style={{ backgroundColor: "#ffbf00", verticalAlign: "middle" }}
style={{
backgroundColor: "#ffbf00",
verticalAlign: "middle",
}}
size="large"
gap={"gap"}
>
{garageName}
</Avatar> &nbsp;
</Avatar>{" "}
&nbsp;
{garageName}
</Title>
</Col>
......@@ -89,23 +93,24 @@ export default function App() {
<Menu.Item key="2" icon={<OrderedListOutlined />}>
<Link to={"/dashboard/all-repair"}>งานซ่อมทั้งหมด</Link>
</Menu.Item>
<Menu.Item key="6" icon={<FileSearchOutlined />}>
<Link to={"/dashboard/search-repair"}>ค้นหาการซ่อม</Link>
</Menu.Item>
{/* <Menu.Item key="4" icon={<ToolOutlined />}>
<Link to={"/dashboard/status"}>สถานะการซ่อม</Link>
</Menu.Item> */}
</SubMenu>
<SubMenu key="sub2" icon={<TeamOutlined />} title="จัดการลูกค้า">
{/* <SubMenu key="sub2" icon={<TeamOutlined />} title="จัดการลูกค้า">
<Menu.Item key="5" icon={<UserAddOutlined />}>
<Link to={"/dashboard/add-member"}>ลงทะเบียนลูกค้า</Link>
</Menu.Item>
<Menu.Item key="6" icon={<FileSearchOutlined />}>
<Link to={"/dashboard/search-repair"}>ค้นหาการซ่อม</Link>
</Menu.Item>
<Menu.Item key="7" icon={<TeamOutlined />}>
<Link to={"/dashboard/member"}>ลูกค้าของฉัน</Link>
</Menu.Item>
</SubMenu>
{/*
</SubMenu> */}
{/*
<Menu.Item key="10" icon={<DollarOutlined />}>
<Link to={"/dashboard/payment"}>การชำระเงิน</Link>
</Menu.Item> */}
......
......@@ -141,7 +141,35 @@ const PagesRoutes = [
// Admin Approve
{
path: '/admin/approve',
component: lazy(() => import('../../view/Admin/Approve')),
component: lazy(() => import('../../view/Admin/ApproveSetting/Approve')),
layout: 'VerticalLayout',
},
// Admin Approve Garage Detail
{
path: '/admin/approve/detail',
component: lazy(() => import('../../view/Admin/ApproveSetting/DetailApprove')),
layout: 'VerticalLayout',
},
// Admin Member Setting
{
path: '/admin/all-member',
component: lazy(() => import('../../view/Admin/MemberSetting/Member')),
layout: 'VerticalLayout',
},
// Admin Member History
{
path: '/admin/all-member/repair-history',
component: lazy(() => import('../../view/Admin/MemberSetting/HistoryRepair')),
layout: 'VerticalLayout',
},
// Admin Reported
{
path: '/admin/reported',
component: lazy(() => import('../../view/Admin/Reported')),
layout: 'VerticalLayout',
},
......
......@@ -134,7 +134,17 @@ export const InsertSpare = (data) => {
});
};
// get data FetctDetailByGarageID
// get data FetctDetailAll Spare
export const FetchAllSpare = () => {
return axios
.get(process.env.REACT_APP_SECRET_API + "/repairdetail/getallspare")
.then((response) => response.data)
.catch((err) => {
console.log(err);
});
};
// get data FetctSpairByDetailID
export const FetchSpareByDetailID = (data) => {
return axios
......@@ -170,6 +180,16 @@ export const UpdateDetail = (data) => {
});
};
export const ApproveGarage = (data) => {
console.log(data);
return axios
.put(process.env.REACT_APP_SECRET_API + "/garage/approve", data)
.then((response) => response.data)
.catch((err) => {
console.log(err);
});
};
// Insert Member
export const InsertMember = (data) => {
// console.log('service', data)
......@@ -210,7 +230,6 @@ export const InsertReport = (data) => {
});
};
// get All Member
export const FetchMemberAll = () => {
return axios
......@@ -221,6 +240,15 @@ export const FetchMemberAll = () => {
});
};
// get All Report
export const FetchReportAll = () => {
return axios
.get(process.env.REACT_APP_SECRET_API + "/report/all")
.then((response) => response.data)
.catch((err) => {
console.log(err);
});
};
// // logout
// export const sendLogout = () => {
......
import React from 'react'
function Approve() {
return (
<>Approve</>
)
}
export default Approve
\ No newline at end of file
import React, { useState, useEffect } from "react";
import Highlighter from "react-highlight-words";
import { Col, Row, Typography, Button, Table, Input, Space } from "antd";
import { SearchOutlined } from "@ant-design/icons";
import { Link } from "react-router-dom";
// import services
import { FetchGarage } from "../../../services";
const { Title, Text } = Typography;
function Approve() {
const [datas, setDatas] = useState([]);
const [searchText, setSearchText] = useState("");
const [searchedColumn, setSearchedColumn] = useState("");
useEffect(() => {
const getGarage = async () => {
await FetchGarage().then((response) => {
if (response.code === 500) {
console.log("data", response);
} else {
// console.log("data", response);
setDatas(response.data);
}
});
};
getGarage();
}, []);
let non_approve = [];
if (datas !== null) {
datas.forEach((e) => {
if (e.confirmation === "non-approved") {
non_approve.push(e);
}
});
}
// console.log("non-approve", non_approve);
const getColumnSearchProps = (dataIndex) => ({
filterDropdown: ({
setSelectedKeys,
selectedKeys,
confirm,
clearFilters,
}) => (
<div style={{ padding: 8 }}>
<Input
ref={(node) => {
// searchInput = node;
}}
placeholder={`ค้นหา ${dataIndex}`}
value={selectedKeys[0]}
onChange={(e) =>
setSelectedKeys(e.target.value ? [e.target.value] : [])
}
onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)}
style={{ marginBottom: 8, display: "block" }}
/>
<Space>
<Button
type="primary"
onClick={() => handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{ width: 90 }}
>
ค้นหา
</Button>
<Button
onClick={() => handleReset(clearFilters)}
size="small"
style={{ width: 90 }}
>
ล้าง
</Button>
</Space>
</div>
),
filterIcon: (filtered) => (
<SearchOutlined style={{ color: filtered ? "#1890ff" : undefined }} />
),
onFilter: (value, record) =>
record[dataIndex]
? record[dataIndex]
.toString()
.toLowerCase()
.includes(value.toLowerCase())
: "",
onFilterDropdownVisibleChange: (visible) => {
if (visible) {
// setTimeout(() => searchInput.select(), 100);
}
},
render: (text) =>
searchedColumn === dataIndex ? (
<Highlighter
highlightStyle={{ backgroundColor: "#ffc069", padding: 0 }}
searchWords={[searchText]}
autoEscape
textToHighlight={text ? text.toString() : ""}
/>
) : (
text
),
});
const handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm();
setSearchText(selectedKeys[0]);
setSearchedColumn(dataIndex);
// this.setState({
// searchText: selectedKeys[0],
// searchedColumn: dataIndex,
// });
};
const handleReset = (clearFilters) => {
clearFilters();
// this.setState({ searchText: "" });
setSearchText("");
};
const columns = [
{
title: "ลำดับ",
width: "5%",
render: (value, item, index) => {
return <>{index+1}</>;
},
},
{
title: "วันที่ลงทะเบียน",
dataIndex: "registration_date",
key: "registration_date",
width: "10%",
...getColumnSearchProps("registration_date"),
},
{
title: "ชื่อร้าน",
dataIndex: "garage_name",
key: "garage_name",
width: "20%",
},
{
title: "ประเภทร้านซ่อม",
// dataIndex: "member_name",
key: "garage_type",
width: "35%",
render: (record) => {
return <>{JSON.parse(record.garage_type).join(", ")} </>;
},
},
{
title: "การอนุมัติ",
width: "10%",
render: () => {
return <><Text>ยังไม่อนุมัติ</Text></>;
},
},
{
title: "เพิ่มเติม",
key: "garageID",
width: "15%",
render: (record) => {
return (
<>
<Link
to={{
pathname: "/admin/approve/detail",
state: {
data: record,
},
}}
>
<Text style={{ color: "blue" }}>
{/* <ToolOutlined style={{fontSize: "200%"}} /> */}
ดูรายละเอียดเพิ่มเติม
</Text>
</Link>
</>
);
},
},
];
return (
<>
<Row style={{ padding: "3% 0 0 0" }}>
<Col span={24}>
<Title level={3}>อนุมัติร้านซ่อม</Title>
</Col>
</Row>
<div className="div-p-5">
<Table
scroll={{ x: 500 }}
bordered
columns={columns}
dataSource={non_approve}
/>
</div>
</>
);
}
export default Approve;
import React, { useState } from "react";
import { useLocation } from "react-router-dom";
import { PageHeader, Button, Row, Col, Modal } from "antd";
// import { ExclamationCircleOutlined } from "@ant-design/icons";
import {
withScriptjs,
withGoogleMap,
GoogleMap,
Marker,
} from "react-google-maps";
import { ApproveGarage } from "../../../services";
import IconCar from "../../../assets/icons/car.png";
function DetailApprove() {
const [visible, setVisible] = useState(false);
const [visible2, setVisible2] = useState(false);
const [confirmLoading, setConfirmLoading] = useState(false);
let location = useLocation;
const data = location().state.data;
let newLatLng = [
{
lat: JSON.parse(data.address_map)[0],
lng: JSON.parse(data.address_map)[1],
},
];
// console.log(newLatLng);
const MapWithAMarker = withScriptjs(
withGoogleMap(() => (
<GoogleMap defaultZoom={15} defaultCenter={newLatLng[0]}>
<Marker
position={newLatLng[0]}
icon={{
url: IconCar,
scaledSize: new window.google.maps.Size(40, 40),
}}
/>
</GoogleMap>
))
);
const showModal = () => {
setVisible2(true);
};
// console.log("data", data);
const handleOk = (id) => {
let data = {
garageID: id
}
ApproveGarage(data)
// console.log("id", id);
setConfirmLoading(true);
setTimeout(() => {
setVisible2(false);
setConfirmLoading(false);
window.location.reload(false)
}, 2000);
};
const handleCancel = () => {
// console.log("Clicked cancel button");
setVisible2(false);
};
return (
<>
<Row className="div-p-5">
<Col span={24} className="pageHeader" style={{ padding: "2%" }}>
<PageHeader
className="site-page-header"
onBack={() => window.history.back()}
title={data.garage_name}
subTitle="ข้อมูลของร้าน"
extra={[
<Button key="3" onClick={() => setVisible(true)}>
ดูตำแหน่งของร้าน
</Button>,
]}
>
<Row className="text-left" gutter={[0, 16]}>
<Col sx={24} sm={24} lg={{ span: 11, offset: 1 }}>
เจ้าของร้าน : คุณ {data.user_name}{" "}
</Col>
<Col sx={24} sm={24} lg={{ span: 11, offset: 1 }}>
ชื่อร้าน : {data.garage_name}{" "}
</Col>
<Col sx={24} sm={24} lg={{ span: 11, offset: 1 }}>
ประเภท : {JSON.parse(data.garage_type).join(", ")}{" "}
</Col>
<Col sx={24} sm={24} lg={{ span: 11, offset: 1 }}>
สมัครเข้าร่วมเมื่อ : {data.registration_date}{" "}
</Col>
<Col sx={24} sm={24} lg={{ span: 11, offset: 1 }}>
E-mail : {data.email}{" "}
</Col>
<Col sx={24} sm={24} lg={{ span: 11, offset: 1 }}>
หมายเลขติดต่อ : {data.tel}{" "}
</Col>
<Col sx={24} sm={24} lg={{ span: 23, offset: 1 }}>
เวลาเปิด-ปิด ของร้าน : {data.on_time} - {data.off_time} น.{" "}
</Col>
<Col sx={24} sm={24} lg={{ span: 23, offset: 1 }}>
<b>ที่อยู่ของร้าน</b> : {data.address_number} หมู่ {data.moo}{" "}
ซอย {data.alley} ถนน {data.road} ต.{data.sub_district} อ.
{data.district} จ.{data.province} {data.pos_code}{" "}
</Col>
</Row>
<Col style={{ padding: "3% 0 0 0" }} span={24}>
<Button
className="bt-them"
onClick={showModal}
>
อนุมัติ
</Button>
</Col>
</PageHeader>
</Col>
</Row>
<Modal
title={<>ตำแหน่งของร้าน {data.garage_name}</>}
centered
visible={visible}
onOk={() => setVisible(false)}
onCancel={() => setVisible(false)}
width={700}
>
<MapWithAMarker
googleMapURL="https://maps.googleapis.com/maps/api/js?key=AIzaSyBYQsoMGSxKVOe6vilIiEedgPhRDjcPbC8&libraries=geometry,drawing,places"
loadingElement={<div style={{ height: "100%" }} />}
containerElement={<div style={{ height: "400px" }} />}
mapElement={<div style={{ height: "100%" }} />}
/>
</Modal>
<Modal
title="อนุมัติร้านซ่อม"
visible={visible2}
onOk={() => {
handleOk(data.garageID);
}}
confirmLoading={confirmLoading}
onCancel={handleCancel}
>
<p>ยืนยันที่จะให้ร้าน {data.garage_name} เข้าร่วมกับระบบจัดการร้านซ่อม</p>
</Modal>
</>
);
}
export default DetailApprove;
......@@ -58,7 +58,7 @@ function Garage() {
</Col>
<Col span={24}>
<Collapse>
<Collapse defaultActiveKey={['0']}>
{datas.length !== 0 ? (
<>
{datas.map((val, index) => {
......
import React, { useState, useEffect } from "react";
import { useLocation } from "react-router-dom";
import { Card, Col, Row, Avatar, Image, Typography, Collapse } from "antd";
// import Service
import { FetchDetailByMember, FetchAllSpare } from "../../../services";
const { Text, Title } = Typography;
const { Panel } = Collapse;
function HistoryRepair() {
let location = useLocation();
const Ndata = location.state.data;
//set useState
const [datas, setDatas] = useState([]);
const [spares, setSpares] = useState([]);
// console.log("tel", Ndata.member_tel);
useEffect(() => {
let data = {
member_tel: Ndata.member_tel,
};
const getDetailByMember = async () => {
if (data.member_tel !== undefined) {
await FetchDetailByMember(data).then(async (response) => {
await setDatas(response.data);
// console.log("data", response.data);
});
} else {
setDatas([]);
}
};
getDetailByMember();
const getAllSpare = async () => {
await FetchAllSpare().then((response) => {
if (response.data) {
setSpares(response.data);
}
// console.log("spares", response.data);
});
};
getAllSpare();
}, [Ndata]);
return (
<>
<Row>
<Col span={24} className="div-p-5 text-left">
<Card
title={
<>
<Avatar
src={<Image src={Ndata.imageUrl} style={{ width: 32 }} />}
/>{" "}
<Text strong>{Ndata.member_name}</Text> {<br />}
</>
}
>
{datas.length !== 0 ? (
<>
{datas.map((val, index) => {
return (
<>
{/* defaultActiveKey={["1"]} */}
<Collapse>
<Panel
header={
<>
{val.device_type === "รถยนต์" ||
val.device_type === "รถจักรยานยนต์" ? (
<Col>
<Row>
<Title level={5}>{val.device_type}</Title>
</Row>
<Row>
<Text>
{val.car_number} {val.car_province}
</Text>
</Row>
</Col>
) : (
<Col>
<Row>
<Title level={5}>{val.device_type}</Title>
</Row>
<Row>
<Text>{val.equipment}</Text>
</Row>
</Col>
)}
</>
}
key="1"
extra={
<>
<Col>
<Row>
<Text>
<b>รับซ่อมเมื่อ</b> {val.repair_date}
</Text>
</Row>
<Row>
<Text>{val.status}</Text>
</Row>
</Col>
</>
}
>
{/* Content */}
<div>
<Row gutter={[0, 16]}>
<Col xs={24} lg={{ span: 11, offset: 1 }}>
<Text>
<b>ร้านซ่อม :</b> {val.garage_name}
</Text>
</Col>
<Col xs={24} lg={{ span: 11, offset: 1 }}>
<Text>
<b>การซ่อมเบื้องต้น :</b> {val.repair_details}
</Text>
</Col>
<Col xs={24} lg={{ span: 16, offset: 1 }}>
<Text>
<b>รายละเอียดการซ่อม</b>
</Text>
<br />
{spares.length !== 0 ? (
<>
{spares.map((data, index) => {
return (
<>
{/* {val.detailsID} */}
{/* {data.detailsID} */}
{val.detailsID === data.detailsID ? (
<>
<Row>
<Col
lg={{ span: 11, offset: 1 }}
>
<Text>
-{" "}
{
JSON.parse(data.spare)
.spareName
}
</Text>
</Col>
</Row>
</>
) : null}
</>
);
})}
</>
) : null}
</Col>
</Row>
</div>
</Panel>
</Collapse>
</>
);
})}
</>
) : null}
</Card>
</Col>
</Row>
</>
);
}
export default HistoryRepair;
import React, { useState, useEffect } from "react";
import { Table, Input, Button, Space, Row, Col, Typography, Avatar, Image } from "antd";
import Highlighter from "react-highlight-words";
import { SearchOutlined } from "@ant-design/icons";
import { Link } from "react-router-dom";
// import Service
import { FetchMemberAll } from "../../../services";
const { Title, Text } = Typography
export default function Member() {
const [searchText, setSearchText] = useState("");
const [searchedColumn, setSearchedColumn] = useState("");
const [datas, setDatas] = useState([]);
// let userId = JSON.parse(localStorage.getItem("user")).userData.userId;
useEffect(() => {
// let data = {
// userId: userId,
// };
const getMember = async () => {
await FetchMemberAll().then(async (response) => {
if (response.code === 500) {
console.log("data", response);
} else {
await setDatas(response.data);
}
// console.log('data', response)
});
};
getMember();
}, []);
const getColumnSearchProps = (dataIndex) => ({
filterDropdown: ({
setSelectedKeys,
selectedKeys,
confirm,
clearFilters,
}) => (
<div style={{ padding: 8 }}>
<Input
ref={(node) => {
// searchInput = node;
}}
placeholder={`ค้นหา ${dataIndex}`}
value={selectedKeys[0]}
onChange={(e) =>
setSelectedKeys(e.target.value ? [e.target.value] : [])
}
onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)}
style={{ marginBottom: 8, display: "block" }}
/>
<Space>
<Button
type="primary"
onClick={() => handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{ width: 90 }}
>
ค้นหา
</Button>
<Button
onClick={() => handleReset(clearFilters)}
size="small"
style={{ width: 90 }}
>
ล้าง
</Button>
</Space>
</div>
),
filterIcon: (filtered) => (
<SearchOutlined style={{ color: filtered ? "#1890ff" : undefined }} />
),
onFilter: (value, record) =>
record[dataIndex]
? record[dataIndex]
.toString()
.toLowerCase()
.includes(value.toLowerCase())
: "",
onFilterDropdownVisibleChange: (visible) => {
if (visible) {
// setTimeout(() => searchInput.select(), 100);
}
},
render: (text) =>
searchedColumn === dataIndex ? (
<Highlighter
highlightStyle={{ backgroundColor: "#ffc069", padding: 0 }}
searchWords={[searchText]}
autoEscape
textToHighlight={text ? text.toString() : ""}
/>
) : (
text
),
});
const handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm();
setSearchText(selectedKeys[0]);
setSearchedColumn(dataIndex);
// this.setState({
// searchText: selectedKeys[0],
// searchedColumn: dataIndex,
// });
};
const handleReset = (clearFilters) => {
clearFilters();
// this.setState({ searchText: "" });
setSearchText("");
};
const columns = [
{
title: "Line",
width: "20%",
render: (record) => {
return (
<>
<Avatar
src={<Image src={record.imageUrl} style={{ width: 32 }} />}
/> {" "}
<Text strong>{record.userName}</Text> {<br />}
</>
);
},
},
{
title: "หมายเลขสมาชิก",
dataIndex: "member_tel",
key: "member_tel",
width: "20%",
...getColumnSearchProps("member_tel"),
},
{
title: "ชื่อ",
dataIndex: "member_name",
key: "member_name",
width: "20%",
...getColumnSearchProps("member_name"),
},
{
title: "วันที่ลงทะเบียน",
dataIndex: "registration_date",
key: "registration_date",
width: "20%",
...getColumnSearchProps("registration_date"),
},
{
title: "ประวัติการซ่อม",
key: "member_tel",
width: "20%",
render: (record) => {
return (
<>
<Link
to={{
pathname: "/admin/all-member/repair-history",
state: {
data: record,
},
}}
>
<Text style={{ color: "blue" }}>
{/* <ToolOutlined style={{fontSize: "200%"}} /> */}
ดูประวัติการซ่อม
</Text>
</Link>
</>
);
},
},
];
return (
<>
<Row style={{padding: "3% 0 0 0"}}>
<Col span={24}>
<Title level={3}>ลูกค้าทั้งหมด</Title>
</Col>
</Row>
<div className="div-p-5">
<Table
scroll={{ x: 500 }}
bordered
columns={columns}
dataSource={datas}
/>
</div>
</>
);
}
import React, { useState, useEffect } from "react";
import { Col, Row, Comment, List, Typography } from "antd";
import { FetchReportAll } from "../../services";
import { PhoneOutlined } from "@ant-design/icons";
// import IconGarage from "../../assets/icons/garage.png";
import IconMember from "../../assets/icons/profile.png";
const { Title } = Typography;
function Reported() {
//set useState
const [datas, setDatas] = useState([]);
useEffect(() => {
const getAllReport = async () => {
await FetchReportAll().then((response) => {
if (response.data) {
setDatas(response.data);
// console.log("report", response.data);
}
});
};
getAllReport();
}, []);
return (
<>
<Row className="text-left div-p-5">
<Col>
<Title level={3}>การแจ้งปัญหาการใช้งาน</Title>
</Col>
<Col style={{ padding: "2%" }} span={24}>
{datas.length !== 0 ? (
<>
<List
className="comment-list"
header={`${datas.length} ปัญหาที่แจ้งเข้ามา`}
itemLayout="horizontal"
dataSource={datas}
renderItem={(item) => (
<li>
<Comment
actions={[
<span key="comment-basic-reply-to">
{item.party === "garage" ? (
<>
ร้านซ่อม, <PhoneOutlined /> {item.report_tel}
</>
) : (
<>
ลูกค้า, <PhoneOutlined /> {item.report_tel}
</>
)}
</span>,
]}
author={item.name}
avatar={IconMember}
content={item.report_detail}
datetime={item.report_date}
/>
</li>
)}
/>
</>
) : null}
</Col>
</Row>
</>
);
}
export default Reported;
......@@ -4,7 +4,6 @@ import {
PageHeader,
Button,
Statistic,
Descriptions,
Row,
Col,
Modal,
......@@ -114,22 +113,19 @@ export default function GarageDetail() {
</Button>,
]}
>
<Row gutter={[0, 16]}>
<Col span={24}>
<Descriptions size="small" column={2}>
<Descriptions.Item label="เจ้าของร้าน">
คุณ {garage.user_name}
</Descriptions.Item>
<Descriptions.Item label="ชื่อร้าน">
{garage.garage_name}
</Descriptions.Item>
<Descriptions.Item label="ประเภท">
{JSON.parse(garage.garage_type).join(", ")}
</Descriptions.Item>
<Descriptions.Item label="เข้าร่วมระบบ">
{garage.registration_date}
</Descriptions.Item>
</Descriptions>
<Row className="text-left" gutter={[0, 16]}>
<Col sx={24} sm={24} lg={{ span: 11, offset: 1 }}>
เจ้าของร้าน : คุณ {garage.user_name}
</Col>
<Col sx={24} sm={24} lg={{ span: 11, offset: 1 }}>
ชื่อร้าน : {garage.garage_name}
</Col>
<Col sx={24} sm={24} lg={{ span: 11, offset: 1 }}>
ประเภท : {JSON.parse(garage.garage_type).join(", ")}
</Col>
<Col sx={24} sm={24} lg={{ span: 11, offset: 1 }}>
เข้าร่วมระบบ : {garage.registration_date}
</Col>
<Statistic
......
......@@ -36,15 +36,15 @@ const { confirm } = Modal;
const { Option } = Select;
export default function SpareAdd(props) {
const {detailID, memberTel} = props;
// console.log(memberTel, detailID)
const { detailID, memberTel, sandStatus, sandPayment } = props;
// console.log(sandPayment, sandStatus)
// Set State
const [visible, setVisible] = useState(false);
const [confirmLoading, setConfirmLoading] = useState(false);
const [datas, setDatas] = useState([]);
const [status, setStatus] = useState('อยู่ระหว่างการซ่อม');
const [payment, setPayment] = useState('ยังไม่ได้ชำระ');
const [status, setStatus] = useState(sandStatus);
const [payment, setPayment] = useState(sandPayment);
// state spare
const [spareName, setSpareName] = useState();
......@@ -55,8 +55,8 @@ export default function SpareAdd(props) {
useEffect(() => {
const getSpare = async () => {
let data = {
detailID: detailID
}
detailID: detailID,
};
await FetchSpareByDetailID(data).then((response) => {
if (response.data) {
setDatas(response.data);
......@@ -64,6 +64,7 @@ export default function SpareAdd(props) {
});
setSumPrice(qty * qtyPrice);
};
getSpare();
}, [detailID, qty, qtyPrice]);
......@@ -156,19 +157,18 @@ export default function SpareAdd(props) {
};
const handleSave = () => {
let data = {
status: status,
status_payment: payment,
sumPrice: sum,
detailsID: detailID
}
detailsID: detailID,
};
// console.log('data', data)
UpdateDetail(data)
UpdateDetail(data);
setTimeout(() => {
window.location.reload(false)
window.location.reload(false);
}, 1);
}
};
return (
<>
......@@ -308,14 +308,14 @@ export default function SpareAdd(props) {
<Title level={5}>
<Text>สถานะการซ่อม</Text>
</Title>
<div className="div-select">
<Select
allowClear
style={{ width: "100%" }}
defaultValue="อยู่ระหว่างการซ่อม"
defaultValue={sandStatus}
onChange={(e) => {
setStatus(e);
// console.log(e)
}}
>
<Option value="อยู่ระหว่างการซ่อม">
......@@ -330,12 +330,12 @@ export default function SpareAdd(props) {
<Title level={5}>
<Text>การชำระเงิน</Text>
</Title>
<div className="div-select">
<Select
allowClear
style={{ width: "100%" }}
defaultValue={{ value: 'ยังไม่ได้ชำระ' }}
defaultValue={sandPayment}
onChange={(e) => {
setPayment(e);
}}
......
import React, { useEffect, useState } from "react";
import { Col, Divider, Row, Typography } from "antd";
import { Col, Divider, Row, Typography, Avatar, Image } from "antd";
import { MobileOutlined, DollarOutlined } from "@ant-design/icons";
// import Service
......@@ -77,6 +77,10 @@ export default function App(props) {
<Col xs={24} md={{ span: 11, offset: 1 }} lg={{ span: 7, offset: 1 }}>
<Text className="color-bfbf">ลูกค้า</Text>
<br /> <br />
<Avatar
src={<Image src={datas.imageUrl} style={{ width: 32 }} />}
/>
<Title level={4} className="color-fff">
<Text className="color-fff">คุณ {datas.member_name}</Text>
</Title>
......
......@@ -5,7 +5,7 @@ import { Link } from "react-router-dom";
// Import services
import {
FetctDetailByGarage,
FetctMemberByGarage,
// FetctMemberByGarage,
FetchMemberAll,
} from "../../../services";
......@@ -24,7 +24,7 @@ export default function Ecommerce() {
// let location = useLocation();
const [datas, setDatas] = useState([]);
const [member, setMember] = useState([]);
// const [member, setMember] = useState([]);
const [allMember, setAllMember] = useState([]);
// const detailID = location.state
......@@ -42,20 +42,20 @@ export default function Ecommerce() {
});
};
let data = {
userId: JSON.parse(localStorage.getItem("user")).userData.userId,
};
const getMember = async () => {
await FetctMemberByGarage(data).then(async (response) => {
if (response.code === 500) {
console.log("data", response);
} else {
await setMember(response.data);
}
// console.log('data', response.data)
});
};
// let data = {
// userId: JSON.parse(localStorage.getItem("user")).userData.userId,
// };
// const getMember = async () => {
// await FetctMemberByGarage(data).then(async (response) => {
// if (response.code === 500) {
// console.log("data", response);
// } else {
// await setMember(response.data);
// }
// // console.log('data', response.data)
// });
// };
const getMemberAll = async () => {
await FetchMemberAll().then(async (response) => {
......@@ -66,12 +66,10 @@ export default function Ecommerce() {
};
getDetailByGarage();
getMember();
getMemberAll();
}, []);
let sumPrice = 0;
let listMember = [];
let listAllMember = [];
if (datas !== null) {
......@@ -80,12 +78,12 @@ export default function Ecommerce() {
}
}
if (member !== null) {
for (let i = 0; i < member.length; i++) {
// console.log(member)
listMember.push(member[i]);
}
}
// if (member !== null) {
// for (let i = 0; i < member.length; i++) {
// // console.log(member)
// listMember.push(member[i]);
// }
// }
if (allMember !== null) {
for (let i = 0; i < allMember.length; i++) {
......@@ -124,28 +122,29 @@ export default function Ecommerce() {
<Divider />
<Row>
<Col span={12}>
{/* <Col span={12}>
<Row gutter={16}>
<Col xs={24} lg={{ span: 11 }}>
<Statistic title="ปฏิทิน" value={dateNow} />
</Col>
<Col xs={24} lg={{ span: 11, offset: 1 }}>
<Statistic
title="ลูกค้าทั้งหมดของระบบ"
value={listAllMember.length}
/>
</Col>
</Row>
</Col>
</Col> */}
<Col span={12}>
<Col span={24}>
<Row gutter={16}>
<Col xs={24} lg={{ span: 11 }}>
<Col xs={24} lg={{ span: 8 }}>
<Statistic title="ปฏิทิน" value={dateNow} />
</Col>
<Col xs={24} lg={{ span: 8 }}>
<Link to={"/dashboard/member"}>
<Statistic title="ลูกค้าของฉัน" value={listMember.length} />
<Statistic
title="ลูกค้าทั้งหมดของระบบ"
value={listAllMember.length}
/>
</Link>
</Col>
<Col xs={24} lg={{ span: 11, offset: 1 }}>
<Col xs={24} lg={{ span: 7, offset: 1 }}>
<Statistic
title="รายได้ทั้งหมดของร้าน (บาท)"
value={sumPrice}
......
import React, { useState, useEffect } from "react";
import { Table, Input, Button, Space, Row, Col, Typography } from "antd";
import { Table, Input, Button, Space, Row, Col, Typography, Avatar, Image } from "antd";
import Highlighter from "react-highlight-words";
import { SearchOutlined } from "@ant-design/icons";
// import { Link } from "react-router-dom";
// import Service
import { FetctMemberByGarage } from "../../../services";
import { FetchMemberAll } from "../../../services";
const { Title } = Typography
const { Title, Text } = Typography
export default function Member() {
const [searchText, setSearchText] = useState("");
......@@ -15,14 +17,14 @@ export default function Member() {
const [datas, setDatas] = useState([]);
let userId = JSON.parse(localStorage.getItem("user")).userData.userId;
// let userId = JSON.parse(localStorage.getItem("user")).userData.userId;
useEffect(() => {
let data = {
userId: userId,
};
// let data = {
// userId: userId,
// };
const getMember = async () => {
await FetctMemberByGarage(data).then(async (response) => {
await FetchMemberAll().then(async (response) => {
if (response.code === 500) {
console.log("data", response);
} else {
......@@ -32,27 +34,8 @@ export default function Member() {
});
};
getMember();
}, [userId]);
let listData = [];
if (datas.length !== 0) {
for (let i = 0; i < datas.length; i++) {
let ads = JSON.parse(datas[i].member_ads);
let newData = {
member_name: datas[i].member_name,
member_tel: datas[i].member_tel,
register: datas[i].registration_date,
address_details: ads.address_details,
sub_district: ads.sub_district,
district: ads.district,
province: ads.province,
poscode: ads.poscode,
};
listData.push(newData);
}
}
}, []);
const getColumnSearchProps = (dataIndex) => ({
filterDropdown: ({
......@@ -139,6 +122,20 @@ export default function Member() {
};
const columns = [
{
title: "Line",
width: "30%",
render: (record) => {
return (
<>
<Avatar
src={<Image src={record.imageUrl} style={{ width: 32 }} />}
/> {" "}
<Text strong>{record.userName}</Text> {<br />}
</>
);
},
},
{
title: "หมายเลขสมาชิก",
dataIndex: "member_tel",
......@@ -150,34 +147,26 @@ export default function Member() {
title: "ชื่อ",
dataIndex: "member_name",
key: "member_name",
width: "20%",
width: "30%",
...getColumnSearchProps("member_name"),
},
{
title: "ที่อยู่",
render: (record) => {
return (
<>
{record.address_details}, {record.sub_district}, {record.district},{" "}
{record.province}, {record.poscode}
</>
);
},
},
{
title: "วันที่ลงทะเบียน",
dataIndex: "register",
key: "register",
dataIndex: "registration_date",
key: "registration_date",
width: "20%",
...getColumnSearchProps("register"),
...getColumnSearchProps("registration_date"),
},
];
return (
<>
<Row style={{padding: "3% 0 0 0"}}>
<Col span={24}>
<Title level={3}>ลูกค้าทั้งหมดของร้าน</Title>
<Title level={3}>ลูกค้าทั้งหมดของระบบ</Title>
</Col>
</Row>
<div className="div-p-5">
......@@ -185,7 +174,7 @@ export default function Member() {
scroll={{ x: 500 }}
bordered
columns={columns}
dataSource={listData}
dataSource={datas}
/>
</div>
</>
......
......@@ -18,15 +18,17 @@ export default function ShowDetail() {
//use State
const detailID = location.state;
const memberTel = location.state;
// console.log(detailID, memberTel.memberTel);
const detailID = location.state.detailsID;
const memberTel = location.state.memberTel;
const sandStatus = location.state.sandStatus;
const sandPayment = location.state.sandPayment;
console.log('test', sandStatus, sandPayment);
return (
<>
<TitleShowDetail detailID={detailID.detailsID} />
<TitleShowDetail detailID={detailID} />
{/* Show Repair id = {detailID.detailsID} */}
<SpareAdd detailID={detailID.detailsID} memberTel={memberTel.memberTel} />
<SpareAdd detailID={detailID} memberTel={memberTel} sandStatus={sandStatus} sandPayment={sandPayment} />
</>
);
}
import React, { useState, useEffect } from "react";
import Highlighter from "react-highlight-words";
import { Table, Space, Typography, Row, Col, Input, Button } from "antd";
import {
Table,
Space,
Typography,
Row,
Col,
Input,
Button,
Avatar,
Image,
} from "antd";
import { Link } from "react-router-dom";
import { SearchOutlined } from "@ant-design/icons";
......@@ -30,7 +40,7 @@ export default function App() {
getDetailByGarage();
}, []);
// console.log('datas' , datas)
console.log('datas' , datas)
///test
......@@ -116,9 +126,28 @@ export default function App() {
const columns = [
{
title: "ชื่อลูกค้า",
dataIndex: "member_name",
// dataIndex: "member_name",
key: "member_name",
...getColumnSearchProps("member_name"),
render: (record) => {
return (
<>
<Row>
<Col>
<Avatar
src={<Image src={record.imageUrl} style={{ width: 32 }} />}
/>
</Col>
<Col offset={1}>
<Row>
<Text strong>{record.userName}</Text>
</Row>
<Row>{record.member_name}</Row>
</Col>
</Row>
</>
);
},
},
{
title: "รหัสลูกค้า",
......@@ -219,6 +248,8 @@ export default function App() {
state: {
detailsID: record.detailsID,
memberTel: record.member_tel,
sandStatus: record.status,
sandPayment: record.status_payment
},
}}
>
......
import React, { useEffect, useState } from "react";
import React, { useState, useEffect } from "react";
import { Bar } from "@ant-design/plots";
import { Col, Row, Typography } from "antd";
import { CanvasJSChart } from "canvasjs-react-charts";
// Import services
// // Import services
import { FetctDetailByGarage } from "../../services";
export default function Ecommerce(props) {
const { Title } = Typography;
export default function DemoBar() {
const [datas, setDatas] = useState([]);
useEffect(() => {
......@@ -22,69 +24,56 @@ export default function Ecommerce(props) {
getDetailByGarage();
}, []);
// console.log("datas", datas.length);
let carlist = [];
let motolist = [];
let agirculturelist = [];
let repairSum = []
let succeed = []
let notSucceed = []
let repairSum = [];
let succeed = [];
let notSucceed = [];
if (datas !== null) {
for (let i = 0; i < datas.length; i++) {
if (datas[i].device_type === "รถยนต์") {
// console.log(datas[i].device_type);
carlist.push(datas[i].device_type);
}
if (datas[i].device_type === "รถจักรยานยนต์") {
motolist.push(datas[i].device_type);
}
if (datas[i].device_type === "อุปกรณ์การเกษตร") {
agirculturelist.push(datas[i].device_type);
}
// console.log(datas[i].status)
repairSum.push(datas[i].length)
repairSum.push(datas[i].length);
if (datas[i].status === "อยู่ระหว่างการซ่อม") {
succeed.push(datas[i].status)
notSucceed.push(datas[i].status);
// console.log(datas[i].status)
}
if (datas[i].status === "สำเร็จ") {
notSucceed.push(datas[i].status)
succeed.push(datas[i].status);
}
}
}
const options = {
animationEnabled: true,
theme: "light2", // "light1", "dark1", "dark2"
title: {
text: "สรุปการซ่อม",
const data = [
{
type: "การซ่อมทั้งหมด",
value: repairSum.length,
},
data: [
{
// Change type to "bar", "area", "spline", "pie",etc.
type: "column",
// indexLabel: "{label}: {y}%",
startAngle: 90,
dataPoints: [
{ y: repairSum.length, label: "การซ่อมทั้งหมด" },
{ y: notSucceed.length, label: "สำเร็จ" },
{ y: succeed.length, label: "กำลังดำเนินการซ่อม" },
],
type: "สำเร็จ",
value: succeed.length,
},
{
type: "กำลังซ่อม",
value: notSucceed.length,
},
];
const config = {
data,
xField: "value",
yField: "type",
seriesField: "type",
legend: {
position: "top-right",
},
],
};
return (
<>
<CanvasJSChart
options={options}
/* onRef={ref => this.chart = ref} */
/>
<Row>
<Col span={24}>
<Title level={4}>สรุปการซ่อม</Title>
</Col>
</Row>
<Bar {...config} />
</>
);
}
import React, { useEffect, useState } from "react";
import { Typography } from "antd";
import React, { useState, useEffect } from "react";
import { Pie, measureTextWidth } from "@ant-design/plots";
import { Link } from "react-router-dom";
import { CanvasJSChart } from "canvasjs-react-charts";
// Import services
// // Import services
import { FetctDetailByGarage } from "../../services";
import { Col, Row, Typography } from "antd";
const { Title } = Typography;
......@@ -18,8 +15,6 @@ export default function Ecommerce(props) {
let local = {
garageID: JSON.parse(localStorage.getItem("user")).userData.userId,
};
// console.log("local", local);
// console.log(local);
await FetctDetailByGarage(local).then(async (response) => {
await setDatas(response.data);
});
......@@ -27,8 +22,6 @@ export default function Ecommerce(props) {
getDetailByGarage();
}, []);
// console.log("datas", datas);
// console.log("datas", datas.length);
let carlist = [];
let motolist = [];
let agirculturelist = [];
......@@ -52,37 +45,122 @@ export default function Ecommerce(props) {
// console.log('data is null', datas)
}
// console.log("datas", carlist,motolist, agirculturelist );
function renderStatistic(containerWidth, text, style) {
const { width: textWidth, height: textHeight } = measureTextWidth(
text,
style
);
const R = containerWidth / 2; // r^2 = (w / 2)^2 + (h - offsetY)^2
let scale = 1;
if (containerWidth < textWidth) {
scale = Math.min(
Math.sqrt(
Math.abs(
Math.pow(R, 2) /
(Math.pow(textWidth / 2, 2) + Math.pow(textHeight, 2))
)
),
1
);
}
const textStyleStr = `width:${containerWidth}px;`;
return `<div style="${textStyleStr};font-size:${scale}em;line-height:${
scale < 1 ? 1 : "inherit"
};">${text}</div>`;
}
const data = [
{
type: "รถยนต์",
value: carlist.length,
},
const options = {
animationEnabled: true,
theme: "light1", // "light1", "dark1", "dark2"
{
type: "อุปกรณ์เกษตร",
value: agirculturelist.length,
},
{
type: "รถจักยานยนต์",
value: motolist.length,
},
];
const config = {
appendPadding: 10,
data,
angleField: "value",
colorField: "type",
radius: 1,
innerRadius: 0.64,
meta: {
value: {
formatter: (v) => `${v} ¥`,
},
},
label: {
type: "inner",
offset: "-50%",
style: {
textAlign: "center",
},
autoRotate: false,
content: "{value}",
},
statistic: {
title: {
text: "รายการซ่อมทั้งหมด",
offsetY: -4,
customHtml: (container, view, datum) => {
const { width, height } = container.getBoundingClientRect();
const d = Math.sqrt(Math.pow(width / 2, 2) + Math.pow(height / 2, 2));
const text = datum ? datum.type : "การซ่่อมทั้งหมด";
return renderStatistic(d, text, {
fontSize: "10px",
});
},
},
content: {
offsetY: 4,
style: {
fontSize: "20px",
},
customHtml: (container, view, datum, data) => {
const { width } = container.getBoundingClientRect();
const text = datum
? `${datum.value}`
: `${data.reduce((r, d) => r + d.value, 0)}`;
return renderStatistic(width, text, {
fontSize: 32,
});
},
},
},
data: [
// 添加 中心统计文本 交互
interactions: [
{
type: "doughnut", //doughnut
startAngle: -90,
// style={{width: '50px'}},
dataPoints: [
{ y: carlist.length, label: "รถยนต์" },
{ y: motolist.length, label: "รถจักรยานยนต์" },
{ y: agirculturelist.length, label: "อุปกรณ์การเกษตร" },
],
type: "element-selected",
},
{
type: "element-active",
},
{
type: "pie-statistic-active",
},
],
};
return (
<div style={{ heigth: "200px" }}>
<CanvasJSChart
options={options}
/* onRef={ref => this.chart = ref} */
/>
<Link to={"/dashboard/all-repair"}>
<Title level={5}>การซ่อมทั้งหมด {totol.length} รายการ</Title>
</Link>
</div>
<>
<Row>
<Col span={18}>
<Title level={4}>การซ่อมของร้าน</Title>
</Col>
</Row>
<Pie {...config} />
</>
);
}
// export default DemoPie;`
// ReactDOM.render(<DemoPie />, document.getElementById('container'));
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment