Skip to content

Commit

Permalink
Add metadata for SEO and open graph integration
Browse files Browse the repository at this point in the history
  • Loading branch information
saisab29 committed Dec 9, 2024
1 parent d6600b9 commit e13e9df
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 70 deletions.
13 changes: 11 additions & 2 deletions __tests__/Card.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/* eslint-disable jsx-a11y/alt-text */
/* eslint-disable @next/next/no-img-element */
/* eslint-disable @typescript-eslint/no-explicit-any */
import "@testing-library/jest-dom";
import { render, screen, fireEvent } from "@testing-library/react";
import { Card } from "@/app/Component/Card";
Expand Down Expand Up @@ -49,7 +52,10 @@ describe("Card Component", () => {
);
const mainImage = screen.getByAltText("Test Project thumbnail");
expect(mainImage).toHaveAttribute("src");
expect(mainImage.getAttribute("src")).toContain("/path/to/image.jpg");
expect(mainImage).toHaveAttribute(
"src",
expect.stringContaining("/path/to/image.jpg")
);
});

test("renders sub-image correctly", () => {
Expand All @@ -66,7 +72,10 @@ describe("Card Component", () => {

const subImage = screen.getByAltText("Test Project logo");
expect(subImage).toHaveAttribute("src");
expect(subImage.getAttribute("src")).toContain("/path/to/logo.jpg");
expect(subImage).toHaveAttribute(
"src",
expect.stringContaining("/path/to/logo.jpg")
);
});

test("navigates to correct link", () => {
Expand Down
Binary file added public/images/cardanoapi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 92 additions & 0 deletions src/app/Component/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
"use client";
import { useState } from "react";
import { Card } from "./Card";

interface Project {
id: string;
projectName: string;
url: string;
imageUrl: string;
subImageUrl: string;
description: string;
}

interface PaginationProps {
data: Project[];
cardsPerPage: number;
totalPages: number;
}

export default function Pagination({
data,
cardsPerPage,
totalPages,
}: PaginationProps) {
const [currentPage, setCurrentPage] = useState<number>(1);

// Calculate the index range for the cards to display on the current page
const indexOfLastCard = currentPage * cardsPerPage;
const indexOfFirstCard = indexOfLastCard - cardsPerPage;
const currentCards = data.slice(indexOfFirstCard, indexOfLastCard);

// Handle page change
const handlePageChange = (pageNumber: number): void => {
setCurrentPage(pageNumber);
};

return (
<>
<div className="flex-grow flex flex-wrap justify-around sm:justify-center sm:gap-x-20">
{currentCards.map((project) => (
<Card
key={project.id}
id={project.id}
projectName={project.projectName}
url={project.url}
imageUrl={project.imageUrl}
subImageUrl={project.subImageUrl}
description={project.description}
/>
))}
</div>

{/* Pagination Controls */}
<div className="bottom-0 left-0 right-0 py-4 flex justify-center">
<button
onClick={() => handlePageChange(currentPage - 1)}
disabled={currentPage === 1}
className={`px-4 py-2 mx-2 border rounded-full bg-[#D9D9D9] ${
currentPage === 1 ? "text-[#6D7D8B]" : ""
} `}
>
Previous
</button>

{/* Page Numbers */}
{[...Array(totalPages)].map((_, index) => (
<button
key={index}
onClick={() => handlePageChange(index + 1)}
className={`px-4 py-2 mx-2 border rounded-full ${
currentPage === index + 1
? "bg-black text-white"
: "bg-[#D9D9D9] text-black"
}`}
>
{index + 1}
</button>
))}

<button
onClick={() => handlePageChange(currentPage + 1)}
disabled={currentPage === totalPages}
className={`px-4 py-2 mx-2 border rounded-full bg-[#D9D9D9] ${
currentPage === totalPages ? "text-[#6D7D88]" : ""
}`}
>
Next
</button>
</div>
</>
);
}
78 changes: 78 additions & 0 deletions src/app/api/og/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* eslint-disable jsx-a11y/alt-text */

/* eslint-enable jsx-a11y/alt-text */
import Image from "next/image";
import { ImageResponse } from "next/og";

export const runtime = "edge";

export async function GET(request: Request) {
const { searchParams } = new URL(request.url);

const hasTitle = searchParams.has("title");
const title = hasTitle ? searchParams.get("title") : "Cardano API";

// Fetch the Roboto font
const fontData = await fetch(
"https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Me5Q.ttf"
).then((res) => res.arrayBuffer());

// Fetch the image and convert to base64
const imageBuffer = await fetch(
new URL("../../../../public/images/cardanoapi.png", import.meta.url)
).then((res) => res.arrayBuffer());

const imageBase64 = `data:image/png;base64,${Buffer.from(
imageBuffer
).toString("base64")}`;

return new ImageResponse(
(
<div
style={{
display: "flex",
width: "100%",
height: "100%",
alignItems: "center",
justifyContent: "center",
fontFamily: "'Arial', sans-serif",
backgroundColor: "#bcd7e5",
}}
>
<Image
src={imageBase64}
alt="Cardano API"
style={{
width: "200px",
height: "200px",
marginTop: "20px",
borderRadius: "50%",
}}
></Image>
<div tw="flex flex-col px-4">
<h1 style={{ fontSize: "48px", fontWeight: "bold", margin: "0" }}>
{title}
</h1>

<p
style={{ fontSize: "24px", fontWeight: "bold", marginTop: "20px" }}
>
Explore a list of Cardano API Projects
</p>
</div>
</div>
),
{
width: 800,
height: 600, // Adjust size as needed
fonts: [
{
name: "Roboto",
data: fontData,
style: "normal",
weight: 400,
},
],
}
);
}
94 changes: 26 additions & 68 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,78 +1,36 @@
"use client";
import { useState } from "react";
import { Card } from "./Component/Card";
import { Metadata } from "next";
import data from "../data.json";
import Pagination from "./Component/Pagination"; // New client component

export const metadata: Metadata = {
title: "Cardano API",
description: "A list of Cardano Api projects",
openGraph: {
title: "Cardano Api",
description: "A list of Cardano Api Projects",
images: [
{
url: "http://localhost:3000/api/og",
width: 1200,
height: 630,
alt: "Cardano Api",
},
],
siteName: "https://cardanoapi.io",
},
};

export default function Home() {
const cardsPerPage = 8;
const [currentPage, setCurrentPage] = useState<number>(1);

// Calculate the index range for the cards to display on the current page
const indexOfLastCard = currentPage * cardsPerPage;
const indexOfFirstCard = indexOfLastCard - cardsPerPage;
const currentCards = data.slice(indexOfFirstCard, indexOfLastCard);

// Calculate the total number of pages
const totalPages = Math.ceil(data.length / cardsPerPage);

// Handle page change
const handlePageChange = (pageNumber: number): void => {
setCurrentPage(pageNumber);
};

return (
<div className="sm:px-44 py-4 sm:py-8 flex flex-col min-h-screen">
<div className="flex-grow flex flex-wrap justify-around sm:justify-center sm:gap-x-20">
{currentCards.map((project) => (
<Card
key={project.id}
id={project.id}
projectName={project.projectName}
url={project.url}
imageUrl={project.imageUrl}
subImageUrl={project.subImageUrl}
description={project.description}
/>
))}
</div>

{/* Pagination Controls */}
<div className=" bottom-0 left-0 right-0 py-4 flex justify-center">
<button
onClick={() => handlePageChange(currentPage - 1)}
disabled={currentPage === 1}
className={`px-4 py-2 mx-2 border rounded-full bg-[#D9D9D9] ${
currentPage === 1 ? "text-[#6D7D8B]" : ""
} `}
>
Previous
</button>

{/*Page Numbers*/}
{[...Array(totalPages)].map((_, index) => (
<button
key={index}
onClick={() => handlePageChange(index + 1)}
className={`px-4 py-2 mx-2 border rounded-full ${
currentPage === index + 1
? "bg-black text-white"
: "bg-[#D9D9D9] text-black"
}`}
>
{index + 1}
</button>
))}

<button
onClick={() => handlePageChange(currentPage + 1)}
disabled={currentPage === totalPages}
className={`px-4 py-2 mx-2 border rounded-full bg-[#D9D9D9] ${
currentPage === totalPages ? "text-[#6D7D88]" : ""
}`}
>
Next
</button>
</div>
<div className="sm:px-44 py-4 sm:py-8 flex flex-col min-h-screen">
<Pagination
data={data}
cardsPerPage={cardsPerPage}
totalPages={totalPages}
/>
</div>
);
}

0 comments on commit e13e9df

Please sign in to comment.