0% found this document useful (0 votes)
13 views6 pages

Sss

The document is a React component for an Admin Layout in a PetShop application, utilizing Ant Design for UI elements. It manages user authentication, product types, and navigation, while providing a responsive sidebar and header with user account options. The layout includes a search functionality and dynamically renders product cards or child components based on the current route.

Uploaded by

Thạch Đông
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views6 pages

Sss

The document is a React component for an Admin Layout in a PetShop application, utilizing Ant Design for UI elements. It manages user authentication, product types, and navigation, while providing a responsive sidebar and header with user account options. The layout includes a search functionality and dynamically renders product cards or child components based on the current route.

Uploaded by

Thạch Đông
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

import React, { useState, useEffect } from 'react';

import {
TeamOutlined,
UserOutlined,
ShoppingCartOutlined,
CaretDownOutlined
} from '@ant-design/icons';
import { Breadcrumb, Layout, Menu, theme, Badge, Popover, Col } from 'antd';
import { useNavigate, useLocation } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import * as UserService from '../../services/UserService';
import { resetUser } from '../../redux/slides/userSlide';
import Loading from '../LoadingComponent/Loading';
import SliderComponent from '../../components/SliderComponent/SliderComponent';
import CardComponent from '../../components/CardComponent/CardComponent';
import ButtonInputSearch from '../ButtonInputSearch/ButtonInputSearch';
import { searchProduct } from '../../redux/slides/productSlide';
import * as ProductService from "../../services/ProductService";
import {
WrapperContentPopup,
WrapperHeaderAccout,
WrapperTextHeader,
WrapperTextHeaderSmall,
WrapperProducts,
WrapperButtonMore
} from './style';

const { Header, Content, Footer, Sider } = Layout;

