feat: add footer components including FooterInfo, FooterMenuBuilder, and FooterMenuBuilderWrapper
- Implemented FooterInfo component to display logo, slogan, and social links. - Created FooterMenuBuilder component for rendering a list of links with a title. - Added FooterMenuBuilderWrapper to encapsulate the layout for menu items.
This commit is contained in:
+5
-1
@@ -1,3 +1,4 @@
|
|||||||
|
import Footer from '@/components/layout/footer/Footer';
|
||||||
import './globals.css';
|
import './globals.css';
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
|
|
||||||
@@ -16,7 +17,10 @@ export default async function RootLayout({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={locale} dir={locale === 'fa' ? 'rtl' : 'ltr'}>
|
<html lang={locale} dir={locale === 'fa' ? 'rtl' : 'ltr'}>
|
||||||
<body className="min-h-svh w-full overflow-x-hidden">{children}</body>
|
<body className="min-h-svh w-full overflow-x-hidden">
|
||||||
|
{children}
|
||||||
|
<Footer />
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { quickLinks } from './quickLinks.const';
|
import { quickLinks } from './quickLinks.const';
|
||||||
|
import { whoAreWeLinks } from './whoAreWe.const';
|
||||||
|
|
||||||
export const footerMenu = {
|
export const footerMenu = {
|
||||||
quickLinks,
|
quickLinks,
|
||||||
|
whoAreWeLinks,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,16 @@
|
|||||||
import { appConstants } from '..';
|
import routeFactory from '../routeFactory';
|
||||||
|
|
||||||
export const quickLinks = [
|
export const quickLinks = [
|
||||||
{
|
{
|
||||||
title: appConstants.routeFactory.home.title,
|
title: routeFactory.home.title,
|
||||||
|
link: routeFactory.home.route(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: routeFactory.products.title,
|
||||||
|
link: routeFactory.products.route(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: routeFactory.projects.title,
|
||||||
|
link: routeFactory.projects.route(),
|
||||||
},
|
},
|
||||||
] as any[];
|
] as any[];
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import routeFactory from '../routeFactory';
|
||||||
|
|
||||||
|
export const whoAreWeLinks = [
|
||||||
|
{
|
||||||
|
title: routeFactory.about.title,
|
||||||
|
link: routeFactory.about.route(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: routeFactory.contact.title,
|
||||||
|
link: routeFactory.contact.route(),
|
||||||
|
},
|
||||||
|
] as any[];
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import { footerMenu } from './footerMenu';
|
import { footerMenu } from './footerMenu';
|
||||||
import routeFactory from './routeFactory';
|
import routeFactory from './routeFactory';
|
||||||
|
import socials from './socials';
|
||||||
|
|
||||||
export const appConstants = {
|
export const appConstants = {
|
||||||
routeFactory,
|
routeFactory,
|
||||||
footerMenu,
|
footerMenu,
|
||||||
|
socials,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,8 +5,20 @@ export default {
|
|||||||
title: t('pages_home_title'),
|
title: t('pages_home_title'),
|
||||||
route: () => '/',
|
route: () => '/',
|
||||||
},
|
},
|
||||||
|
products: {
|
||||||
|
title: t('page_products_title'),
|
||||||
|
route: () => '/products',
|
||||||
|
},
|
||||||
|
projects: {
|
||||||
|
title: t('page_projects_title'),
|
||||||
|
route: () => '/projects',
|
||||||
|
},
|
||||||
about: {
|
about: {
|
||||||
title: t('pages_about_title'),
|
title: t('pages_about_title'),
|
||||||
route: () => '/about-us',
|
route: () => '/about-us',
|
||||||
},
|
},
|
||||||
|
contact: {
|
||||||
|
title: t('page_contact_title'),
|
||||||
|
route: () => '/contact',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export default [
|
||||||
|
{
|
||||||
|
title: 'instagram',
|
||||||
|
link: 'https://www.instagram.com/yourprofile',
|
||||||
|
},
|
||||||
|
];
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
@@ -4,6 +4,7 @@ import aboutBanner from './about_banner.png';
|
|||||||
import factoryVector from './factory_vector.png';
|
import factoryVector from './factory_vector.png';
|
||||||
import aboutImg_1 from './about-img-1.png';
|
import aboutImg_1 from './about-img-1.png';
|
||||||
import aboutImg_2 from './about-img-2.png';
|
import aboutImg_2 from './about-img-2.png';
|
||||||
|
import homeProductBack from './home_product_back.jpeg';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
homeBanner,
|
homeBanner,
|
||||||
@@ -12,4 +13,5 @@ export default {
|
|||||||
factoryVector,
|
factoryVector,
|
||||||
aboutImg_1,
|
aboutImg_1,
|
||||||
aboutImg_2,
|
aboutImg_2,
|
||||||
|
homeProductBack,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import images from '@/assets/images/images';
|
||||||
|
import { t } from '@/locales/translates';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import FooterMenuBuilder from './FooterMenuBuilder';
|
||||||
|
import { appConstants } from '@/assets/constants';
|
||||||
|
import FooterMenuBuilderWrapper from './FooterMenuBuilderWrapper';
|
||||||
|
import FooterInfo from './FooterInfo';
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<div className="relative w-full bg-gray-500 pt-24 text-white">
|
||||||
|
<div className="absolute inset-0 z-10 flex items-end justify-start">
|
||||||
|
<div className="w-1/2 md:w-2/5">
|
||||||
|
<Image
|
||||||
|
alt="footer-bg"
|
||||||
|
src={images.factoryVector}
|
||||||
|
className="h-full w-full object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="relative z-20 container mx-auto">
|
||||||
|
<div className="flex max-w-[920px] flex-col gap-5 pb-10">
|
||||||
|
<p className="text-5xl tracking-tighter">
|
||||||
|
{t('footer_title') as string}
|
||||||
|
</p>
|
||||||
|
<h5 className="text-base tracking-normal">
|
||||||
|
{t('footer_description') as string}
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-start justify-between gap-8 border-y border-gray-300/50 py-14 max-lg:flex-col-reverse">
|
||||||
|
<FooterInfo withLogo className="lg:max-w-[200px]" />
|
||||||
|
<div className="grid w-full grid-cols-2 gap-5 md:grid-cols-3 md:gap-10 lg:max-w-3/5">
|
||||||
|
<FooterMenuBuilder
|
||||||
|
title={t('footer_links_quick_links') as string}
|
||||||
|
links={appConstants.footerMenu.quickLinks}
|
||||||
|
className="max-md:text-center"
|
||||||
|
/>
|
||||||
|
<FooterMenuBuilder
|
||||||
|
title={t('footer_links_who_we_are') as string}
|
||||||
|
links={appConstants.footerMenu.whoAreWeLinks}
|
||||||
|
className="max-md:text-center"
|
||||||
|
/>
|
||||||
|
<FooterMenuBuilderWrapper
|
||||||
|
title={t('footer_links_contact') as string}
|
||||||
|
className="max-md:col-span-2 max-md:text-center"
|
||||||
|
>
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<Link
|
||||||
|
href="tel:+9812345678"
|
||||||
|
className="text-sm tracking-tight text-gray-100 hover:text-gray-200"
|
||||||
|
>
|
||||||
|
+98 12345678
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="mailto:info@sample.com"
|
||||||
|
className="text-sm tracking-tight text-gray-100 hover:text-gray-200"
|
||||||
|
>
|
||||||
|
info@sample.com
|
||||||
|
</Link>
|
||||||
|
<span className="text-sm tracking-tight text-gray-100 hover:text-gray-200">
|
||||||
|
{t('footer_links_address') as string}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</FooterMenuBuilderWrapper>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="py-8 lg:py-14">
|
||||||
|
<p className="text-center text-sm">
|
||||||
|
{t('footer_copyright') as string}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { appConstants } from '@/assets/constants';
|
||||||
|
import images from '@/assets/images/images';
|
||||||
|
import { t } from '@/locales/translates';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
export default function FooterInfo({
|
||||||
|
withLogo,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
withLogo?: boolean;
|
||||||
|
className?: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className={`flex w-full flex-col gap-3 lg:w-auto ${className}`}>
|
||||||
|
{withLogo && (
|
||||||
|
<Link href="/" className="mx-auto h-8 w-auto">
|
||||||
|
<Image
|
||||||
|
alt="logo"
|
||||||
|
src={images.logo}
|
||||||
|
className="h-full w-auto object-contain"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<p className="text-sm tracking-normal">{t('footer_slogan') as string}</p>
|
||||||
|
<div className="flex items-center gap-4 max-lg:justify-center">
|
||||||
|
{appConstants.socials.map((social) => (
|
||||||
|
<Link
|
||||||
|
href={social.link}
|
||||||
|
key={social.title}
|
||||||
|
className="text-white lg:flex-1"
|
||||||
|
>
|
||||||
|
{/* <Image
|
||||||
|
alt={social.title}
|
||||||
|
src={images[social.title]}
|
||||||
|
className="h-6 w-6 object-contain"
|
||||||
|
/> */}
|
||||||
|
{social.title}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import Link from 'next/link';
|
||||||
|
import FooterMenuBuilderWrapper from './FooterMenuBuilderWrapper';
|
||||||
|
|
||||||
|
export default function FooterMenuBuilder({
|
||||||
|
title,
|
||||||
|
links,
|
||||||
|
className = '',
|
||||||
|
}: {
|
||||||
|
title: string;
|
||||||
|
links: { title: string; link: string }[];
|
||||||
|
className?: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<FooterMenuBuilderWrapper title={title} className={className}>
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
{links.map((link) => (
|
||||||
|
<Link
|
||||||
|
title={link.title}
|
||||||
|
href={link.link}
|
||||||
|
className="text-sm tracking-tight text-gray-100 hover:text-gray-200"
|
||||||
|
key={link.title}
|
||||||
|
>
|
||||||
|
{link.title}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</FooterMenuBuilderWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
export default function FooterMenuBuilderWrapper({
|
||||||
|
title,
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
title: string;
|
||||||
|
children: React.ReactNode;
|
||||||
|
className: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className={`flex flex-col gap-6 ${className}`}>
|
||||||
|
<span className="text-lg tracking-tight">{title}</span>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@ export default function HomePageProducts() {
|
|||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div
|
<div
|
||||||
className={`relative w-full bg-cover bg-fixed bg-center bg-no-repeat pt-28 pb-48`}
|
className={`relative w-full bg-cover bg-fixed bg-center bg-no-repeat pt-28 pb-48`}
|
||||||
style={{ backgroundImage: `url(${images.homeBanner.src})` }}
|
style={{ backgroundImage: `url(${images.homeProductBack.src})` }}
|
||||||
>
|
>
|
||||||
<div className="absolute inset-0 z-10 bg-black opacity-50" />
|
<div className="absolute inset-0 z-10 bg-black opacity-50" />
|
||||||
<div className="relative z-20 container mx-auto grid grid-cols-2 gap-28">
|
<div className="relative z-20 container mx-auto grid grid-cols-2 gap-28">
|
||||||
|
|||||||
+21
-11
@@ -8,17 +8,14 @@ const en = {
|
|||||||
pages_blog_title: 'Blog',
|
pages_blog_title: 'Blog',
|
||||||
pages_project_title: 'Project',
|
pages_project_title: 'Project',
|
||||||
pages_contact_description: 'Get in touch with us through this page',
|
pages_contact_description: 'Get in touch with us through this page',
|
||||||
com_home_banner_title:'Excellence innovating',
|
com_home_banner_title: 'Excellence innovating',
|
||||||
com_home_banner_title_bold:'industry for today',
|
com_home_banner_title_bold: 'industry for today',
|
||||||
com_home_banner_description:'At the heart of our operations is a commitment to delivering superior products through cutting- <br/> edge technology and innovative processes. ',
|
com_home_banner_description:
|
||||||
com_home_banner_button:' Explore More',
|
'At the heart of our operations is a commitment to delivering superior products through cutting- <br/> edge technology and innovative processes. ',
|
||||||
com_home_Banner_link1:' Advanced Manufacturing Solutions',
|
com_home_banner_button: ' Explore More',
|
||||||
com_home_Banner_link2:'Quality Assurance Systems',
|
com_home_Banner_link1: ' Advanced Manufacturing Solutions',
|
||||||
com_home_Banner_link3:'State-of-the-Art Technology',
|
com_home_Banner_link2: 'Quality Assurance Systems',
|
||||||
|
com_home_Banner_link3: 'State-of-the-Art Technology',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
com_about_info_title: 'Building quality through',
|
com_about_info_title: 'Building quality through',
|
||||||
com_about_info_title_bold: 'industrial innovation',
|
com_about_info_title_bold: 'industrial innovation',
|
||||||
@@ -35,6 +32,19 @@ const en = {
|
|||||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ',
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ',
|
||||||
|
|
||||||
page_products_title: 'Products',
|
page_products_title: 'Products',
|
||||||
|
page_contact_title: 'Contact Us',
|
||||||
|
page_projects_title: 'Projects',
|
||||||
|
|
||||||
|
footer_title: 'Industrial Solutions for a Modern World',
|
||||||
|
footer_description:
|
||||||
|
'We are committed to providing personalized industrial solutions that meet the unique needs of our clients. Our team of experts is dedicated to delivering high-quality products and services that drive success in today’s competitive market.',
|
||||||
|
footer_slogan:
|
||||||
|
'We are committed to providing personalized industrial solutions.',
|
||||||
|
footer_links_quick_links: 'Quick Links',
|
||||||
|
footer_links_who_we_are: 'Who We Are',
|
||||||
|
footer_links_contact: 'Contact',
|
||||||
|
footer_copyright: 'Copyright © 2025 All Rights Reserved.',
|
||||||
|
footer_links_address: '123 Industrial Ave, Suite 456, City, Country',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default en;
|
export default en;
|
||||||
|
|||||||
Reference in New Issue
Block a user