diff --git a/public/assets/css/all.css b/public/assets/css/all.css
index faaddbf..4097a9b 100644
--- a/public/assets/css/all.css
+++ b/public/assets/css/all.css
@@ -10425,7 +10425,7 @@ ul.pagination li:hover a {
}
.disable-mobile {
- display: none;
+ display: none !important;
}
.enable-mobile {
diff --git a/src/App.js b/src/App.js
index 7f7a8df..91aef56 100644
--- a/src/App.js
+++ b/src/App.js
@@ -11,6 +11,7 @@ import {LoginPage} from './_containers/LoginPage/index'
import { ForgotPasswordPage } from "./_containers/ForgotPasswordPage";
import RegisterPage from "./_containers/RegisterPage";
import HomePage from "./_containers/HomePage";
+import ListCustomer from "./_containers/ListCustomer";
function App() {
const dispatch = useDispatch();
@@ -51,6 +52,12 @@ function App() {
component={HomePage}
authentication={authentication}
/>
+
diff --git a/src/_components/Auth/InputDate/index.js b/src/_components/Auth/InputDate/index.js
index 1846b31..af4f344 100644
--- a/src/_components/Auth/InputDate/index.js
+++ b/src/_components/Auth/InputDate/index.js
@@ -23,7 +23,7 @@ const InputDate = (props) => {
};
return (
-
+
{props.errorText ? (
{props.errorText}
diff --git a/src/_components/Auth/InputText/index.js b/src/_components/Auth/InputText/index.js
index 3273a59..5477fea 100644
--- a/src/_components/Auth/InputText/index.js
+++ b/src/_components/Auth/InputText/index.js
@@ -93,7 +93,7 @@ const InputText = (props) => {
};
return (
-
+
{props.errorText && props?.typeErrText != "underAbsolute" ? (
{
await apiCaller('/logout', "POST", {})
window.location.href = "/login";
localStorage.removeItem("authentication");
localStorage.removeItem("access_token");
+ setIsOpenMenuMobile(false)
}
+ const renderListHeader = () => {
+ return (
+ <>
+
+ "header-item" + (isActive ? " header-item-selected" : "")
+ }
+ onClick={() => setIsOpenMenuMobile(false)}
+ >
+ Thông tin chung
+
+
+ "header-item" + (isActive ? " header-item-selected" : "")
+ }
+ onClick={() => setIsOpenMenuMobile(false)}
+ >
+ Danh sách khách hàng
+
+ >
+ )
+ }
+
+ const handleClickOutside = (event) => {
+ if (menuMobileRef.current && !menuMobileRef.current.contains(event.target)) {
+ setIsOpenMenuMobile(false);
+ }
+ };
+
+ useEffect(() => {
+ document.addEventListener('click', handleClickOutside, true);
+ return () => {
+ document.removeEventListener('click', handleClickOutside, true);
+ };
+ }, []);
+
return (
@@ -22,9 +64,23 @@ export default function HeaderMain() {
-
setIsHoverLogout(true)} onMouseOut={() => setIsHoverLogout(false)} onClick={handleLogout}>
-
- {isHoverLogout &&
Đăng xuất}
+
+
+ {renderListHeader()}
+
+
setIsHoverLogout(true)} onMouseOut={() => setIsHoverLogout(false)} onClick={handleLogout}>
+
+ {isHoverLogout &&
Đăng xuất}
+
+
+
+
+
+ {isOpenMenuMobile &&
+ {renderListHeader()}
+
Đăng xuất
+
}
+
diff --git a/src/_containers/HomePage/HomePage.style.scss b/src/_containers/HomePage/HomePage.style.scss
index dea3b66..841ddce 100644
--- a/src/_containers/HomePage/HomePage.style.scss
+++ b/src/_containers/HomePage/HomePage.style.scss
@@ -46,7 +46,7 @@
.name-agency {
font-size: 28px;
font-weight: 700;
- padding-top: 10px;
+ padding-top: 6px;
@include screen_mobile {
padding-top: 0;
@@ -70,6 +70,7 @@
.box-link {
flex-direction: column;
+
.title-box-link {
font-size: 24px;
font-weight: 700;
diff --git a/src/_containers/HomePage/index.js b/src/_containers/HomePage/index.js
index 3244e1a..2e264d4 100644
--- a/src/_containers/HomePage/index.js
+++ b/src/_containers/HomePage/index.js
@@ -24,7 +24,8 @@ export default function HomePage() {
const authentication = useSelector((state) => state.authentication);
const handleCopy = (type, value) => {
- navigator.clipboard.writeText(value)
+ const link = value?.trim()?.substring(0,5)?.includes('http') ? value : `https://${value?.trim()}`
+ navigator.clipboard.writeText(link)
if (!!isCopied?.[type]) {
return;
}
@@ -52,15 +53,29 @@ export default function HomePage() {
)
}
- const renderInfoAgencyItem = (text) => {
+ const renderIconInfoAgency = (type) => {
+ switch (type) {
+ case 'birthday':
+ return (
+
+ );
+ case 'phone':
+ return (
+
+ );
+ case 'email':
+ return (
+
+ )
+ default:
+ return null;
+ }
+ }
+
+ const renderInfoAgencyItem = (text, type) => {
return (
-
+ {renderIconInfoAgency(type)}
{text}
)
@@ -103,14 +118,14 @@ export default function HomePage() {
{authentication.fullname}
- {renderInfoAgencyItem(moment(authentication.birthday).format("DD/MM/YYYY"))}
- {renderInfoAgencyItem(authentication.phone)}
- {renderInfoAgencyItem(authentication.email)}
+ {renderInfoAgencyItem(moment(authentication.birthday).format("DD/MM/YYYY"), 'birthday')}
+ {renderInfoAgencyItem(authentication.phone, 'phone')}
+ {renderInfoAgencyItem(authentication.email, 'email')}
{renderBoxLink('Link Đăng ký tuyến dưới', authentication.downline_register, homeType.REGISTER)}
- {/* {renderBoxLink('Link Landing page cho khách hàng', authentication.promotional_link, homeType.LANDING)} */}
+ {renderBoxLink('Link Landing page cho khách hàng', authentication.promotional_link, homeType.LANDING)}
diff --git a/src/_containers/ListCustomer/ListCustomer.style.scss b/src/_containers/ListCustomer/ListCustomer.style.scss
new file mode 100644
index 0000000..8062d73
--- /dev/null
+++ b/src/_containers/ListCustomer/ListCustomer.style.scss
@@ -0,0 +1,161 @@
+@import "/src/_styles/mixin";
+
+.main-container {
+
+ @include screen_mobile {
+ padding: 0 16px;
+ }
+
+ .filter-container {
+ display: flex;
+ flex-direction: column;
+
+ .filter-form {
+ display: flex;
+ align-items: center;
+ gap: 24px;
+
+ @include screen_mobile {
+ flex-direction: column;
+ gap: 0;
+ align-items: unset;
+ }
+
+ .input-base-filter {
+ height: 48px;
+
+ .icon_label {
+ margin-right: 12px;
+ }
+ }
+
+ .keyword-filter-form {
+ flex: 1;
+ }
+
+ .date-filter-form {
+ flex: 1;
+ display: flex;
+ gap: 24px;
+
+ @include screen_mobile {
+ gap: 16px;
+ }
+ }
+
+ .input-container {
+ flex: 1;
+ }
+ }
+
+ .filter-action {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 24px;
+
+ @include screen_mobile {
+ justify-content: center;
+ }
+
+ .btn-filter {
+ display: flex;
+ align-items: center;
+ height: 40px;
+ border-radius: 20px;
+ line-height: 40px;
+ padding: 0 25px;
+ font-size: 16px;
+ border: none;
+ font-family: 'Myriadpro-SemiBold';
+
+ svg {
+ margin-right: 8px;
+ }
+ }
+
+ .btn-cancel-filter {
+ color: #4b4a4a;
+ background-color: #DDDDDD;
+ }
+
+ .btn-cancel-filter:hover {
+ opacity: 0.6;
+ }
+ }
+ }
+
+ .list-customer-container {
+ margin-top: 64px;
+
+ .total-customer {
+ font-weight: 700;
+ margin-bottom: 16px;
+ }
+
+ .empty-text {
+ font-weight: 700;
+ font-size: 18px;
+ text-align: center;
+ }
+
+ .list-customer {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(48.6%, 1fr));
+ gap: 24px;
+
+ .customer-item {
+ // flex: 1 1 300px;
+ padding: 16px;
+ border-radius: 24px;
+ border: 1px solid #E1E1E1;
+ box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
+
+ .customer-name {
+ font-size: 24px;
+ font-weight: 700;
+ margin-bottom: 16px;
+ }
+
+ .customer-row {
+ display: flex;
+ gap: 16px;
+ margin-bottom: 8px;
+ }
+
+ .customer-row.message .customer-info {
+ width: 100%;
+ }
+
+ .customer-row-mobile {
+ @include screen_mobile {
+ flex-direction: column;
+ gap: 8px;
+ }
+
+ .customer-info {
+ @include screen_mobile {
+ width: 100%;
+ }
+ }
+ }
+
+ .customer-info {
+ width: 50%;
+ display: flex;
+ gap: 8px;
+
+ svg {
+ width: 24px;
+ height: 24px;
+ }
+
+ span {
+ flex: 1;
+ text-align: justify;
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/_containers/ListCustomer/index.js b/src/_containers/ListCustomer/index.js
new file mode 100644
index 0000000..f0b8ef1
--- /dev/null
+++ b/src/_containers/ListCustomer/index.js
@@ -0,0 +1,178 @@
+import { useEffect, useState } from "react";
+import InputText from "../../_components/Auth/InputText";
+import HeaderMain from "../../_components/Header/HeaderMain";
+import InputDate from "../../_components/Auth/InputDate";
+import './ListCustomer.style.scss'
+import { apiCaller } from "../../_helpers";
+import { configConstants } from "../../_constants";
+import dayjs from "dayjs";
+
+export default function ListCustomer() {
+ const [filter, setFilter] = useState({
+ keyword: '',
+ start_date: '',
+ end_date: ''
+ })
+ const [listCustomer, setListCustomer] = useState([])
+ const [isLoading, setIsLoading] = useState(false)
+ const [isFilter, setIsFilter] = useState(false)
+
+ const getData = async (dataFilter) => {
+ setIsLoading(true)
+ const endPoint = '/agent/get_customer?' +
+ (!!dataFilter?.keyword ? `keyword=${dataFilter.keyword}&` : '') +
+ (!!dataFilter?.start_date ? `start_date=${dayjs(dataFilter.start_date).format('YYYY-MM-DD')}&` : '') +
+ (!!dataFilter?.end_date ? `end_date=${dayjs(dataFilter.end_date).format('YYYY-MM-DD')}` : '');
+ try {
+ const res = await apiCaller(endPoint, 'GET', {}, null, false, configConstants.API_URL_SETEST, true, true)
+ setIsLoading(false)
+ if(res?.status) {
+ setListCustomer(res?.data)
+ }
+ } catch (err) {
+ setIsLoading(false)
+ }
+ }
+
+ const changeFilter = (key, value) => {
+ setFilter(prev => ({
+ ...prev,
+ [key]: value
+ }))
+ }
+
+ const validateFilter = () => {
+ return !!filter.keyword || !!filter.start_date || !!filter.end_date
+ }
+
+ const handleCancelFilter = () => {
+ const iniFilter = {
+ end_date: '',
+ keyword: '',
+ start_date: ''
+ }
+ setIsFilter(false)
+ setFilter(iniFilter)
+ getData(iniFilter)
+ }
+
+ const handleFilter = () => {
+ setIsFilter(true)
+ getData(filter)
+ }
+
+ useEffect(() => {
+ getData(filter)
+ }, [])
+
+ const renderIconKeyWord = () => {
+ return (
+
+ )
+ }
+
+ const renderIconDate = () => {
+ return (
+
+ )
+ }
+
+ return (
+
+
+
+
+
+
+
+
+ changeFilter('keyword', text)}
+ type="text"
+ name="keyword"
+ placeholder="Nhập tên / số điện thoại / email"
+ autoFocus={true}
+ renderLabelIcon={renderIconKeyWord}
+ />
+
+
+ changeFilter('start_date', date)}
+ name="start_date"
+ renderLabelIcon={renderIconDate}
+ placeholder={"Từ ngày"}
+ maxDate={new Date()}
+ />
+ changeFilter('end_date', date)}
+ name="end_date"
+ renderLabelIcon={renderIconDate}
+ placeholder={"Đến ngày"}
+ maxDate={new Date()}
+ />
+
+
+
+
+
+
+
+
+
+ {!!listCustomer.length &&
{`Tổng số khách hàng: ${listCustomer.length}`}
}
+
+ {listCustomer?.map(item => (
+
+
{item?.guest_name}
+
+
+
+
+
{dayjs(item?.date_receive).format('DD/MM/YYYY')}
+
+ {!!item?.grade &&
+
+
{`Lớp ${item?.grade}`}
+
}
+
+ {item?.message &&
}
+
+ ))}
+
+ {!listCustomer.length && !isLoading &&
Không có dữ liệu.
}
+
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/_helpers/apiCaller.js b/src/_helpers/apiCaller.js
index dee98a8..3370081 100644
--- a/src/_helpers/apiCaller.js
+++ b/src/_helpers/apiCaller.js
@@ -18,24 +18,25 @@ export function apiCaller(
isLoading = true,
isFullResponse = false,
) {
- if (headers === undefined || headers === null) {
+ // if (headers === undefined || headers === null) {
headers = {
"X-API-KEY": configConstants.API_KEY,
+ Authorization: `Bearer ${JSON.parse(localStorage.getItem("access_token"))}`,
};
- if (localStorage.getItem("authentication")) {
- let authentication = JSON.parse(localStorage.getItem("authentication"));
- headers["jwt_token"] = authentication.jwt_token;
- }
- } else {
- if (localStorage.getItem("authentication")) {
- let authentication = JSON.parse(localStorage.getItem("authentication"));
- headers["jwt_token"] = authentication.jwt_token;
- }
- headers = {
- "X-API-KEY": configConstants.API_KEY,
- ...headers,
- }
- }
+ // if (localStorage.getItem("authentication")) {
+ // let authentication = JSON.parse(localStorage.getItem("authentication"));
+ // headers["jwt_token"] = authentication.jwt_token;
+ // }
+ // } else {
+ // if (localStorage.getItem("authentication")) {
+ // let authentication = JSON.parse(localStorage.getItem("authentication"));
+ // headers["jwt_token"] = authentication.jwt_token;
+ // }
+ // headers = {
+ // "X-API-KEY": configConstants.API_KEY,
+ // ...headers,
+ // }
+ // }
if (isLoading) {
$(".loading").removeClass("hide");
}
@@ -43,10 +44,10 @@ export function apiCaller(
method,
timeout: configConstants.API_TIMEOUT,
url: `${basUrl}${endpoint}`,
- auth: {
- username: configConstants.AUTH_BASIC_USER_NAME,
- password: configConstants.AUTH_BASIC_PASSWORD,
- },
+ // auth: {
+ // username: configConstants.AUTH_BASIC_USER_NAME,
+ // password: configConstants.AUTH_BASIC_PASSWORD,
+ // },
data: body,
headers: headers,
})