283 lines
8.1 KiB
TypeScript
Raw Normal View History

2025-04-13 22:38:33 +01:00
"use client";
import { Dispatch, SetStateAction, useCallback, useState } from 'react';
2025-04-28 19:03:29 +01:00
import Artifact from '@appTypes/Artifact';
import { Currency } from '@appTypes/StoreModel';
import Sidebar from '@components/Sidebar';
import { useStoreState } from '@hooks/store';
2025-04-13 22:38:33 +01:00
// Artifacts Data
2025-04-28 19:03:29 +01:00
const artifacts: Artifact[] = [
{
id: 1,
name: "Golden Scarab",
description: "An ancient Egyptian artifact symbolizing rebirth.",
location: "Cairo, Egypt",
image: "/images/artifact1.jpg",
price: 150,
},
{
id: 2,
name: "Aztec Sunstone",
description: "A replica of the Aztec calendar (inscriptions intact).",
location: "Peru",
image: "/images/artifact2.jpg",
price: 200,
},
{
id: 3,
name: "Medieval Chalice",
description: "Used by royalty in medieval ceremonies.",
location: "Cambridge, England",
image: "/images/artifact3.jpg",
price: 120,
},
{
id: 4,
name: "Roman Coin",
description: "An authentic Roman coin from the 2nd century CE.",
location: "Rome, Italy",
image: "/images/artifact4.jpg",
price: 80,
},
{
id: 5,
name: "Samurai Mask",
description: "Replica of Japanese Samurai battle masks.",
location: "Tokyo, Japan",
image: "/images/artifact5.jpg",
price: 300,
},
{
id: 6,
name: "Ancient Greek Vase",
description: "Depicts Greek mythology, found in the Acropolis.",
location: "Athens, Greece",
image: "/images/artifact6.jpg",
price: 250,
},
{
id: 7,
name: "Incan Pendant",
description: "Represents the Sun God Inti.",
location: "India",
image: "/images/artifact7.jpg",
price: 175,
},
{
id: 8,
name: "Persian Carpet Fragment",
description: "Ancient Persian artistry.",
location: "Petra, Jordan",
image: "/images/artifact8.jpg",
price: 400,
},
{
id: 9,
name: "Stone Buddha",
description: "Authentic stone Buddha carving.",
location: "India",
image: "/images/artifact9.jpg",
price: 220,
},
{
id: 10,
name: "Victorian Brooch",
description: "A beautiful Victorian-era brooch with a ruby centre.",
location: "Oxford, England",
image: "/images/artifact10.jpg",
price: 150,
},
{
id: 11,
name: "Ancient Scroll",
description: "A mysterious scroll from ancient times.",
location: "Madrid, Spain",
image: "/images/artifact11.jpg",
price: 500,
},
{
id: 12,
name: "Ming Dynasty Porcelain",
description: "Porcelain from China's Ming Dynasty.",
location: "Beijing, China",
image: "/images/artifact12.jpg",
price: 300,
},
{
id: 13,
name: "African Tribal Mask",
description: "A unique tribal mask from Africa.",
location: "Nigeria",
image: "/images/artifact13.jpg",
price: 250,
},
{
id: 14,
name: "Crystal Skull",
description: "A mystical pre-Columbian artifact.",
location: "Colombia",
image: "/images/artifact14.jpg",
price: 1000,
},
{
id: 15,
name: "Medieval Armor Fragment",
description: "A fragment of medieval armor.",
location: "Normandy, France",
image: "/images/artifact15.jpg",
price: 400,
},
2025-04-13 22:38:33 +01:00
];
2025-04-14 13:50:13 +01:00
// Modal Component
2025-04-13 22:38:33 +01:00
// Shop Component
2025-03-17 13:21:02 +00:00
export default function Shop() {
2025-04-28 19:03:29 +01:00
const [currentPage, setCurrentPage] = useState(1);
const [selectedArtifact, setSelectedArtifact] = useState<Artifact | null>(null); // Track selected artifact for modal
const artifactsPerPage = 9; // Number of artifacts per page
const indexOfLastArtifact = currentPage * artifactsPerPage;
const indexOfFirstArtifact = indexOfLastArtifact - artifactsPerPage;
const currentArtifacts = artifacts.slice(indexOfFirstArtifact, indexOfLastArtifact);
const selectedCurrency = useStoreState((state) => state.currency.selectedCurrency);
const conversionRates = useStoreState((state) => state.currency.conversionRates);
const currencyTickers = useStoreState((state) => state.currency.tickers);
const convertPrice = useCallback((price: number, currency: Currency) => (price * conversionRates[currency]).toFixed(2), []);
2025-04-13 22:38:33 +01:00
2025-04-28 19:03:29 +01:00
const handleNextPage = () => {
if (indexOfLastArtifact < artifacts.length) {
setCurrentPage((prev) => prev + 1);
}
};
2025-04-13 22:38:33 +01:00
2025-04-28 19:03:29 +01:00
const handlePreviousPage = () => {
if (currentPage > 1) {
setCurrentPage((prev) => prev - 1);
}
};
2025-04-14 13:50:13 +01:00
2025-04-28 19:03:29 +01:00
function Modal({ artifact }: { artifact: Artifact }) {
if (!artifact) return null;
2025-04-14 13:50:13 +01:00
2025-04-28 19:03:29 +01:00
const handleOverlayClick = (e: { target: any; currentTarget: any }) => {
if (e.target === e.currentTarget) {
setSelectedArtifact(null);
}
};
2025-04-13 22:38:33 +01:00
2025-04-28 19:03:29 +01:00
return (
<div
className="fixed inset-0 bg-neutral-900 bg-opacity-50 flex justify-center items-center z-50"
onClick={handleOverlayClick}
>
<div className="bg-white rounded-md shadow-lg max-w-lg w-full p-6">
<h3 className="text-xl font-bold mb-4">{artifact.name}</h3>
<img src={artifact.image} alt={artifact.name} className="w-full h-64 object-cover rounded-md mb-4" />
<p className="text-neutral-600 mb-2">{artifact.description}</p>
<p className="text-neutral-500 font-bold mb-4">Location: {artifact.location}</p>
<p className="text-red-600 font-bold">Price: ${artifact.price}</p>
<div className="flex justify-end gap-4 mt-6">
<button
onClick={() => alert("Reserved Successfully!")}
className="px-4 py-2 bg-yellow-500 text-white rounded-md hover:bg-yellow-400"
>
Reserve
</button>
<button
onClick={() => alert("Purchased Successfully!")}
className="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-500"
>
Buy
</button>
<button
onClick={() => setSelectedArtifact(null)}
className="px-4 py-2 bg-neutral-300 rounded-md hover:bg-neutral-400"
>
Close
</button>
</div>
</div>
</div>
);
}
2025-04-14 13:50:13 +01:00
2025-04-28 19:03:29 +01:00
// ArtifactCard Component
function ArtifactCard({ artifact }: { artifact: Artifact }) {
return (
<div
className="flex flex-col bg-white shadow-md rounded-md overflow-hidden cursor-pointer hover:scale-105 transition-transform"
onClick={() => setSelectedArtifact(artifact)} // Opens modal
>
<img src={artifact.image} alt={artifact.name} className="w-full h-56 object-cover" />
<div className="p-4">
<h3 className="text-lg font-bold">{artifact.name}</h3>
<p className="text-neutral-700 mb-2">{artifact.description}</p>
<p className="text-neutral-500 mb-2">{artifact.location}</p>
<p className="text-blue-600 font-bold text-md mt-4">
{currencyTickers[selectedCurrency]}
{convertPrice(artifact.price, selectedCurrency)}
</p>
</div>
</div>
);
}
2025-04-13 22:38:33 +01:00
2025-04-28 19:03:29 +01:00
return (
<div className="flex flex-col min-h-screen bg-neutral-100">
{/* Main Content */}
<div className="flex flex-1 overflow-y-auto mr-[19rem]">
{/* Artifact Grid */}
<div className="flex-grow grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 p-6">
{currentArtifacts.map((artifact) => (
<ArtifactCard key={artifact.id} artifact={artifact} />
))}
</div>
</div>
{/* Sidebar */}
<div className="bg-white shadow-lg h-screen fixed right-0 overflow-y-auto">
<Sidebar
logTitle="Artifact Collection"
logSubtitle="Record new artifacts - name, description, image, location and price"
recentsTitle="Recent Updates"
events={
[
/* example events if needed */
]
}
selectedEventId=""
setSelectedEventId={() => {}}
hoveredEventId=""
setHoveredEventId={() => {}}
button1Name="Add New Artifact"
button2Name="Search Artifacts"
/>
</div>
2025-04-13 22:38:33 +01:00
2025-04-28 19:03:29 +01:00
{/* Pagination Footer */}
<footer className="bg-white border-t border-neutral-300 py-2 text-center flex justify-center items-center mr-[19rem]">
2025-04-28 19:03:29 +01:00
<button
onClick={handlePreviousPage}
disabled={currentPage === 1}
className={`mx-2 px-4 py-1 bg-blue-700 text-white rounded-md font-bold shadow-md ${
currentPage === 1 ? "opacity-50 cursor-not-allowed" : "hover:bg-blue-600"
}`}
>
&larr; Previous
</button>
<button
onClick={handleNextPage}
disabled={indexOfLastArtifact >= artifacts.length}
className={`mx-2 px-4 py-1 bg-blue-500 text-white rounded-md font-bold shadow-md ${
indexOfLastArtifact >= artifacts.length ? "opacity-50 cursor-not-allowed" : "hover:bg-blue-600"
}`}
>
Next &rarr;
</button>
</footer>
{/* Modal */}
{selectedArtifact && <Modal artifact={selectedArtifact} />}
</div>
);
2025-04-14 13:50:13 +01:00
}