Skip to content

Commit

Permalink
fix: performance issue on archive page
Browse files Browse the repository at this point in the history
  • Loading branch information
7sferry committed Jan 4, 2025
1 parent cbf19fc commit 5b52577
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 113 deletions.
123 changes: 123 additions & 0 deletions src/components/ArchiveContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/************************
* Made by [MR Ferry™] *
* on Januari 2025 *
************************/

import { ArchiveContainerProps, ArchiveNode, DateArchive } from "../types/DataTypes.ts";
import { MdArchive } from "react-icons/md";
import { Link } from "gatsby";
import React, { useState } from "react";
import { getMonthYearDate } from "../utils/DateUtils.tsx";

const ArchiveContainer = ({ posts }: ArchiveContainerProps) => {
const lastDate = getMonthYearDate(posts[0].publishDate);
const [activeMonth, setActiveMonth] = useState<string[]>([lastDate]);
const [activeYear, setActiveYear] = useState<string[]>([lastDate.split("-")[0]]);

const toggleActiveYear = (year: string) => {
let newActiveYear = [...activeYear];
let newActiveMonth = [...activeMonth];

if (newActiveYear.includes(year)) {
newActiveYear = newActiveYear.filter((o) => o !== year);
newActiveMonth = newActiveMonth.filter((o) => {
const yearMonth = o.split("-");
return yearMonth[0] !== year;
});
} else {
newActiveYear.push(year);
}

setActiveMonth(newActiveMonth);
setActiveYear(newActiveYear);
};

const toggleActiveMonth = (yearMonth: string) => {
let newActiveMonth = [...activeMonth];

if (newActiveMonth.includes(yearMonth)) {
newActiveMonth = newActiveMonth.filter((o) => o !== yearMonth);
} else {
newActiveMonth.push(yearMonth);
}

setActiveMonth(newActiveMonth);
};

let postByMonth = new Map<string, ArchiveNode[]>();
if (posts) {
posts.forEach((o) => {
const monthYearDate = getMonthYearDate(o.publishDate);
let post = postByMonth.get(monthYearDate);
if (post) {
post.push(o);
} else {
post = [o];
}
postByMonth.set(monthYearDate, post);
});
}

let postByYear = new Map<string, DateArchive[]>();
postByMonth.forEach((v, k) => {
const yearMonth = k.split("-");
let year = yearMonth[0];
let post = postByYear.get(year);
const object = { date: k, archiveNodes: v };
if (post) {
post.push(object);
} else {
post = [object];
}
postByYear.set(year, post);
});

return (
<ul className="archive-container parent-archive-container">
{Array.from(postByYear.entries()).map((post, i) => {
const year = post[0];
let dateArchives = post[1];
return (
<li key={i} className={"item"}>
<button className={`archive-link`} onClick={() => toggleActiveYear(year)}>
<i className="archive-icon">
<MdArchive />
</i>
<span>{year}</span>
</button>

<ul className={`archive-container ${activeYear.includes(year) ? "visible" : "not-visible"}`}>
{dateArchives.map((dateArchive) => {
const month = dateArchive.date.split("-")[1];
return (
<li key={month} className={"item"}>
<button className="archive-link" onClick={() => toggleActiveMonth(dateArchive.date)}>
<span>{month}</span>
</button>
<ul
className={`archive-container ${
activeMonth.includes(dateArchive.date) ? "visible" : "not-visible"
}`}
>
{dateArchive.archiveNodes.map((content) => {
return (
<li className={"item"} key={content.slug}>
<Link className={"archive-link"} to={`/blog/${content.slug}`}>
<small>{content.title}</small>
</Link>
</li>
);
})}
</ul>
</li>
);
})}
</ul>
</li>
);
})}
</ul>
);
};

export default ArchiveContainer;
115 changes: 4 additions & 111 deletions src/templates/archive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
* on May 2020 *
************************/

