Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

52 dynamically render pois #64

Merged
merged 2 commits into from
Mar 4, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
226 changes: 54 additions & 172 deletions src/components/poiList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,65 @@ interface POI {
description: string;
audioField: string;
duration: string;
imageUrl: string;
image: string;
isComplete: boolean;
}

interface Audio {
_id: string;
name: string;
url: string;
duration: string;
description: string;
__v: number;
}

export default function POICardList() {
const [cardsDone, setCardsDone] = useState(0);
const [data, setData] = useState<POI[]>(() => {
if (typeof window !== "undefined") {
const storedData = sessionStorage.getItem("poiData");
return storedData ? JSON.parse(storedData) : initialData;
const [data, setData] = useState<POI[]>([]);

useEffect(() => {
async function fetchData() {
try {
//fetch POI data
const poiResponse = await fetch("/api/poi");
const poiData = await poiResponse.json();

//fetch audio data so we also have audio duration info
const audioResponse = await fetch("/api/audiofile");
const audioData = await audioResponse.json();

// Create a lookup map using the name field
const audioMap = Object.fromEntries(audioData.map((audio: Audio) => [audio.name, audio.duration]));

// Merge POIs with corresponding audio durations based on name
const mergedData = poiData.POIs.map((poi: POI) => ({
...poi,
duration: audioMap[poi.name] || "0:00", // fallback of 0:00
}));

// Store in sessionStorage and update state
sessionStorage.setItem("poiData", JSON.stringify(mergedData));
setData(mergedData);
} catch (error) {
console.error("Error fetching data:", error);
}
}
return initialData;
});

//use sessionStorage if possible, otherwise make GET
const storedData = sessionStorage.getItem("poiData");
if (storedData) {
setData(JSON.parse(storedData));
} else {
fetchData();
}
}, []);

useEffect(() => {
sessionStorage.setItem("poiData", JSON.stringify(data));
setCardsDone(data.filter((item) => item.isComplete).length);
if (data.length > 0) {
sessionStorage.setItem("poiData", JSON.stringify(data));
setCardsDone(data.filter((item) => item.isComplete).length);
}
}, [data]);

const toggleComplete = (id: string) => {
Expand All @@ -52,7 +94,7 @@ export default function POICardList() {
<div className="text-black">
Visited Spots: <span className="text-orange-400"> {cardsDone + "/" + data.length}</span>
</div>
<Progress value={(cardsDone / data.length) * 100} colorPalette="orange" />
<Progress value={data.length > 0 ? (cardsDone / data.length) * 100 : 0} colorPalette="orange" />
</div>

<div>
Expand All @@ -64,7 +106,7 @@ export default function POICardList() {
query: {
name: POI.name,
duration: POI.duration,
url: POI.imageUrl,
url: POI.image,
description: POI.description,
progress: cardsDone,
totalCards: data.length,
Expand Down Expand Up @@ -95,7 +137,7 @@ export default function POICardList() {
{POI.isComplete && <FaCheck color="white" />}
</button>
</div>
<POICard title={POI.name} duration={POI.duration} imageUrl={POI.imageUrl}></POICard>
<POICard title={POI.name} duration={POI.duration} imageUrl={POI.image}></POICard>
</div>
</Link>
))}
Expand All @@ -104,163 +146,3 @@ export default function POICardList() {
</div>
);
}

const initialData: POI[] = [
{
_id: "1",
name: "Eiffel Tower",
description:
"A wrought-iron lattice tower in Paris, France, known for its stunning architecture and panoramic views.",
audioField: "eiffel_tower_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "2",
name: "Great Wall of China",
description: "A historic fortification stretching across China, built to protect against invasions.",
audioField: "great_wall_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "3",
name: "Machu Picchu",
description: "An ancient Incan citadel set high in the Andes Mountains in Peru, known for its breathtaking ruins.",
audioField: "machu_picchu_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "4",
name: "Colosseum",
description:
"A massive ancient amphitheater in Rome, Italy, once used for gladiatorial contests and public spectacles.",
audioField: "colosseum_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "5",
name: "Statue of Liberty",
description: "A symbol of freedom and democracy, located on Liberty Island in New York Harbor.",
audioField: "statue_liberty_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "6",
name: "Taj Mahal",
description:
"A stunning white marble mausoleum in India, built by Mughal Emperor Shah Jahan in memory of his wife.",
audioField: "taj_mahal_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "7",
name: "Christ the Redeemer",
description:
"A colossal statue of Jesus Christ in Rio de Janeiro, Brazil, overlooking the city from Mount Corcovado.",
audioField: "christ_redeemer_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "8",
name: "Sydney Opera House",
description:
"An architectural masterpiece in Australia, known for its sail-like design and world-class performances.",
audioField: "sydney_opera_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "9",
name: "Pyramids of Giza",
description: "One of the Seven Wonders of the Ancient World, located in Egypt and built as tombs for pharaohs.",
audioField: "pyramids_giza_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "10",
name: "Niagara Falls",
description:
"A powerful set of waterfalls on the border of the USA and Canada, attracting millions of visitors each year.",
audioField: "niagara_falls_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "11",
name: "Grand Canyon",
description: "A breathtaking natural wonder in Arizona, USA, carved by the Colorado River over millions of years.",
audioField: "grand_canyon_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "12",
name: "Mount Everest",
description:
"The tallest mountain in the world, located in the Himalayas, attracting climbers from around the globe.",
audioField: "mount_everest_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "13",
name: "Stonehenge",
description: "A mysterious prehistoric stone circle in England, believed to have been used for ceremonies.",
audioField: "stonehenge_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "14",
name: "The Louvre Museum",
description: "A world-famous museum in Paris, home to iconic artworks like the Mona Lisa and the Venus de Milo.",
audioField: "louvre_museum_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
{
_id: "15",
name: "Chichen Itza",
description: "A significant Mayan archaeological site in Mexico, featuring the famous pyramid El Castillo.",
audioField: "chichen_itza_audio.mp3",
duration: "1:00",
imageUrl:
"https://images.unsplash.com/uploads/141148589884100082977/a816dbd7?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
isComplete: false,
},
];
Loading