import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Homepage from "./pages/Homepage";
import Login from "./pages/Login";
import SignUp from "./pages/SignUp";
import CountryDetail from "./pages/CountryDetail";
function App() {
return (
<>
<Router>
<Routes>
<Route path="/" element={<Homepage />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/countries" element={<CountryDetail />} />
</Routes>
</Router>
</>
);
}
export default App;
import React from "react";
import Hero from "../components/homepage/hero";
import Header from "../components/common/Header";
import Countries from "../components/homepage/Countries";
import WhyAfriTour from "../components/homepage/WhyAfriTour";
import Newsletter from "../components/homepage/Newsletter";
import Footer from "../components/homepage/Footer";
import FooterTest from "../components/homepage/FooterTest";
import Accommodations from "../components/homepage/Accommodations";
const Homepage = () => {
return (
<div>
<Header />
<Hero />
<WhyAfriTour />
<Countries />
<Accommodations/>
<Newsletter />
<Footer />
</div>
);
};
export default Homepage;
import React, { useEffect } from "react";
import { useSearchParams } from "react-router-dom";
import { countries } from "../data/countries";
import { Link } from "react-router-dom";
import { useState } from "react";
const CountryDetail = () => {
const [searchParams] = useSearchParams();
const countryParam = [Link]("country");
const country = [Link](
(eachCountry) => [Link] === countryParam,
);
const [imageIndex, setImageIndex] = useState({});
const [preloadedImages, setPreloadedImages] = useState(new Set());
const [selectedFilter, setSelectedFilter] = useState("all");
const [currentFactIndex, setCurrentFactIndex] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCurrentFactIndex((prevIndex) => (prevIndex + 1) %
[Link]);
}, 5000);
return () => clearInterval(interval);
}, [[Link]]);
const preloadImage = (imageSrc) => {
if () {
const img = new Image();
[Link] = imageSrc;
[Link] = () => {
setPreloadedImages((prev) => new Set([...prev, imageSrc]));
};
}
};
const handleImageClick = (locationId, imagesLocation) => {
setImageIndex((changingState) => {
const currentImageIndex = changingState[locationId] || 0;
const nextImageIndex =
currentImageIndex === [Link] - 1
? 0
: currentImageIndex + 1;
const imageAfterNext =
nextImageIndex === [Link] - 1 ? 0 : nextImageIndex + 1;
preloadImage(imagesLocation[imageAfterNext]);
return {
...changingState,
[locationId]: nextImageIndex,
};
});
};
if (!country) {
return (
<div className="flex min-h-screen items-center justify-center">
<div className="text-center">
<p className="mb-2 text-xl font-bold text-stone-800">
Country not found for parameter: {countryParam}
</p>
<p className="text-stone-600">
Try: /countries?country=egypt, /countries?country=morocco, etc.
</p>
</div>
</div>
);
}
const handleFilterClick = (filterName) => {
setSelectedFilter(filterName);
[Link]("Selected filter:", filterName);
};
return (
<div className="relative flex min-h-screen w-full flex-col">
{/* HERO SECTION */}
<div className="relative flex h-screen items-center justify-center">
<div className="absolute inset-0 z-0">
<img
src={[Link]}
alt=""
className="h-full w-full object-cover"
/>
</div>
<div className="absolute inset-0 z-10 bg-gradient-to-br from-stone-900/80
via-amber-900/40 to-stone-800/90"></div>
<div className="relative z-30 text-center">
<div className="rounded-2xl border border-white/10 bg-white/5 p-8
backdrop-blur-sm">
<h1 className="mb-4 text-6xl font-bold text-white">
{[Link]}
</h1>
<p className="max-w-2xl text-xl text-stone-200">
{[Link]}
</p>
</div>
</div>
</div>
{/* {Cultural Facts} */}
<section className="bg-amber-50 py-12">
<div className="mx-auto max-w-6xl px-4">
<div className="rounded-xl border-l-4 border-amber-600 bg-white p-6
shadow-md">
<div className="mb-3 flex items-center">
<div className="mr-3 flex h-8 w-8 items-center justify-center
rounded-full bg-amber-600">
<span className="text-sm font-bold text-white">!</span>
</div>
<h3 className="text-lg font-bold text-stone-800">
Cultural Insight
</h3>
</div>
<p className="text-lg leading-relaxed text-stone-700">
{[Link][currentFactIndex]}
</p>
<div className="mt-4 flex space-x-1">
{[Link]((_, index) => (
<div
key={index}
className={`h-1 rounded-full transition-all duration-300 ${
index === currentFactIndex
? "w-8 bg-amber-600"
: "w-2 bg-amber-200"
}`}
/>
))}
</div>
</div>
</div>
</section>
{/* Facts */}
<div className="bg-stone-50 px-8 py-16">
<div className="mx-auto max-w-6xl">
<h2 className="mb-12 text-center text-3xl font-bold text-stone-800">
Quick Facts About {[Link]}
</h2>
{/* Facts Grid */}
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{/* Population */}
<div className="rounded-xl bg-white p-6 shadow-md transition-shadow
hover:bg-amber-50 hover:shadow-lg">
<div className="mb-2 text-2xl text-amber-600">👥</div>
<h3 className="mb-1 text-lg font-bold text-stone-800">
Population
</h3>
<p className="text-stone-600">{[Link]}</p>
</div>
{/* Capital */}
<div className="rounded-xl bg-white p-6 shadow-md transition-shadow
hover:bg-amber-50 hover:shadow-lg">
<div className="mb-2 text-2xl text-amber-600"></div>
<h3 className="mb-1 text-lg font-bold text-stone-800">Capital</h3>
<p className="text-stone-600">{[Link]}</p>
</div>
{/* Language */}
<div className="rounded-xl bg-white p-6 shadow-md transition-shadow
hover:bg-amber-50 hover:shadow-lg">
<div className="mb-2 text-2xl text-amber-600"></div>
<h3 className="mb-1 text-lg font-bold text-stone-800">
Language
</h3>
<p className="text-stone-600">{[Link]}</p>
</div>
{/* Currency */}
<div className="rounded-xl bg-white p-6 shadow-md transition-shadow
hover:bg-amber-50 hover:shadow-lg">
<div className="mb-2 text-2xl text-amber-600">💰</div>
<h3 className="mb-1 text-lg font-bold text-stone-800">
Currency
</h3>
<p className="text-stone-600">{[Link]}</p>
</div>
{/* Best Time */}
<div className="rounded-xl bg-white p-6 shadow-md transition-shadow
hover:bg-amber-50 hover:shadow-lg">
<div className="mb-2 text-2xl text-amber-600">🌞</div>
<h3 className="mb-1 text-lg font-bold text-stone-800">
Best Time
</h3>
<p className="text-stone-600">{[Link]}</p>
</div>
{/* Time Zone */}
<div className="rounded-xl bg-white p-6 shadow-md transition-shadow
hover:bg-amber-50 hover:shadow-lg">
<div className="mb-2 text-2xl text-amber-600">🕐</div>
<h3 className="mb-1 text-lg font-bold text-stone-800">
Time Zone
</h3>
<p className="text-stone-600">{[Link]}</p>
</div>
</div>
</div>
</div>
{/* Locations Section */}
<div className="p-8">
<h2 className="mb-4 text-2xl font-bold text-stone-400">
Top Destination
</h2>
{/* Filter Buttons */}
<div className="mb-6 flex flex-wrap gap-2">
<button
onClick={() => handleFilterClick("all")}
className={`rounded-full px-4 py-2 font-medium ${selectedFilter ===
"all" ? "bg-stone-800 text-white" : "bg-stone-200 text-stone-700 hover:bg-stone-
300"}`}
>
All
</button>
<button
onClick={() => handleFilterClick("ancient")}
className={`rounded-full px-4 py-2 font-medium ${selectedFilter ===
"ancient" ? "bg-stone-800 text-white" : "bg-stone-200 text-stone-700 hover:bg-
stone-300"}`}
>
Ancient
</button>
<button
onClick={() => handleFilterClick("adventure")}
className={`rounded-full px-4 py-2 font-medium ${selectedFilter ===
"adventure" ? "bg-stone-800 text-white" : "bg-stone-200 text-stone-700 hover:bg-
stone-300"}`}
>
Adventure
</button>
<button
onClick={() => handleFilterClick("safari")}
className={`rounded-full px-4 py-2 font-medium ${selectedFilter ===
"safari" ? "bg-stone-800 text-white" : "bg-stone-200 text-stone-700 hover:bg-stone-
300"}`}
>
Safari
</button>
<button
onClick={() => handleFilterClick("cultural")}
className={`rounded-full px-4 py-2 font-medium ${selectedFilter ===
"cultural" ? "bg-stone-800 text-white" : "bg-stone-200 text-stone-700 hover:bg-
stone-300"}`}
>
Cultural
</button>
</div>
{/* Map through locations */}
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{[Link]
.filter((location) => {
if (selectedFilter === "all") {
return true;
}
return [Link](selectedFilter);
})
.map((location) => (
<div
key={[Link]}
className="rounded-lg bg-white p-4 shadow-md"
>
<img
src={[Link][imageIndex[[Link]] || 0]}
alt={[Link]}
className="mb-3 h-48 w-full cursor-pointer rounded-md object-
cover transition-all duration-300 ease-in-out hover:scale-105"
onClick={() =>
handleImageClick([Link], [Link])
}
/>
<h3 className="text-lg font-bold text-stone-800">
{[Link]}
</h3>
<p className="font-semibold text-amber-600">
${[Link]}
</p>
<p className="mt-2 text-sm text-stone-600">{[Link]}</p>
</div>
))}
</div>
</div>
</div>
);
};
export default CountryDetail;