-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add metadata for SEO and open graph integration
- Loading branch information
Showing
5 changed files
with
207 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}, | ||
], | ||
} | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
} |