feat: add HomeStorySection component and ShowMoreIcon SVG icon

- Implemented HomeStorySection component to display project statistics and images.
- Added ShowMoreIcon component for UI enhancement.
This commit is contained in:
2025-06-03 10:45:10 +03:30
parent a5a287f11f
commit 05e50f0eee
20 changed files with 191 additions and 42 deletions
+30
View File
@@ -155,3 +155,33 @@
--color-black: var(--black); --color-black: var(--black);
--color-transparent: var(--transparent); --color-transparent: var(--transparent);
} }
.container {
width: 100%;
padding-inline: 10rem;
@media (width >=40rem) {
max-width: 40rem;
padding-inline: 1rem;
}
@media (width >=48rem) {
max-width: 48rem;
padding-inline: 1rem;
}
@media (width >=64rem) {
max-width: 64rem;
padding-inline: 3rem;
}
@media (width >=80rem) {
max-width: 80rem;
padding-inline: 5rem;
}
@media (width >=96rem) {
max-width: 96rem;
padding-inline: 8rem;
}
}
+2
View File
@@ -1,5 +1,6 @@
import Header from '@/components/layout/header'; import Header from '@/components/layout/header';
import AboutTopInfo from '@/components/pages/about/TopInfo'; import AboutTopInfo from '@/components/pages/about/TopInfo';
import HomeStorySection from '@/components/pages/home/HomeStorySection';
import HomePageProducts from '@/components/pages/home/Products'; import HomePageProducts from '@/components/pages/home/Products';
async function getData() { async function getData() {
@@ -15,6 +16,7 @@ export default async function Home() {
<Header /> <Header />
<AboutTopInfo /> <AboutTopInfo />
<HomePageProducts /> <HomePageProducts />
<HomeStorySection className="my-24" />
</main> </main>
); );
} }
+3 -3
View File
@@ -6,11 +6,11 @@ export default {
route: () => '/', route: () => '/',
}, },
products: { products: {
title: t('page_products_title'), title: t('pages_products_title'),
route: () => '/products', route: () => '/products',
}, },
projects: { projects: {
title: t('page_projects_title'), title: t('pages_projects_title'),
route: () => '/projects', route: () => '/projects',
}, },
about: { about: {
@@ -18,7 +18,7 @@ export default {
route: () => '/about-us', route: () => '/about-us',
}, },
contact: { contact: {
title: t('page_contact_title'), title: t('pages_contact_title'),
route: () => '/contact', route: () => '/contact',
}, },
}; };
+2
View File
@@ -5,6 +5,7 @@ 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'; import homeProductBack from './home_product_back.jpeg';
import whatWeDoImage from './what-we-do-image.png';
export default { export default {
homeBanner, homeBanner,
@@ -14,4 +15,5 @@ export default {
aboutImg_1, aboutImg_1,
aboutImg_2, aboutImg_2,
homeProductBack, homeProductBack,
whatWeDoImage,
}; };
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

@@ -1,3 +1,4 @@
import { Icon } from '@/components/uikit/icons';
import { IAachievementTextBoxProps } from './achievementTextBox'; import { IAachievementTextBoxProps } from './achievementTextBox';
export default function AchievementTextBox({ export default function AchievementTextBox({
@@ -5,6 +6,7 @@ export default function AchievementTextBox({
}: IAachievementTextBoxProps) { }: IAachievementTextBoxProps) {
return ( return (
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Icon name="achievement" className="text-primary" />
<span className="text-base text-gray-500">{title}</span> <span className="text-base text-gray-500">{title}</span>
</div> </div>
); );
+3 -1
View File
@@ -13,7 +13,9 @@ export default function FooterInfo({
className?: string; className?: string;
}) { }) {
return ( return (
<div className={`flex w-full flex-col gap-3 lg:w-auto ${className}`}> <div
className={`flex w-full flex-col gap-3 max-lg:text-center lg:w-auto ${className}`}
>
{withLogo && ( {withLogo && (
<Link href="/" className="mx-auto h-8 w-auto"> <Link href="/" className="mx-auto h-8 w-auto">
<Image <Image
+1 -1
View File
@@ -32,7 +32,7 @@ export default function Header() {
}} }}
/> />
<div> <div>
<Button endIcon={'x'}> <Button endIcon="showMore">
{t('com_home_banner_button') as string} {t('com_home_banner_button') as string}
</Button> </Button>
</div> </div>
@@ -1,6 +1,4 @@
import images from '@/assets/images/images';
import Navbar from '../../navbar'; import Navbar from '../../navbar';
import Button from '@/components/uikit/button';
import { IInnerPageBannerProps } from './banner'; import { IInnerPageBannerProps } from './banner';
export default function InnerPageBanner({ export default function InnerPageBanner({
+4 -4
View File
@@ -17,8 +17,8 @@
// { href: '/about', label: t('pages_about_title') as string }, // { href: '/about', label: t('pages_about_title') as string },
// { href: '/blog', label: t('pages_contact_title') as string }, // { href: '/blog', label: t('pages_contact_title') as string },
// { href: '/contact', label: t('pages_contact_title') as string }, // { href: '/contact', label: t('pages_contact_title') as string },
// { href: '/product', label: t('pages_product_title') as string }, // { href: '/product', label: t('pages_products_title') as string },
// { href: '/project', label: t('pages_project_title') as string }, // { href: '/project', label: t('pages_projects_title') as string },
// ]; // ];
// const linkClass = (href: string) => // const linkClass = (href: string) =>
@@ -104,8 +104,8 @@ export default function Navbar() {
{ href: '/about', label: t('pages_about_title') as string }, { href: '/about', label: t('pages_about_title') as string },
{ href: '/blog', label: t('pages_contact_title') as string }, { href: '/blog', label: t('pages_contact_title') as string },
{ href: '/contact', label: t('pages_contact_title') as string }, { href: '/contact', label: t('pages_contact_title') as string },
{ href: '/product', label: t('pages_product_title') as string }, { href: '/product', label: t('pages_products_title') as string },
{ href: '/project', label: t('pages_project_title') as string }, { href: '/project', label: t('pages_projects_title') as string },
]; ];
const linkClass = (href: string) => const linkClass = (href: string) =>
pathname === href ? 'text-primary font-semibold' : 'text-white'; pathname === href ? 'text-primary font-semibold' : 'text-white';
+4 -2
View File
@@ -1,3 +1,4 @@
import { Icon } from '@/components/uikit/icons';
import { ISectionTitleProps } from './sectionTitle'; import { ISectionTitleProps } from './sectionTitle';
export default function SectionTitle({ export default function SectionTitle({
@@ -11,9 +12,10 @@ export default function SectionTitle({
className={`flex flex-col gap-4 ${reverseColor ? 'text-white' : 'text-gray-500'}`} className={`flex flex-col gap-4 ${reverseColor ? 'text-white' : 'text-gray-500'}`}
> >
<div className={`flex items-center gap-2`}> <div className={`flex items-center gap-2`}>
<h3 className="text-sm tracking-[0.175rem]">{title}</h3> <Icon name="setting" className="text-primary" />
<h3 className="text-sm leading-1 tracking-[0.175rem]">{title}</h3>
</div> </div>
<h2 className="text-[3.25rem] font-extralight"> <h2 className="text-[3.25rem] leading-14 font-extralight tracking-tight">
{description} {description}
{description_bold && ( {description_bold && (
<strong className="block font-bold">{description_bold}</strong> <strong className="block font-bold">{description_bold}</strong>
+5 -3
View File
@@ -26,8 +26,8 @@ export default function AboutTopInfo() {
className="h-full w-full object-cover" className="h-full w-full object-cover"
/> />
</div> </div>
<div className="flex items-center justify-center gap-10 pb-5"> <div className="flex items-center justify-center gap-5 pb-5">
<span className="text-primary text-5xl">25 +</span> <span className="text-primary text-5xl">+25</span>
<span className="text-base text-gray-300"> <span className="text-base text-gray-300">
{t('com_about_info_years_experience') as string} {t('com_about_info_years_experience') as string}
</span> </span>
@@ -60,7 +60,9 @@ export default function AboutTopInfo() {
))} ))}
</div> </div>
<div className="mt-10"> <div className="mt-10">
<Button>{t('pages_contact_title') as string}</Button> <Button endIcon="showMore">
{t('pages_contact_title') as string}
</Button>
</div> </div>
</div> </div>
</div> </div>
@@ -0,0 +1,73 @@
import images from '@/assets/images/images';
import SectionTitle from '@/components/layout/sectionTitle';
import { t } from '@/locales/translates';
import Image from 'next/image';
export default function HomeStorySection({
className = '',
}: {
className?: string;
}) {
const statisticsData = [
{
title: t('com_home_story_projects_count') as string,
count: '10K',
},
{
title: t('com_home_story_customer_count') as string,
count: '500',
},
{
title: t('com_home_story_experience') as string,
count: '25',
},
];
return (
<div className={`container mx-auto flex flex-col gap-12 ${className}`}>
<div className="grid grid-cols-2 gap-10">
<SectionTitle
title={t('com_home_story_title') as string}
description={t('com_home_story_slogan') as string}
description_bold={t('com_home_story_slogan_bold') as string}
/>
<div className="grid grid-cols-2 gap-3">
{[images.homeBanner, images.aboutImg_1].map((e, i) => (
<div
className="aspect-video w-full overflow-hidden rounded-3xl"
key={i}
>
<Image src={e} alt="" className="w-full object-cover" />
</div>
))}
</div>
</div>
<div className="grid grid-cols-2 gap-10">
<div className="aspect-video w-full overflow-hidden rounded-3xl">
<Image
src={images.whatWeDoImage}
alt=""
className="h-full w-full object-cover"
/>
</div>
<div className="flex flex-col py-8">
<p className="text-base font-light text-gray-500">
{t('com_home_story_description') as string}
</p>
<hr className="my-10 text-gray-100/50" />
<div className="grid grid-cols-3 justify-between gap-1">
{statisticsData.map((stat, index) => (
<div key={index} className="flex flex-col gap-1">
<h3 className="text-primary text-2xl font-bold">
+{stat.count}
</h3>
<p className="text-sm text-gray-500">{stat.title}</p>
</div>
))}
</div>
</div>
</div>
</div>
);
}
+1 -1
View File
@@ -31,7 +31,7 @@ export default function HomePageProducts() {
<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">
<SectionTitle <SectionTitle
title={t('page_products_title') as string} title={t('pages_products_title') as string}
description={t('com_home_products_title') as string} description={t('com_home_products_title') as string}
reverseColor reverseColor
/> />
+10 -7
View File
@@ -1,14 +1,17 @@
export interface IBaseButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> { import { IconName } from '../icons';
export interface IBaseButtonProps
extends ButtonHTMLAttributes<HTMLButtonElement> {
children: ReactNode; children: ReactNode;
loading?: boolean; loading?: boolean;
disabled?: boolean; disabled?: boolean;
className?: string className?: string;
} }
export interface ITextButtonProps extends IBaseButtonProps{ export interface ITextButtonProps extends IBaseButtonProps {
endIcon?: ReactNode; endIcon?: IconName;
} }
export interface IIconButtonProps extends IBaseButtonProps{ export interface IIconButtonProps extends IBaseButtonProps {
color?: 'primary' | 'secondary' color?: 'primary' | 'secondary';
size?: 'small' | 'medium' | 'large' size?: 'small' | 'medium' | 'large';
} }
+5 -2
View File
@@ -1,6 +1,7 @@
'use client'; 'use client';
import React from 'react'; import React from 'react';
import { IIconButtonProps, ITextButtonProps } from './button'; import { IIconButtonProps, ITextButtonProps } from './button';
import { Icon } from '../icons';
const Button: React.FC<ITextButtonProps> = ({ const Button: React.FC<ITextButtonProps> = ({
children, children,
@@ -12,7 +13,7 @@ const Button: React.FC<ITextButtonProps> = ({
}) => { }) => {
return ( return (
<button <button
className={`group relative flex h-12 cursor-pointer rounded-[0.5625rem] bg-[#FA003F] p-px ${className || ''}`} className={`group bg-primary relative flex h-12 cursor-pointer rounded-[0.5625rem] p-[0.125rem] ${className || ''}`}
disabled={disabled || loading} disabled={disabled || loading}
{...props} {...props}
> >
@@ -46,7 +47,9 @@ const Button: React.FC<ITextButtonProps> = ({
</div> </div>
{endIcon && !loading ? ( {endIcon && !loading ? (
<span className="flex items-center justify-center p-3">{endIcon}</span> <span className="flex items-center justify-center p-3">
<Icon name={endIcon} className="text-white" />
</span>
) : null} ) : null}
</button> </button>
); );
+2
View File
@@ -5,6 +5,7 @@ import { SettingIcon } from './settingIcon';
import { AchievementIcon } from './achievementIcon'; import { AchievementIcon } from './achievementIcon';
import { PhoneIcon } from './phoneIcon'; import { PhoneIcon } from './phoneIcon';
import { InstagramIcon } from './instagramIcon'; import { InstagramIcon } from './instagramIcon';
import ShowMoreIcon from './showMoreIcon';
export const icons = { export const icons = {
close: CloseIcon, close: CloseIcon,
@@ -13,6 +14,7 @@ export const icons = {
achievement: AchievementIcon, achievement: AchievementIcon,
phone: PhoneIcon, phone: PhoneIcon,
instagram: InstagramIcon, instagram: InstagramIcon,
showMore: ShowMoreIcon,
}; };
export type IconName = keyof typeof icons; export type IconName = keyof typeof icons;
@@ -0,0 +1,21 @@
export default function ShowMoreIcon(props: React.SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
width="25"
height="26"
viewBox="0 0 25 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.50488 19.6178C7.20488 19.6178 7.00488 19.5121 6.80488 19.3009C6.40488 18.8785 6.40488 18.2448 6.80488 17.8224L16.8049 7.26141C17.2049 6.83897 17.8049 6.83897 18.2049 7.26141C18.6049 7.68385 18.6049 8.31751 18.2049 8.73995L8.20488 19.3009C8.00488 19.5121 7.80488 19.6178 7.50488 19.6178Z"
fill="currentColor"
/>
<path
d="M17.5049 18.5617C16.9049 18.5617 16.5049 18.1392 16.5049 17.5056V9.05678H8.50488C7.90488 9.05678 7.50488 8.63434 7.50488 8.00068C7.50488 7.36702 7.90488 6.94458 8.50488 6.94458H17.5049C18.1049 6.94458 18.5049 7.36702 18.5049 8.00068V17.5056C18.5049 18.1392 18.1049 18.5617 17.5049 18.5617Z"
fill="currentColor"
/>
</svg>
);
}
+12 -6
View File
@@ -4,9 +4,9 @@ const en = {
pages_about_title: 'About Us', pages_about_title: 'About Us',
pages_about_description: 'Learn more about us on this page', pages_about_description: 'Learn more about us on this page',
pages_contact_title: 'Contact Us', pages_contact_title: 'Contact Us',
pages_product_title: 'Product', pages_products_title: 'Products',
pages_blog_title: 'Blog', pages_blog_title: 'Blog',
pages_project_title: 'Project', pages_projects_title: 'Projects',
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',
@@ -31,10 +31,6 @@ const en = {
com_home_products_description: com_home_products_description:
'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_contact_title: 'Contact Us',
page_projects_title: 'Projects',
footer_title: 'Industrial Solutions for a Modern World', footer_title: 'Industrial Solutions for a Modern World',
footer_description: 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 todays competitive market.', '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 todays competitive market.',
@@ -45,6 +41,16 @@ const en = {
footer_links_contact: 'Contact', footer_links_contact: 'Contact',
footer_copyright: 'Copyright © 2025 All Rights Reserved.', footer_copyright: 'Copyright © 2025 All Rights Reserved.',
footer_links_address: '123 Industrial Ave, Suite 456, City, Country', footer_links_address: '123 Industrial Ave, Suite 456, City, Country',
// Home Page Components
com_home_story_title: 'Our Story',
com_home_story_slogan: 'Building quality through',
com_home_story_slogan_bold: 'industrial innovation',
com_home_story_description:
'We are a leading provider of industrial solutions, dedicated to delivering high-quality products and services that meet the unique needs of our clients. Our team of experts is committed to driving success in todays competitive market through innovation and excellence.',
com_home_story_projects_count: 'Completed Projects',
com_home_story_customer_count: 'Happy Customers',
com_home_story_experience: 'Years of Experience',
}; };
export default en; export default en;
+10 -9
View File
@@ -6,17 +6,18 @@ const fa = {
pages_about_title: 'About Us', pages_about_title: 'About Us',
pages_about_description: 'Learn more about us on this page', pages_about_description: 'Learn more about us on this page',
pages_contact_title: 'Contact Us', pages_contact_title: 'Contact Us',
pages_product_title: 'Product', pages_products_title: 'Product',
pages_blog_title: 'Blog', pages_blog_title: 'Blog',
pages_project_title: 'Project', pages_projects_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:'اطلاعات بیشتر', '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: 'اطلاعات بیشتر',
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',
} as Translates; } as Translates;
export default fa; export default fa;