Improved Archive page

This commit is contained in:
2026-06-16 21:03:22 +03:00
parent 62a87a1169
commit 1f8b9bedc0
3 changed files with 143 additions and 46 deletions

View File

@@ -28,15 +28,26 @@ const sortedYears = Object.keys(dataByYear).map(Number).sort((a, b) => b - a);
const Archive = () => { const Archive = () => {
const [performersByYear, setPerformersByYear] = useState<Record<number, PerformerCard[]>>({}); const [performersByYear, setPerformersByYear] = useState<Record<number, PerformerCard[]>>({});
const [expandedYears, setExpandedYears] = useState<Record<number, boolean>>({});
useEffect(() => { useEffect(() => {
const initial: Record<number, PerformerCard[]> = {}; const initial: Record<number, PerformerCard[]> = {};
const initialExpanded: Record<number, boolean> = {};
for (const year of sortedYears) { for (const year of sortedYears) {
initial[year] = dataByYear[year].map((p) => ({ ...p, showDesc: false })); initial[year] = dataByYear[year].map((p) => ({ ...p, showDesc: false }));
initialExpanded[year] = false;
} }
setPerformersByYear(initial); setPerformersByYear(initial);
setExpandedYears(initialExpanded);
}, []); }, []);
const toggleYear = (year: number) => {
setExpandedYears((prev) => ({
...prev,
[year]: !prev[year],
}));
};
const togglePerformerDesc = (year: number, id: string) => { const togglePerformerDesc = (year: number, id: string) => {
setPerformersByYear((prev) => ({ setPerformersByYear((prev) => ({
...prev, ...prev,
@@ -51,50 +62,73 @@ const Archive = () => {
<h1>Arkisto</h1> <h1>Arkisto</h1>
{sortedYears.map((year) => ( {sortedYears.map((year) => (
<React.Fragment key={year}> <React.Fragment key={year}>
<h2 className={styles.year}>{year}</h2> <div
{(performersByYear[year] ?? []).map((p) => ( className={styles.yearTitle}
<div className={styles.performerContainer} key={p.id}> onClick={() => toggleYear(year)}
<img >
className={styles.performerImage} <h2 className={styles.year}>{year}</h2>
src={'/performers/' + year + '/' + p.id + '.jpg'} <button className={shared.openingChevron}>
width={100} {expandedYears[year] ? (
height={100} <BiChevronDown size='3rem' />
loading="lazy" ) : (
alt={p.name} <BiChevronLeft size='3rem' />
/> )}
<div className={styles.performerTextContainer}> </button>
<div </div>
className={styles.performerTitle} <div className={styles.yearPerformers}>
onClick={() => togglePerformerDesc(year, p.id)} <CSSTransition
> in={expandedYears[year]}
<h2>{p.name}</h2> timeout={300}
<button className={shared.openingChevron}> classNames='heightTransition'
{p.showDesc ? ( unmountOnExit
<BiChevronDown size='3rem' /> >
) : ( <div className={styles.yearPerformersContent}>
<BiChevronLeft size='3rem' /> {(performersByYear[year] ?? []).map((p) => (
)} <div className={styles.performerContainer} key={p.id}>
</button> <img
</div> className={styles.performerImage}
<CSSTransition src={'/performers/' + year + '/' + p.id + '.jpg'}
in={p.showDesc} width={100}
timeout={1000} height={100}
classNames='fadeTransition' loading="lazy"
> alt={p.name}
{p.showDesc ? ( />
<div> <div className={styles.performerTextContainer}>
{p.paragraphs.map((parag, index) => ( <div
<p key={index}>{parag.toString()}</p> className={styles.performerTitle}
))} onClick={() => togglePerformerDesc(year, p.id)}
>
<h2>{p.name}</h2>
<button className={shared.openingChevron}>
{p.showDesc ? (
<BiChevronDown size='3rem' />
) : (
<BiChevronLeft size='3rem' />
)}
</button>
</div>
<CSSTransition
in={p.showDesc}
timeout={1000}
classNames='fadeTransition'
>
{p.showDesc ? (
<div>
{p.paragraphs.map((parag, index) => (
<p key={index}>{parag.toString()}</p>
))}
</div>
) : (
<span></span>
)}
</CSSTransition>
<hr />
</div> </div>
) : ( </div>
<span></span> ))}
)}
</CSSTransition>
<hr />
</div> </div>
</div> </CSSTransition>
))} </div>
</React.Fragment> </React.Fragment>
))} ))}
</section> </section>

View File

@@ -7,11 +7,40 @@
margin-bottom: 1em; margin-bottom: 1em;
} }
.yearTitle {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
width: 100%;
margin-bottom: 1em;
h2 {
flex: 1;
min-width: 0;
}
h2:hover {
color: rgb(117, 117, 117);
transition: color 0.3s;
}
}
.yearPerformers {
width: 100%;
overflow: hidden;
}
.yearPerformersContent {
width: 100%;
}
.performerContainer { .performerContainer {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
align-items: flex-start; align-items: flex-start;
width: 90%; width: 100%;
box-sizing: border-box;
p { p {
padding-left: 1rem; padding-left: 1rem;
@@ -22,14 +51,14 @@
width: 100%; width: 100%;
margin-top: 2rem; margin-top: 2rem;
margin-bottom: 2rem; margin-bottom: 2rem;
width: 100%;
} }
} }
.performerTextContainer { .performerTextContainer {
width: 80%; flex: 1;
margin-left: 1rem; margin-left: 1rem;
margin-top: 1rem; margin-top: 1rem;
min-width: 0;
} }
.performerTitle { .performerTitle {
@@ -41,7 +70,8 @@
h2 { h2 {
margin-left: 1rem; margin-left: 1rem;
width: 100%; flex: 1;
min-width: 0;
} }
h2:hover { h2:hover {

View File

@@ -15,3 +15,36 @@
opacity: 0; opacity: 0;
transition: opacity 1000ms; transition: opacity 1000ms;
} }
// Height transition for Archive page
.heightTransition-enter {
max-height: 0;
overflow: hidden;
}
.heightTransition-enter-active {
max-height: 10000px;
overflow: hidden;
transition: max-height 300ms ease-out;
}
.heightTransition-enter-done {
max-height: 10000px;
overflow: hidden;
}
.heightTransition-exit {
max-height: 10000px;
overflow: hidden;
}
.heightTransition-exit-active {
max-height: 0;
overflow: hidden;
transition: max-height 300ms ease-out;
}
.heightTransition-exit-done {
max-height: 0;
overflow: hidden;
}