-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert grading systems to object upon caching (#45)
* Move sort state to query state. * Save selected columns to localstorage. * Added 'dodaj plezalisce' cta to the end of crags list. * Align actions row to center. * Add message when filters produce no results. Also hide table header in this case. * Adjust nr label for routes/boulders/both cases. * Adjust padding on table/compact and fix compact/table switching. * Fix columns in localstorage. * Fix range slider so that the thumbs do not exceed container at the far end positions. * Export approach time filter to component and make it collapsible. * Add filter chips and reorganize crag filters. * make cached grading systems an object instead of array * add types to generated grading systems --------- Co-authored-by: salamca <[email protected]>
- Loading branch information
Showing
13 changed files
with
2,443 additions
and
25 deletions.
There are no files selected for viewing
3 changes: 0 additions & 3 deletions
3
.../[cragSlug]/(crag)/components/crag-routes/crag-route-list/crag-route/difficulty-votes.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import FilterChip from "./filter-chip"; | ||
import { Filter } from "./filtersHelp"; | ||
|
||
type TActiveFiltersProps = { | ||
filters: Record<string, Filter>; | ||
}; | ||
|
||
function ActiveFilters({ filters }: TActiveFiltersProps) { | ||
return ( | ||
<div className="flex flex-wrap gap-2"> | ||
{Object.values(filters) | ||
.filter((filter) => filter.isActive()) | ||
.map((filter) => ( | ||
<FilterChip key={filter.label} filter={filter} /> | ||
))} | ||
</div> | ||
); | ||
} | ||
|
||
export default ActiveFilters; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import Button from "@/components/ui/button"; | ||
import IconClose from "@/components/ui/icons/close"; | ||
import { Filter } from "./filtersHelp"; | ||
|
||
type TFilterChipProps = { | ||
filter: Filter; | ||
}; | ||
|
||
function FilterChip({ filter }: TFilterChipProps) { | ||
return ( | ||
<div className="inline-flex items-center rounded-lg bg-blue-50 py-px pl-3 pr-2"> | ||
<div> | ||
{filter.label}: {filter.valueToString()} | ||
</div> | ||
<Button variant="quaternary" onClick={filter.handleReset}> | ||
<IconClose /> | ||
</Button> | ||
</div> | ||
); | ||
} | ||
|
||
export default FilterChip; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import IconFilter from "@/components/ui/icons/filter"; | ||
import { Fragment } from "react"; | ||
import { Filter, MultiFilter, RangeFilter } from "./filtersHelp"; | ||
import Button from "@/components/ui/button"; | ||
import IconReset from "@/components/ui/icons/reset"; | ||
import { IconSize } from "@/components/ui/icons/icon-size"; | ||
|
||
type TFiltersPane = { | ||
open: boolean; | ||
filtersData: Record<string, Filter>; | ||
onResetAll: () => void; | ||
}; | ||
|
||
function FiltersPane({ open, filtersData, onResetAll }: TFiltersPane) { | ||
/** | ||
* on >=md filters pane is always visible and is displayed as a card | ||
* on <md filters pane slides in from the side when filters are being changed | ||
**/ | ||
return ( | ||
<div | ||
className={`absolute left-0 w-80 shrink-0 rounded-r-lg bg-neutral-100 transition-transform md:relative md:block md:rounded-lg ${ | ||
open ? "translate-x-0" : "-translate-x-80 md:translate-x-0" | ||
}`} | ||
> | ||
<div className="flex px-8 pb-1 pt-6"> | ||
<div> | ||
<IconFilter /> | ||
</div> | ||
<div className="ml-4">Filtriraj</div> | ||
</div> | ||
|
||
{Object.values(filtersData) | ||
.filter((filter) => { | ||
if ( | ||
filter instanceof MultiFilter && | ||
Object.keys(filter.options).length == 0 | ||
) { | ||
// do not display a multi filter with no options | ||
return false; | ||
} | ||
|
||
if (filter instanceof RangeFilter && filter.min == filter.max) { | ||
// do not display a range filter with same min and max as it makes no sense then | ||
return false; | ||
} | ||
|
||
return true; | ||
}) | ||
.map((filter) => ( | ||
<Fragment key={filter.label}>{filter.renderFilterGroup()}</Fragment> | ||
))} | ||
|
||
<div className="mt-5 border-t border-neutral-200 px-8 pb-5 pt-4"> | ||
<Button variant="tertiary" onClick={onResetAll}> | ||
<span className="flex gap-2"> | ||
<IconReset size={IconSize.regular} /> | ||
Ponastavi vse | ||
</span> | ||
</Button> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default FiltersPane; |
Oops, something went wrong.