Untitled
unknown
plain_text
8 months ago
16 kB
5
Indexable
// import MobileFilter from '@/components/client/book/mobile.filter';
// import { getBooksAPI, getCategoryAPI } from '@/services/api';
import { getBookAPI, getCategoryAPI } from '@/services/api';
import { FilterTwoTone, ReloadOutlined } from '@ant-design/icons';
import {
Row, Col, Form, Checkbox, Divider, InputNumber,
Button, Rate, Tabs, Pagination, Spin
} from 'antd';
import type { FormProps } from 'antd';
import { useEffect, useState } from 'react';
import { useNavigate, useOutletContext } from 'react-router-dom';
import 'styles/home.scss';
type FieldType = {
range: {
from: number;
to: number
}
category: string[]
};
const HomePage = () => {
// const [searchTerm] = useOutletContext() as any;
const [listCategory, setListCategory] = useState<ICategory[]>([]);
const [listBook, setListBook] = useState<IBook[]>([]);
const [current, setCurrent] = useState<number>(1);
const [pageSize, setPageSize] = useState<number>(10);
const [total, setTotal] = useState<number>(0);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [filter, setFilter] = useState<string>("");
const [sortQuery, setSortQuery] = useState<string>("sort=-sold");
const [showMobileFilter, setShowMobileFilter] = useState<boolean>(false);
const [form] = Form.useForm();
const navigate = useNavigate();
useEffect(() => {
const initCategory = async () => {
const res = await getCategoryAPI();
if (res && res.data) {
const d = res.data.categories.map(item => {
return item;
})
setListCategory(d);
}
}
initCategory();
}, []);
useEffect(() => {
fetchBook();
}, [current, pageSize, filter, sortQuery]);
const fetchBook = async () => {
setIsLoading(true)
let query = `current=${current}&pageSize=${pageSize}`;
if (filter) {
query += `&${filter}`;
}
if (sortQuery) {
query += `&${sortQuery}`;
}
const res = await getBookAPI(query);
console.log(res);
if (res && res.data) {
setListBook(res.data.result);
setTotal(res.data.meta.total)
}
setIsLoading(false)
}
const handleOnchangePage = (pagination: { current: number, pageSize: number }) => {
if (pagination && pagination.current !== current) {
setCurrent(pagination.current)
}
if (pagination && pagination.pageSize !== pageSize) {
setPageSize(pagination.pageSize)
setCurrent(1);
}
}
const handleChangeFilter = (changedValues: any, values: any) => {
//only fire if category changes
if (changedValues.category) {
const cate = values.category;
if (cate && cate.length > 0) {
const f = cate.join(',');
setFilter(`category=${f}`)
} else {
//reset data -> fetch all
setFilter('');
}
}
}
const onFinish: FormProps<FieldType>['onFinish'] = async (values) => {
if (values?.range?.from >= 0 && values?.range?.to >= 0) {
let f = `price>=${values?.range?.from}&price<=${values?.range?.to}`;
if (values?.category?.length) {
const cate = values?.category?.join(',');
f += `&category=${cate}`
}
setFilter(f);
}
}
const onChange = (key: string) => {
// console.log(key);
};
const items = [
{
key: "sort=-sold",
label: `Phổ biến`,
children: <></>,
},
{
key: 'sort=-updatedAt',
label: `Hàng Mới`,
children: <></>,
},
{
key: 'sort=price',
label: `Giá Thấp Đến Cao`,
children: <></>,
},
{
key: 'sort=-price',
label: `Giá Cao Đến Thấp`,
children: <></>,
},
];
return (
<>
<div style={{ background: '#efefef', padding: "20px 0" }}>
<div className="homepage-container" style={{ maxWidth: 1440, margin: '0 auto', overflow: "hidden" }}>
<Row gutter={[20, 20]}>
<Col md={4} sm={0} xs={0}>
<div style={{ padding: "20px", background: '#fff', borderRadius: 5 }}>
<div style={{ display: 'flex', justifyContent: "space-between" }}>
<span> <FilterTwoTone />
<span style={{ fontWeight: 500 }}> Bộ lọc tìm kiếm</span>
</span>
<ReloadOutlined title="Reset" onClick={() => {
form.resetFields();
setFilter('');
}}
/>
</div>
<Divider />
<Form
onFinish={onFinish}
form={form}
onValuesChange={(changedValues, values) => handleChangeFilter(changedValues, values)}
>
<Form.Item
name="category"
label="Danh mục sản phẩm"
labelCol={{ span: 24 }}
>
<Checkbox.Group>
<Row>
{listCategory?.map((item, index) => {
return (
<Col span={24} key={`index-${index}`} style={{ padding: '7px 0' }}>
<Checkbox value={item.catID} >
{item.catName}
</Checkbox>
</Col>
)
})}
</Row>
</Checkbox.Group>
</Form.Item>
<Divider />
<Form.Item
label="Khoảng giá"
labelCol={{ span: 24 }}
>
<Row gutter={[10, 10]} style={{ width: "100%" }}>
<Col xl={11} md={24}>
<Form.Item name={["range", 'from']}>
<InputNumber
name='from'
min={0}
placeholder="đ TỪ"
formatter={(value) => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
style={{ width: '100%' }}
/>
</Form.Item>
</Col>
<Col xl={2} md={0}>
<div > - </div>
</Col>
<Col xl={11} md={24}>
<Form.Item name={["range", 'to']}>
<InputNumber
name='to'
min={0}
placeholder="đ ĐẾN"
formatter={(value) => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
style={{ width: '100%' }}
/>
</Form.Item>
</Col>
</Row>
<div>
<Button onClick={() => form.submit()}
style={{ width: "100%" }} type='primary'>Áp dụng</Button>
</div>
</Form.Item>
<Divider />
<Form.Item
label="Đánh giá"
labelCol={{ span: 24 }}
>
<div>
<Rate value={5} disabled style={{ color: '#ffce3d', fontSize: 15 }} />
<span className="ant-rate-text"></span>
</div>
<div>
<Rate value={4} disabled style={{ color: '#ffce3d', fontSize: 15 }} />
<span className="ant-rate-text">trở lên</span>
</div>
<div>
<Rate value={3} disabled style={{ color: '#ffce3d', fontSize: 15 }} />
<span className="ant-rate-text">trở lên</span>
</div>
<div>
<Rate value={2} disabled style={{ color: '#ffce3d', fontSize: 15 }} />
<span className="ant-rate-text">trở lên</span>
</div>
<div>
<Rate value={1} disabled style={{ color: '#ffce3d', fontSize: 15 }} />
<span className="ant-rate-text">trở lên</span>
</div>
</Form.Item>
</Form>
</div>
</Col>
<Col md={20} xs={24} >
<Spin spinning={isLoading} tip="Loading...">
<div style={{ padding: "20px", background: '#fff', borderRadius: 5 }}>
<Row >
<Tabs
defaultActiveKey="sort=-sold"
items={items}
onChange={(value) => { setSortQuery(value) }}
style={{ overflowX: "auto" }}
/>
<Col xs={24} md={0}>
<div style={{ marginBottom: 20 }} >
<span onClick={() => setShowMobileFilter(true)}>
<FilterTwoTone />
<span style={{ fontWeight: 500 }}> Lọc</span>
</span>
</div>
</Col>
</Row>
{<Row className='customize-row'>
{listBook?.map((item, index) => {
return (
<div
onClick={() => navigate(`/book/${item.bookID}`)}
className="column" key={`book-${index}`}>
<div className='wrapper'>
<div className='thumbnail'>
<img src={`${import.meta.env.VITE_BACKEND_URL}${item.image}`} alt="thumbnail book" />
</div>
<div className='text'>{item.bookTitle}</div>
<div className='price'>
{new Intl.NumberFormat('vi-VN', { style: 'currency', currency: 'VND' }).format(item?.bookPrice ?? 0)}
</div>
{/* <div className='rating'>
<Rate value={5} disabled style={{ color: '#ffce3d', fontSize: 10 }} />
<span>Đã bán {item?. ?? 0}</span>
</div> */}
</div>
</div>
)
})}
</Row>}
<div style={{ marginTop: 30 }}></div>
<Row style={{ display: "flex", justifyContent: "center" }}>
<Pagination
current={current}
total={total}
pageSize={pageSize}
responsive
onChange={(p, s) => handleOnchangePage({ current: p, pageSize: s })}
/>
</Row>
</div>
</Spin>
</Col>
</Row>
</div>
</div>
{/* <MobileFilter
isOpen={showMobileFilter}
setIsOpen={setShowMobileFilter}
handleChangeFilter={handleChangeFilter}
listCategory={listCategory}
onFinish={onFinish}
/> */}
</>
)
}
export default HomePage;Editor is loading...
Leave a Comment