const AdminLayout = ({children}) => {


const navigate = useNavigate();
const location = useLocation();
const dispatch = useDispatch();
const [collapsed, setCollapsed] = useState(false);
const [search, setSearch] = useState('');
const [isOpenPopup, setIsOpenPopup] = useState(false);
const [loading, setLoading] = useState(false);
const [userName, setUserName] = useState('');
const [userAvatar, setUserAvatar] = useState('');
const [typeProducts, setTypeProducts] = useState([]);
const [limit, setLimit] = useState(10);

const user = useSelector((state) => state.user);


const order = useSelector((state) => state.order);
const searchProduct = useSelector((state) => state?.product?.search);
const { data: products, isPreviousData } = useSelector((state) =>
state?.product?.products || {});

const { token: { colorBgContainer, borderRadiusLG } } = theme.useToken();


const isHomePage = location.pathname === '/';

useEffect(() => {
setLoading(true);
setUserName(user?.name);
setUserAvatar(user?.avatar);
const fetchAllTypeProduct = async () => {
const res = await ProductService.getAllTypeProduct();
if(res?.status === 'OK') {
setTypeProducts(res?.data);
}
setLoading(false);
};
fetchAllTypeProduct();
}, [user?.name, user?.avatar]);

const handleLogout = async () => {


setLoading(true);
await UserService.logoutUser();
dispatch(resetUser());
setLoading(false);
};

const handleNavigateLogin = () => {


navigate('/sign-in');
};

const handleOnClickNavigate = (type) => {


if(type === 'profile') {
navigate('/profile-user');
} else if(type === 'admin') {
navigate('/system/admin');
} else if(type === 'my-order') {
navigate('/my-order', {
state: {
id: user?.id,
token: user?.access_token,
}
});
} else {
handleLogout();
}
setIsOpenPopup(false);
};

const onSearch = (e) => {


setSearch(e.target.value);
dispatch(searchProduct(e.target.value));
};

const content = (
<div>
<WrapperContentPopup onClick={() => handleOnClickNavigate('profile')}>Thông
tin người dùng</WrapperContentPopup>
{user?.isAdmin && (
<WrapperContentPopup onClick={() => handleOnClickNavigate('admin')}>Quản lí
hệ thống</WrapperContentPopup>
)}
<WrapperContentPopup onClick={() => handleOnClickNavigate('my-order')}>Đơn
hàng của tôi</WrapperContentPopup>
<WrapperContentPopup onClick={() => handleOnClickNavigate()}>Đăng
xuất</WrapperContentPopup>
</div>
);

// Create menu items for type products


const typeProductItems = typeProducts.map(type => getItem(type, `type-${type}`,
null));
// Define menu items
function getItem(label, key, icon, children) {
return { key, icon, children, label };
}

const items = [
getItem('Thông tin người dùng', 'sub1', <UserOutlined />, [
getItem('Thông tin người dùng', 'profile'),
user?.isAdmin && getItem('Quản lí hệ thống', 'admin'),
getItem('Đơn hàng của tôi', 'my-order'),
getItem('Đăng xuất', 'logout'),
]),
getItem('Danh mục sản phẩm', 'sub2', <TeamOutlined />, typeProductItems),
].filter(Boolean); // Filter out falsy values (for conditional items)

const handleMenuClick = (e) => {


const key = e.key;
console.log("Menu clicked:", key); // Debug log

if(key === 'profile' || key === 'admin' || key === 'my-order' || key ===
'logout') {
handleOnClickNavigate(key === 'logout' ? '' : key);
} else if(key.startsWith('type-')) {
const type = key.replace('type-', '');
const path = `/product/${type.normalize('NFD').replace(/[\u0300-\u036f]/g,
'').replace(/ /g, '_')}`;
console.log("Navigating to:", path); // Debug log
navigate(path, {state: type});
}
};

const renderHomePageContent = () => {


return (
<div style={{width: '100%', backgroundColor: '#fcf8ee'}}>
<div style={{height: 'auto', width: '100%', margin: '0 auto'}}
id='container'>
<div style={{paddingTop: '10px'}}>
<SliderComponent arrImages={[
require('../../assets/images/slider1.jpg'),
require('../../assets/images/slider2.jpg'),
require('../../assets/images/slider3.jpg')
]} />
</div>

<WrapperProducts>
{products?.data?.map((product) => {
return (
<CardComponent
key={product._id}
countInStock={product.countInStock}
description={product.description}
image={product.image}
name={product.name}
price={product.price}
rating={product.rating}
type={product.type}
discount={product.discount}
selled={product.selled}
id={product._id}
/>
);
})}
</WrapperProducts>

<div style={{width: '100%', display: 'flex', justifyContent: 'center',


marginTop: '10px', paddingBottom: '20px'}}>
<WrapperButtonMore
textbutton={isPreviousData ? 'Loading...' : 'Xem thêm'}
type="outline"
styletextbutton={{ fontWeight: 500, color: products?.total ===
products?.data?.length && '#fff' }}
styleButton={{
color: `${products?.total === products?.data?.length ? '#ccc' :
'rgb(11, 116, 229)'}`,
width: '240px',
height: '38px',
borderRadius: '4px',
border: '1px solid rgb(11, 116, 229)'
}}
disabled={products?.total === products?.data?.length ||
products?.totalPage === 1}
onClick={() => {
setLimit((prev) => prev + 5);
}}
/>
</div>
</div>
</div>
);
};

return (
<Layout style={{ minHeight: '100vh' }}>
<Sider collapsible collapsed={collapsed} onCollapse={value =>
setCollapsed(value)}>
<div style={{ height: 32, margin: 16, background: 'rgba(255, 255, 255,
0.2)', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<div style={{ color: 'white', fontSize: '18px', fontWeight: 'bold',
cursor: 'pointer' }} onClick={() => navigate('/')}>
PetShop
</div>
</div>
<Menu
theme="dark"
defaultSelectedKeys={['1']}
mode="inline"
items={items}
onClick={handleMenuClick}
/>
</Sider>
<Layout>
<Header style={{ padding: 0, background: '#3d6912', display: 'flex',
alignItems: 'center', justifyContent: 'space-between' }}>
<div style={{ display: 'flex', alignItems: 'center', color: 'white',
marginLeft: 16 }}>
<div style={{ color: 'white', fontSize: '20px', fontWeight: 'bold',
cursor: 'pointer' }} onClick={() => navigate('/')}>
PetShop
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', marginRight: 16 }}>
<Loading isloading={loading}>
<WrapperHeaderAccout>
{userAvatar ? (
<img src={userAvatar} alt="avatar" style={{width: '30px', height:
'30px', borderRadius: '50%', objectFit: 'cover'}}/>
) : (
<UserOutlined style={{fontSize:'30px', color: 'white'}}/>
)}
{user?.access_token ? (
<>
<Popover content={content} trigger='click' open={isOpenPopup}>
<div style={{cursor: 'pointer', color: 'white'}} onClick={()
=> setIsOpenPopup((prev) => !prev)}>
{userName?.length ? userName : user?.email}
</div>
</Popover>
</>
) : (
<div onClick={handleNavigateLogin} style={{cursor: 'pointer',
color: 'white'}}>
<WrapperTextHeaderSmall>Đăng nhập/Đăng
ký</WrapperTextHeaderSmall>
<div>
<WrapperTextHeaderSmall>Tài khoản</WrapperTextHeaderSmall>
<CaretDownOutlined />
</div>
</div>
)}
</WrapperHeaderAccout>
</Loading>

{user?.access_token && (
<div onClick={() => navigate('/order')} style={{cursor: 'pointer',
marginLeft: 24}}>
<Badge count={order?.orderItems?.length} size="small">
<ShoppingCartOutlined style={{fontSize:'30px', color: '#fff'}}/>
</Badge>
</div>
)}
</div>
</Header>
<Content style={{ margin: '0 16px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>Trang chủ</Breadcrumb.Item>
<Breadcrumb.Item>Sản phẩm</Breadcrumb.Item>
</Breadcrumb>

{/* Search section */}


<div style={{ padding: 24, minHeight: 100, background: colorBgContainer,
borderRadius: borderRadiusLG, marginBottom: 16 }}>
<Col span={24}>
<ButtonInputSearch
size='large'
textbutton='Tìm kiếm'
placeholder="Nhập tên sản phẩm cần tìm"
onChange={onSearch}
/>
</Col>
</div>

{/* Content section */}


<div style={{ padding: 24, minHeight: 360, background: colorBgContainer,
borderRadius: borderRadiusLG }}>
{/* Render children or HomePage content based on current route */}
{isHomePage ? renderHomePageContent() : children}
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>
PetShop ©{new Date().getFullYear()} Created by Your Name
</Footer>
</Layout>
</Layout>
);
};

export default AdminLayout;

You might also like