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 { cookies } from 'next/headers';
|
||||
|
||||
@@ -16,7 +17,10 @@ export default async function RootLayout({
|
||||
|
||||
return (
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { quickLinks } from './quickLinks.const';
|
||||
import { whoAreWeLinks } from './whoAreWe.const';
|
||||
|
||||
export const footerMenu = {
|
||||
quickLinks,
|
||||
whoAreWeLinks,
|
||||
};
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
import { appConstants } from '..';
|
||||
import routeFactory from '../routeFactory';
|
||||
|
||||
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[];
|
||||
|
||||
@@ -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 routeFactory from './routeFactory';
|
||||
import socials from './socials';
|
||||
|
||||
export const appConstants = {
|
||||
routeFactory,
|
||||
footerMenu,
|
||||
socials,
|
||||
};
|
||||
|
||||
@@ -5,8 +5,20 @@ export default {
|
||||
title: t('pages_home_title'),
|
||||
route: () => '/',
|
||||
},
|
||||
products: {
|
||||
title: t('page_products_title'),
|
||||
route: () => '/products',
|
||||
},
|
||||
projects: {
|
||||
title: t('page_projects_title'),
|
||||
route: () => '/projects',
|
||||
},
|
||||
about: {
|
||||
title: t('pages_about_title'),
|
||||
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 aboutImg_1 from './about-img-1.png';
|
||||
import aboutImg_2 from './about-img-2.png';
|
||||
import homeProductBack from './home_product_back.jpeg';
|
||||
|
||||
export default {
|
||||
homeBanner,
|
||||
@@ -12,4 +13,5 @@ export default {
|
||||
factoryVector,
|
||||
aboutImg_1,
|
||||
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={`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="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_project_title: 'Project',
|
||||
pages_contact_description: 'Get in touch with us through this page',
|
||||
com_home_banner_title:'Excellence innovating',
|
||||
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_button:' Explore More',
|
||||
com_home_Banner_link1:' Advanced Manufacturing Solutions',
|
||||
com_home_Banner_link2:'Quality Assurance Systems',
|
||||
com_home_Banner_link3:'State-of-the-Art Technology',
|
||||
|
||||
|
||||
|
||||
|
||||
com_home_banner_title: 'Excellence innovating',
|
||||
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_button: ' Explore More',
|
||||
com_home_Banner_link1: ' Advanced Manufacturing Solutions',
|
||||
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_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. ',
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user