1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-20 14:54:15 +01:00

Add accordion item component

This commit is contained in:
vincent 2022-08-15 14:51:13 +02:00
parent 7ca3955c1d
commit 5677ef3b6d
3 changed files with 59 additions and 13 deletions

View File

@ -0,0 +1,30 @@
/* eslint-disable fabmanager/scoped-translation */
import React, { useState, useEffect } from 'react';
import { CaretDown } from 'phosphor-react';
interface AccordionItemProps {
isOpen: boolean,
onChange: (id: number, isOpen: boolean) => void,
id: number,
label: string
}
/**
* Renders an accordion item
*/
export const AccordionItem: React.FC<AccordionItemProps> = ({ isOpen, onChange, id, label, children }) => {
const [state, setState] = useState(isOpen);
useEffect(() => {
onChange(id, state);
}, [state]);
return (
<div id={id.toString()} className={`accordion-item ${state ? '' : 'collapsed'}`}>
<header onClick={() => setState(!state)}>
{label}
<CaretDown size={16} weight="bold" />
</header>
{children}
</div>
);
};

View File

@ -13,7 +13,8 @@ import { ProductsList } from './products-list';
import ProductAPI from '../../api/product';
import ProductCategoryAPI from '../../api/product-category';
import MachineAPI from '../../api/machine';
import { CaretDown, X } from 'phosphor-react';
import { AccordionItem } from './accordion-item';
import { X } from 'phosphor-react';
import Switch from 'react-switch';
import Select from 'react-select';
@ -45,15 +46,14 @@ const Products: React.FC<ProductsProps> = ({ onSuccess, onError }) => {
const [productCategories, setProductCategories] = useState<ProductCategory[]>([]);
const [machines, setMachines] = useState<checklistOption[]>([]);
const [update, setUpdate] = useState(false);
const [accordion, setAccordion] = useState({});
useEffect(() => {
ProductAPI.index().then(data => {
setProducts(data);
setFilteredProductList(data);
});
}, []);
useEffect(() => {
ProductCategoryAPI.index().then(data => {
// Map product categories by position
const sortedCategories = data
@ -68,6 +68,7 @@ const Products: React.FC<ProductsProps> = ({ onSuccess, onError }) => {
});
setProductCategories(sortedCategories);
}).catch(onError);
MachineAPI.index({ disabled: false }).then(data => {
setMachines(buildChecklistOptions(data));
}).catch(onError);
@ -230,6 +231,7 @@ const Products: React.FC<ProductsProps> = ({ onSuccess, onError }) => {
// { value: 3, label: t('app.admin.store.products.sort.price_high') }
];
};
/**
* Sorts products list
*/
@ -246,6 +248,13 @@ const Products: React.FC<ProductsProps> = ({ onSuccess, onError }) => {
}
};
/**
* Open/close accordion items
*/
const handleAccordion = (id, state) => {
setAccordion({ ...accordion, [id]: state });
};
return (
<div className='products'>
<header>
@ -263,10 +272,11 @@ const Products: React.FC<ProductsProps> = ({ onSuccess, onError }) => {
</div>
</header>
<div className='accordion'>
<div className='accordion-item'>
<input type="checkbox" defaultChecked />
<header>{t('app.admin.store.products.filter_categories')}
<CaretDown size={16} weight="bold" /></header>
<AccordionItem id={0}
isOpen={accordion[0]}
onChange={handleAccordion}
label={t('app.admin.store.products.filter_categories')}
>
<div className='content'>
<div className="list scrollbar">
{productCategories.map(pc => (
@ -278,12 +288,13 @@ const Products: React.FC<ProductsProps> = ({ onSuccess, onError }) => {
</div>
<FabButton onClick={applyFilters} className="is-info">{t('app.admin.store.products.filter_apply')}</FabButton>
</div>
</div>
</AccordionItem>
<div className='accordion-item'>
<input type="checkbox" defaultChecked />
<header>{t('app.admin.store.products.filter_machines')}
<CaretDown size={16} weight="bold" /></header>
<AccordionItem id={1}
isOpen={accordion[1]}
onChange={handleAccordion}
label={t('app.admin.store.products.filter_machines')}
>
<div className='content'>
<div className="list scrollbar">
{machines.map(m => (
@ -295,7 +306,7 @@ const Products: React.FC<ProductsProps> = ({ onSuccess, onError }) => {
</div>
<FabButton onClick={applyFilters} className="is-info">{t('app.admin.store.products.filter_apply')}</FabButton>
</div>
</div>
</AccordionItem>
</div>
</div>
<div className='products-list span-7'>

View File

@ -10,6 +10,10 @@
&-item {
position: relative;
padding-bottom: 1.6rem;
&.collapsed {
.content { max-height: 0; }
header svg { transform: rotateZ(180deg); }
}
& > input[type=checkbox] {
position: absolute;
@ -33,6 +37,7 @@
background: none;
border: none;
@include text-base(600);
cursor: pointer;
svg { transition: transform 250ms ease-in-out; }
}
.content {