forked from UKSOURCE/hailearning.edu.vn
refactor json header, footer, home and styling ui
This commit is contained in:
@@ -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'
|
|
||||||
},
|
interface MenuItem {
|
||||||
{
|
label: string;
|
||||||
label: 'Pages',
|
href: string;
|
||||||
href: '#',
|
submenu?: MenuItem[];
|
||||||
submenu: [
|
megaMenuContent?: React.ReactNode;
|
||||||
{
|
}
|
||||||
label: 'Service',
|
|
||||||
href: '#',
|
// We need to recursively map 'children' to 'submenu'
|
||||||
submenu: [
|
const mapMenuItems = (items: JsonMenuItem[]): MenuItem[] => {
|
||||||
{ label: 'Service', href: '/service' },
|
return items.map(item => {
|
||||||
{ label: 'Service Details', href: '/service-details' }
|
const newItem: MenuItem = {
|
||||||
]
|
label: item.label,
|
||||||
},
|
href: item.href,
|
||||||
{
|
};
|
||||||
label: 'Country List',
|
|
||||||
href: '#',
|
|
||||||
submenu: [
|
|
||||||
{ label: 'Country List', href: '/country-list' },
|
if (item.children && item.children.length > 0) {
|
||||||
{ label: 'Country Details', href: '/country-details' }
|
newItem.submenu = mapMenuItems(item.children);
|
||||||
]
|
|
||||||
},
|
|
||||||
{ 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 = () => {
|
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,9 @@
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import headerData from './header.json';
|
||||||
|
|
||||||
const HeaderTop = () => {
|
const HeaderTop = () => {
|
||||||
|
const { phone, email, location, socialLinks, languages } = headerData.top;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="header-top-section">
|
<div className="header-top-section">
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
@@ -10,20 +13,20 @@ 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>
|
||||||
|
|
||||||
<div className="header-right">
|
<div className="header-right">
|
||||||
<div className="flag-wrap">
|
<div className="flag-wrap">
|
||||||
@@ -32,26 +35,27 @@ const HeaderTop = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="nice-select" tabIndex={0}>
|
<div className="nice-select" tabIndex={0}>
|
||||||
<span className="current">
|
<span className="current">
|
||||||
English
|
{languages[0]?.name || 'English'}
|
||||||
</span>
|
</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",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user