forked from UKSOURCE/hailearning.edu.vn
417 lines
15 KiB
TypeScript
417 lines
15 KiB
TypeScript
"use client";
|
||
|
||
import React, { useState, useEffect } from "react";
|
||
import Link from "next/link";
|
||
import visaData from "../visa.json";
|
||
|
||
const ASSET_URL = process.env.NEXT_PUBLIC_API_URL || "";
|
||
|
||
interface CountryDetailsClientProps {
|
||
country: {
|
||
id: number;
|
||
name: string;
|
||
icon: string;
|
||
services: string[];
|
||
};
|
||
}
|
||
|
||
export default function CountryDetailsClient({
|
||
country,
|
||
}: CountryDetailsClientProps) {
|
||
const [showBackToTop, setShowBackToTop] = useState(false);
|
||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||
|
||
// Get detailed data from visa.json
|
||
const countryData = visaData.visaSystem.detailedView.activeCountry;
|
||
const relatedCountries =
|
||
visaData.visaSystem.detailedView.relatedCountries.map((c: any) => ({
|
||
...c,
|
||
icon: `${ASSET_URL}/${c.icon}`,
|
||
}));
|
||
const contactInfo = visaData.visaSystem.contactInfo;
|
||
|
||
useEffect(() => {
|
||
const handleScroll = () => setShowBackToTop(window.scrollY > 100);
|
||
window.addEventListener("scroll", handleScroll);
|
||
return () => window.removeEventListener("scroll", handleScroll);
|
||
}, []);
|
||
|
||
const scrollToTop = () => window.scrollTo({ top: 0, behavior: "smooth" });
|
||
|
||
return (
|
||
<>
|
||
{/* Back to Top */}
|
||
<button
|
||
onClick={scrollToTop}
|
||
className={`fixed bottom-8 right-8 w-12 h-12 rounded-full bg-white shadow-lg flex items-center justify-center cursor-pointer transition-all z-40 ${
|
||
showBackToTop ? "opacity-100" : "opacity-0 pointer-events-none"
|
||
}`}
|
||
>
|
||
<svg
|
||
className="w-6 h-6 text-blue-600"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M7 11l5-5m0 0l5 5m-5-5v12"
|
||
/>
|
||
</svg>
|
||
</button>
|
||
{/* Header Top */}
|
||
<div className="bg-gray-900 text-white py-3 hidden lg:block">
|
||
<div className="max-w-7xl mx-auto px-8 flex justify-between items-center text-sm">
|
||
<ul className="flex gap-8">
|
||
<li>
|
||
<a href="tel:+093783575222">+09 378 357 5222</a>
|
||
</li>
|
||
<li>69 Street, 5th Avenue LA, United States</li>
|
||
<li>
|
||
<a href="mailto:info@example.com">info@example.com</a>
|
||
</li>
|
||
</ul>
|
||
<select className="bg-gray-900 text-white border-0 outline-none cursor-pointer">
|
||
<option>English</option>
|
||
<option>Bangla</option>
|
||
<option>Hindi</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Header */}
|
||
<header className="sticky top-0 z-20 bg-white shadow-md">
|
||
<div className="max-w-7xl mx-auto px-4 lg:px-8 py-4 flex justify-between items-center">
|
||
<Link href="/" className="flex-shrink-0">
|
||
<img
|
||
src={`${ASSET_URL}/assets/img/logo/black-logo.svg`}
|
||
alt="logo"
|
||
className="h-10"
|
||
/>
|
||
</Link>
|
||
<nav className="hidden lg:flex gap-8">
|
||
<Link href="/" className="text-gray-700 hover:text-blue-600">
|
||
Home
|
||
</Link>
|
||
<Link href="/about" className="text-gray-700 hover:text-blue-600">
|
||
About Us
|
||
</Link>
|
||
<Link
|
||
href="/country-list"
|
||
className="text-gray-700 hover:text-blue-600"
|
||
>
|
||
VISA
|
||
</Link>
|
||
<Link href="/contact" className="text-gray-700 hover:text-blue-600">
|
||
Contact Us
|
||
</Link>
|
||
</nav>
|
||
<button
|
||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||
className="lg:hidden text-2xl"
|
||
>
|
||
☰
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
{/* Mobile Menu */}
|
||
{isMobileMenuOpen && (
|
||
<div className="fixed inset-0 z-30 lg:hidden">
|
||
<div
|
||
className="absolute inset-0 bg-black/50"
|
||
onClick={() => setIsMobileMenuOpen(false)}
|
||
></div>
|
||
<div className="absolute left-0 top-0 w-80 h-full bg-white p-6 overflow-y-auto">
|
||
<button
|
||
onClick={() => setIsMobileMenuOpen(false)}
|
||
className="float-right text-2xl"
|
||
>
|
||
✕
|
||
</button>
|
||
<nav className="space-y-3 mt-8">
|
||
<Link href="/" className="block py-2">
|
||
Home
|
||
</Link>
|
||
<Link href="/about" className="block py-2">
|
||
About Us
|
||
</Link>
|
||
<Link href="/country-list" className="block py-2">
|
||
Visa
|
||
</Link>
|
||
<Link href="/contact" className="block py-2">
|
||
Contact Us
|
||
</Link>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Breadcrumb */}
|
||
<section
|
||
className="py-20 px-4 lg:px-8 bg-cover relative"
|
||
style={{
|
||
backgroundImage: `url('${ASSET_URL}/${countryData.mainImage}')`,
|
||
}}
|
||
>
|
||
<div className="absolute inset-0 bg-black/30"></div>
|
||
<div className="max-w-7xl mx-auto relative z-10 text-center text-white">
|
||
<h1 className="text-5xl font-bold mb-6">{countryData.title}</h1>
|
||
<ul className="flex justify-center gap-4">
|
||
<li>
|
||
<Link href="/">Home</Link>
|
||
</li>
|
||
<li>›</li>
|
||
<li>{countryData.name}</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
{/* Country Details */}
|
||
<section className="py-20 px-4 lg:px-8">
|
||
<div className="max-w-7xl mx-auto">
|
||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||
{/* Main Content */}
|
||
<div className="lg:col-span-2">
|
||
<img
|
||
src={`${ASSET_URL}/${countryData.mainImage}`}
|
||
alt={countryData.name}
|
||
className="w-full rounded-lg mb-8"
|
||
/>
|
||
|
||
<h2 className="text-4xl font-bold mb-4">{countryData.name}</h2>
|
||
<p className="text-gray-700 mb-4">{countryData.description}</p>
|
||
<p className="text-gray-700 mb-4">{countryData.additionalInfo}</p>
|
||
<h5 className="text-xl font-semibold mb-6">
|
||
{countryData.tagline}
|
||
</h5>
|
||
|
||
{/* Visa Types */}
|
||
<div className="grid grid-cols-2 gap-6 mb-8">
|
||
{countryData.visaTypes.map((typeGroup: any, idx: number) => (
|
||
<React.Fragment key={idx}>
|
||
{typeGroup.items.map((item: any, itemIdx: number) => (
|
||
<div
|
||
key={itemIdx}
|
||
className="p-6 border-l-4 border-blue-600"
|
||
>
|
||
<h5 className="font-bold mb-2">{item.title}</h5>
|
||
<p className="text-sm text-gray-600">
|
||
{item.description}
|
||
</p>
|
||
</div>
|
||
))}
|
||
</React.Fragment>
|
||
))}
|
||
</div>
|
||
|
||
{/* Visa Process */}
|
||
<h3 className="text-2xl font-bold mb-6">USA Visa Process</h3>
|
||
<ul className="space-y-4 mb-8">
|
||
{countryData.visaProcess.steps.map((process: any) => (
|
||
<li key={process.number} className="flex gap-4">
|
||
<span className="font-bold text-blue-600 flex-shrink-0">
|
||
{process.number}.
|
||
</span>
|
||
<span>
|
||
<strong>{process.title}</strong> – {process.description}
|
||
</span>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
|
||
{/* Gallery */}
|
||
<div className="grid grid-cols-2 gap-6 mb-8">
|
||
{countryData.gallery.map((image: string, idx: number) => (
|
||
<img
|
||
key={idx}
|
||
src={`${ASSET_URL}/${image}`}
|
||
alt={`${countryData.name} gallery`}
|
||
className="rounded-lg w-full"
|
||
/>
|
||
))}
|
||
</div>
|
||
|
||
{/* Visa Types List */}
|
||
<h3 className="text-2xl font-bold mb-6">Types of Visas</h3>
|
||
{countryData.visaCategories.steps.map(
|
||
(subGroup: string[], groupIdx: number) => (
|
||
<ul className="visa-list-2" key={groupIdx}>
|
||
{/* Map lần 2 để render từng chuỗi trong mảng con */}
|
||
{subGroup.map((category: string, idx: number) => (
|
||
<li key={idx}>
|
||
<i className="fa-solid fa-chevrons-right"></i>
|
||
{category}
|
||
</li>
|
||
))}
|
||
</ul>
|
||
),
|
||
)}
|
||
|
||
{/* Service Options */}
|
||
<h3 className="text-2xl font-bold mb-6">
|
||
Our {countryData.name} Visa Service Options
|
||
</h3>
|
||
<ul className="space-y-4">
|
||
{countryData.visaProcess.steps.map((process: any) => (
|
||
<li key={process.number} className="flex gap-4">
|
||
<span className="font-bold text-blue-600 flex-shrink-0">
|
||
{process.number}.
|
||
</span>
|
||
<span>
|
||
<strong>{process.title}</strong> – {process.description}
|
||
</span>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
</div>
|
||
|
||
{/* Sidebar */}
|
||
<div className="lg:col-span-1">
|
||
{/* Related Countries */}
|
||
<div className="bg-white rounded-lg shadow-lg p-6 mb-6">
|
||
{relatedCountries.map((c: any) => (
|
||
<div
|
||
key={c.id}
|
||
className="flex items-center justify-between py-4 border-b last:border-0 cursor-pointer hover:text-blue-600"
|
||
>
|
||
<div className="flex items-center gap-3">
|
||
<img src={c.icon} alt={c.name} className="w-10 h-10" />
|
||
<h5 className="font-medium">{c.name}</h5>
|
||
</div>
|
||
<span className="text-blue-600">›</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* Contact Box */}
|
||
<div
|
||
className="rounded-lg p-6 text-white relative"
|
||
style={{
|
||
backgroundImage: `url('${ASSET_URL}/assets/img/inner-page/country-details/bg.jpg')`,
|
||
backgroundSize: "cover",
|
||
}}
|
||
>
|
||
<div className="absolute inset-0 bg-black/60 rounded-lg"></div>
|
||
<div className="relative z-10">
|
||
<h3 className="text-2xl font-bold mb-2">
|
||
Visa & Immigration
|
||
</h3>
|
||
<p className="mb-6">Need Help? Book Lab Visit</p>
|
||
|
||
<div className="space-y-4">
|
||
<div className="flex gap-3">
|
||
<div className="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center flex-shrink-0">
|
||
📞
|
||
</div>
|
||
<div>
|
||
<span className="text-sm">Call Us:</span>
|
||
<p className="font-bold">
|
||
<a href={`tel:${contactInfo.phone}`}>
|
||
{contactInfo.phone}
|
||
</a>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex gap-3">
|
||
<div className="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center flex-shrink-0">
|
||
✉️
|
||
</div>
|
||
<div>
|
||
<span className="text-sm">Mail Us:</span>
|
||
<p className="font-bold">
|
||
<a href={`mailto:${contactInfo.email}`}>
|
||
{contactInfo.email}
|
||
</a>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex gap-3">
|
||
<div className="w-10 h-10 rounded-full bg-blue-600 flex items-center justify-center flex-shrink-0">
|
||
📍
|
||
</div>
|
||
<div>
|
||
<span className="text-sm">Location:</span>
|
||
<p className="font-bold">{contactInfo.location}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Footer */}
|
||
<footer
|
||
className="py-20 px-4 lg:px-8 bg-cover text-white relative"
|
||
style={{
|
||
backgroundImage: `url('${ASSET_URL}/assets/img/home-1/footer-bg.jpg')`,
|
||
}}
|
||
>
|
||
<div className="absolute inset-0 bg-black/60"></div>
|
||
<div className="max-w-7xl mx-auto relative z-10 text-center">
|
||
<h2 className="text-3xl font-bold mb-4">
|
||
<a href="tel:+16336547896">+163 3654 7896</a>
|
||
</h2>
|
||
<h2 className="text-xl mb-8">
|
||
69 Street, 5th Avenue LA, United States
|
||
</h2>
|
||
<Link href="/">
|
||
<img
|
||
src={`${ASSET_URL}/assets/img/logo/white-logo.svg`}
|
||
alt="logo"
|
||
className="h-10 mx-auto mb-8"
|
||
/>
|
||
</Link>
|
||
<ul className="flex flex-wrap justify-center gap-8 mb-8">
|
||
<li>
|
||
<a href="/" className="hover:text-blue-300">
|
||
Home
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="/about" className="hover:text-blue-300">
|
||
About Us
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="/country-list" className="hover:text-blue-300">
|
||
Visa
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="/blog" className="hover:text-blue-300">
|
||
Pages
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="/contact" className="hover:text-blue-300">
|
||
Contact Us
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
<div className="flex justify-center gap-6">
|
||
<a href="#" className="hover:text-blue-300">
|
||
𝕏
|
||
</a>
|
||
<a href="#" className="hover:text-blue-300">
|
||
📷
|
||
</a>
|
||
<a href="#" className="hover:text-blue-300">
|
||
in
|
||
</a>
|
||
<a href="#" className="hover:text-blue-300">
|
||
▶
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
</>
|
||
);
|
||
}
|