Before Width: | Height: | Size: 966 B After Width: | Height: | Size: 996 B |
Before Width: | Height: | Size: 516 B After Width: | Height: | Size: 525 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 829 B After Width: | Height: | Size: 856 B |
Before Width: | Height: | Size: 864 B After Width: | Height: | Size: 882 B |
@ -1,6 +0,0 @@ |
||||
.specifications-li:hover div{ |
||||
background-color: rgba(25,110,192,0.15); |
||||
} |
||||
.specifications-li div{ |
||||
transition: all 0.2s; |
||||
} |
@ -1,11 +1,11 @@ |
||||
import React from "react"; |
||||
import "./index.scss"; |
||||
|
||||
export default function index() { |
||||
export default function Switch({checked}) { |
||||
return ( |
||||
<div className="switch"> |
||||
<input type="checkbox" id="toggle" /> |
||||
<label for="toggle"></label> |
||||
<div className="switchbox transition-all"> |
||||
<input className="transition-all" type="checkbox" id="toggle" checked={checked} /> |
||||
<label className="transition-all" for="toggle"></label> |
||||
</div> |
||||
); |
||||
} |
||||
|
@ -0,0 +1,17 @@ |
||||
import proxy from "../proxy"; |
||||
const transport = { |
||||
list: |
||||
(data = {}) => |
||||
async (dispatch) => { |
||||
await proxy.get("transport/list", data, { dispatch }); |
||||
}, |
||||
set: |
||||
(data = {}, data2 = {}, data3 = {}) => |
||||
async (dispatch) => { |
||||
await proxy.post("transport/setTransport", data, { dispatch }); |
||||
await proxy.get("userFactor/info", data2, { dispatch }); |
||||
await proxy.get("transport/list", data3, { dispatch }); |
||||
}, |
||||
}; |
||||
|
||||
export default transport; |
@ -0,0 +1,28 @@ |
||||
import { toast } from "react-toastify"; |
||||
|
||||
const initialState = { |
||||
loading: false, |
||||
error: null, |
||||
list: [], |
||||
}; |
||||
export default function transport(state = initialState, action) { |
||||
let { type, data } = action; |
||||
switch (type) { |
||||
case "transport/list": |
||||
return { |
||||
...state, |
||||
loading: false, |
||||
list: data, |
||||
error: null, |
||||
}; |
||||
case "transport/info": |
||||
return { ...state, loading: false, error: null}; |
||||
case "transport/loading": |
||||
return { ...state, loading: true }; |
||||
case "transport/error": |
||||
toast.error(data.message); |
||||
return { ...state, loading: false, error: data.message }; |
||||
default: |
||||
return state; |
||||
} |
||||
} |
@ -0,0 +1,61 @@ |
||||
const grades = [ |
||||
"پیش دبستان", |
||||
"اول", |
||||
"دوم", |
||||
"سوم", |
||||
"چهارم", |
||||
"پنجم", |
||||
"ششم", |
||||
"هفتم", |
||||
"هشتم", |
||||
"نهم", |
||||
"دهم", |
||||
"یازدهم", |
||||
"دوازدهم", |
||||
]; |
||||
class filter { |
||||
productsPage = (products, options) => { |
||||
const { grade, subject, sort } = options; |
||||
|
||||
if (grade.length > 0 || subject.length > 0 || sort) { |
||||
localStorage.setItem("filter", "ON"); |
||||
} |
||||
let finalSort; |
||||
let byGradeFilter = []; |
||||
if (grade.length > 0) { |
||||
grade.map((item1) => { |
||||
for (let i = 0; i < products.length; i++) { |
||||
if (grades[products[i].gradeId] === item1) { |
||||
byGradeFilter.push(products[i]); |
||||
} |
||||
} |
||||
}); |
||||
} else { |
||||
byGradeFilter = products; |
||||
} |
||||
let bySubjectFilter = []; |
||||
if (subject.length > 0) { |
||||
subject.map((item1) => { |
||||
for (let i = 0; i < byGradeFilter.length; i++) { |
||||
if (byGradeFilter[i].name === item1) { |
||||
bySubjectFilter.push(byGradeFilter[i]); |
||||
} |
||||
} |
||||
}); |
||||
} else { |
||||
bySubjectFilter = byGradeFilter; |
||||
} |
||||
|
||||
if (sort === "گران ترین") { |
||||
finalSort = bySubjectFilter.sort((item1, item2) => { |
||||
return item1.product[0].price - item2.product[0].price; |
||||
}); |
||||
} else { |
||||
finalSort = bySubjectFilter; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
const _filter = new filter(); |
||||
|
||||
export default _filter; |
@ -1,36 +1,131 @@ |
||||
import React from "react"; |
||||
import React, { useState, useMemo } from "react"; |
||||
import { connect } from "react-redux"; |
||||
import { book } from "../../../redux/actions"; |
||||
import Checkbox from "../../../components/Checkbox"; |
||||
import VerticalExpandableProductFilter from "../../../components/VerticalExpandableProductFilter"; |
||||
|
||||
export const Sidebar = ({ onChange, grades }) => { |
||||
const categories = [ |
||||
"کتاب فیزیکی", |
||||
"کتاب دیجیتال", |
||||
"دوره ویدیویی", |
||||
"بسته های آموزشی", |
||||
]; |
||||
import Switch from "../../../components/Switch"; |
||||
|
||||
//assets
|
||||
import dropdownIcon from "../../../assets/icons/dropdown-blue.svg"; |
||||
|
||||
export const Sidebar = ({ |
||||
onChange, |
||||
levels, |
||||
subjects, |
||||
productTypes, |
||||
setFilterOptions, |
||||
filterOptions, |
||||
}) => { |
||||
const [toggleList, setToggleList] = useState({ |
||||
subject: false, |
||||
grade: false, |
||||
productType: false, |
||||
}); |
||||
|
||||
const Dropdown = ({ list, title, name, active }) => { |
||||
return ( |
||||
<div className="flex flex-col"> |
||||
<div |
||||
className="flex flex-row justify-between items-center py-5 cursor-pointer" |
||||
onClick={() => |
||||
setToggleList({ ...toggleList, [name]: !toggleList[name] }) |
||||
} |
||||
> |
||||
<strong className="font-semibold text-tiny text-green4F"> |
||||
{title} |
||||
</strong> |
||||
<img |
||||
src={dropdownIcon} |
||||
alt="" |
||||
className={`w-4 transform transition-all ${ |
||||
toggleList[name] ? "rotate-180" : "" |
||||
}`}
|
||||
/> |
||||
</div> |
||||
<ul |
||||
className={`list-none p-0 mt-2 mb-0 mx-0 flex overflow-x-hidden flex-col transition-all`} |
||||
style={{ |
||||
maxHeight: !toggleList[name] ? 0 : "calc(100vh / 2.2)", |
||||
overflowY: !toggleList[name] ? "hidden" : "scroll", |
||||
}} |
||||
> |
||||
{list.map((item, index) => ( |
||||
<li |
||||
key={index} |
||||
className="flex flex-row items-center mb-3" |
||||
onClick={() => |
||||
active !== item |
||||
? setFilterOptions({ ...filterOptions, [name]: item }) |
||||
: setFilterOptions({ ...filterOptions, [name]: null }) |
||||
} |
||||
> |
||||
<Checkbox checked={active === item} /> |
||||
<span className="text-tiny font-medium">{item}</span> |
||||
</li> |
||||
))} |
||||
</ul> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
const CkeckItem = ({ title, name }) => { |
||||
return ( |
||||
<div |
||||
className="flex flex-row justify-between items-center py-4" |
||||
onClick={() => |
||||
setFilterOptions({ |
||||
...filterOptions, |
||||
[name]: !filterOptions.available, |
||||
}) |
||||
} |
||||
> |
||||
<span className="font-semibold text-tiny text-green4F">{title}</span> |
||||
<Switch checked={filterOptions.available} /> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
return ( |
||||
<div className="flex flex-col w-1/4 p-4"> |
||||
<VerticalExpandableProductFilter |
||||
onChange={onChange} |
||||
name="grade" |
||||
list={Object.values(grades)} |
||||
title="پایه تحصیلی" |
||||
/> |
||||
<VerticalExpandableProductFilter |
||||
name="category" |
||||
list={categories} |
||||
title="دسته بندی" |
||||
/> |
||||
<div |
||||
className="flex flex-col w-1/4 px-4 pt-5 pb-2 bg-gray-50 transform translate-y-5 border border-solid border-gray-200 rounded-md" |
||||
style={{ |
||||
height: "fit-content", |
||||
}} |
||||
> |
||||
<strong className="text-lg text-green4F mb-10">فیلترها</strong> |
||||
<div className="flex flex-col divide-y divide-solid divide-gray-200"> |
||||
<Dropdown |
||||
list={productTypes} |
||||
title="نوع محصول" |
||||
name="productType" |
||||
active={filterOptions.productType} |
||||
/> |
||||
<Dropdown |
||||
list={Object.values(levels)} |
||||
title={"پایه تحصیلی"} |
||||
name="grade" |
||||
active={filterOptions.grade} |
||||
/> |
||||
<Dropdown |
||||
list={subjects} |
||||
title={"عنوان کتاب"} |
||||
name="subject" |
||||
active={filterOptions.subject} |
||||
/> |
||||
<CkeckItem title="فقط کالاهای موجود" name={"available"} /> |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
const mapStateToProps = (state) => ({ |
||||
grades: state.publicApi.grades, |
||||
levels: state.book.levels, |
||||
subjects: state.book.subjects, |
||||
productTypes: state.book.productTypes, |
||||
filterOptions: state.book.filterOptions, |
||||
}); |
||||
|
||||
const mapDispatchToProps = {}; |
||||
const mapDispatchToProps = { |
||||
setFilterOptions: book.setFilterOptions, |
||||
}; |
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Sidebar); |
||||
|