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:
@@ -1,3 +1,4 @@
|
||||
import { Icon } from '@/components/uikit/icons';
|
||||
import { IAachievementTextBoxProps } from './achievementTextBox';
|
||||
|
||||
export default function AchievementTextBox({
|
||||
@@ -5,6 +6,7 @@ export default function AchievementTextBox({
|
||||
}: IAachievementTextBoxProps) {
|
||||
return (
|
||||
<div className="flex items-center gap-3">
|
||||
<Icon name="achievement" className="text-primary" />
|
||||
<span className="text-base text-gray-500">{title}</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -13,7 +13,9 @@ export default function FooterInfo({
|
||||
className?: string;
|
||||
}) {
|
||||
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 && (
|
||||
<Link href="/" className="mx-auto h-8 w-auto">
|
||||
<Image
|
||||
|
||||
@@ -32,7 +32,7 @@ export default function Header() {
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<Button endIcon={'x'}>
|
||||
<Button endIcon="showMore">
|
||||
{t('com_home_banner_button') as string}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import images from '@/assets/images/images';
|
||||
import Navbar from '../../navbar';
|
||||
import Button from '@/components/uikit/button';
|
||||
import { IInnerPageBannerProps } from './banner';
|
||||
|
||||
export default function InnerPageBanner({
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
// { href: '/about', label: t('pages_about_title') as string },
|
||||
// { href: '/blog', 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: '/project', label: t('pages_project_title') as string },
|
||||
// { href: '/product', label: t('pages_products_title') as string },
|
||||
// { href: '/project', label: t('pages_projects_title') as string },
|
||||
// ];
|
||||
|
||||
// const linkClass = (href: string) =>
|
||||
@@ -104,8 +104,8 @@ export default function Navbar() {
|
||||
{ href: '/about', label: t('pages_about_title') as string },
|
||||
{ href: '/blog', 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: '/project', label: t('pages_project_title') as string },
|
||||
{ href: '/product', label: t('pages_products_title') as string },
|
||||
{ href: '/project', label: t('pages_projects_title') as string },
|
||||
];
|
||||
const linkClass = (href: string) =>
|
||||
pathname === href ? 'text-primary font-semibold' : 'text-white';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Icon } from '@/components/uikit/icons';
|
||||
import { ISectionTitleProps } from './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'}`}
|
||||
>
|
||||
<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>
|
||||
<h2 className="text-[3.25rem] font-extralight">
|
||||
<h2 className="text-[3.25rem] leading-14 font-extralight tracking-tight">
|
||||
{description}
|
||||
{description_bold && (
|
||||
<strong className="block font-bold">{description_bold}</strong>
|
||||
|
||||
@@ -26,8 +26,8 @@ export default function AboutTopInfo() {
|
||||
className="h-full w-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-center gap-10 pb-5">
|
||||
<span className="text-primary text-5xl">25 +</span>
|
||||
<div className="flex items-center justify-center gap-5 pb-5">
|
||||
<span className="text-primary text-5xl">+25</span>
|
||||
<span className="text-base text-gray-300">
|
||||
{t('com_about_info_years_experience') as string}
|
||||
</span>
|
||||
@@ -60,7 +60,9 @@ export default function AboutTopInfo() {
|
||||
))}
|
||||
</div>
|
||||
<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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -31,7 +31,7 @@ export default function HomePageProducts() {
|
||||
<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">
|
||||
<SectionTitle
|
||||
title={t('page_products_title') as string}
|
||||
title={t('pages_products_title') as string}
|
||||
description={t('com_home_products_title') as string}
|
||||
reverseColor
|
||||
/>
|
||||
|
||||
+11
-8
@@ -1,14 +1,17 @@
|
||||
export interface IBaseButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
import { IconName } from '../icons';
|
||||
|
||||
export interface IBaseButtonProps
|
||||
extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
children: ReactNode;
|
||||
loading?: boolean;
|
||||
disabled?: boolean;
|
||||
className?: string
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export interface ITextButtonProps extends IBaseButtonProps{
|
||||
endIcon?: ReactNode;
|
||||
export interface ITextButtonProps extends IBaseButtonProps {
|
||||
endIcon?: IconName;
|
||||
}
|
||||
export interface IIconButtonProps extends IBaseButtonProps {
|
||||
color?: 'primary' | 'secondary';
|
||||
size?: 'small' | 'medium' | 'large';
|
||||
}
|
||||
export interface IIconButtonProps extends IBaseButtonProps{
|
||||
color?: 'primary' | 'secondary'
|
||||
size?: 'small' | 'medium' | 'large'
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
import React from 'react';
|
||||
import { IIconButtonProps, ITextButtonProps } from './button';
|
||||
import { Icon } from '../icons';
|
||||
|
||||
const Button: React.FC<ITextButtonProps> = ({
|
||||
children,
|
||||
@@ -12,7 +13,7 @@ const Button: React.FC<ITextButtonProps> = ({
|
||||
}) => {
|
||||
return (
|
||||
<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}
|
||||
{...props}
|
||||
>
|
||||
@@ -46,7 +47,9 @@ const Button: React.FC<ITextButtonProps> = ({
|
||||
</div>
|
||||
|
||||
{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}
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { SettingIcon } from './settingIcon';
|
||||
import { AchievementIcon } from './achievementIcon';
|
||||
import { PhoneIcon } from './phoneIcon';
|
||||
import { InstagramIcon } from './instagramIcon';
|
||||
import ShowMoreIcon from './showMoreIcon';
|
||||
|
||||
export const icons = {
|
||||
close: CloseIcon,
|
||||
@@ -13,6 +14,7 @@ export const icons = {
|
||||
achievement: AchievementIcon,
|
||||
phone: PhoneIcon,
|
||||
instagram: InstagramIcon,
|
||||
showMore: ShowMoreIcon,
|
||||
};
|
||||
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user