Skip to content

Commit

Permalink
🎨 add category
Browse files Browse the repository at this point in the history
  • Loading branch information
0xfynnix committed May 10, 2024
1 parent e0bfee1 commit 3c72f55
Show file tree
Hide file tree
Showing 4 changed files with 2,016 additions and 1,931 deletions.
15 changes: 7 additions & 8 deletions packages/nextjs/components/ImgShow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@ import Link from "next/link";
import { FaHeart, FaRegHeart } from "react-icons/fa";

// Update the component to accept props
export function ImgShow({ images }) {
export const ImgShow: React.FC<{ images: { link: string; image: string; category: string }[] }> = ({ images }) => {
return (
<>
<main className="grid grid-cols-3 gap-2 p-4 md:gap-4 lg:grid-cols-4 xl:grid-cols-5">
{images.map((img, index) => (
<ImageShowItem key={index} img={img} />
<ImageShowItem key={index} image={img} />
))}
</main>
</>
);
}
};

const ImageShowItem = ({ img }) => {
const ImageShowItem: React.FC<{ image: { link: string; image: string; category: string } }> = ({ image }) => {
const [isLiked, setIsLiked] = useState(false);
const toggleLike = () => setIsLiked(!isLiked);
return (
<div className="relative group overflow-hidden rounded-md">
<div className="w-full h-[calc(100%-2rem)]">
<Link
className="absolute top w-full h-[calc(100%-2rem)] inset-0 z-10"
href={img.link}
href={image.link}
target="_blank" // Opens the link in a new tab
rel="noopener noreferrer" // Security measure for opening links in a new tab
>
Expand All @@ -33,15 +33,14 @@ const ImageShowItem = ({ img }) => {
alt={`Image`}
className="aspect-square object-cover w-full h-full"
height={400}
src={img.image}
src={image.image}
width={400}
/>
</div>

<div className="px-2 h-8 w-full bg-sky-500 flex justify-between items-center">
<div className="space-x-2">
<div className="badge badge-outline">collection #1</div>
<div className="badge badge-outline">collection #2</div>
<div className="badge badge-outline">{image.category}</div>
</div>
<button onClick={toggleLike}>{isLiked ? <FaRegHeart /> : <FaHeart />}</button>
</div>
Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"react-hot-toast": "^2.4.0",
"react-icons": "^5.2.1",
"react-markdown": "^9.0.0",
"swr": "^2.2.5",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
"use-debounce": "^8.0.4",
Expand Down
80 changes: 71 additions & 9 deletions packages/nextjs/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,99 @@ import { useEffect, useState } from "react";
import { NextPage } from "next";
import { ImgShow } from "~~/components/ImgShow";

const fetcher = (...args) => fetch(...args).then(res => res.json());
const ETHSpace: NextPage = () => {
// State to store the array of images
const [pageIndex, setPageIndex] = useState(1);
const [category, setCategory] = useState("All");
const [categories, setCategories] = useState([]);
const [images, setImages] = useState([]);
const [loading, setLoading] = useState(false);

// Fetch images from your backend
const fetchImages = async () => {
const fetchImages = async (page: number) => {
setLoading(true);
try {
const response = await fetch("https://bodhi-data.deno.dev/imgs", {
const categories = await fetch("https://bodhi-data.deno.dev/constant?key=bodhi_img_categories", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const data = await response.json();
const categoriesData = await categories.json();
console.log(categoriesData);
const reg = /\\/g;

const replaceAfter = categoriesData.value.replace(reg, "");
const categoriesString = replaceAfter.substring(2, replaceAfter.length - 2);
const categoriesArray = categoriesString.split('","');
setCategories(categoriesArray);
const cursorResponse = await fetch("https://bodhi-data.deno.dev/imgs_latest_id", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const lastedIdData = await cursorResponse.json();
const cursor = lastedIdData.latestId - (page - 1) * 10;
const categoryParams = category === "All" ? "" : `&category=${category}`;
const response = await fetch(`https://bodhi-data.deno.dev/imgs?cursor=${cursor}&limit=10${categoryParams}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const data = await response.json();
// Assuming the data format matches what the ImgShow component expects
const formattedImages = data.images.map(img => ({
const formattedImages = data.images.map((img: { link: any; id_on_chain: string }) => ({
image: img.link,
link: "https://bodhi.wtf/" + img.id_on_chain
link: "https://bodhi.wtf/" + img.id_on_chain,
category: categoriesArray[0] || "nsfw",
}));
setImages(formattedImages);
} catch (error) {
console.error("Failed to fetch images:", error);
}
setLoading(false);
};

useEffect(() => {
fetchImages();
}, []);
fetchImages(pageIndex);
}, [pageIndex, category]);

return <ImgShow images={images} />;
return (
<>
<div className="flex items-center h-[5rem] px-[2rem] justify-end">
<select
value={category}
onChange={e => setCategory(e.target.value)}
className="select text-center select-primary w-[12rem] h-[2rem]"
>
<option disabled selected>
Select Category
</option>
<option>All</option>
{categories.map((category: string, index: number) => {
return <option key={index}>{category}</option>;
})}
</select>
</div>
{loading ? (
<div className="flex justify-center items-center">
Loading<span className="loading loading-dots loading-xs"></span>
</div>
) : null}
<ImgShow images={images} />
<div className="join flex justify-center items-center">
<button onClick={() => setPageIndex(pageIndex - 1)} className="join-item btn">
«
</button>
<button className="join-item btn">Page {pageIndex}</button>
<button onClick={() => setPageIndex(pageIndex + 1)} className="join-item btn">
»
</button>
</div>
</>
);
};

export default ETHSpace;
Loading

0 comments on commit 3c72f55

Please sign in to comment.