Files
uldp.edu.vn/app/visa/[slug]/page.tsx
r2xrzh9q2z-lab 426749c480 fix data
2026-02-02 11:41:42 +07:00

285 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useState, useEffect } from "react";
import React from "react";
import visaData from "../visa.json";
import Breadcrumb from "../components/Breadcrumb";
const ASSET_URL = process.env.NEXT_PUBLIC_API_URL || "";
interface VisaCountryData {
id: number;
name: string;
icon: string;
services: string[];
}
interface CountryDetailsProps {
params: Promise<{
slug: string;
}>;
}
// Helper function to map slugs to country names
const getCountryFromSlug = (slug: string): string => {
const slugToCountry: { [key: string]: string } = {
france: "France",
uk: "UK",
canada: "Canada",
germany: "Germany",
spain: "Spain",
"south-korea": "South Korea",
japan: "Japan",
croatia: "Croatia",
england: "England",
indonesia: "Indonesia",
"united-states-of-america": "United States of America",
};
return slugToCountry[slug] || slug;
};
export default function CountryDetailsPage({ params }: CountryDetailsProps) {
const [country, setCountry] = useState<VisaCountryData | null>(null);
const [loading, setLoading] = useState(true);
const [slug, setSlug] = useState<string>("");
useEffect(() => {
// Unwrap the params Promise
Promise.resolve(params).then((resolvedParams) => {
const currentSlug = resolvedParams.slug;
setSlug(currentSlug);
const countryName = getCountryFromSlug(currentSlug);
const foundCountry = visaData.visaSystem.summaryList.find(
(c) => c.name === countryName,
);
if (foundCountry) {
setCountry(foundCountry);
}
setLoading(false);
});
}, [params]);
if (loading) {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="spinner"></div>
</div>
);
}
if (!country) {
return (
<div className="flex items-center justify-center min-h-screen">
<h1>Country not found</h1>
</div>
);
}
const breadcrumbData = visaData.visaSystem.breadcrumb;
const countryData = visaData.visaSystem.detailedView.activeCountry;
const relatedCountries = visaData.visaSystem.detailedView.relatedCountries;
const contactInfo = visaData.visaSystem.contactInfo;
return (
<>
{/* Breadcrumb-Wrapper Section Start */}
<Breadcrumb
title={breadcrumbData.list.title}
breadcrumbItems={[
{ label: "Home", href: "/" },
{ label: countryData.name },
]}
backgroundImage={`${ASSET_URL}/${breadcrumbData.list.image}`}
/>
{/* Country-details Section Start */}
<section className="country-details-section section-padding fix">
<div className="container">
<div className="country-details-wrapper">
<div className="row g-4">
{/* Main Content */}
<div className="col-lg-8">
<div className="country-details-post">
<div className="details-image">
<img
src={`${ASSET_URL}/${countryData.mainImage}`}
alt="img"
/>
</div>
<div className="country-details-content">
<h2>{countryData.name}</h2>
<p>{countryData.description}</p>
<p className="mt-3">{countryData.additionalInfo}</p>
<h5>{countryData.tagline}</h5>
{/* Visa Types */}
<div className="tourist-visa-box">
{/* Render mảng đầu tiên (index 0) */}
{countryData.visaTypes[0] && (
<div className="tourist-box style-2">
{countryData.visaTypes[0].items.map(
(item: any, itemIdx: number) => (
<div key={itemIdx} className="tourist-content">
<h5>{item.title}</h5>
<p>{item.description}</p>
</div>
),
)}
</div>
)}
{/* Render mảng thứ hai (index 1) */}
{countryData.visaTypes[1] && (
<div className="tourist-box">
{countryData.visaTypes[1].items.map(
(item: any, itemIdx: number) => (
<div key={itemIdx} className="tourist-content">
<h5>{item.title}</h5>
<p>{item.description}</p>
</div>
),
)}
</div>
)}
</div>
{/* Visa Process */}
<h3 className="text">{countryData.visaProcess.title}</h3>
<ul className="list-item">
{countryData.visaProcess.steps.map(
(process: any, idx: number) => (
<li key={idx}>
{process.number}. {process.title}
<span>{process.description}</span>
</li>
),
)}
</ul>
{/* Gallery */}
<div className="row g-4 mb-4">
{countryData.gallery.map((image: string, idx: number) => (
<div key={idx} className="col-lg-6">
<div className="thumb">
<img src={`${ASSET_URL}/${image}`} alt="img" />
</div>
</div>
))}
</div>
{/* Visa Categories */}
<h3 className="text mb-3">
{countryData.visaCategories.title}
</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">{countryData.visaService.title}</h3>
<ul className="list-item">
{countryData.visaService.steps.map(
(process: any, idx: number) => (
<li key={idx}>
{process.number}. {process.title}
<span>{process.description}</span>
</li>
),
)}
</ul>
</div>
</div>
</div>
{/* Sidebar */}
<div className="col-lg-4">
<div className="country-details-sideber">
{relatedCountries.map((relCountry: any, idx: number) => (
<div key={idx} className="icon-box-item">
<div className="left-item">
<div className="icon">
<img
src={`${ASSET_URL}/${relCountry.icon}`}
alt="img"
/>
</div>
<h5>{relCountry.name}</h5>
</div>
<i className="fa-solid fa-chevrons-right"></i>
</div>
))}
{/* Contact Box */}
<div
className="visa-contact-box bg-cover"
style={{
backgroundImage: `url(${ASSET_URL}/assets/img/inner-page/country-details/bg.jpg)`,
padding: "30px",
borderRadius: "8px",
color: "white",
}}
>
<div className="content">
<h3>{contactInfo.sectionTitle}</h3>
<p>{contactInfo.helpText}</p>
<div className="icon-item">
<div className="icon">
<i className="fa-solid fa-phone"></i>
</div>
<div className="cont">
<span>{contactInfo.phone.label}: </span>
<h6>
<a href={`tel:${contactInfo.phone.link}`}>
{contactInfo.phone.value}
</a>
</h6>
</div>
</div>
<div className="icon-item">
<div className="icon">
<i className="fa-regular fa-envelope"></i>
</div>
<div className="cont">
<span>{contactInfo.email.label}: </span>
<h6>
<a href={`mailto:${contactInfo.email.link}`}>
{contactInfo.email.value}
</a>
</h6>
</div>
</div>
<div className="icon-item">
<div className="icon">
<i className="fa-regular fa-location-dot"></i>
</div>
<div className="cont">
<span>{contactInfo.location.label}: </span>
<h6>{contactInfo.location.address}</h6>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</>
);
}