import React, { useState } from "react";
import { HeadProps, Link, Slice } from "gatsby";
import { MdArchive } from "react-icons/md";
import React from "react";
import { HeadProps, Slice } from "gatsby";
import "./archive.css";
import Layout from "../components/Layout";
import Seo from "../components/Seo";
import { ArchiveNode, DateArchive } from "../types/DataTypes";
import { getArchiveQuery } from "../utils/GetArchiveQuery";
import { getMonthYearDate } from "../utils/DateUtils";
import ArchiveContainer from "../components/ArchiveContainer.tsx";

const ArchivePage = () => {
let archiveQuery = getArchiveQuery();
Expand All @@ -25,117 +23,12 @@ const ArchivePage = () => {
);
}

const lastDate = getMonthYearDate(posts[0].publishDate);
const [activeMonth, setActiveMonth] = useState<string[]>([lastDate]);
const [activeYear, setActiveYear] = useState<string[]>([lastDate.split("-")[0]]);

const toggleActiveYear = (year: string) => {
let newActiveYear = [...activeYear];
let newActiveMonth = [...activeMonth];

if (newActiveYear.includes(year)) {
newActiveYear = newActiveYear.filter((o) => o !== year);
newActiveMonth = newActiveMonth.filter((o) => {
const yearMonth = o.split("-");
return yearMonth[0] !== year;
});
} else {
newActiveYear.push(year);
}

setActiveMonth(newActiveMonth);
setActiveYear(newActiveYear);
};

const toggleActiveMonth = (yearMonth: string) => {
let newActiveMonth = [...activeMonth];

if (newActiveMonth.includes(yearMonth)) {
newActiveMonth = newActiveMonth.filter((o) => o !== yearMonth);
} else {
newActiveMonth.push(yearMonth);
}

setActiveMonth(newActiveMonth);
};

let postByMonth = new Map<string, ArchiveNode[]>();
if (posts) {
posts.forEach((o) => {
const monthYearDate = getMonthYearDate(o.publishDate);
let post = postByMonth.get(monthYearDate);
if (post) {
post.push(o);
} else {
post = [o];
}
postByMonth.set(monthYearDate, post);
});
}

let postByYear = new Map<string, DateArchive[]>();
postByMonth.forEach((v, k) => {
const yearMonth = k.split("-");
let year = yearMonth[0];
let post = postByYear.get(year);
const object = { date: k, archiveNodes: v };
if (post) {
post.push(object);
} else {
post = [object];
}
postByYear.set(year, post);
});

return (
<Layout>
<div className="tech-tags mb-2 mobile-only text-center">
<Slice alias={"Tags"} />
</div>
<ul className="archive-container parent-archive-container">
{Array.from(postByYear.entries()).map((post, i) => {
const year = post[0];
let dateArchives = post[1];
return (
<li key={i} className={"item"}>
<button className={`archive-link`} onClick={() => toggleActiveYear(year)}>
<i className="archive-icon">
<MdArchive />
</i>
<span>{year}</span>
</button>

<ul className={`archive-container ${activeYear.includes(year) ? "visible" : "not-visible"}`}>
{dateArchives.map((dateArchive) => {
const month = dateArchive.date.split("-")[1];
return (
<li key={month} className={"item"}>
<button className="archive-link" onClick={() => toggleActiveMonth(dateArchive.date)}>
<span>{month}</span>
</button>
<ul
className={`archive-container ${
activeMonth.includes(dateArchive.date) ? "visible" : "not-visible"
}`}
>
{dateArchive.archiveNodes.map((content) => {
return (
<li className={"item"} key={content.slug}>
<Link className={"archive-link"} to={`/blog/${content.slug}`}>
<small>{content.title}</small>
</Link>
</li>
);
})}
</ul>
</li>
);
})}
</ul>
</li>
);
})}
</ul>
<ArchiveContainer posts={posts} />
</Layout>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/types/DataTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,8 @@ export interface IndexProp {
readonly pageContext: IndexContextProp;
}

export interface ArchiveProp {
readonly data: ArchiveAttr;
export interface ArchiveContainerProps {
readonly posts: ArchiveNode[];
}

export interface ArchiveAttr {
Expand Down

0 comments on commit 5b52577

Please sign in to comment.