feature list grant

master
HOANGLAOTA 1 year ago
parent 7b348d6879
commit 8fc72f55ad
  1. 7
      src/App.js
  2. 4
      src/_components/Auth/InputSelect/index.js
  3. 37
      src/_components/Auth/InputSelect/index.scss
  4. 6
      src/_components/Auth/InputText/index.scss
  5. 19
      src/_components/Header/HeaderMain/index.js
  6. 19
      src/_constants/headerNews.js
  7. 9
      src/_containers/ListCustomer/ListCustomer.style.scss
  8. 27
      src/_containers/ListCustomer/index.js
  9. 194
      src/_containers/ListGrantPage/ListGrantPage.style.scss
  10. 273
      src/_containers/ListGrantPage/index.js

@ -12,6 +12,7 @@ import { ForgotPasswordPage } from "./_containers/ForgotPasswordPage";
import RegisterPage from "./_containers/RegisterPage";
import HomePage from "./_containers/HomePage";
import ListCustomer from "./_containers/ListCustomer";
import ListGrantPage from "./_containers/ListGrantPage";
function App() {
const dispatch = useDispatch();
@ -58,6 +59,12 @@ function App() {
component={ListCustomer}
authentication={authentication}
/>
<RouteRedirectToLogin
path="/grants"
exact={true}
component={ListGrantPage}
authentication={authentication}
/>
<Redirect from="*" to="/" />
</Switch>
</Router>

@ -38,7 +38,7 @@ const InputRadio = (props) => {
<div
className={classnames(
{
[props.className]: props.className,
[props.className]: props?.classNameContainer,
focus: isOpen,
warning_select: props.errorText,
},
@ -70,7 +70,7 @@ const InputRadio = (props) => {
}}
>
<div
className={`input_select_main_wrapper ${props.classNameProps}`}
className={`input_select_main_wrapper ` + props?.className}
style={{
marginBottom: props.mgBottom,
}}

@ -5,6 +5,7 @@ $border-color: #4a4848;
.input_radio_base {
position: relative;
.error_select {
span {
color: $red;
@ -12,20 +13,25 @@ $border-color: #4a4848;
display: flex;
}
}
.error_text {
margin-bottom: 9px;
}
.error_text_absolute {
position: absolute;
bottom: calc(100% + 2px);
}
.error_text_absolute_new {
position: absolute;
top: calc(100% + 2px);
}
.input_select {
cursor: pointer;
}
.input_select_main_wrapper {
display: flex;
align-items: center;
@ -34,6 +40,7 @@ $border-color: #4a4848;
border: 1px solid $border-color;
border-radius: 10px;
margin-bottom: 22px;
.input_select_main {
display: flex;
align-items: center;
@ -44,15 +51,18 @@ $border-color: #4a4848;
align-items: center;
flex: 1;
height: 100%;
.icon_label {
width: 31px;
margin-right: 26px;
border: 0px solid transparent;
border-bottom-width: 1px;
@include screen_mobile {
margin-right: 1rem !important;
margin-right: 0 !important;
}
}
.input_text {
height: 100%;
border: none;
@ -65,10 +75,17 @@ $border-color: #4a4848;
&:focus {
outline: none;
}
@include screen_mobile {
font-size: 0.9rem !important;
}
}
svg {
@include screen_mobile {
width: 18px;
}
}
}
}
@ -83,6 +100,7 @@ $border-color: #4a4848;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
z-index: 1;
/* width */
&::-webkit-scrollbar {
width: 6px;
@ -105,10 +123,12 @@ $border-color: #4a4848;
.option_item {
padding: 12px 30px;
&:hover {
background-color: whitesmoke;
cursor: pointer;
}
span {
font-size: 18px;
font-family: "Myriadpro-Regular";
@ -119,6 +139,7 @@ $border-color: #4a4848;
}
}
}
&.active {
display: block;
}
@ -137,8 +158,10 @@ $border-color: #4a4848;
right: 3%;
min-width: 12.5rem;
}
.option_item {
padding: 12px 20px;
span {
font-size: 18px;
font-family: "AvertaStdCY" !important;
@ -155,6 +178,7 @@ $border-color: #4a4848;
box-shadow: 1px 3px 3px 0px rgba(23, 23, 23, 0.16);
border-top-left-radius: 10px;
border-top-right-radius: 10px;
.input_select_main_wrapper {
border-color: white;
border-radius: 0px;
@ -162,14 +186,17 @@ $border-color: #4a4848;
border-top-right-radius: 10px;
background-color: white;
}
.drop_down {
box-shadow: 1px 3px 3px 0px rgba(23, 23, 23, 0.16);
}
.input_select_main {
border: 0px solid #a1afbe;
border-bottom-width: 1px;
}
}
&.warning_select {
.input_select_main_wrapper {
border-color: $red !important;
@ -177,20 +204,24 @@ $border-color: #4a4848;
border-style: solid !important;
}
}
.rotate_180 {
transform: rotate(180deg);
}
.cursor_pointer {
cursor: pointer;
}
input {
font-family: "Myriadpro-Regular";
&::placeholder {
/* Chrome, Firefox, Opera, Safari 10.1+ */
font-family: "Myriadpro-Regular";
color: #8e9298;
opacity: 1; /* Firefox */
opacity: 1;
/* Firefox */
}
&:-ms-input-placeholder {
@ -210,6 +241,7 @@ $border-color: #4a4848;
.input_radio_base_news {
&.focus {
border-radius: 10px;
.input_select_main_wrapper {
border-radius: 10px;
}
@ -228,6 +260,7 @@ $border-color: #4a4848;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@include screen_mobile {
width: 100%;
max-width: 100% !important;

@ -9,7 +9,7 @@ $border-color: #4a4848;
.error_input {
span {
color: $red;
font-size: 18px;
font-size: 16px;
}
}
@ -141,6 +141,10 @@ $border-color: #4a4848;
}
}
.input_text_base_container:has(.error_text_absolute_new) .input_text_base {
margin-bottom: 38px;
}
::-ms-reveal {
display: none;
}

@ -3,6 +3,7 @@ import './HeaderMain.style.scss'
import { useEffect, useRef, useState } from "react";
import {history} from '../../../_helpers/history'
import { apiCaller } from "../../../_helpers";
import { listHeader } from "../../../_constants/headerNews";
export default function HeaderMain() {
const [isHoverLogout, setIsHoverLogout] = useState(false)
const [isOpenMenuMobile, setIsOpenMenuMobile] = useState(false)
@ -19,25 +20,19 @@ export default function HeaderMain() {
const renderListHeader = () => {
return (
<>
{listHeader.map(item => (
<NavLink
exact
to="/"
exact={item?.exact}
to={item.href}
className={isActive =>
"header-item" + (isActive ? " header-item-selected" : "")
}
onClick={() => setIsOpenMenuMobile(false)}
key={item.id}
>
Thông tin chung
</NavLink>
<NavLink
to="/customers"
className={isActive =>
"header-item" + (isActive ? " header-item-selected" : "")
}
onClick={() => setIsOpenMenuMobile(false)}
>
Danh sách khách hàng
{item.name}
</NavLink>
))}
</>
)
}

@ -21,3 +21,22 @@ export const NameTitleNewsItem = {
PROFILE: "Hồ sơ",
// LOGIN: "login_news",
};
export const listHeader = [
{
id: 1,
name: 'Thông tin chung',
href: '/',
exact: true
},
{
id: 2,
name: 'Danh sách khách hàng',
href: '/customers',
},
{
id: 3,
name: 'Danh sách tuyến dưới',
href: '/grants'
}
]

@ -12,13 +12,13 @@
.filter-form {
display: flex;
align-items: center;
// align-items: center;
gap: 24px;
@include screen_mobile {
flex-direction: column;
gap: 0;
align-items: unset;
// align-items: unset;
}
.input-base-filter {
@ -86,7 +86,7 @@
}
.list-customer-container {
margin-top: 64px;
margin-top: 20px;
.total-customer {
font-weight: 700;
@ -97,6 +97,7 @@
font-weight: 700;
font-size: 18px;
text-align: center;
margin-top: 64px;
}
.list-customer {
@ -114,7 +115,7 @@
.customer-name {
font-size: 24px;
font-weight: 700;
margin-bottom: 16px;
margin-bottom: 8px;
}
.customer-row {

@ -13,6 +13,11 @@ export default function ListCustomer() {
start_date: '',
end_date: ''
})
const [errFilter, setErrFilter] = useState({
keyword: '',
start_date: '',
end_date: ''
})
const [listCustomer, setListCustomer] = useState([])
const [isLoading, setIsLoading] = useState(false)
const [isFilter, setIsFilter] = useState(false)
@ -39,6 +44,10 @@ export default function ListCustomer() {
...prev,
[key]: value
}))
setErrFilter(prev => ({
...prev,
[key]: ''
}))
}
const validateFilter = () => {
@ -51,12 +60,23 @@ export default function ListCustomer() {
keyword: '',
start_date: ''
}
setIsFilter(false)
setErrFilter(iniFilter)
setFilter(iniFilter)
if(!isFilter) {
return;
}
setIsFilter(false)
getData(iniFilter)
}
const handleFilter = () => {
if(!!filter.keyword && filter.keyword.length < 3) {
setErrFilter(prev => ({
...prev,
keyword: 'Nhập tối thiểu 3 kí tự'
}))
return;
}
setIsFilter(true)
getData(filter)
}
@ -96,6 +116,9 @@ export default function ListCustomer() {
placeholder="Nhập tên / số điện thoại / email"
autoFocus={true}
renderLabelIcon={renderIconKeyWord}
errorText={errFilter.keyword}
typeErrText='underAbsolute'
errorAbsolute={true}
/>
</div>
<div className="date-filter-form">
@ -122,7 +145,7 @@ export default function ListCustomer() {
</div>
</div>
<div className="filter-action">
<button className="btn-cancel-filter btn-filter" onClick={handleCancelFilter} disabled={!isFilter}>
<button className="btn-cancel-filter btn-filter" onClick={handleCancelFilter}>
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24"><path fill="#4b4a4a" d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10s10-4.47 10-10S17.53 2 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8s8 3.59 8 8s-3.59 8-8 8m3.59-13L12 10.59L8.41 7L7 8.41L10.59 12L7 15.59L8.41 17L12 13.41L15.59 17L17 15.59L13.41 12L17 8.41z"/></svg>
Hủy
</button>

@ -0,0 +1,194 @@
@import "/src/_styles/mixin";
.list-grant-main-container {
@include screen_mobile {
padding: 0 16px;
}
.filter-container {
display: flex;
flex-direction: column;
.filter-form {
display: flex;
flex-direction: column;
.filter-form-row {
display: flex;
gap: 24px;
@include screen_mobile {
flex-direction: column;
gap: 0;
}
}
.grant-level-filter-form {
flex: 1;
display: flex;
gap: 24px;
@include screen_mobile {
flex-direction: column;
gap: 0;
}
}
.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_date_base {
margin-bottom: 0;
}
}
.input-container {
flex: 1;
}
.input_radio_base {
margin-bottom: 24px;
}
}
.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;
}
}
.filter-form-row-second {
display: flex;
gap: 24px;
align-items: center;
@include screen_mobile {
flex-direction: column;
}
}
}
.list-grant-container {
margin-top: 20px;
.total-grant {
font-weight: 700;
margin-bottom: 16px;
}
.empty-text {
font-weight: 700;
font-size: 18px;
text-align: center;
margin-top: 64px;
}
.list-grant {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(48.6%, 1fr));
gap: 24px;
.grant-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;
.grant-name {
font-size: 24px;
font-weight: 700;
margin-bottom: 8px;
}
.grant-row {
display: flex;
gap: 16px;
margin-bottom: 8px;
}
.grant-row.message .grant-info {
width: 100%;
}
.grant-row-mobile {
@include screen_mobile {
flex-direction: column;
gap: 8px;
}
.grant-info {
@include screen_mobile {
width: 100%;
}
}
}
.grant-info {
width: 50%;
display: flex;
gap: 8px;
svg {
width: 24px;
height: 24px;
}
span {
flex: 1;
text-align: justify;
}
}
}
}
}
}

@ -0,0 +1,273 @@
import { useEffect, useState } from "react";
import InputText from "../../_components/Auth/InputText";
import HeaderMain from "../../_components/Header/HeaderMain";
import InputDate from "../../_components/Auth/InputDate";
import { apiCaller } from "../../_helpers";
import { configConstants } from "../../_constants";
import dayjs from "dayjs";
import './ListGrantPage.style.scss'
import InputRadio from "../../_components/Auth/InputSelect";
import { useSelector } from "react-redux";
// role agents
export default function ListGrantPage() {
const authentication = useSelector((state) => state.authentication);
const [listLevel] = useState(Array(authentication?.role === 'agents' ? 2 : 9).fill(0).map((_, i) => ({
title: `Cấp ${i + 1}`,
value: (i + 1).toString(),
})))
const [filter, setFilter] = useState({
keyword: '',
up_grant: '',
grant: null,
start_date: '',
end_date: '',
})
const [errFilter, setErrFilter] = useState({
keyword: '',
up_grant: '',
grant: null,
start_date: '',
end_date: '',
})
const [listGrant, setListGrant] = useState([])
const [isLoading, setIsLoading] = useState(false)
const [isFilter, setIsFilter] = useState(false)
const getData = async (dataFilter) => {
setIsLoading(true)
const endPoint = '/agent/agent_of_general?' +
(!!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')}&` : '') +
(!!dataFilter?.grant ? `grant=${dataFilter.grant?.value}&` : '') +
(!!dataFilter?.up_grant ? `up_grant=${dataFilter.up_grant}` : '');
try {
const res = await apiCaller(endPoint, 'GET', {}, null, false, configConstants.API_URL_SETEST, true, true)
setIsLoading(false)
if(res?.status) {
setListGrant(res?.data)
}
} catch (err) {
setIsLoading(false)
}
}
const changeFilter = (key, value) => {
setFilter(prev => ({
...prev,
[key]: value
}))
setErrFilter(prev => ({
...prev,
[key]: ''
}))
}
const validateFilter = () => {
return Object.values(filter).some(item => !!item)
}
const handleCancelFilter = () => {
const iniFilter = {
keyword: '',
up_grant: '',
grant: null,
start_date: '',
end_date: '',
}
setErrFilter(iniFilter)
setFilter(iniFilter)
if(!isFilter) {
return;
}
setIsFilter(false)
getData(iniFilter)
}
const handleFilter = () => {
if(!!filter.keyword && filter.keyword.length < 3) {
setErrFilter(prev => ({
...prev,
keyword: 'Nhập tối thiểu 3 kí tự'
}))
return;
}
if(!!filter.up_grant && filter.up_grant.length < 3) {
setErrFilter(prev => ({
...prev,
up_grant: 'Nhập tối thiểu 3 kí tự'
}))
return;
}
setIsFilter(true)
getData(filter)
}
useEffect(() => {
getData(filter)
}, [])
const renderIconKeyWord = () => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 16 16"><path fill="#404041" fill-rule="evenodd" d="M0 2.965C0 1.88.88 1 1.965 1h2.807c1.085 0 1.965.88 1.965 1.965v.561c0 1.086-.88 1.965-1.965 1.965H1.965A1.965 1.965 0 0 1 0 3.526zm1.965-.28a.28.28 0 0 0-.28.28v.561a.28.28 0 0 0 .28.281h2.807a.28.28 0 0 0 .28-.28v-.562a.28.28 0 0 0-.28-.28zm6.175.561c0-.465.377-.842.842-.842h6.176a.842.842 0 1 1 0 1.684H8.982a.842.842 0 0 1-.842-.842M.28 8.298c0-.465.378-.842.843-.842H11.79a.842.842 0 1 1 0 1.684H1.123a.842.842 0 0 1-.842-.842M.28 13.35c0-.464.378-.841.843-.841h13.474a.842.842 0 1 1 0 1.684H1.123a.842.842 0 0 1-.842-.842" clip-rule="evenodd"/><path fill="#404041" d="M14.877 9.14a.842.842 0 1 0 0-1.684a.842.842 0 0 0 0 1.684"/></svg>
)
}
const renderIconDate = () => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 36 36"><path fill="#404041" d="M32.25 6H29v2h3v22H4V8h3V6H3.75A1.78 1.78 0 0 0 2 7.81v22.38A1.78 1.78 0 0 0 3.75 32h28.5A1.78 1.78 0 0 0 34 30.19V7.81A1.78 1.78 0 0 0 32.25 6" class="clr-i-outline clr-i-outline-path-1"/><path fill="#404041" d="M8 14h2v2H8z" class="clr-i-outline clr-i-outline-path-2"/><path fill="#404041" d="M14 14h2v2h-2z" class="clr-i-outline clr-i-outline-path-3"/><path fill="#404041" d="M20 14h2v2h-2z" class="clr-i-outline clr-i-outline-path-4"/><path fill="#404041" d="M26 14h2v2h-2z" class="clr-i-outline clr-i-outline-path-5"/><path fill="#404041" d="M8 19h2v2H8z" class="clr-i-outline clr-i-outline-path-6"/><path fill="#404041" d="M14 19h2v2h-2z" class="clr-i-outline clr-i-outline-path-7"/><path fill="#404041" d="M20 19h2v2h-2z" class="clr-i-outline clr-i-outline-path-8"/><path fill="#404041" d="M26 19h2v2h-2z" class="clr-i-outline clr-i-outline-path-9"/><path fill="#404041" d="M8 24h2v2H8z" class="clr-i-outline clr-i-outline-path-10"/><path fill="#404041" d="M14 24h2v2h-2z" class="clr-i-outline clr-i-outline-path-11"/><path fill="#404041" d="M20 24h2v2h-2z" class="clr-i-outline clr-i-outline-path-12"/><path fill="#404041" d="M26 24h2v2h-2z" class="clr-i-outline clr-i-outline-path-13"/><path fill="#404041" d="M10 10a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v6a1 1 0 0 0 1 1" class="clr-i-outline clr-i-outline-path-14"/><path fill="#404041" d="M26 10a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v6a1 1 0 0 0 1 1" class="clr-i-outline clr-i-outline-path-15"/><path fill="#404041" d="M13 6h10v2H13z" class="clr-i-outline clr-i-outline-path-16"/><path fill="none" d="M0 0h36v36H0z"/></svg>
)
}
const renderIconUpGrant = () => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 50 50"><path fill="#404041" d="M14.237 39.5H44.72V13.419H14.237zm15.489-23.485l10.99 9.598h-2.769v11.516h-6.436V29h-4.065v8.129H21.35V25.613h-2.84zM10.85 6.984V1.018H4.076V50h6.774V10.033h35.226V6.984z"/></svg>
)
}
const renderIconLevel = () => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 48 48"><g fill="none" stroke="#404041" stroke-linecap="round" stroke-linejoin="round" stroke-width="4"><path d="M24 42L4 18.5L9.695 6h28.61L44 18.5z"/><path d="m32 18l-8 9l-8-9"/></g></svg>
)
}
return (
<div className="bg-main rel">
<HeaderMain />
<div className="body-home-container">
<div className="sunE-container">
<div className="list-grant-main-container">
<div className="filter-container">
<div className="filter-form">
<div className="filter-form-row">
<div className="keyword-filter-form">
<InputText
classNameContainer='input-container'
className='input-base-filter'
value={filter.keyword}
setValue={(text) => changeFilter('keyword', text)}
type="text"
name="keyword"
placeholder="Nhập tên / số điện thoại / email / mã đại lý"
autoFocus={true}
renderLabelIcon={renderIconKeyWord}
errorText={errFilter.keyword}
typeErrText='underAbsolute'
errorAbsolute={true}
/>
</div>
<div className="grant-level-filter-form">
<div>
<InputText
classNameContainer='input-container'
className='input-base-filter'
value={filter.up_grant}
setValue={(text) => changeFilter('up_grant', text)}
type="text"
name="up_grant"
placeholder="Nhập mã tuyến trên"
renderLabelIcon={renderIconUpGrant}
errorText={errFilter.up_grant}
typeErrText='underAbsolute'
errorAbsolute={true}
/>
</div>
<InputRadio
classNameContainer='input-container'
className='input-base-filter'
options={listLevel}
value={filter.grant}
setValue={(option) => changeFilter('grant', option)}
name="grant"
renderLabelIcon={renderIconLevel}
placeholder={"Chọn cấp đại lý"}
/>
</div>
</div>
<div className="filter-form-row-second">
<div className="date-filter-form">
<InputDate
classNameContainer='input-container'
className='input-base-filter'
value={filter.start_date}
setValue={(date) => changeFilter('start_date', date)}
name="start_date"
renderLabelIcon={renderIconDate}
placeholder={"Từ ngày"}
maxDate={new Date()}
/>
<InputDate
classNameContainer='input-container'
className='input-base-filter'
value={filter.end_date}
setValue={(date) => changeFilter('end_date', date)}
name="end_date"
renderLabelIcon={renderIconDate}
placeholder={"Đến ngày"}
maxDate={new Date()}
/>
</div>
<div className="filter-action">
<button className="btn-cancel-filter btn-filter" onClick={handleCancelFilter}>
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24"><path fill="#4b4a4a" d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10s10-4.47 10-10S17.53 2 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8s8 3.59 8 8s-3.59 8-8 8m3.59-13L12 10.59L8.41 7L7 8.41L10.59 12L7 15.59L8.41 17L12 13.41L15.59 17L17 15.59L13.41 12L17 8.41z"/></svg>
Hủy
</button>
<button className="btn-line-blue btn-filter" onClick={handleFilter} disabled={!validateFilter()}>
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24"><g fill="none" fill-rule="evenodd"><path d="M24 0v24H0V0zM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"/><path fill="#ffffff" d="M10.5 2a8.5 8.5 0 1 0 5.262 15.176l3.652 3.652a1 1 0 0 0 1.414-1.414l-3.652-3.652A8.5 8.5 0 0 0 10.5 2M4 10.5a6.5 6.5 0 1 1 13 0a6.5 6.5 0 0 1-13 0"/></g></svg>
Tìm kiếm
</button>
</div>
</div>
</div>
</div>
<div className="list-grant-container">
{!!listGrant.length && <p className="total-grant">{`Tổng số tuyến dưới: ${listGrant.length}`}</p>}
<div className="list-grant">
{listGrant?.map(item => (
<div className="grant-item" key={item?.id}>
<p className="grant-name">{item?.name}</p>
<div className="grant-row">
<div className="grant-info">
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 24 24"><path fill="#00B9B7" d="M19 14V7.5L14 4L9 7.5V9H7V6.5l7-5l7 5V14zm-4.5-6h1V7h-1zm-2 0h1V7h-1zm2 2h1V9h-1zm-2 0h1V9h-1zM7 18.5l6.95 1.9l5.95-1.85q-.125-.225-.363-.388T19 18h-5.05q-.675 0-1.075-.05t-.825-.2l-2.325-.775l.55-1.95l2.025.675q.425.125 1 .2t1.7.1q0-.275-.162-.525t-.388-.325L8.6 13H7zM1 22V11h7.6q.175 0 .35.038t.325.087L15.15 13.3q.825.3 1.338 1.05T17 16h2q1.25 0 2.125.825T22 19v1l-8 2.5l-7-1.95V22zm2-2h2v-7H3z"/></svg>
<span>{item?.agents_code}</span>
</div>
<div className="grant-info">
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 48 48"><g fill="none" stroke="#00B9B7" stroke-linecap="round" stroke-linejoin="round" stroke-width="4"><path d="M24 42L4 18.5L9.695 6h28.61L44 18.5z"/><path d="m32 18l-8 9l-8-9"/></g></svg>
<span>{item?.grant}</span>
</div>
</div>
<div className="grant-row">
<div className="grant-info">
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 50 50"><path fill="#00B9B7" d="M14.237 39.5H44.72V13.419H14.237zm15.489-23.485l10.99 9.598h-2.769v11.516h-6.436V29h-4.065v8.129H21.35V25.613h-2.84zM10.85 6.984V1.018H4.076V50h6.774V10.033h35.226V6.984z"/></svg>
<span>{item?.up_grant}</span>
</div>
<div className="grant-info">
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 256 256"><path fill="#00B9B7" d="m224 154.8l-47.09-21.11l-.18-.08a19.94 19.94 0 0 0-19 1.75a13 13 0 0 0-1.12.84l-22.31 19c-13-7.05-26.43-20.37-33.49-33.21l19.06-22.66a12 12 0 0 0 .85-1.15a20 20 0 0 0 1.66-18.83a1.4 1.4 0 0 1-.08-.18L101.2 32a20.06 20.06 0 0 0-20.78-11.85A60.27 60.27 0 0 0 28 80c0 81.61 66.39 148 148 148a60.27 60.27 0 0 0 59.85-52.42A20.06 20.06 0 0 0 224 154.8M176 204A124.15 124.15 0 0 1 52 80a36.29 36.29 0 0 1 28.48-35.54l18.82 42l-19.16 22.82a12 12 0 0 0-.86 1.16A20 20 0 0 0 78 130.08c9.42 19.28 28.83 38.56 48.31 48a20 20 0 0 0 19.69-1.45a12 12 0 0 0 1.11-.85l22.43-19.07l42 18.81A36.29 36.29 0 0 1 176 204"/></svg>
<span>{item?.phone}</span>
</div>
</div>
<div className="grant-row grant-row-mobile">
<div className="grant-info">
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 24 24"><path fill="#00B9B7" d="M22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2zm-2 0l-8 5l-8-5zm0 12H4V8l8 5l8-5z"/></svg>
<span>{item?.email}</span>
</div>
<div className="grant-info">
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 24 24"><path fill="#00B9B7" d="M21 10.12h-6.78l2.74-2.82c-2.73-2.7-7.15-2.8-9.88-.1a6.887 6.887 0 0 0 0 9.8c2.73 2.7 7.15 2.7 9.88 0c1.36-1.35 2.04-2.92 2.04-4.9h2c0 1.98-.88 4.55-2.64 6.29c-3.51 3.48-9.21 3.48-12.72 0c-3.5-3.47-3.53-9.11-.02-12.58a8.987 8.987 0 0 1 12.65 0L21 3zM12.5 8v4.25l3.5 2.08l-.72 1.21L11 13V8z"/></svg>
<span>{dayjs(item?.created_date).format('DD/MM/YYYY')}</span>
</div>
</div>
</div>
))}
</div>
{!listGrant.length && !isLoading && <p className="empty-text">Không dữ liệu.</p>}
</div>
</div>
</div>
</div>
</div>
)
}
Loading…
Cancel
Save