Skip to content

Commit d8c2afb

Browse files
authored
refactor(home): restructure home page and optimize image loading (#403)
Signed-off-by: vedantlavale <vedantlavale@gmail.com> Signed-off-by: Vedant <145031740+vedantlavale@users.noreply.github.com>
1 parent 41632e0 commit d8c2afb

9 files changed

Lines changed: 469 additions & 434 deletions

File tree

src/app/blog/[slug]/page.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Metadata } from "next";
2+
import Image from "next/image";
23
import {
34
getAllPosts,
45
getPostBySlug,
@@ -92,12 +93,14 @@ export default async function BlogPostPage({
9293
<Link
9394
href={`/blog/${rp.slug}`}
9495
className="no-underline grid grid-cols-1 sm:grid-cols-2 sm:gap-9 xl:gap-0 xl:grid-cols-1">
95-
{/* eslint-disable-next-line @next/next/no-img-element */}
96-
<img
96+
<Image
9797
src={rp.featuredImage}
9898
alt={rp.title}
99+
width={560}
100+
height={280}
101+
sizes="(min-width: 1280px) 25vw, (min-width: 640px) 50vw, 100vw"
99102
className="w-full md:h-[140px] object-cover"
100-
loading="lazy"
103+
unoptimized
101104
/>
102105
<div>
103106
<h3 className="mt-3 sm:mt-0 xl:mt-3 text-[20px] font-medium text-black line-clamp-1">
@@ -142,12 +145,13 @@ function AuthorBlock({
142145
const inner = (
143146
<>
144147
{author.image && (
145-
// eslint-disable-next-line @next/next/no-img-element
146-
<img
148+
<Image
147149
src={author.image}
148150
alt={author.name ?? ""}
151+
width={72}
152+
height={72}
149153
className="inline-block h-[72px] w-[72px] rounded-full bg-white"
150-
loading="lazy"
154+
unoptimized
151155
/>
152156
)}
153157
<div className="font-normal">

src/app/page.tsx

Lines changed: 12 additions & 364 deletions
Large diffs are not rendered by default.

src/components/BlogPostList/index.tsx

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { useState } from "react";
44
import Link from "next/link";
5+
import Image from "next/image";
56
import { format } from "date-fns";
67
import type { PostMeta } from "@/lib/posts";
78

@@ -51,12 +52,13 @@ export default function BlogPostList({ posts, listTitle }: BlogPostListProps) {
5152
key={post.slug}
5253
href={`/blog/${post.slug}`}
5354
className="grid grid-cols-[1fr] gap-0 sm:grid-cols-[280px_1fr] sm:gap-x-8 no-underline">
54-
{/* eslint-disable-next-line @next/next/no-img-element */}
55-
<img
55+
<Image
5656
src={post.featuredImage}
5757
alt={post.title}
58+
width={560}
59+
height={280}
60+
sizes="(min-width: 640px) 280px, 100vw"
5861
className="w-full md:h-[140px] object-cover"
59-
loading="lazy"
6062
/>
6163
<div>
6264
<h3 className="mt-3 sm:mt-0 text-[20px] font-medium text-black">
@@ -83,79 +85,71 @@ export default function BlogPostList({ posts, listTitle }: BlogPostListProps) {
8385
{totalPages > 1 && (
8486
<ul className="pagination pagination-default">
8587
<li className={`page-item ${page === 1 ? "disabled" : ""}`}>
86-
<a
87-
aria-disabled={page === 1 ? "true" : undefined}
88+
<button
89+
type="button"
90+
disabled={page === 1}
8891
aria-label="First"
8992
className="page-link"
90-
role="button"
91-
tabIndex={page === 1 ? -1 : 0}
92-
onClick={e => {
93-
e.preventDefault();
93+
onClick={() => {
9494
if (page !== 1) goTo(1);
9595
}}>
9696
<span aria-hidden="true">&laquo;&laquo;</span>
97-
</a>
97+
</button>
9898
</li>
9999
<li className={`page-item ${page === 1 ? "disabled" : ""}`}>
100-
<a
101-
aria-disabled={page === 1 ? "true" : undefined}
100+
<button
101+
type="button"
102+
disabled={page === 1}
102103
aria-label="Previous"
103104
className="page-link"
104-
role="button"
105-
tabIndex={page === 1 ? -1 : 0}
106-
onClick={e => {
107-
e.preventDefault();
105+
onClick={() => {
108106
if (page > 1) goTo(page - 1);
109107
}}>
110108
<span aria-hidden="true">&laquo;</span>
111-
</a>
109+
</button>
112110
</li>
113111
{visiblePages.map(p => (
114112
<li
115113
key={p}
116114
className={`page-item ${p === page ? "active" : ""}`}>
117-
<a
115+
<button
116+
type="button"
117+
disabled={p === page}
118118
aria-current={p === page ? "page" : undefined}
119119
aria-label={`Page ${p}`}
120120
className="page-link"
121-
role="button"
122-
onClick={e => {
123-
e.preventDefault();
121+
onClick={() => {
124122
goTo(p);
125123
}}>
126124
{p}
127-
</a>
125+
</button>
128126
</li>
129127
))}
130128
<li
131129
className={`page-item ${page === totalPages ? "disabled" : ""}`}>
132-
<a
133-
aria-disabled={page === totalPages ? "true" : undefined}
130+
<button
131+
type="button"
132+
disabled={page === totalPages}
134133
aria-label="Next"
135134
className="page-link"
136-
role="button"
137-
tabIndex={page === totalPages ? -1 : 0}
138-
onClick={e => {
139-
e.preventDefault();
135+
onClick={() => {
140136
if (page < totalPages) goTo(page + 1);
141137
}}>
142138
<span aria-hidden="true">&raquo;</span>
143-
</a>
139+
</button>
144140
</li>
145141
<li
146142
className={`page-item ${page === totalPages ? "disabled" : ""}`}>
147-
<a
148-
aria-disabled={page === totalPages ? "true" : undefined}
143+
<button
144+
type="button"
145+
disabled={page === totalPages}
149146
aria-label="Last"
150147
className="page-link"
151-
role="button"
152-
tabIndex={page === totalPages ? -1 : 0}
153-
onClick={e => {
154-
e.preventDefault();
148+
onClick={() => {
155149
if (page < totalPages) goTo(totalPages);
156150
}}>
157151
<span aria-hidden="true">&raquo;&raquo;</span>
158-
</a>
152+
</button>
159153
</li>
160154
</ul>
161155
)}

src/components/ContributorsGrid/index.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client";
22

3+
import Image from "next/image";
34
import { useState, useEffect } from "react";
45

56
interface Contributor {
@@ -46,12 +47,13 @@ export default function ContributorsGrid({ endpoint }: { endpoint: string }) {
4647
href={`https://github.com/${c.userName}`}
4748
className="no-underline">
4849
<div className="flex flex-col justify-center items-center">
49-
{/* eslint-disable-next-line @next/next/no-img-element */}
50-
<img
50+
<Image
5151
className="rounded-full h-32 w-32 bg-slate-600 p-0.5"
5252
src={c.avatarUrl}
5353
alt={`Avatar of ${c.userName}`}
54-
loading="lazy"
54+
width={128}
55+
height={128}
56+
unoptimized
5557
/>
5658
<span className="text-center mt-1">{c.userName}</span>
5759
</div>

src/components/Header/__tests__/__snapshots__/Header.test.tsx.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ exports[`Header > renders the home link and menu 1`] = `
1717
<img
1818
alt="Hiero logo"
1919
class="h-[40px] w-[128px]"
20+
height="40"
2021
src="/images/Hiero-Icon-wLogo.svg"
22+
width="128"
2123
/>
2224
</a>
2325
<div

src/components/Header/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Image from "next/image";
12
import Link from "next/link";
23
import Container from "@/components/Container";
34
import Menu from "@/components/Menu";
@@ -8,10 +9,11 @@ export default function Header() {
89
<Container>
910
<div className="flex flex-row justify-between items-center">
1011
<Link href="/" aria-label="Go to homepage">
11-
{/* eslint-disable-next-line @next/next/no-img-element */}
12-
<img
12+
<Image
1313
src="/images/Hiero-Icon-wLogo.svg"
1414
alt="Hiero logo"
15+
width={128}
16+
height={40}
1517
className="h-[40px] w-[128px]"
1618
/>
1719
</Link>

src/components/Menu/index.tsx

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
"use client";
22

3+
import Image from "next/image";
4+
import Link from "next/link";
35
import { usePathname } from "next/navigation";
46
import { useEffect, useState } from "react";
57

68
interface MenuItem {
79
name: string;
810
href: string;
911
external?: boolean;
12+
newTab?: boolean;
1013
}
1114

1215
const menuItems: MenuItem[] = [
@@ -75,10 +78,11 @@ export default function Menu() {
7578
}}
7679
aria-label="Open menu"
7780
aria-expanded={isOpen}>
78-
{/* eslint-disable-next-line @next/next/no-img-element */}
79-
<img
81+
<Image
8082
src="/images/Hiero-Icon-Nav-Menu.svg"
8183
alt="Open menu"
84+
width={20}
85+
height={20}
8286
className="w-5 h-5"
8387
/>
8488
</button>
@@ -88,10 +92,11 @@ export default function Menu() {
8892
className={`absolute hidden items-center justify-center w-full h-screen bg-black top-0 left-0 text-white sm:relative sm:h-auto sm:top-auto sm:bg-transparent sm:left-auto sm:w-9/12 sm:max-w-xl sm:block ${isOpen ? "active-navigation" : ""}`}
8993
aria-hidden={isDesktop ? false : !isOpen}>
9094
<div className="absolute top-[27px] sm:hidden">
91-
{/* eslint-disable-next-line @next/next/no-img-element */}
92-
<img
95+
<Image
9396
src="/images/Hiero-Icon-wLogo-white-text.svg"
9497
alt="Hiero logo"
98+
width={128}
99+
height={40}
95100
className="h-[40px] w-[128px]"
96101
/>
97102
</div>
@@ -103,29 +108,48 @@ export default function Menu() {
103108
setIsOpen(false);
104109
}}
105110
aria-label="Close menu">
106-
{/* eslint-disable-next-line @next/next/no-img-element */}
107-
<img
111+
<Image
108112
src="/images/Hiero-Icon-ModalClose.svg"
109113
alt="Close menu"
114+
width={20}
115+
height={20}
110116
className="w-5 h-5"
111117
/>
112118
</button>
113119

114120
<ul id="menu" className="flex flex-col sm:flex-row justify-between">
115121
{menuItems.map(item => {
122+
const active = isActive(item.href);
123+
const isExternal = item.external ?? item.href.startsWith("http");
124+
const openInNewTab = item.newTab ?? isExternal;
125+
116126
return (
117127
<li
118128
key={item.name}
119129
className={`text-center sm:text-left ${item.name === "Connect" ? "sm:hidden" : ""}`.trim()}>
120-
<a
121-
href={item.href}
122-
className={isActive(item.href) ? "active" : ""}
123-
aria-current={isActive(item.href) ? "page" : undefined}
124-
onClick={() => {
125-
setIsOpen(false);
126-
}}>
127-
{item.name}
128-
</a>
130+
{isExternal ? (
131+
<a
132+
href={item.href}
133+
target={openInNewTab ? "_blank" : undefined}
134+
rel={openInNewTab ? "noopener noreferrer" : undefined}
135+
className={active ? "active" : ""}
136+
aria-current={active ? "page" : undefined}
137+
onClick={() => {
138+
setIsOpen(false);
139+
}}>
140+
{item.name}
141+
</a>
142+
) : (
143+
<Link
144+
href={item.href}
145+
className={active ? "active" : ""}
146+
aria-current={active ? "page" : undefined}
147+
onClick={() => {
148+
setIsOpen(false);
149+
}}>
150+
{item.name}
151+
</Link>
152+
)}
129153
</li>
130154
);
131155
})}
@@ -134,12 +158,13 @@ export default function Menu() {
134158
<a
135159
href="https://github.com/hiero-ledger/"
136160
target="_blank"
137-
rel="noopener"
161+
rel="noopener noreferrer"
138162
className="flex">
139-
{/* eslint-disable-next-line @next/next/no-img-element */}
140-
<img
163+
<Image
141164
src="/images/Hiero-Icon-Github.svg"
142165
alt="GitHub"
166+
width={35}
167+
height={35}
143168
className="h-[35px] w-[35px] sm:h-[17px] sm:w-[17px]"
144169
/>
145170
</a>

0 commit comments

Comments
 (0)