Improved Archive page
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user