tidy up event filters a lil bit, add toggle function
This commit is contained in:
@ -16,6 +16,8 @@ import styles from "./eventContainer.module.scss";
|
|||||||
import { formatDate, formatYearMonth } from "@/lib/date";
|
import { formatDate, formatYearMonth } from "@/lib/date";
|
||||||
import { parse } from "date-fns";
|
import { parse } from "date-fns";
|
||||||
import { unique } from "@/lib/common";
|
import { unique } from "@/lib/common";
|
||||||
|
import Icon from "../general/Icon";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: canonical / alternate URLs https://github.com/47ng/nuqs?tab=readme-ov-file#seo
|
TODO: canonical / alternate URLs https://github.com/47ng/nuqs?tab=readme-ov-file#seo
|
||||||
@ -64,22 +66,40 @@ export const EventContainer = ({
|
|||||||
.includes(category)
|
.includes(category)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [showFilter, setShowFilter] = useState(false);
|
||||||
|
function toggleFilter() {
|
||||||
|
setShowFilter(!showFilter);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.events}>
|
<div className={styles.events}>
|
||||||
<EventFilter
|
|
||||||
eventCategories={filterableCategories}
|
|
||||||
setCategory={setCategory}
|
|
||||||
activeCategory={category}
|
|
||||||
eventOrganizers={filterableOrganizers}
|
|
||||||
setOrganizer={setOrganizer}
|
|
||||||
activeOrganizer={organizer}
|
|
||||||
/>
|
|
||||||
<div className={styles.eventWrapper}>
|
<div className={styles.eventWrapper}>
|
||||||
<div className={styles.displayOptions}>
|
<div className={styles.displayOptions}>
|
||||||
<button onClick={() => setMode(null)}>Vis liste</button>
|
<button onClick={() => setMode(null)} className="button secondary">
|
||||||
<button onClick={() => setMode("calendar")}>Vis kalender</button>
|
<span>Vis liste</span>
|
||||||
<button>Filtrer</button>
|
<Icon />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setMode("calendar")}
|
||||||
|
className="button secondary"
|
||||||
|
>
|
||||||
|
<span>Vis kalender</span>
|
||||||
|
<Icon />
|
||||||
|
</button>
|
||||||
|
<button onClick={toggleFilter} className="button tertiary">
|
||||||
|
<span>Filter</span>
|
||||||
|
<Icon />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<EventFilter
|
||||||
|
eventCategories={filterableCategories}
|
||||||
|
setCategory={setCategory}
|
||||||
|
activeCategory={category}
|
||||||
|
eventOrganizers={filterableOrganizers}
|
||||||
|
setOrganizer={setOrganizer}
|
||||||
|
activeOrganizer={organizer}
|
||||||
|
isVisible={showFilter}
|
||||||
|
/>
|
||||||
{mode === "list" && <EventList events={filteredEvents} />}
|
{mode === "list" && <EventList events={filteredEvents} />}
|
||||||
{mode === "calendar" && <EventCalendar events={filteredEvents} />}
|
{mode === "calendar" && <EventCalendar events={filteredEvents} />}
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,6 +9,7 @@ export const EventFilter = ({
|
|||||||
eventOrganizers,
|
eventOrganizers,
|
||||||
setOrganizer,
|
setOrganizer,
|
||||||
activeOrganizer,
|
activeOrganizer,
|
||||||
|
isVisible,
|
||||||
}: {
|
}: {
|
||||||
eventCategories: EventCategory[];
|
eventCategories: EventCategory[];
|
||||||
setCategory: (slug: string | null) => void;
|
setCategory: (slug: string | null) => void;
|
||||||
@ -16,6 +17,7 @@ export const EventFilter = ({
|
|||||||
eventOrganizers: EventOrganizer[];
|
eventOrganizers: EventOrganizer[];
|
||||||
setOrganizer: (slug: string | null) => void;
|
setOrganizer: (slug: string | null) => void;
|
||||||
activeOrganizer: string | null;
|
activeOrganizer: string | null;
|
||||||
|
isVisible: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const onOrganizerSelect = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
const onOrganizerSelect = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
const organizer = e.target.value;
|
const organizer = e.target.value;
|
||||||
@ -23,44 +25,52 @@ export const EventFilter = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.eventFilter}>
|
<div className={styles.eventFilter} data-show={isVisible}>
|
||||||
<span className="suphead">Kategori</span>
|
<div className={styles.filterContent}>
|
||||||
<ul>
|
<div className={styles.filterItem}>
|
||||||
{eventCategories
|
<span className={`suphead ${styles.heading}`}>Kategori</span>
|
||||||
.filter((x) => x.showInFilters)
|
<ul>
|
||||||
.map((category) => (
|
{eventCategories
|
||||||
<li
|
.filter((x) => x.showInFilters)
|
||||||
key={category.slug}
|
.map((category) => (
|
||||||
className={activeCategory === category.slug ? styles.active : ""}
|
<li
|
||||||
|
key={category.slug}
|
||||||
|
className={
|
||||||
|
activeCategory === category.slug ? styles.active : ""
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setCategory(
|
||||||
|
activeCategory === category.slug ? null : category.slug
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{category.name}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className={styles.filterItem}>
|
||||||
|
<label htmlFor="organizer" className={`suphead ${styles.heading}`}>
|
||||||
|
Arrangør
|
||||||
|
</label>
|
||||||
|
<div>
|
||||||
|
<select
|
||||||
|
name="organizer"
|
||||||
|
value={activeOrganizer ?? ""}
|
||||||
|
onChange={onOrganizerSelect}
|
||||||
>
|
>
|
||||||
<button
|
<option value="">Vis alle</option>
|
||||||
onClick={() =>
|
{eventOrganizers.map((organizer) => (
|
||||||
setCategory(
|
<option key={organizer.slug} value={organizer.slug}>
|
||||||
activeCategory === category.slug ? null : category.slug
|
{organizer.name}
|
||||||
)
|
</option>
|
||||||
}
|
))}
|
||||||
>
|
</select>
|
||||||
{category.name}
|
</div>
|
||||||
</button>
|
</div>
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
<label htmlFor="organizer" className="suphead">
|
|
||||||
Arrangør
|
|
||||||
</label>
|
|
||||||
<div>
|
|
||||||
<select
|
|
||||||
name="organizer"
|
|
||||||
value={activeOrganizer ?? ""}
|
|
||||||
onChange={onOrganizerSelect}
|
|
||||||
>
|
|
||||||
<option value="">Vis alle</option>
|
|
||||||
{eventOrganizers.map((organizer) => (
|
|
||||||
<option key={organizer.slug} value={organizer.slug}>
|
|
||||||
{organizer.name}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -12,15 +12,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.displayOptions {
|
.displayOptions {
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
gap: .5rem;
|
||||||
gap: var(--spacing-gap-column);
|
align-items: center;
|
||||||
//padding: 0 var(--spacing-sitepadding);
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
transition: background-color .5s ease;
|
||||||
|
|
||||||
button {
|
button:last-child {
|
||||||
border-radius: 0;
|
margin: 0 0 0 auto;
|
||||||
background: var(--color-deepBrick);
|
}
|
||||||
color: var(--color-goldenBeige);
|
|
||||||
|
&[data-showFilter=true] {
|
||||||
|
background-color: var(--color-background-secondary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +95,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1200px) {
|
@media (max-width: 1200px) {
|
||||||
|
.eventList {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
.calendarWeek {
|
.calendarWeek {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
@ -116,4 +124,10 @@
|
|||||||
padding: calc(var(--spacing-gap-column)/2) var(--spacing-sitepadding);
|
padding: calc(var(--spacing-gap-column)/2) var(--spacing-sitepadding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
.eventList {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,10 +1,26 @@
|
|||||||
.eventFilter {
|
.eventFilter {
|
||||||
display: flex;
|
display: grid;
|
||||||
align-items: center;
|
grid-template-rows: 0fr;
|
||||||
gap: 1rem;
|
transition: grid-template-rows .5s ease;
|
||||||
background: var(--color-background-secondary);
|
margin: var(--spacing-sitepadding) calc(var(--spacing-sitepadding)*-1) 0;
|
||||||
margin: var(--spacing-sitepadding) calc(var(--spacing-sitepadding)*-1);
|
|
||||||
padding: 1rem var(--spacing-sitepadding);
|
.filterContent {
|
||||||
|
background-color: var(--color-background);
|
||||||
|
padding: 1rem var(--spacing-sitepadding);
|
||||||
|
min-height: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
transition: visibility .5s, opacity .5s ease, background-color .5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filterItem {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
@ -25,4 +41,14 @@
|
|||||||
color: var(--color-goldenBeige);
|
color: var(--color-goldenBeige);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[data-show=true] {
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
|
||||||
|
.filterContent {
|
||||||
|
background-color: var(--color-background-secondary);
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
.pageHeader {
|
.pageHeader {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: var(--spacing-l) 0 calc(var(--spacing-l) + var(--spacing-sitepadding));
|
padding: var(--spacing-l) 0 var(--spacing-sitepadding);
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
@ -145,6 +145,18 @@ input[type="text"] {
|
|||||||
transition: opacity var(--transition-easing);
|
transition: opacity var(--transition-easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
border-radius: 10rem;
|
||||||
|
background: var(--color-white);
|
||||||
|
color: var(--color-text);
|
||||||
|
border: 2px solid currentColor;
|
||||||
|
padding: .5rem 1rem;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: var(--font-size-body);
|
||||||
|
font-weight: 500;
|
||||||
|
transition: opacity var(--transition-easing);
|
||||||
|
}
|
||||||
|
|
||||||
.number {
|
.number {
|
||||||
font-family: var(--font-serif);
|
font-family: var(--font-serif);
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
Reference in New Issue
Block a user