feat: add thumbs grid
parent
bb5054cb30
commit
09b2f1220d
|
@ -10,6 +10,8 @@ import './style/SquareSpace/global.css'
|
||||||
import './style/SquareSpace/blocks.css'
|
import './style/SquareSpace/blocks.css'
|
||||||
import './style/SquareSpace/table.css'
|
import './style/SquareSpace/table.css'
|
||||||
import './style/SquareSpace/video.css'
|
import './style/SquareSpace/video.css'
|
||||||
|
import './style/thumbs.css'
|
||||||
|
import './style/row.css'
|
||||||
import './photos'
|
import './photos'
|
||||||
|
|
||||||
const Layout = () => <div>
|
const Layout = () => <div>
|
||||||
|
|
|
@ -2,11 +2,12 @@ import React from "react";
|
||||||
import {Outlet, useLoaderData} from "react-router";
|
import {Outlet, useLoaderData} from "react-router";
|
||||||
import {ResistantRow} from "../ResistantRow";
|
import {ResistantRow} from "../ResistantRow";
|
||||||
import {Resistant} from "../../Resistant";
|
import {Resistant} from "../../Resistant";
|
||||||
import {Group, TextInput} from "@mantine/core";
|
import {Center, Grid, Group, SegmentedControl, TextInput} from "@mantine/core";
|
||||||
import {FiltreDepartement} from "./FiltreDepartement";
|
import {FiltreDepartement} from "./FiltreDepartement";
|
||||||
import {IconUsers} from "@tabler/icons-react";
|
import {IconCameraSelfie, IconList, IconMap, IconPhoto, IconUsers} from "@tabler/icons-react";
|
||||||
import {Separator} from "../../components/Separator";
|
import {Separator} from "../../components/Separator";
|
||||||
import {FiltreAcademie} from "./FiltreAcademie";
|
import {FiltreAcademie} from "./FiltreAcademie";
|
||||||
|
import {ResistantThumb} from "../ResistantThumb";
|
||||||
|
|
||||||
export const resistantsLoader = async () => {
|
export const resistantsLoader = async () => {
|
||||||
const spreadsheetId = '1GL1MBChnwNn0t8WtKK5M3PbtCJ_bTJRhoTwAI9jeWck'
|
const spreadsheetId = '1GL1MBChnwNn0t8WtKK5M3PbtCJ_bTJRhoTwAI9jeWck'
|
||||||
|
@ -21,18 +22,30 @@ const normalize = (text: string) => (text || "")
|
||||||
.normalize("NFD")
|
.normalize("NFD")
|
||||||
.replace(/\p{Diacritic}/gu, "")
|
.replace(/\p{Diacritic}/gu, "")
|
||||||
|
|
||||||
|
type ViewMode = "list" | "photos" | "map";
|
||||||
export const ListeResistants = () => {
|
export const ListeResistants = () => {
|
||||||
const { resistants } = useLoaderData() as { resistants: Resistant[] }
|
const { resistants } = useLoaderData() as { resistants: Resistant[] }
|
||||||
const [departement, setDepartement] = React.useState<string|null>(null)
|
const [departement, setDepartement] = React.useState<string|null>(null)
|
||||||
const [academie, setAcademie] = React.useState<string|null>(null)
|
const [academie, setAcademie] = React.useState<string|null>(null)
|
||||||
const [nom, setNom] = React.useState<string|undefined>(undefined)
|
const [nom, setNom] = React.useState<string|undefined>(undefined)
|
||||||
|
const [viewMode, setViewMode ] = React.useState<ViewMode>("photos")
|
||||||
|
|
||||||
const filtreNom = (event: React.ChangeEvent<HTMLInputElement>) => setNom(event.target.value)
|
const filtreNom = (event: React.ChangeEvent<HTMLInputElement>) => setNom(event.target.value)
|
||||||
|
|
||||||
|
const filteredResistants = resistants
|
||||||
|
.filter(r => !nom || normalize(r.noms).includes(normalize(nom.toLowerCase())))
|
||||||
|
.filter(r => !departement || normalize(r.departement).includes(normalize(departement)))
|
||||||
|
.filter(r => !academie || normalize(r.academie).includes(normalize(academie)))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div id="listeResistants">
|
<div id="listeResistants">
|
||||||
<Group position="center">
|
<Group position="center">
|
||||||
|
<SegmentedControl data={[
|
||||||
|
{ value: "list", label: <Center><IconList />Liste</Center>},
|
||||||
|
{ value: "photos", label: <Center><IconCameraSelfie />Photos</Center>},
|
||||||
|
{ value: "map", label: <Center><IconMap />Carte</Center>},
|
||||||
|
]} size="xs" defaultValue="photos" onChange={(value) => setViewMode(value as ViewMode )} />
|
||||||
<TextInput icon={<IconUsers />} placeholder="Nom" onChange={filtreNom}/>
|
<TextInput icon={<IconUsers />} placeholder="Nom" onChange={filtreNom}/>
|
||||||
<FiltreDepartement resistants={resistants} onChange={setDepartement}/>
|
<FiltreDepartement resistants={resistants} onChange={setDepartement}/>
|
||||||
<FiltreAcademie resistants={resistants} onChange={setAcademie}/>
|
<FiltreAcademie resistants={resistants} onChange={setAcademie}/>
|
||||||
|
@ -40,11 +53,14 @@ export const ListeResistants = () => {
|
||||||
|
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|
||||||
{resistants
|
{viewMode === "list" && filteredResistants.map((r) => <ResistantRow resistant={r} key={r.id}/>)}
|
||||||
.filter(r => !nom || normalize(r.noms).includes(normalize(nom.toLowerCase())))
|
{viewMode === "photos" && <Grid columns={4} gutterXs="md" gutterXl="md">
|
||||||
.filter(r => !departement || normalize(r.departement).includes(normalize(departement)))
|
{filteredResistants.map((r) => <Grid.Col span={"auto"} key={r.id}>
|
||||||
.filter(r => !academie || normalize(r.academie).includes(normalize(academie)))
|
<ResistantThumb resistant={r} />
|
||||||
.map((r) => <ResistantRow resistant={r} key={r.noms}/>)}
|
</Grid.Col>)}
|
||||||
|
</Grid>}
|
||||||
|
|
||||||
|
|
||||||
<Outlet/>
|
<Outlet/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -11,7 +11,7 @@ export const ResistantRow = ({resistant}: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="row sqs-row" onClick={() => navigate(resistant.noms)}>
|
<div className="row sqs-row resistant-row" onClick={() => navigate(resistant.noms)}>
|
||||||
<div className="col sqs-col-4 span-4" id="yui_3_17_2_1_1674987238932_138">
|
<div className="col sqs-col-4 span-4" id="yui_3_17_2_1_1674987238932_138">
|
||||||
<div
|
<div
|
||||||
className="sqs-block image-block sqs-block-image sqs-text-ready"
|
className="sqs-block image-block sqs-block-image sqs-text-ready"
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import {Resistant} from "../Resistant";
|
||||||
|
import {useNavigate} from "react-router";
|
||||||
|
import {Separator} from "../components/Separator";
|
||||||
|
import {BackgroundImage, Grid, Text} from "@mantine/core";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
resistant: Resistant
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ResistantThumb = ({resistant}: Props) => {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
return <BackgroundImage src={`https://enfance-libre.frama.io/resistants/assets/${resistant.id}.jpg`} style={{width: "200px", height: "200px"}}>
|
||||||
|
<div className="thumb" onClick={() => navigate(resistant.noms)} style={{width: "200px", height: "200px", position: "relative"}}>
|
||||||
|
<div className="thumb-name"><Text size="sm">{resistant.noms}</Text></div>
|
||||||
|
</div>
|
||||||
|
</BackgroundImage>
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
.resistant-row {
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resistant-row:hover {
|
||||||
|
background-color: #8f96a3;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
.thumb {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb .thumb-name {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
background-color: white;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb:hover {
|
||||||
|
border: black solid 2px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb:hover .thumb-name {
|
||||||
|
display: block;
|
||||||
|
}
|
Loading…
Reference in New Issue