forked from UKSOURCE/hailearning.edu.vn
Merge pull request 'feat/huy-02022026-ui-header-footer-homepage-aboutpage' (#6) from feat/huy-02022026-ui-header-footer-homepage-aboutpage into main
Reviewed-on: UKSOURCE/hailearning.edu.vn#6
This commit is contained in:
@@ -2,95 +2,119 @@
|
|||||||
"hero": {
|
"hero": {
|
||||||
"title": "About Us",
|
"title": "About Us",
|
||||||
"subtitle": "Global Education Simplified",
|
"subtitle": "Global Education Simplified",
|
||||||
"breadcrumb": [
|
"breadcrumb": ["Home", "About Us"],
|
||||||
"Home",
|
|
||||||
"About Us"
|
|
||||||
],
|
|
||||||
"backgroundImage": "/assets/img/inner-page/breadcrumb.jpg"
|
"backgroundImage": "/assets/img/inner-page/breadcrumb.jpg"
|
||||||
},
|
},
|
||||||
"intro": {
|
"intro": {
|
||||||
|
"subheading": "Company Intro",
|
||||||
"heading": "Building Pathways to Your Immigration Success",
|
"heading": "Building Pathways to Your Immigration Success",
|
||||||
"description": "We provide expert guidance, personalized solutions, and transparent processes to help you achieve your immigration goals. Our dedicated team ensures a smooth journey, building pathways to your international success.",
|
"description": "We provide expert guidance, personalized solutions, and transparent processes to help you achieve your immigration goals. Our dedicated team ensures a smooth journey, building pathways to your international success.",
|
||||||
"highlights": [
|
|
||||||
"Expert Visa Consulting",
|
|
||||||
"Smooth Documentation Process",
|
|
||||||
"Personalized Student Guidance"
|
|
||||||
],
|
|
||||||
"image": "/assets/img/inner-page/intro.jpg"
|
"image": "/assets/img/inner-page/intro.jpg"
|
||||||
},
|
},
|
||||||
"mission": {
|
"mission": {
|
||||||
"title": "Our Commitment to Your Future",
|
"subheading": "About Our Consultancy",
|
||||||
|
"heading": "Turning Study Abroad Dreams Into Reality",
|
||||||
|
"description": "We guide students with expert visa consulting, ensuring a smooth process from application to approval, turning study abroad aspirations into life-changing opportunities for a brighter future.",
|
||||||
|
"images": {
|
||||||
|
"main": "/assets/img/home-1/about/about-1.jpg",
|
||||||
|
"secondary": "/assets/img/home-1/about/about-02.jpg",
|
||||||
|
"bgShape": "/assets/img/home-1/about/Vector.png",
|
||||||
|
"planeShape": "/assets/img/home-1/about/plane.png",
|
||||||
|
"topShape": "/assets/img/home-1/about/shape.png",
|
||||||
|
"globeShape": "/assets/img/home-1/about/globe.png"
|
||||||
|
},
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"label": "Mission",
|
"icon": "/assets/img/home-1/icon/01.svg",
|
||||||
"description": "To guide students with expert visa consulting, ensuring a smooth process from application to approval and turning dreams into reality."
|
"label": "Global Reach",
|
||||||
|
"description": "Expanding Opportunities Worldwide"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Vision",
|
"icon": "/assets/img/home-1/icon/01.svg",
|
||||||
"description": "To be the most trusted global education consultancy, expanding opportunities and building paths to international success for every student."
|
"label": "Global Reach",
|
||||||
},
|
"description": "Expanding Opportunities Worldwide"
|
||||||
{
|
|
||||||
"label": "Values",
|
|
||||||
"description": "Transparency, integrity, and excellence in every visa application, ensuring reliable assistance and professional support."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"stats": [
|
|
||||||
{
|
|
||||||
"label": "Years Experience",
|
|
||||||
"value": 10
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Students Helped",
|
|
||||||
"value": 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Success Rate",
|
|
||||||
"value": "95%"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Countries Covered",
|
|
||||||
"value": 50
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"team": {
|
"features": [
|
||||||
"title": "Meet Our Expert Team",
|
"Fastest Visa form processing with skilled immigration agents",
|
||||||
"members": [
|
"Partnership with International Educational Institutions"
|
||||||
{
|
],
|
||||||
"name": "Eleanor Pena",
|
"ctaButton": {
|
||||||
"role": "Lead Legal Consultant",
|
"label": "Get Started",
|
||||||
"image": "/assets/img/home-1/testimonial/client.png",
|
"href": "/about"
|
||||||
"social": {
|
|
||||||
"facebook": "href",
|
|
||||||
"linkedin": "href"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"features": {
|
||||||
|
"backgroundImage": "/assets/img/home-2/feature/bg-shape.png",
|
||||||
|
"subheading": "Your Travel Made Easy",
|
||||||
|
"heading": "Smooth Visa Journey Guaranteed",
|
||||||
|
"description": "We provide expert guidance for every visa application, ensuring smooth processing, personalized support, and reliable assistance",
|
||||||
|
"image": "/assets/img/home-2/feature/02.png",
|
||||||
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "Jerome Bell",
|
"icon": "/assets/img/home-2/icon/01.png",
|
||||||
"role": "Senior Visa Expert",
|
"title": "Expert Consultants",
|
||||||
"image": "/assets/img/home-1/testimonial/client-2.png",
|
"description": "Skilled and knowledgeable visa advisors. Skilled and knowledgeable visa advisors."
|
||||||
"social": {
|
|
||||||
"facebook": "href",
|
|
||||||
"linkedin": "href"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Marvin McKinney",
|
"icon": "/assets/img/home-2/icon/01.png",
|
||||||
"role": "Immigration Advisor",
|
"title": "Personalized Support",
|
||||||
"image": "/assets/img/home-1/news/client.png",
|
"description": "Skilled and knowledgeable visa advisors. Skilled and knowledgeable visa advisors."
|
||||||
"social": {
|
|
||||||
"facebook": "href",
|
|
||||||
"linkedin": "href"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Kathryn Murphy",
|
"icon": "/assets/img/home-2/icon/01.png",
|
||||||
"role": "Education Consultant",
|
"title": "Transparent Process",
|
||||||
"image": "/assets/img/home-1/testimonial/client.png",
|
"description": "Skilled and knowledgeable visa advisors. Skilled and knowledgeable visa advisors."
|
||||||
"social": {
|
|
||||||
"facebook": "href",
|
|
||||||
"linkedin": "href"
|
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"ctaButton": {
|
||||||
|
"label": "Get Started Today",
|
||||||
|
"href": "/contact"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"news": {
|
||||||
|
"subheading": "Visa Tips & Guides",
|
||||||
|
"heading": "Latest Insights & Updates",
|
||||||
|
"ctaButton": {
|
||||||
|
"label": "view all articles",
|
||||||
|
"href": "/blog"
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"title": "Step-by-Step Guide to Applying for a Student Visa",
|
||||||
|
"category": "Student Visa",
|
||||||
|
"date": "20 August ,2025",
|
||||||
|
"comments": 8,
|
||||||
|
"author": {
|
||||||
|
"name": "Sohel",
|
||||||
|
"avatar": "/assets/img/home-1/news/client.png"
|
||||||
|
},
|
||||||
|
"link": "/blog/step-by-step-guide-student-visa",
|
||||||
|
"thumbnail": "/assets/img/home-1/news/news-1.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Tips to Prepare Financial Documents for Visa Approval",
|
||||||
|
"category": "IELTS / TOEFL",
|
||||||
|
"date": "20 August ,2025",
|
||||||
|
"comments": 8,
|
||||||
|
"author": {
|
||||||
|
"name": "Sohel",
|
||||||
|
"avatar": "/assets/img/home-1/news/client.png"
|
||||||
|
},
|
||||||
|
"link": "/blog/financial-documents-visa-approval",
|
||||||
|
"thumbnail": "/assets/img/home-1/news/news-2.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Post-Arrival Guide What Every Student Should Know",
|
||||||
|
"category": "Study Abroad",
|
||||||
|
"date": "20 August ,2025",
|
||||||
|
"comments": 8,
|
||||||
|
"author": {
|
||||||
|
"name": "Sohel",
|
||||||
|
"avatar": "/assets/img/home-1/news/client.png"
|
||||||
|
},
|
||||||
|
"link": "/blog/post-arrival-guide-students",
|
||||||
|
"thumbnail": "/assets/img/home-1/news/news-3.jpg"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
import {
|
import { AboutHero, AboutIntro, AboutMission, AboutFeatures, AboutNews } from "../components/about";
|
||||||
AboutHero,
|
import aboutData from "./about.json";
|
||||||
AboutIntro,
|
|
||||||
AboutMission,
|
|
||||||
AboutStats,
|
|
||||||
AboutTeam,
|
|
||||||
AboutFeatures,
|
|
||||||
AboutNews
|
|
||||||
} from '../components/about';
|
|
||||||
import aboutData from './about.json';
|
|
||||||
|
|
||||||
export default function AboutPage() {
|
export default function AboutPage() {
|
||||||
return (
|
return (
|
||||||
@@ -15,10 +7,8 @@ export default function AboutPage() {
|
|||||||
<AboutHero data={aboutData.hero} />
|
<AboutHero data={aboutData.hero} />
|
||||||
<AboutIntro data={aboutData.intro} />
|
<AboutIntro data={aboutData.intro} />
|
||||||
<AboutMission data={aboutData.mission} />
|
<AboutMission data={aboutData.mission} />
|
||||||
<AboutStats data={aboutData.stats} />
|
<AboutFeatures data={aboutData.features} />
|
||||||
<AboutTeam data={aboutData.team} />
|
<AboutNews data={aboutData.news} />
|
||||||
<AboutFeatures />
|
|
||||||
<AboutNews />
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,32 +6,68 @@ export interface AboutData {
|
|||||||
backgroundImage: string;
|
backgroundImage: string;
|
||||||
};
|
};
|
||||||
intro: {
|
intro: {
|
||||||
|
subheading: string;
|
||||||
heading: string;
|
heading: string;
|
||||||
description: string;
|
description: string;
|
||||||
highlights: string[];
|
|
||||||
image: string;
|
image: string;
|
||||||
};
|
};
|
||||||
mission: {
|
mission: {
|
||||||
title: string;
|
subheading: string;
|
||||||
|
heading: string;
|
||||||
|
description: string;
|
||||||
|
images: {
|
||||||
|
main: string;
|
||||||
|
secondary: string;
|
||||||
|
bgShape: string;
|
||||||
|
planeShape: string;
|
||||||
|
topShape: string;
|
||||||
|
globeShape: string;
|
||||||
|
};
|
||||||
items: {
|
items: {
|
||||||
|
icon: string;
|
||||||
label: string;
|
label: string;
|
||||||
description: string;
|
description: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
features: string[];
|
||||||
stats: {
|
ctaButton: {
|
||||||
label: string;
|
label: string;
|
||||||
value: number | string;
|
href: string;
|
||||||
}[];
|
|
||||||
team: {
|
|
||||||
title: string;
|
|
||||||
members: {
|
|
||||||
name: string;
|
|
||||||
role: string;
|
|
||||||
image: string;
|
|
||||||
social: {
|
|
||||||
facebook: string;
|
|
||||||
linkedin: string;
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
features: {
|
||||||
|
backgroundImage: string;
|
||||||
|
subheading: string;
|
||||||
|
heading: string;
|
||||||
|
description: string;
|
||||||
|
image: string;
|
||||||
|
items: {
|
||||||
|
icon: string;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
}[];
|
||||||
|
ctaButton: {
|
||||||
|
label: string;
|
||||||
|
href: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
news: {
|
||||||
|
subheading: string;
|
||||||
|
heading: string;
|
||||||
|
ctaButton: {
|
||||||
|
label: string;
|
||||||
|
href: string;
|
||||||
|
};
|
||||||
|
items: {
|
||||||
|
title: string;
|
||||||
|
category: string;
|
||||||
|
date: string;
|
||||||
|
comments: number;
|
||||||
|
author: {
|
||||||
|
name: string;
|
||||||
|
avatar: string;
|
||||||
|
};
|
||||||
|
link: string;
|
||||||
|
thumbnail: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,62 +1,44 @@
|
|||||||
import Link from 'next/link';
|
import Link from "next/link";
|
||||||
|
import { AboutData } from "../../about/types";
|
||||||
|
|
||||||
const AboutFeatures = () => {
|
interface AboutFeaturesProps {
|
||||||
|
data: AboutData["features"];
|
||||||
|
}
|
||||||
|
|
||||||
|
const AboutFeatures = ({ data }: AboutFeaturesProps) => {
|
||||||
return (
|
return (
|
||||||
<section className="choose-us-section-2 section-padding fix bg-cover" style={{ backgroundImage: 'url(/assets/img/home-2/feature/bg-shape.png)' }}>
|
<section
|
||||||
|
className="choose-us-section-2 section-padding fix bg-cover"
|
||||||
|
style={{ backgroundImage: `url(${data.backgroundImage})` }}
|
||||||
|
>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="choose-us-wrapper-2">
|
<div className="choose-us-wrapper-2">
|
||||||
<div className="row g-4">
|
<div className="row g-4">
|
||||||
<div className="col-lg-6">
|
<div className="col-lg-6">
|
||||||
<div className="choose-us-image">
|
<div className="choose-us-image">
|
||||||
<img src="/assets/img/home-2/feature/02.png" alt="img" />
|
<img src={data.image} alt="img" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-lg-6">
|
<div className="col-lg-6">
|
||||||
<div className="feature-content">
|
<div className="feature-content">
|
||||||
<div className="section-title mb-0">
|
<div className="section-title mb-0">
|
||||||
<span className="sub-title-2 wow fadeInUp">Your Travel Made Easy</span>
|
<span className="sub-title-2 wow fadeInUp">{data.subheading}</span>
|
||||||
<h2 className="split-text-right split-text-in-right">
|
<h2 className="split-text-right split-text-in-right">{data.heading}</h2>
|
||||||
Smooth Visa Journey Guaranteed
|
|
||||||
</h2>
|
|
||||||
</div>
|
</div>
|
||||||
<p className="text">
|
<p className="text">{data.description}</p>
|
||||||
We provide expert guidance for every visa application, ensuring smooth processing, personalized support, and reliable assistance
|
{data.items.map((item, index) => (
|
||||||
</p>
|
<div key={index} className="choose-us-box">
|
||||||
<div className="choose-us-box">
|
|
||||||
<div className="icon">
|
<div className="icon">
|
||||||
<img src="/assets/img/home-2/icon/01.png" alt="img" />
|
<img src={item.icon} alt="img" />
|
||||||
</div>
|
</div>
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<h5>Expert Consultants</h5>
|
<h5>{item.title}</h5>
|
||||||
<p>
|
<p>{item.description}</p>
|
||||||
Skilled and knowledgeable visa advisors. Skilled and knowled geable visa advisors.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="choose-us-box">
|
))}
|
||||||
<div className="icon">
|
<Link href={data.ctaButton.href} className="theme-btn">
|
||||||
<img src="/assets/img/home-2/icon/01.png" alt="img" />
|
{data.ctaButton.label}
|
||||||
</div>
|
|
||||||
<div className="content">
|
|
||||||
<h5>Personalized Support</h5>
|
|
||||||
<p>
|
|
||||||
Skilled and knowledgeable visa advisors. Skilled and knowled geable visa advisors.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="choose-us-box">
|
|
||||||
<div className="icon">
|
|
||||||
<img src="/assets/img/home-2/icon/01.png" alt="img" />
|
|
||||||
</div>
|
|
||||||
<div className="content">
|
|
||||||
<h5>Transparent Process</h5>
|
|
||||||
<p>
|
|
||||||
Skilled and knowledgeable visa advisors. Skilled and knowled geable visa advisors.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Link href="/contact" className="theme-btn">
|
|
||||||
Get Started Today
|
|
||||||
<i className="fa-solid fa-arrow-right"></i>
|
<i className="fa-solid fa-arrow-right"></i>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { AboutData } from '../../about/types';
|
import { AboutData } from "../../about/types";
|
||||||
|
|
||||||
interface AboutIntroProps {
|
interface AboutIntroProps {
|
||||||
data: AboutData['intro'];
|
data: AboutData["intro"];
|
||||||
}
|
}
|
||||||
|
|
||||||
const AboutIntro = ({ data }: AboutIntroProps) => {
|
const AboutIntro = ({ data }: AboutIntroProps) => {
|
||||||
@@ -10,14 +10,10 @@ const AboutIntro = ({ data }: AboutIntroProps) => {
|
|||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="section-title-area">
|
<div className="section-title-area">
|
||||||
<div className="section-title">
|
<div className="section-title">
|
||||||
<span className="sub-title-2 wow fadeInUp">Company Intro</span>
|
<span className="sub-title-2 wow fadeInUp">{data.subheading}</span>
|
||||||
<h2 className="split-text-right split-text-in-right">
|
<h2 className="split-text-right split-text-in-right">{data.heading}</h2>
|
||||||
{data.heading}
|
|
||||||
</h2>
|
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>{data.description}</p>
|
||||||
{data.description}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="intro-image tp-clip-anim p-relative">
|
<div className="intro-image tp-clip-anim p-relative">
|
||||||
|
|||||||
@@ -1,57 +1,70 @@
|
|||||||
import Link from 'next/link';
|
import Link from "next/link";
|
||||||
import { AboutData } from '../../about/types';
|
import { AboutData } from "../../about/types";
|
||||||
|
|
||||||
interface AboutMissionProps {
|
interface AboutMissionProps {
|
||||||
data: AboutData['mission'];
|
data: AboutData["mission"];
|
||||||
}
|
}
|
||||||
|
|
||||||
const AboutMission = ({ data }: AboutMissionProps) => {
|
const AboutMission = ({ data }: AboutMissionProps) => {
|
||||||
return (
|
return (
|
||||||
<section className="about-section section-padding fix pb-0">
|
<section className="about-section section-padding fix pb-0">
|
||||||
<div className="top-shape">
|
<div className="top-shape">
|
||||||
<img src="/assets/img/home-1/about/globe.png" alt="img" />
|
<img src={data.images.globeShape} alt="img" />
|
||||||
</div>
|
</div>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="about-wrapper">
|
<div className="about-wrapper">
|
||||||
<div className="row g-4">
|
<div className="row g-4">
|
||||||
<div className="col-lg-6">
|
<div className="col-lg-6">
|
||||||
<div className="about-image">
|
<div className="about-image">
|
||||||
<img src="/assets/img/home-1/about/about-1.jpg" alt="img" className="wow img-custom-anim-left" />
|
<img src={data.images.main} alt="img" className="wow img-custom-anim-left" />
|
||||||
<div className="about-image-2">
|
<div className="about-image-2">
|
||||||
<img src="/assets/img/home-1/about/about-02.jpg" alt="img" className="wow img-custom-anim-right" />
|
<img src={data.images.secondary} alt="img" className="wow img-custom-anim-right" />
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-shape">
|
<div className="bg-shape">
|
||||||
<img src="/assets/img/home-1/about/Vector.png" alt="img" />
|
<img src={data.images.bgShape} alt="img" />
|
||||||
</div>
|
</div>
|
||||||
<div className="plane-shape float-bob-y">
|
<div className="plane-shape float-bob-y">
|
||||||
<img src="/assets/img/home-1/about/plane.png" alt="img" />
|
<img src={data.images.planeShape} alt="img" />
|
||||||
</div>
|
</div>
|
||||||
<div className="top-shape float-bob-y">
|
<div className="top-shape float-bob-y">
|
||||||
<img src="/assets/img/home-1/about/shape.png" alt="img" />
|
<img src={data.images.topShape} alt="img" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-lg-6">
|
<div className="col-lg-6">
|
||||||
<div className="about-content">
|
<div className="about-content">
|
||||||
<div className="section-title mb-0">
|
<div className="section-title mb-0">
|
||||||
<span className="sub-title wow fadeInUp">About Our Consultancy</span>
|
<span className="sub-title wow fadeInUp">{data.subheading}</span>
|
||||||
<h2 className="split-text-right split-text-in-right">
|
<h2 className="split-text-right split-text-in-right">{data.heading}</h2>
|
||||||
{data.title}
|
|
||||||
</h2>
|
|
||||||
</div>
|
</div>
|
||||||
|
<p className="text wow fadeInUp" data-wow-delay=".3s">
|
||||||
|
{data.description}
|
||||||
|
</p>
|
||||||
<div className="about-item wow fadeInUp" data-wow-delay=".5s">
|
<div className="about-item wow fadeInUp" data-wow-delay=".5s">
|
||||||
{data.items.map((item, index) => (
|
{data.items.map((item, index) => (
|
||||||
<div key={index} className="content mb-3">
|
<div key={index} className="content">
|
||||||
<span>
|
<span>
|
||||||
<img src="/assets/img/home-1/icon/01.svg" alt="" className="me-2" />
|
<img src={item.icon} alt="" className="me-2 d-inline-block" />
|
||||||
<strong>{item.label}</strong>
|
{item.label}-
|
||||||
</span>
|
</span>
|
||||||
<p>{item.description}</p>
|
<p>{item.description}</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<Link href="/contact" className="theme-btn wow fadeInUp" data-wow-delay=".5s">
|
<ul className="list wow fadeInUp" data-wow-delay=".3s">
|
||||||
Get Started
|
{data.features.map((feature, index) => (
|
||||||
|
<li key={index}>
|
||||||
|
<i className="fa-solid fa-chevrons-right"></i>
|
||||||
|
{feature}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<Link
|
||||||
|
href={data.ctaButton.href}
|
||||||
|
className="theme-btn wow fadeInUp"
|
||||||
|
data-wow-delay=".5s"
|
||||||
|
>
|
||||||
|
{data.ctaButton.label}
|
||||||
<i className="fa-solid fa-arrow-right"></i>
|
<i className="fa-solid fa-arrow-right"></i>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,63 +1,48 @@
|
|||||||
import Link from 'next/link';
|
import Link from "next/link";
|
||||||
|
import { AboutData } from "../../about/types";
|
||||||
|
|
||||||
const AboutNews = () => {
|
interface AboutNewsProps {
|
||||||
const newsItems = [
|
data: AboutData["news"];
|
||||||
{
|
|
||||||
image: '/assets/img/home-1/news/news-1.jpg',
|
|
||||||
category: 'Student Visa',
|
|
||||||
comments: '08',
|
|
||||||
date: '20 August ,2025',
|
|
||||||
title: 'Step-by-Step Guide to Applying for a Student Visa',
|
|
||||||
author: 'Sohel',
|
|
||||||
authorImage: '/assets/img/home-1/news/client.png'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/assets/img/home-1/news/news-2.jpg',
|
|
||||||
category: 'IELTS / TOEFL',
|
|
||||||
comments: '08',
|
|
||||||
date: '20 August ,2025',
|
|
||||||
title: 'Tips to Prepare Financial Documents for Visa Approval',
|
|
||||||
author: 'Sohel',
|
|
||||||
authorImage: '/assets/img/home-1/news/client.png'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/assets/img/home-1/news/news-3.jpg',
|
|
||||||
category: 'Study Abroad',
|
|
||||||
comments: '08',
|
|
||||||
date: '20 August ,2025',
|
|
||||||
title: 'Post-Arrival Guide What Every Student Should Know',
|
|
||||||
author: 'Sohel',
|
|
||||||
authorImage: '/assets/img/home-1/news/client.png'
|
|
||||||
}
|
}
|
||||||
];
|
|
||||||
|
|
||||||
|
const AboutNews = ({ data }: AboutNewsProps) => {
|
||||||
return (
|
return (
|
||||||
<section className="news-section section-padding fix pt-0">
|
<section className="news-section section-padding fix pt-0">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="section-title-area">
|
<div className="section-title-area">
|
||||||
<div className="section-title">
|
<div className="section-title">
|
||||||
<span className="sub-title">Visa Tips & Guides</span>
|
<span className="sub-title">{data.subheading}</span>
|
||||||
<h2 className="split-text-right split-text-in-right">
|
<h2 className="split-text-right split-text-in-right">{data.heading}</h2>
|
||||||
Latest Insights & Updates
|
|
||||||
</h2>
|
|
||||||
</div>
|
</div>
|
||||||
<Link href="/news" className="theme-btn">
|
<Link href={data.ctaButton.href} className="theme-btn">
|
||||||
view all articies
|
{data.ctaButton.label}
|
||||||
<i className="fa-solid fa-arrow-right"></i>
|
<i className="fa-solid fa-arrow-right"></i>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
{newsItems.map((item, index) => (
|
{data.items.map((item, index) => (
|
||||||
<div key={index} className="col-xl-4 col-lg-6 col-md-6">
|
<div key={index} className="col-xl-4 col-lg-6 col-md-6">
|
||||||
<div className="news-card-item">
|
<div className="news-card-item">
|
||||||
<div className="news-image">
|
<div className="news-image">
|
||||||
<img src={item.image} alt="img" />
|
<img src={item.thumbnail} alt="img" />
|
||||||
<span>{item.category}</span>
|
<span>{item.category}</span>
|
||||||
<div className="news-layer-wrapper">
|
<div className="news-layer-wrapper">
|
||||||
<div className="news-layer-image" style={{ backgroundImage: `url('${item.image}')` }}></div>
|
<div
|
||||||
<div className="news-layer-image" style={{ backgroundImage: `url('${item.image}')` }}></div>
|
className="news-layer-image"
|
||||||
<div className="news-layer-image" style={{ backgroundImage: `url('${item.image}')` }}></div>
|
style={{ backgroundImage: `url('${item.thumbnail}')` }}
|
||||||
<div className="news-layer-image" style={{ backgroundImage: `url('${item.image}')` }}></div>
|
></div>
|
||||||
|
<div
|
||||||
|
className="news-layer-image"
|
||||||
|
style={{ backgroundImage: `url('${item.thumbnail}')` }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="news-layer-image"
|
||||||
|
style={{ backgroundImage: `url('${item.thumbnail}')` }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="news-layer-image"
|
||||||
|
style={{ backgroundImage: `url('${item.thumbnail}')` }}
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="news-content">
|
<div className="news-content">
|
||||||
@@ -66,16 +51,14 @@ const AboutNews = () => {
|
|||||||
<span>_ {item.date}</span>
|
<span>_ {item.date}</span>
|
||||||
</div>
|
</div>
|
||||||
<h3>
|
<h3>
|
||||||
<Link href="/news-details">
|
<Link href={item.link}>{item.title}</Link>
|
||||||
{item.title}
|
|
||||||
</Link>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div className="news-bottom">
|
<div className="news-bottom">
|
||||||
<div className="info-item">
|
<div className="info-item">
|
||||||
<img src={item.authorImage} alt="img" />
|
<img src={item.author.avatar} alt="img" />
|
||||||
<span>By {item.author}</span>
|
<span>By {item.author.name}</span>
|
||||||
</div>
|
</div>
|
||||||
<Link href="/news-details" className="link-btn">
|
<Link href={item.link} className="link-btn">
|
||||||
View Articles<i className="fa-solid fa-arrow-right"></i>
|
View Articles<i className="fa-solid fa-arrow-right"></i>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
import { AboutData } from '../../about/types';
|
|
||||||
|
|
||||||
interface AboutStatsProps {
|
|
||||||
data: AboutData['stats'];
|
|
||||||
}
|
|
||||||
|
|
||||||
const AboutStats = ({ data }: AboutStatsProps) => {
|
|
||||||
return (
|
|
||||||
<section className="counter-section section-padding pb-0 fix bg-cover" style={{ backgroundImage: "url('/assets/img/home-1/feature/bg-2.jpg')" }}>
|
|
||||||
<div className="shape">
|
|
||||||
<img src="/assets/img/home-1/feature/shape-2.png" alt="img" />
|
|
||||||
</div>
|
|
||||||
<div className="container">
|
|
||||||
<div className="section-title text-center">
|
|
||||||
<span className="sub-title bg-2 wow fadeInUp">Did You Know</span>
|
|
||||||
<h2 className="text-white split-text-right split-text-in-right">
|
|
||||||
Our Achievements in Numbers
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="counter-wrapper">
|
|
||||||
<div className="container">
|
|
||||||
<div className="counter-main-item">
|
|
||||||
{data.map((stat, index) => {
|
|
||||||
// Helper to extract number and suffix from value
|
|
||||||
const valueStr = String(stat.value);
|
|
||||||
const numericMatch = valueStr.match(/(\d+)/);
|
|
||||||
const numericValue = numericMatch ? numericMatch[0] : "0";
|
|
||||||
const suffix = valueStr.replace(numericValue, "");
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div key={index} className={`counter-item ${index < 3 ? 'style-2' : ''}`}>
|
|
||||||
<h2><span className="odometer" data-count={numericValue}>00</span>{suffix}</h2>
|
|
||||||
<h5>{stat.label}</h5>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AboutStats;
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import { AboutData } from '../../about/types';
|
|
||||||
|
|
||||||
interface AboutTeamProps {
|
|
||||||
data: AboutData['team'];
|
|
||||||
}
|
|
||||||
|
|
||||||
const AboutTeam = ({ data }: AboutTeamProps) => {
|
|
||||||
return (
|
|
||||||
<section className="team-section section-padding fix pt-0">
|
|
||||||
<div className="container">
|
|
||||||
<div className="section-title text-center">
|
|
||||||
<span className="sub-title wow fadeInUp">Our Expert Team</span>
|
|
||||||
<h2 className="split-text-right split-text-in-right">
|
|
||||||
{data.title}
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div className="row g-4">
|
|
||||||
{data.members.map((member, index) => (
|
|
||||||
<div key={index} className="col-xl-3 col-lg-4 col-md-6 wow fadeInUp" data-wow-delay={`${0.2 * (index + 1)}s`}>
|
|
||||||
<div className="news-card-item">
|
|
||||||
<div className="news-image">
|
|
||||||
<img src={member.image} alt={member.name} />
|
|
||||||
</div>
|
|
||||||
<div className="news-content text-center">
|
|
||||||
<h3>{member.name}</h3>
|
|
||||||
<span className="text-primary">{member.role}</span>
|
|
||||||
<div className="social-icon d-flex justify-content-center gap-2 mt-3">
|
|
||||||
{member.social.facebook && <a href={member.social.facebook}><i className="fa-brands fa-facebook-f"></i></a>}
|
|
||||||
{member.social.linkedin && <a href={member.social.linkedin}><i className="fa-brands fa-linkedin-in"></i></a>}
|
|
||||||
<a href="#"><i className="fa-brands fa-twitter"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AboutTeam;
|
|
||||||
@@ -3,5 +3,3 @@ export { default as AboutIntro } from './AboutIntro';
|
|||||||
export { default as AboutMission } from './AboutMission';
|
export { default as AboutMission } from './AboutMission';
|
||||||
export { default as AboutFeatures } from './AboutFeatures';
|
export { default as AboutFeatures } from './AboutFeatures';
|
||||||
export { default as AboutNews } from './AboutNews';
|
export { default as AboutNews } from './AboutNews';
|
||||||
export { default as AboutStats } from './AboutStats';
|
|
||||||
export { default as AboutTeam } from './AboutTeam';
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const VisaSolutions = ({ data }: VisaSolutionsProps) => {
|
|||||||
<div key={index} className={`service-wrapper ${index === 1 ? 'active' : ''}`}>
|
<div key={index} className={`service-wrapper ${index === 1 ? 'active' : ''}`}>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="service-item">
|
<div className="service-item">
|
||||||
<div className="image-hover d-none d-md-block bg-cover" style={{ backgroundImage: "url('/assets/img/home-1/hover-bg.jpg')" }}></div>
|
|
||||||
<div className="left-item">
|
<div className="left-item">
|
||||||
<h5 className="number">{item.number}</h5>
|
<h5 className="number">{item.number}</h5>
|
||||||
<h3>
|
<h3>
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import footerData from './footer.json';
|
||||||
|
|
||||||
const FooterBottom = () => {
|
const FooterBottom = () => {
|
||||||
|
const { bottom } = footerData;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="footer-bottom">
|
<div className="footer-bottom">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="footer-wrapper">
|
<div className="footer-wrapper">
|
||||||
<p>
|
<p>
|
||||||
Copyright© <span>GRAMENTHEME</span> All Rights Reserved.
|
{bottom.copyright.text} <span>{bottom.copyright.brand}</span> {bottom.copyright.rights}
|
||||||
</p>
|
</p>
|
||||||
<ul className="bottom-list">
|
<ul className="bottom-list">
|
||||||
<li>
|
{bottom.menuLinks.map((item, index) => (
|
||||||
<Link href="/contact">Terms & Conditions</Link>
|
<li key={index}>
|
||||||
</li>
|
<Link href={item.href}>{item.label}</Link>
|
||||||
<li>
|
|
||||||
<Link href="/contact">Privacy Policy</Link>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<Link href="/contact">Contact Us</Link>
|
|
||||||
</li>
|
</li>
|
||||||
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,46 +1,37 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import footerData from './footer.json';
|
||||||
|
|
||||||
const FooterTop = () => {
|
const FooterTop = () => {
|
||||||
|
const { top } = footerData;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer className="footer-section fix bg-cover" style={{ backgroundImage: "url('/assets/img/home-1/footer-bg.jpg')" }}>
|
<footer className="footer-section fix bg-cover" style={{ backgroundImage: `url('${top.bgImage}')` }}>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="footer-wrapper">
|
<div className="footer-wrapper">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-xl-12">
|
<div className="col-xl-12">
|
||||||
<div className="footer-item">
|
<div className="footer-item">
|
||||||
<h2>
|
<h2>
|
||||||
<a href="tel:+16336547896">+84 961 83 4040</a>
|
<a href={top.phone.href}>{top.phone.display}</a>
|
||||||
</h2>
|
</h2>
|
||||||
<h2 className="text">734 Luy Ban Bich St, Tan Thanh Ward, Tan Phu Dist, HCMC</h2>
|
<h2 className="text">{top.address}</h2>
|
||||||
<div className="footer-list-item">
|
<div className="footer-list-item">
|
||||||
<Link href="/">
|
<Link href={top.logo.href}>
|
||||||
<img src="/assets/img/logo/white-logo.svg" alt="img" />
|
<img src={top.logo.src} alt={top.logo.alt} />
|
||||||
</Link>
|
</Link>
|
||||||
<ul className="footer-list">
|
<ul className="footer-list">
|
||||||
<li>
|
{top.menuLinks.map((item, index) => (
|
||||||
<Link href="/">Home</Link>
|
<li key={index}>
|
||||||
</li>
|
<Link href={item.href}>{item.label}</Link>
|
||||||
<li>
|
|
||||||
<Link href="/about">About Us</Link>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<Link href="/country-details">Visa</Link>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<Link href="/news-details">Pages</Link>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<Link href="/news">Article</Link>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<Link href="/contact">Contact Us</Link>
|
|
||||||
</li>
|
</li>
|
||||||
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
<div className="social-icon">
|
<div className="social-icon">
|
||||||
<a href="#"><i className="fa-brands fa-twitter"></i></a>
|
{top.socialLinks.map((social, index) => (
|
||||||
<a href="#"><i className="fa-brands fa-instagram"></i></a>
|
<a key={index} href={social.href}>
|
||||||
<a href="#"><i className="fa-brands fa-linkedin"></i></a>
|
<i className={social.icon}></i>
|
||||||
<a href="#"><i className="fa-brands fa-youtube"></i></a>
|
</a>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
80
app/components/layout/Footer/footer.json
Normal file
80
app/components/layout/Footer/footer.json
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"top": {
|
||||||
|
"bgImage": "/assets/img/home-1/footer-bg.jpg",
|
||||||
|
"phone": {
|
||||||
|
"display": "+84 961 83 4040",
|
||||||
|
"href": "tel:+84961834040"
|
||||||
|
},
|
||||||
|
"address": "734 Luy Ban Bich St, Tan Thanh Ward, Tan Phu Dist, HCMC",
|
||||||
|
"logo": {
|
||||||
|
"src": "/assets/img/logo/white-logo.svg",
|
||||||
|
"alt": "logo",
|
||||||
|
"href": "/"
|
||||||
|
},
|
||||||
|
"menuLinks": [
|
||||||
|
{
|
||||||
|
"label": "Home",
|
||||||
|
"href": "/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "About Us",
|
||||||
|
"href": "/about"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Visa",
|
||||||
|
"href": "/country-details"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Pages",
|
||||||
|
"href": "/news-details"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Article",
|
||||||
|
"href": "/news"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Contact Us",
|
||||||
|
"href": "/contact"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"socialLinks": [
|
||||||
|
{
|
||||||
|
"icon": "fa-brands fa-twitter",
|
||||||
|
"href": "#"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fa-brands fa-instagram",
|
||||||
|
"href": "#"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fa-brands fa-linkedin",
|
||||||
|
"href": "#"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fa-brands fa-youtube",
|
||||||
|
"href": "#"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"bottom": {
|
||||||
|
"copyright": {
|
||||||
|
"text": "Copyright©",
|
||||||
|
"brand": "GRAMENTHEME",
|
||||||
|
"rights": "All Rights Reserved."
|
||||||
|
},
|
||||||
|
"menuLinks": [
|
||||||
|
{
|
||||||
|
"label": "Terms & Conditions",
|
||||||
|
"href": "/contact"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Privacy Policy",
|
||||||
|
"href": "/contact"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Contact Us",
|
||||||
|
"href": "/contact"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,36 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
import HeaderTop from './HeaderTop';
|
import HeaderTop from './HeaderTop';
|
||||||
import HeaderBottom from './HeaderBottom';
|
import HeaderBottom from './HeaderBottom';
|
||||||
|
import Offcanvas from './Offcanvas';
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
|
const [isOffcanvasOpen, setIsOffcanvasOpen] = useState(false);
|
||||||
|
const [isSearchOpen, setIsSearchOpen] = useState(false);
|
||||||
|
|
||||||
|
const toggleOffcanvas = () => setIsOffcanvasOpen(!isOffcanvasOpen);
|
||||||
|
const toggleSearch = () => setIsSearchOpen(!isSearchOpen);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HeaderTop />
|
<HeaderTop />
|
||||||
<HeaderBottom />
|
<HeaderBottom
|
||||||
{/* Search Popup - kept here for now as part of header logic/structure */}
|
onToggleOffcanvas={toggleOffcanvas}
|
||||||
<div className="search-popup">
|
onToggleSearch={toggleSearch}
|
||||||
<div className="search-popup__overlay search-toggler"></div>
|
/>
|
||||||
|
|
||||||
|
<Offcanvas
|
||||||
|
isOpen={isOffcanvasOpen}
|
||||||
|
onClose={() => setIsOffcanvasOpen(false)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Search Popup */}
|
||||||
|
<div className={`search-popup ${isSearchOpen ? 'active' : ''}`}>
|
||||||
|
<div
|
||||||
|
className="search-popup__overlay search-toggler"
|
||||||
|
onClick={() => setIsSearchOpen(false)}
|
||||||
|
></div>
|
||||||
<div className="search-popup__content">
|
<div className="search-popup__content">
|
||||||
<form role="search" method="get" className="search-popup__form" action="#">
|
<form role="search" method="get" className="search-popup__form" action="#">
|
||||||
<input type="text" id="search" name="search" placeholder="Search Here..." />
|
<input type="text" id="search" name="search" placeholder="Search Here..." />
|
||||||
|
|||||||
@@ -3,116 +3,50 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import HeaderMenu from './HeaderMenu';
|
import HeaderMenu from './HeaderMenu';
|
||||||
|
|
||||||
const homeMegaMenu = (
|
import headerData from './header.json';
|
||||||
<>
|
|
||||||
<div className="homemenu">
|
|
||||||
<div className="homemenu-thumb">
|
|
||||||
<img src="/assets/img/header/home-1.jpg" alt="img" />
|
|
||||||
<div className="demo-button">
|
|
||||||
<Link href="/" className="theme-btn">
|
|
||||||
Multi Page <i className="fa-solid fa-arrow-right"></i>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="homemenu-content text-center">
|
|
||||||
<h4 className="homemenu-title">
|
|
||||||
Home 01
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="homemenu">
|
|
||||||
<div className="homemenu-thumb mb-15">
|
|
||||||
<img src="/assets/img/header/home-2.jpg" alt="img" />
|
|
||||||
<div className="demo-button">
|
|
||||||
<Link href="/index-2" className="theme-btn">
|
|
||||||
Multi Page <i className="fa-solid fa-arrow-right"></i>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="homemenu-content text-center">
|
|
||||||
<h4 className="homemenu-title">
|
|
||||||
Home 02
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="homemenu">
|
|
||||||
<div className="homemenu-thumb mb-15">
|
|
||||||
<img src="/assets/img/header/home-3.jpg" alt="img" />
|
|
||||||
<div className="demo-button">
|
|
||||||
<Link href="/index-3" className="theme-btn">
|
|
||||||
Multi Page <i className="fa-solid fa-arrow-right"></i>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="homemenu-content text-center">
|
|
||||||
<h4 className="homemenu-title">
|
|
||||||
Home 03
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
const menuItems = [
|
|
||||||
{
|
|
||||||
label: 'Home',
|
// Map the JSON data to satisfy the HeaderMenu props interface
|
||||||
href: '/',
|
interface JsonMenuItem {
|
||||||
megaMenuContent: homeMegaMenu
|
label: string;
|
||||||
},
|
href: string;
|
||||||
{
|
children?: JsonMenuItem[];
|
||||||
label: 'About Us',
|
|
||||||
href: '/about'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Pages',
|
|
||||||
href: '#',
|
|
||||||
submenu: [
|
|
||||||
{
|
|
||||||
label: 'Service',
|
|
||||||
href: '#',
|
|
||||||
submenu: [
|
|
||||||
{ label: 'Service', href: '/service' },
|
|
||||||
{ label: 'Service Details', href: '/service-details' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Country List',
|
|
||||||
href: '#',
|
|
||||||
submenu: [
|
|
||||||
{ label: 'Country List', href: '/country-list' },
|
|
||||||
{ label: 'Country Details', href: '/country-details' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ label: 'Our Pricing', href: '/pricing' },
|
|
||||||
{ label: 'Appointment', href: '/appointment' },
|
|
||||||
{ label: '404 Page', href: '/404' },
|
|
||||||
{ label: 'Coming Soon', href: '/coming-soon' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'VISA',
|
|
||||||
href: '#',
|
|
||||||
submenu: [
|
|
||||||
{ label: 'Visa List', href: '/country-list' },
|
|
||||||
{ label: 'Visa Details', href: '/country-details' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Blog',
|
|
||||||
href: '#',
|
|
||||||
submenu: [
|
|
||||||
{ label: 'Blog Grid', href: '/news-grid' },
|
|
||||||
{ label: 'Blog Standard', href: '/news' },
|
|
||||||
{ label: 'Blog Details', href: '/news-details' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Contact Us',
|
|
||||||
href: '/contact'
|
|
||||||
}
|
}
|
||||||
];
|
|
||||||
|
|
||||||
const HeaderBottom = () => {
|
interface MenuItem {
|
||||||
|
label: string;
|
||||||
|
href: string;
|
||||||
|
submenu?: MenuItem[];
|
||||||
|
megaMenuContent?: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to recursively map 'children' to 'submenu'
|
||||||
|
const mapMenuItems = (items: JsonMenuItem[]): MenuItem[] => {
|
||||||
|
return items.map(item => {
|
||||||
|
const newItem: MenuItem = {
|
||||||
|
label: item.label,
|
||||||
|
href: item.href,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
newItem.submenu = mapMenuItems(item.children);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newItem;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const menuItems: MenuItem[] = mapMenuItems(headerData.menu as JsonMenuItem[]);
|
||||||
|
|
||||||
|
interface HeaderBottomProps {
|
||||||
|
onToggleOffcanvas: () => void;
|
||||||
|
onToggleSearch: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HeaderBottom: React.FC<HeaderBottomProps> = ({ onToggleOffcanvas, onToggleSearch }) => {
|
||||||
return (
|
return (
|
||||||
<header id="header-sticky" className="header-1">
|
<header id="header-sticky" className="header-1">
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
@@ -130,15 +64,22 @@ const HeaderBottom = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="header-right d-flex align-items-center mt-0">
|
<div className="header-right d-flex align-items-center mt-0">
|
||||||
<div className="header-call-item">
|
<div className="header-call-item">
|
||||||
<a href="#" className="main-header__search search-toggler">
|
<button
|
||||||
|
onClick={onToggleSearch}
|
||||||
|
className="main-header__search search-toggler"
|
||||||
|
>
|
||||||
<i className="fa-regular fa-magnifying-glass"></i>
|
<i className="fa-regular fa-magnifying-glass"></i>
|
||||||
</a>
|
</button>
|
||||||
<Link href="/contact" className="theme-btn">
|
<Link href="/contact" className="theme-btn">
|
||||||
Apply now
|
Apply now
|
||||||
<i className="fa-solid fa-arrow-right"></i>
|
<i className="fa-solid fa-arrow-right"></i>
|
||||||
</Link>
|
</Link>
|
||||||
<div className="header__hamburger my-auto">
|
<div className="header__hamburger my-auto">
|
||||||
<div className="sidebar__toggle">
|
<div
|
||||||
|
className="sidebar__toggle"
|
||||||
|
onClick={onToggleOffcanvas}
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
>
|
||||||
<i className="fa-solid fa-bars-staggered"></i>
|
<i className="fa-solid fa-bars-staggered"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,57 @@
|
|||||||
import Link from 'next/link';
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import headerData from "./header.json";
|
||||||
|
|
||||||
|
interface HeaderData {
|
||||||
|
top: {
|
||||||
|
phone: string;
|
||||||
|
email: string;
|
||||||
|
location: string;
|
||||||
|
socialLinks: Array<{
|
||||||
|
platform: string;
|
||||||
|
url: string;
|
||||||
|
icon: string;
|
||||||
|
}>;
|
||||||
|
languages: Array<{
|
||||||
|
name: string;
|
||||||
|
value: string;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const HeaderTop = () => {
|
const HeaderTop = () => {
|
||||||
|
const [data, setData] = useState<HeaderData>(headerData);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchHeaderData = async () => {
|
||||||
|
try {
|
||||||
|
const apiUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3000";
|
||||||
|
const response = await fetch(`${apiUrl}/api/header`);
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const result = await response.json();
|
||||||
|
if (result.success && result.data && result.data.top) {
|
||||||
|
setData({
|
||||||
|
top: result.data.top,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("Failed to fetch header data from API, using fallback:", error);
|
||||||
|
// Use fallback data (already set as initial state)
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchHeaderData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const { phone, email, location, socialLinks, languages } = data.top;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="header-top-section">
|
<div className="header-top-section">
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
@@ -10,17 +61,17 @@ const HeaderTop = () => {
|
|||||||
<li className="style-2 d-flex align-items-center me-4">
|
<li className="style-2 d-flex align-items-center me-4">
|
||||||
<span className="me-2">Help Line</span>
|
<span className="me-2">Help Line</span>
|
||||||
<i className="fa-solid fa-phone me-2"></i>
|
<i className="fa-solid fa-phone me-2"></i>
|
||||||
<a href="tel:+84961834040">+84 961 83 4040</a>
|
<a href={`tel:${phone.replace(/\s/g, "")}`}>{phone}</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li className="d-flex align-items-center me-4">
|
<li className="d-flex align-items-center me-4">
|
||||||
<i className="fa-solid fa-location-dot me-2"></i>
|
<i className="fa-solid fa-location-dot me-2"></i>
|
||||||
734 Luy Ban Bich St, Tan Thanh Ward, Tan Phu Dist, HCMC
|
{location}
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li className="d-flex align-items-center">
|
<li className="d-flex align-items-center">
|
||||||
<i className="fa-solid fa-envelope me-2"></i>
|
<i className="fa-solid fa-envelope me-2"></i>
|
||||||
<a href="mailto:get-info@hai.edu.vn">get-info@hai.edu.vn</a>
|
<a href={`mailto:${email}`}>{email}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -31,27 +82,26 @@ const HeaderTop = () => {
|
|||||||
<i className="fa-solid fa-globe"></i>
|
<i className="fa-solid fa-globe"></i>
|
||||||
</div>
|
</div>
|
||||||
<div className="nice-select" tabIndex={0}>
|
<div className="nice-select" tabIndex={0}>
|
||||||
<span className="current">
|
<span className="current">{languages[0]?.name || "English"}</span>
|
||||||
English
|
|
||||||
</span>
|
|
||||||
<ul className="list">
|
<ul className="list">
|
||||||
<li data-value="1" className="option selected focus">
|
{languages.map((lang, index) => (
|
||||||
English
|
<li
|
||||||
</li>
|
key={index}
|
||||||
<li data-value="1" className="option">
|
data-value={lang.value}
|
||||||
Bangla
|
className={`option ${index === 0 ? "selected focus" : ""}`}
|
||||||
</li>
|
>
|
||||||
<li data-value="1" className="option">
|
{lang.name}
|
||||||
Hindi
|
|
||||||
</li>
|
</li>
|
||||||
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="social-item">
|
<div className="social-item">
|
||||||
<a href="#"><i className="fa-brands fa-linkedin"></i></a>
|
{socialLinks.map((social, index) => (
|
||||||
<a href="#"><i className="fa-brands fa-twitter"></i></a>
|
<a key={index} href={social.url} target="_blank" rel="noopener noreferrer">
|
||||||
<a href="#"><i className="fa-brands fa-instagram"></i></a>
|
<i className={social.icon}></i>
|
||||||
<a href="#"><i className="fa-brands fa-youtube"></i></a>
|
</a>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
150
app/components/layout/Header/Offcanvas.tsx
Normal file
150
app/components/layout/Header/Offcanvas.tsx
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import headerData from './header.json';
|
||||||
|
|
||||||
|
interface SocialLink {
|
||||||
|
platform: string;
|
||||||
|
url: string;
|
||||||
|
icon: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MenuItem {
|
||||||
|
label: string;
|
||||||
|
href: string;
|
||||||
|
children?: MenuItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OffcanvasProps {
|
||||||
|
isOpen: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Offcanvas: React.FC<OffcanvasProps> = ({ isOpen, onClose }) => {
|
||||||
|
// Explicitly casting headerData to the expected structure
|
||||||
|
const data = headerData as {
|
||||||
|
top: {
|
||||||
|
socialLinks: SocialLink[];
|
||||||
|
};
|
||||||
|
offcanvas: {
|
||||||
|
description: string;
|
||||||
|
contactInfo: {
|
||||||
|
address: string;
|
||||||
|
email: string;
|
||||||
|
workingHours: string;
|
||||||
|
phone: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
menu: MenuItem[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const { offcanvas, top, menu } = data;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="fix-area">
|
||||||
|
<div className={`offcanvas__info ${isOpen ? 'info-open' : ''}`}>
|
||||||
|
<div className="offcanvas__wrapper">
|
||||||
|
<div className="offcanvas__content">
|
||||||
|
<div className="offcanvas__top mb-5 d-flex justify-content-between align-items-center">
|
||||||
|
<div className="offcanvas__logo">
|
||||||
|
<Link href="/">
|
||||||
|
<Image
|
||||||
|
src="/assets/img/logo/black-logo.svg"
|
||||||
|
alt="logo-img"
|
||||||
|
width={150}
|
||||||
|
height={50}
|
||||||
|
priority
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div className="offcanvas__close">
|
||||||
|
<button onClick={onClose} aria-label="Close menu">
|
||||||
|
<i className="fas fa-times"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="text d-none d-xl-block">
|
||||||
|
{offcanvas.description}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* Mobile Menu Area */}
|
||||||
|
<div className="mobile-menu fix mb-3 d-xl-none">
|
||||||
|
<nav className="mean-nav">
|
||||||
|
<ul>
|
||||||
|
{menu.map((item: MenuItem, idx: number) => (
|
||||||
|
<li key={idx}>
|
||||||
|
<Link href={item.href} onClick={onClose}>
|
||||||
|
{item.label}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="offcanvas__contact d-xl-block">
|
||||||
|
<h4 className="d-xl-block">Contact Info</h4>
|
||||||
|
<ul className="d-xl-block">
|
||||||
|
<li className="d-flex align-items-center">
|
||||||
|
<div className="offcanvas__contact-icon">
|
||||||
|
<i className="fal fa-map-marker-alt"></i>
|
||||||
|
</div>
|
||||||
|
<div className="offcanvas__contact-text">
|
||||||
|
<a target="_blank" href="#" rel="noopener noreferrer">
|
||||||
|
{offcanvas.contactInfo.address}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li className="d-flex align-items-center">
|
||||||
|
<div className="offcanvas__contact-icon mr-15">
|
||||||
|
<i className="fal fa-envelope"></i>
|
||||||
|
</div>
|
||||||
|
<div className="offcanvas__contact-text">
|
||||||
|
<a href={`mailto:${offcanvas.contactInfo.email}`}>
|
||||||
|
<span>{offcanvas.contactInfo.email}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li className="d-flex align-items-center">
|
||||||
|
<div className="offcanvas__contact-icon mr-15">
|
||||||
|
<i className="fal fa-clock"></i>
|
||||||
|
</div>
|
||||||
|
<div className="offcanvas__contact-text">
|
||||||
|
<span>{offcanvas.contactInfo.workingHours}</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li className="d-flex align-items-center">
|
||||||
|
<div className="offcanvas__contact-icon mr-15">
|
||||||
|
<i className="far fa-phone"></i>
|
||||||
|
</div>
|
||||||
|
<div className="offcanvas__contact-text">
|
||||||
|
<a href={`tel:${offcanvas.contactInfo.phone.replace(/\s/g, '')}`}>
|
||||||
|
{offcanvas.contactInfo.phone}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div className="social-icon d-flex align-items-center">
|
||||||
|
{top.socialLinks.map((social: SocialLink, idx: number) => (
|
||||||
|
<a key={idx} href={social.url} target="_blank" rel="noopener noreferrer">
|
||||||
|
<i className={social.icon}></i>
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`offcanvas__overlay ${isOpen ? 'overlay-open' : ''}`}
|
||||||
|
onClick={onClose}
|
||||||
|
></div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Offcanvas;
|
||||||
142
app/components/layout/Header/header.json
Normal file
142
app/components/layout/Header/header.json
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
{
|
||||||
|
"top": {
|
||||||
|
"phone": "+09 378 357 5222",
|
||||||
|
"email": "info@hailearning.edu.vn",
|
||||||
|
"location": "69 Street, 5th Avenue LA, United States",
|
||||||
|
"socialLinks": [
|
||||||
|
{
|
||||||
|
"platform": "linkedin",
|
||||||
|
"url": "https://linkedin.com",
|
||||||
|
"icon": "fa-brands fa-linkedin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"platform": "twitter",
|
||||||
|
"url": "https://twitter.com",
|
||||||
|
"icon": "fa-brands fa-twitter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"platform": "instagram",
|
||||||
|
"url": "https://instagram.com",
|
||||||
|
"icon": "fa-brands fa-instagram"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"platform": "youtube",
|
||||||
|
"url": "https://youtube.com",
|
||||||
|
"icon": "fa-brands fa-youtube"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"languages": [
|
||||||
|
{
|
||||||
|
"name": "English",
|
||||||
|
"value": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bangla",
|
||||||
|
"value": "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Hindi",
|
||||||
|
"value": "3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"offcanvas": {
|
||||||
|
"description": "Nullam dignissim, ante scelerisque the is euismod fermentum odio sem semper the is erat, a feugiat leo urna eget eros. Duis Aenean a imperdiet risus.",
|
||||||
|
"contactInfo": {
|
||||||
|
"address": "Main Street, Melbourne, Australia",
|
||||||
|
"email": "info@hailearning.edu.vn",
|
||||||
|
"workingHours": "Mod-Friday, 09am - 05pm",
|
||||||
|
"phone": "+09 378 357 5222"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"menu": [
|
||||||
|
{
|
||||||
|
"label": "Home",
|
||||||
|
"href": "/",
|
||||||
|
"children": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "About Us",
|
||||||
|
"href": "/about",
|
||||||
|
"children": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Pages",
|
||||||
|
"href": "#",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "Service",
|
||||||
|
"href": "/service",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "Service",
|
||||||
|
"href": "/service"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Service Details",
|
||||||
|
"href": "/service-details"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Country List",
|
||||||
|
"href": "/country-list",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "Country List",
|
||||||
|
"href": "/country-list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Country Details",
|
||||||
|
"href": "/country-details"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Our Pricing",
|
||||||
|
"href": "/pricing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Appointment",
|
||||||
|
"href": "/appointment"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "VISA",
|
||||||
|
"href": "#",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "Visa List",
|
||||||
|
"href": "/visa-list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Visa Details",
|
||||||
|
"href": "/visa-details"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Blog",
|
||||||
|
"href": "#",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"label": "Blog Grid",
|
||||||
|
"href": "/blog-grid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Blog Standard",
|
||||||
|
"href": "/blog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Blog Details",
|
||||||
|
"href": "/blog-details"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Contact Us",
|
||||||
|
"href": "/contact"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
120
app/home.json
120
app/home.json
@@ -1,123 +1,5 @@
|
|||||||
{
|
{
|
||||||
"header": {
|
|
||||||
"top": {
|
|
||||||
"phone": "+09 378 357 5222",
|
|
||||||
"email": "info@hailearning.edu.vn",
|
|
||||||
"location": "69 Street, 5th Avenue LA, United States",
|
|
||||||
"socialLinks": [
|
|
||||||
{
|
|
||||||
"platform": "linkedin",
|
|
||||||
"url": "https://linkedin.com",
|
|
||||||
"icon": "fa-brands fa-linkedin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"platform": "twitter",
|
|
||||||
"url": "https://twitter.com",
|
|
||||||
"icon": "fa-brands fa-twitter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"platform": "instagram",
|
|
||||||
"url": "https://instagram.com",
|
|
||||||
"icon": "fa-brands fa-instagram"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"platform": "youtube",
|
|
||||||
"url": "https://youtube.com",
|
|
||||||
"icon": "fa-brands fa-youtube"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"menu": [
|
|
||||||
{
|
|
||||||
"label": "Home",
|
|
||||||
"href": "/",
|
|
||||||
"children": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "About Us",
|
|
||||||
"href": "/about",
|
|
||||||
"children": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Pages",
|
|
||||||
"href": "#",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"label": "Service",
|
|
||||||
"href": "/service",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"label": "Service",
|
|
||||||
"href": "/service"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Service Details",
|
|
||||||
"href": "/service-details"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Country List",
|
|
||||||
"href": "/country-list",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"label": "Country List",
|
|
||||||
"href": "/country-list"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Country Details",
|
|
||||||
"href": "/country-details"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Our Pricing",
|
|
||||||
"href": "/pricing"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Appointment",
|
|
||||||
"href": "/appointment"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "VISA",
|
|
||||||
"href": "#",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"label": "Visa List",
|
|
||||||
"href": "/visa-list"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Visa Details",
|
|
||||||
"href": "/visa-details"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Blog",
|
|
||||||
"href": "#",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"label": "Blog Grid",
|
|
||||||
"href": "/blog-grid"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Blog Standard",
|
|
||||||
"href": "/blog"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Blog Details",
|
|
||||||
"href": "/blog-details"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Contact Us",
|
|
||||||
"href": "/contact"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hero": {
|
"hero": {
|
||||||
"title": "From Application to Visa – We've Got You Covered",
|
"title": "From Application to Visa – We've Got You Covered",
|
||||||
"subtitle": "Global Education Simplified",
|
"subtitle": "Global Education Simplified",
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
|
||||||
|
import Header from "./components/layout/Header/Header";
|
||||||
|
import Footer from "./components/layout/Footer/Footer";
|
||||||
import Loader from "./components/Loader";
|
import Loader from "./components/Loader";
|
||||||
import BackToTop from "./components/BackToTop";
|
import BackToTop from "./components/BackToTop";
|
||||||
import MouseCursor from "./components/MouseCursor";
|
import MouseCursor from "./components/MouseCursor";
|
||||||
import Script from "next/script";
|
import Script from "next/script";
|
||||||
import Header from "./components/layout/Header/Header";
|
|
||||||
import Footer from "./components/layout/Footer/Footer";
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Visaway – Immigration & Visa Consulting HTML Template",
|
title: "Visaway – Immigration & Visa Consulting HTML Template",
|
||||||
@@ -20,76 +21,41 @@ export default function RootLayout({
|
|||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
{/* Favicon */}
|
|
||||||
<link rel="shortcut icon" href="/assets/img/favicon.png" />
|
<link rel="shortcut icon" href="/assets/img/favicon.png" />
|
||||||
|
|
||||||
{/* Bootstrap min.css */}
|
|
||||||
<link rel="stylesheet" href="/assets/css/bootstrap.min.css" />
|
<link rel="stylesheet" href="/assets/css/bootstrap.min.css" />
|
||||||
{/* All Min Css */}
|
|
||||||
<link rel="stylesheet" href="/assets/css/all.min.css" />
|
<link rel="stylesheet" href="/assets/css/all.min.css" />
|
||||||
{/* Animate.css */}
|
|
||||||
<link rel="stylesheet" href="/assets/css/animate.css" />
|
<link rel="stylesheet" href="/assets/css/animate.css" />
|
||||||
{/* Magnific Popup.css */}
|
|
||||||
<link rel="stylesheet" href="/assets/css/magnific-popup.css" />
|
<link rel="stylesheet" href="/assets/css/magnific-popup.css" />
|
||||||
{/* MeanMenu.css */}
|
|
||||||
<link rel="stylesheet" href="/assets/css/meanmenu.css" />
|
<link rel="stylesheet" href="/assets/css/meanmenu.css" />
|
||||||
{/* Odometer.css */}
|
|
||||||
<link rel="stylesheet" href="/assets/css/odometer.css" />
|
<link rel="stylesheet" href="/assets/css/odometer.css" />
|
||||||
{/* Swiper Bundle.css */}
|
|
||||||
<link rel="stylesheet" href="/assets/css/swiper-bundle.min.css" />
|
<link rel="stylesheet" href="/assets/css/swiper-bundle.min.css" />
|
||||||
{/* Nice Select.css */}
|
|
||||||
<link rel="stylesheet" href="/assets/css/nice-select.css" />
|
<link rel="stylesheet" href="/assets/css/nice-select.css" />
|
||||||
{/* Main.css */}
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css" />
|
<link rel="stylesheet" href="/assets/css/main.css" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body className="smooth-scroll-yes">
|
<body className="smooth-scroll-yes">
|
||||||
<Loader />
|
<Loader />
|
||||||
<BackToTop />
|
<BackToTop />
|
||||||
<MouseCursor />
|
<MouseCursor />
|
||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
{children}
|
{children}
|
||||||
<Footer />
|
<Footer />
|
||||||
{/* Scripts */}
|
|
||||||
<Script
|
<Script src="/assets/js/jquery-3.7.1.min.js" strategy="beforeInteractive" />
|
||||||
src="/assets/js/jquery-3.7.1.min.js"
|
<Script src="/assets/js/viewport.jquery.js" strategy="afterInteractive" />
|
||||||
strategy="beforeInteractive"
|
<Script src="/assets/js/bootstrap.bundle.min.js" strategy="afterInteractive" />
|
||||||
/>
|
<Script src="/assets/js/jquery.nice-select.min.js" strategy="afterInteractive" />
|
||||||
<Script
|
<Script src="/assets/js/jquery.waypoints.js" strategy="afterInteractive" />
|
||||||
src="/assets/js/viewport.jquery.js"
|
|
||||||
strategy="afterInteractive"
|
|
||||||
/>
|
|
||||||
<Script
|
|
||||||
src="/assets/js/bootstrap.bundle.min.js"
|
|
||||||
strategy="afterInteractive"
|
|
||||||
/>
|
|
||||||
<Script
|
|
||||||
src="/assets/js/jquery.nice-select.min.js"
|
|
||||||
strategy="afterInteractive"
|
|
||||||
/>
|
|
||||||
<Script
|
|
||||||
src="/assets/js/jquery.waypoints.js"
|
|
||||||
strategy="afterInteractive"
|
|
||||||
/>
|
|
||||||
<Script src="/assets/js/odometer.min.js" strategy="afterInteractive" />
|
<Script src="/assets/js/odometer.min.js" strategy="afterInteractive" />
|
||||||
<Script
|
<Script src="/assets/js/swiper-bundle.min.js" strategy="afterInteractive" />
|
||||||
src="/assets/js/swiper-bundle.min.js"
|
<Script src="/assets/js/jquery.meanmenu.min.js" strategy="afterInteractive" />
|
||||||
strategy="afterInteractive"
|
<Script src="/assets/js/jquery.magnific-popup.min.js" strategy="afterInteractive" />
|
||||||
/>
|
|
||||||
<Script
|
|
||||||
src="/assets/js/jquery.meanmenu.min.js"
|
|
||||||
strategy="afterInteractive"
|
|
||||||
/>
|
|
||||||
<Script
|
|
||||||
src="/assets/js/jquery.magnific-popup.min.js"
|
|
||||||
strategy="afterInteractive"
|
|
||||||
/>
|
|
||||||
<Script src="/assets/js/wow.min.js" strategy="afterInteractive" />
|
<Script src="/assets/js/wow.min.js" strategy="afterInteractive" />
|
||||||
<Script src="/assets/js/gsap.js" strategy="afterInteractive" />
|
<Script src="/assets/js/gsap.js" strategy="afterInteractive" />
|
||||||
<Script src="/assets/js/lenis.min.js" strategy="afterInteractive" />
|
<Script src="/assets/js/lenis.min.js" strategy="afterInteractive" />
|
||||||
<Script
|
<Script src="/assets/js/ScrollTrigger.min.js" strategy="afterInteractive" />
|
||||||
src="/assets/js/ScrollTrigger.min.js"
|
|
||||||
strategy="afterInteractive"
|
|
||||||
/>
|
|
||||||
<Script src="/assets/js/SplitText.min.js" strategy="afterInteractive" />
|
<Script src="/assets/js/SplitText.min.js" strategy="afterInteractive" />
|
||||||
<Script src="/assets/js/main.js" strategy="afterInteractive" />
|
<Script src="/assets/js/main.js" strategy="afterInteractive" />
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user