Merge remote-tracking branch 'origin/navbar'

This commit is contained in:
2025-06-10 15:59:38 +03:30
18 changed files with 515 additions and 35 deletions
+18
View File
@@ -0,0 +1,18 @@
[
{
"first_name": "asd",
"last_name": "asd",
"phone": "123213123213",
"email": "asd@asd.asd",
"message": "asdad",
"createdAt": "2025-06-09T12:36:14.614Z"
},
{
"first_name": "fvgvbfc",
"last_name": "fcfvgf",
"phone": "09876535434234",
"email": "Zsddftgf@fgh.ir",
"message": "ggbghdghfrgb",
"createdAt": "2025-06-09T13:32:58.185Z"
}
]
+11
View File
@@ -78,6 +78,17 @@ declare const messages: {
"com_contact_phone": "Enter your phone no.", "com_contact_phone": "Enter your phone no.",
"com_contact_textarea": "Write Message", "com_contact_textarea": "Write Message",
"com_contact_first_name_required": "Name is required",
"com_contact_last_name_required": "Last name is required",
"com_contact_email_required": "Email is required",
"com_contact_phone_required": "Phone is required",
"com_contact_textarea_required": "Message is required",
"com_contact_email_error": "Email is not valid",
"com_contact_phone_error": "The contact number is not valid (for example: 09123456789)",
"com_contact_textarea_error": "Message must be at least 10 characters long.",
"com_contact_button_submit": "Submit Message",
"pages_notFound_title": "404 Not Found Page", "pages_notFound_title": "404 Not Found Page",
"pages_notFound_description": "You can either head back to the Homepage or try a search.", "pages_notFound_description": "You can either head back to the Homepage or try a search.",
"pages_notFound_button":"Go To Home" "pages_notFound_button":"Go To Home"
+11
View File
@@ -75,6 +75,17 @@
"com_contact_phone": "Enter your phone no.", "com_contact_phone": "Enter your phone no.",
"com_contact_textarea": "Write Message", "com_contact_textarea": "Write Message",
"com_contact_first_name_required": "Name is required",
"com_contact_last_name_required": "Last name is required",
"com_contact_email_required": "Email is required",
"com_contact_phone_required": "Phone is required",
"com_contact_textarea_required": "Message is required",
"com_contact_email_error": "Email is not valid",
"com_contact_phone_error": "The contact number is not valid (for example: 09123456789)",
"com_contact_textarea_error": "Message must be at least 10 characters long.",
"com_contact_button_submit": "Submit Message",
"pages_notFound_title": "404 Not Found Page", "pages_notFound_title": "404 Not Found Page",
"pages_notFound_description": "You can either head back to the Homepage or try a search.", "pages_notFound_description": "You can either head back to the Homepage or try a search.",
"pages_notFound_button":"Go To Home" "pages_notFound_button":"Go To Home"
+23 -1
View File
@@ -56,7 +56,29 @@
"pages_products_content_description": "آجرها به عنوان یکی از قدیمی‌ترین و پرکاربردترین مصالح ساختمانی بشر، در طول تاریخ دچار تحول زیادی شده‌اند. امروزه این مصالح در طیف بسیار متنوعی تولید و عرضه می‌شوند و به مهندسان و معماران این امکان را می‌دهند تا مناسب‌ترین آجر را برای هر پروژه و نیازی، از سازه‌های سنتی و تاریخی تا ساختمان‌های مدرن و پیشرفته، انتخاب کنند. برای درک بهتر این تنوع، می‌توان آجرها را بر اساس چند معیار کلیدی طبقه‌بندی کرد که هر یک ویژگی‌ها و کاربردهای خاص خود را دارند.\n۱. طبقه‌بندی بر اساس روش تولید: از سنت تا صنعت پیشرفته\nروش تولید آجرها مستقیماً بر ظاهر، بافت و ویژگی‌های آن‌ها تأثیر می‌گذارد.\nآجرهای دستی/قالبی: این آجرها با فشار دادن دستی خاک رس در قالب تولید می‌شوند. نتیجه، آجری با بافت نسبتاً زبر، لبه‌های نامنظم و ظاهری سنتی‌تر است که هر قطعه حس منحصر به فردی دارد. این نوع آجر اغلب برای پروژه‌های مرمت یا ساخت ساختمان‌هایی با سبک روستایی یا قدیمی استفاده می‌شود.\nآجرهای ماشینی: این آجرها با استفاده از ماشین‌آلات صنعتی تولید می‌شوند که دقت ابعادی و یکنواختی ظاهری بسیار بالاتری دارند. آجرهای ماشینی خود به دو دسته اصلی تقسیم می‌شوند:\nآجرهای سوراخ‌دار/توخالی: این آجرها دارای سوراخ‌هایی هستند که چندین مزیت دارند: کاهش وزن ساختمان، بهبود عایق حرارتی و صوتی و افزایش چسبندگی ملات.\nآجرهای توپر: این آجرها بدون سوراخ بوده و مقاومت فشاری بسیار بالایی دارند. آن‌ها برای سازه‌های باربر و دیوارهایی که به حداکثر استحکام نیاز دارند، ایده‌آل هستند.\n۲. طبقه‌بندی بر اساس نوع و ترکیب مواد اولیه: از خاک رس تا بتن\nجنس آجر تعیین‌کننده ویژگی‌های فیزیکی و شیمیایی آن است.", "pages_products_content_description": "آجرها به عنوان یکی از قدیمی‌ترین و پرکاربردترین مصالح ساختمانی بشر، در طول تاریخ دچار تحول زیادی شده‌اند. امروزه این مصالح در طیف بسیار متنوعی تولید و عرضه می‌شوند و به مهندسان و معماران این امکان را می‌دهند تا مناسب‌ترین آجر را برای هر پروژه و نیازی، از سازه‌های سنتی و تاریخی تا ساختمان‌های مدرن و پیشرفته، انتخاب کنند. برای درک بهتر این تنوع، می‌توان آجرها را بر اساس چند معیار کلیدی طبقه‌بندی کرد که هر یک ویژگی‌ها و کاربردهای خاص خود را دارند.\n۱. طبقه‌بندی بر اساس روش تولید: از سنت تا صنعت پیشرفته\nروش تولید آجرها مستقیماً بر ظاهر، بافت و ویژگی‌های آن‌ها تأثیر می‌گذارد.\nآجرهای دستی/قالبی: این آجرها با فشار دادن دستی خاک رس در قالب تولید می‌شوند. نتیجه، آجری با بافت نسبتاً زبر، لبه‌های نامنظم و ظاهری سنتی‌تر است که هر قطعه حس منحصر به فردی دارد. این نوع آجر اغلب برای پروژه‌های مرمت یا ساخت ساختمان‌هایی با سبک روستایی یا قدیمی استفاده می‌شود.\nآجرهای ماشینی: این آجرها با استفاده از ماشین‌آلات صنعتی تولید می‌شوند که دقت ابعادی و یکنواختی ظاهری بسیار بالاتری دارند. آجرهای ماشینی خود به دو دسته اصلی تقسیم می‌شوند:\nآجرهای سوراخ‌دار/توخالی: این آجرها دارای سوراخ‌هایی هستند که چندین مزیت دارند: کاهش وزن ساختمان، بهبود عایق حرارتی و صوتی و افزایش چسبندگی ملات.\nآجرهای توپر: این آجرها بدون سوراخ بوده و مقاومت فشاری بسیار بالایی دارند. آن‌ها برای سازه‌های باربر و دیوارهایی که به حداکثر استحکام نیاز دارند، ایده‌آل هستند.\n۲. طبقه‌بندی بر اساس نوع و ترکیب مواد اولیه: از خاک رس تا بتن\nجنس آجر تعیین‌کننده ویژگی‌های فیزیکی و شیمیایی آن است.",
"com_products_products_category_title": "محصولات دسته {title}", "com_products_products_category_title": "محصولات دسته {title}",
"com_contact_touch_title": "با ما تماس بگیرید",
"com_contact_touch_title_bold": "",
"com_contact_touch_description": "برای هرگونه سوال، پشتیبانی یا بحث در مورد چگونگی رفع نیازهای صنعتی خود با ما تماس بگیرید.",
"com_contact_touch_option_1":"تماس بگیرید",
"com_contact_touch_option_2":"ایمیل",
"com_contact_touch_option_3":"آدرس ما",
"com_contact_touch_option_3_description":"خیابان سن خوان، پلاک ۷، گراف، فلوریسترات ۲۲A، کد پستی ۳۰۲۱",
"com_contact_title": "با ما تماس بگیرید",
"com_contact_title_bold": "",
"com_contact_first_name": "نام خود را وارد کنید",
"com_contact_last_name": "نام خانوادگی خود را وارد کنید",
"com_contact_email": "ایمیل خود را وارد کنید.",
"com_contact_phone": "شماره تلفن خود را وارد کنید.",
"com_contact_textarea": "پیام خود را وارد کنید",
"com_contact_first_name_required": "نام الزامی است",
"com_contact_last_name_required": "نام خانوادگی الزامی است",
"com_contact_email_required": "ایمیل الزامی است",
"com_contact_phone_required": "شماره تلفن الزامی است",
"com_contact_textarea_required": "پیام الزامی است",
"com_contact_email_error": "ایمیل معتبر نیست",
"com_contact_phone_error": "شماره تماس معتبر نیست (مثلاً: 09123456789)",
"com_contact_textarea_error": "پیام باید حداقل ۱۰ کاراکتر باشد",
"com_contact_button_submit": "ارسال پیام",
"pages_notFound_title": "صفحه ۴۰۴ پیدا نشد", "pages_notFound_title": "صفحه ۴۰۴ پیدا نشد",
"pages_notFound_description": "صفحه‌ای که به دنبال آن هستید وجود ندارد یا منتقل شده است. لطفاً آدرس را بررسی کنید یا به صفحه اصلی بازگردید.", "pages_notFound_description": "صفحه‌ای که به دنبال آن هستید وجود ندارد یا منتقل شده است. لطفاً آدرس را بررسی کنید یا به صفحه اصلی بازگردید.",
"pages_notFound_button": "بازگشت به صفحه اصلی" "pages_notFound_button": "بازگشت به صفحه اصلی"
+1 -1
View File
@@ -20,7 +20,7 @@ export default async function Contact({ params }: { params: IPageParams }) {
/> />
<div className="relative flex w-full flex-col bg-gray-200 pt-4 md:pt-28"> <div className="relative flex w-full flex-col bg-gray-200 pt-4 md:pt-28">
<div className="absolute inset-x-0 inset-y-64 z-10 flex items-end justify-start"> <div className="absolute inset-x-0 inset-y-64 z-2 flex items-end justify-start">
<div className="max-md:hidden md:w-1/2"> <div className="max-md:hidden md:w-1/2">
<Image <Image
alt="footer-bg" alt="footer-bg"
+2
View File
@@ -2,6 +2,7 @@ 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 HomeStorySection from '@/components/pages/home/HomeStorySection';
import HomePageProducts from '@/components/pages/home/Products'; import HomePageProducts from '@/components/pages/home/Products';
import HomePageProjects from '@/components/pages/home/Projects';
import type { IPageParams } from '@/models/layout.d'; import type { IPageParams } from '@/models/layout.d';
import { getTranslations } from 'next-intl/server'; import { getTranslations } from 'next-intl/server';
@@ -15,6 +16,7 @@ export default async function Home({ params }: { params: IPageParams }) {
<Header /> <Header />
<AboutTopInfo /> <AboutTopInfo />
<HomePageProducts locale={locale} /> <HomePageProducts locale={locale} />
<HomePageProjects locale={locale} />
<HomeStorySection className="my-24" /> <HomeStorySection className="my-24" />
</main> </main>
); );
@@ -7,6 +7,7 @@ const filePath = path.resolve(process.cwd(), 'contactMessages.json');
export async function POST(request: NextRequest) { export async function POST(request: NextRequest) {
try { try {
const body = await request.json(); const body = await request.json();
console.log(body)
const { first_name, last_name, phone, email, message } = body; const { first_name, last_name, phone, email, message } = body;
if (!first_name || !last_name || !phone || !email || !message) { if (!first_name || !last_name || !phone || !email || !message) {
@@ -25,7 +26,9 @@ export async function POST(request: NextRequest) {
} }
const newMessage = { const newMessage = {
name, first_name,
last_name,
phone,
email, email,
message, message,
createdAt: new Date().toISOString(), createdAt: new Date().toISOString(),
@@ -41,6 +44,8 @@ export async function POST(request: NextRequest) {
message: 'Your message has been received.', message: 'Your message has been received.',
}); });
} catch (error) { } catch (error) {
console.log(error)
console.log(error)
return NextResponse.json( return NextResponse.json(
{ error, message: 'مشکلی پیش آمده.' }, { error, message: 'مشکلی پیش آمده.' },
{ status: 400 }, { status: 400 },
+118
View File
@@ -0,0 +1,118 @@
export const productCategories = [
{
id: '1',
title: 'Ghazaghi',
fa_title: 'قزاقی',
icon: 'categoryGhazaghi',
typesCount: 22,
priceTypeTitle: 'Economy',
fa_priceTypeTitle: 'اقتصادی',
bestForTitle: 'Best For Interior Part',
fa_bestForTitle: 'Best For Interior Part',
fa_description: `Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features`,
description: `Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features`,
},
{
id: '2',
title: 'Ghermez',
fa_title: 'قرمز',
icon: 'categoryGhermez',
typesCount: 12,
priceTypeTitle: 'Luxury',
fa_priceTypeTitle: 'لاکچری',
bestForTitle: 'Best For Exterior Part',
fa_bestForTitle: 'Best For Exterior Part',
fa_description: `Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features`,
description: `Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features`,
},
{
id: '3',
title: 'oryZard',
fa_title: 'زرد',
icon: 'categoryZard',
typesCount: 11,
priceTypeTitle: 'Economy',
fa_priceTypeTitle: 'اقتصادی',
bestForTitle: 'Best For Facing',
fa_bestForTitle: 'Best For Facing',
fa_description: `Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features`,
description: `Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features`,
},
{
id: '40',
title: 'Semirom',
fa_title: 'سمیرم',
icon: 'categorySemirom',
typesCount: 40,
priceTypeTitle: 'Economy',
fa_priceTypeTitle: 'اقتصادی',
bestForTitle: 'Best For Building',
fa_bestForTitle: 'Best For Building',
fa_description: `Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features`,
description: `Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features`,
},
] as APIProductCategoryEntity[];
interface APIProductCategoryEntity {
id: string;
title: string;
fa_title?: string;
icon: string;
typesCount: number;
priceTypeTitle: string;
fa_priceTypeTitle?: string;
bestForTitle: string;
fa_bestForTitle?: string;
fa_description?: `Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features`;
description?: `Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
Facing Bricks: Characteristics and Features`;
}
+51
View File
@@ -0,0 +1,51 @@
import { NextResponse } from 'next/server';
import { cookies } from 'next/headers';
import { productCategories } from './data';
export async function GET(request: Request) {
let data = productCategories;
const cookieStore = await cookies();
const lang = (await cookieStore).get('lang')?.value || 'fa';
if (lang === 'fa') {
data = productCategories.map(
({
id,
title,
fa_title,
icon,
typesCount,
priceTypeTitle,
fa_priceTypeTitle,
bestForTitle,
fa_bestForTitle,
description,
fa_description,
}) => {
if (lang === 'fa') {
return {
id,
icon,
typesCount,
title: fa_title || title,
priceTypeTitle: fa_priceTypeTitle || priceTypeTitle,
bestForTitle: fa_bestForTitle || bestForTitle,
description: fa_description || description,
};
}
return {
id,
icon,
typesCount,
title,
priceTypeTitle,
bestForTitle,
description,
};
},
);
}
return NextResponse.json({ data: productCategories });
}
+125 -9
View File
@@ -1,32 +1,148 @@
'use client'; 'use client';
import { useState } from 'react';
import Button from '@/components/uikit/button'; import Button from '@/components/uikit/button';
import FormField from '@/components/uikit/inputs'; import FormField from '@/components/uikit/inputs';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import api from '@/lib/axios';
import { setContact } from '@/services/contact';
const ContactForm = () => { const ContactForm = () => {
const t = useTranslations(); const t = useTranslations();
const [formData, setFormData] = useState({
first_name: '',
last_name: '',
email: '',
phone: '',
message: '',
});
const [errors, setErrors] = useState<Record<string, string>>({});
const [loading, setLoading] = useState(false);
const validate = () => {
const newErrors: Record<string, string> = {};
if (!formData.first_name.trim())
newErrors.first_name = t('com_contact_first_name_required');
if (!formData.last_name.trim())
newErrors.last_name = t('com_contact_last_name_required');
if (!formData.email) {
newErrors.email = t('com_contact_email_required');
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
newErrors.email = t('com_contact_email_error');
}
if (!formData.phone) {
newErrors.phone = t('com_contact_phone_required');
} else if (!/^09\d{9}$/.test(formData.phone)) {
newErrors.phone = t('com_contact_phone_error');
}
if (!formData.message.trim()) {
newErrors.message = t('com_contact_textarea_required');
} else if (formData.message.trim().length < 10) {
newErrors.message = t('com_contact_textarea_error');
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleChange = (field: string, value: string) => {
setFormData({ ...formData, [field]: value });
setErrors({ ...errors, [field]: '' });
};
const handleSubmit = (e: React.FormEvent) => {
console.log(e);
e.preventDefault();
setLoading(true);
setContact(formData).finally(() => {
setLoading(false);
});
};
return ( return (
<div className="w-full rounded-4xl bg-white p-4 md:w-1/2"> <form
onSubmit={handleSubmit}
className="z-10 w-full rounded-4xl bg-white p-4 md:w-1/2"
>
<h2 className="mt-8 mb-10 text-5xl text-gray-800"> <h2 className="mt-8 mb-10 text-5xl text-gray-800">
{t('com_contact_title')}{' '} {t('com_contact_title')}{' '}
<span className="text-5xl font-bold"> <span className="text-5xl font-bold">
{t('com_contact_title_bold')} {t('com_contact_title_bold')}
</span> </span>
</h2> </h2>
<div className="space-y-6"> <div className="space-y-6">
<div className="flex flex-col gap-6 md:flex-row md:gap-8"> <div className="flex flex-col gap-6 md:flex-row md:gap-8">
<FormField type="text" placeholder={t('com_contact_first_name')} /> <div className="w-full">
<FormField type="text" placeholder={t('com_contact_last_name')} /> <FormField
</div> type="text"
<FormField type="email" placeholder={t('com_contact_email')} /> placeholder={t('com_contact_first_name')}
<FormField type="tel" placeholder={t('com_contact_phone')} /> value={formData.first_name}
<FormField type="textarea" placeholder={t('com_contact_textarea')} /> onChange={(e: any) => handleChange('first_name', e.target.value)}
/>
{errors.first_name && (
<p className="text-primary mt-1 text-sm">{errors.first_name}</p>
)}
</div>
<Button>Submit Message</Button> <div className="w-full">
<FormField
type="text"
placeholder={t('com_contact_last_name')}
value={formData.last_name}
onChange={(e: any) => handleChange('last_name', e.target.value)}
/>
{errors.last_name && (
<p className="text-primary mt-1 text-sm">{errors.last_name}</p>
)}
</div>
</div>
<div>
<FormField
type="email"
placeholder={t('com_contact_email')}
value={formData.email}
onChange={(e: any) => handleChange('email', e.target.value)}
/>
{errors.email && (
<p className="text-primary mt-1 text-sm">{errors.email}</p>
)}
</div>
<div>
<FormField
type="tel"
placeholder={t('com_contact_phone')}
value={formData.phone}
onChange={(e: any) => handleChange('phone', e.target.value)}
/>
{errors.phone && (
<p className="text-primary mt-1 text-sm">{errors.phone}</p>
)}
</div>
<div>
<FormField
type="textarea"
placeholder={t('com_contact_textarea')}
value={formData.message}
onChange={(e: any) => handleChange('message', e.target.value)}
/>
{errors.message && (
<p className="text-primary mt-1 text-sm">{errors.message}</p>
)}
</div>
<Button disabled={loading}>{t('com_contact_button_submit')}</Button>
</div> </div>
</div> </form>
); );
}; };
+10 -14
View File
@@ -1,5 +1,6 @@
'use client'; 'use client';
import SectionTitle from '@/components/layout/sectionTitle';
import { Icon } from '@/components/uikit/icons'; import { Icon } from '@/components/uikit/icons';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
@@ -8,23 +9,18 @@ const TouchUs = () => {
return ( return (
<div className="w-full p-8 md:w-1/2"> <div className="w-full p-8 md:w-1/2">
<div className="mb-3.5 flex items-center gap-0.5 text-base"> <SectionTitle
<Icon name="setting" className="text-primary h-4 w-4" /> title={t('pages_contact_title')}
<p>{t('pages_contact_title')}</p> description={t('com_contact_touch_title')}
</div> description_bold={t('com_contact_touch_title_bold')}
<h1 className="mb-5 text-3xl font-light text-gray-800 md:text-5xl"> />
{t('com_contact_touch_title')}{' '} <p className="mt-4 mb-10 text-base font-normal text-gray-600">
<span className="text-3xl font-light md:text-5xl md:font-bold">
{t('com_contact_touch_title_bold')}
</span>
</h1>
<p className="mb-10 text-base font-normal text-gray-600">
{t('com_contact_touch_description')} {t('com_contact_touch_description')}
</p> </p>
<div className="flex flex-col justify-between gap-10"> <div className="flex flex-col justify-between gap-10">
<div className="flex items-center"> <div className="flex items-center">
<div className="mr-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500"> <div className="me-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500">
<Icon name="phone" className="text-white" /> <Icon name="phone" className="text-white" />
</div> </div>
<div> <div>
@@ -36,7 +32,7 @@ const TouchUs = () => {
</div> </div>
<div className="flex items-center"> <div className="flex items-center">
<div className="mr-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500"> <div className="me-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500">
<Icon name="email" className="text-white" /> <Icon name="email" className="text-white" />
</div> </div>
<div> <div>
@@ -48,7 +44,7 @@ const TouchUs = () => {
</div> </div>
<div className="flex items-center"> <div className="flex items-center">
<div className="mr-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500"> <div className="me-4 flex h-10 w-10 items-center justify-center rounded-full bg-red-500">
<Icon name="location" className="text-white" /> <Icon name="location" className="text-white" />
</div> </div>
<div> <div>
+66
View File
@@ -0,0 +1,66 @@
import images from '@/assets/images/images';
import SectionTitle from '@/components/layout/sectionTitle';
import { getProductCategories } from '@/services/products';
import Link from 'next/link';
import routeFactory from '@/assets/constants/routeFactory';
import { getTranslations } from 'next-intl/server';
import { TLocales } from '@/models/layout';
import { getProjectCategories } from '@/services/projects';
import { IProjectCardProps } from '../project/project';
interface Props {
locale: TLocales;
}
export default async function HomePageProjects({ locale }: Props) {
const t = await getTranslations({ locale });
// const projectCategories: IProjectCardProps[] = await getProjectCategories();
const routes = routeFactory(t, locale);
return (
<div className="w-full">
<div
className={`relative w-full bg-white bg-cover bg-fixed bg-center bg-no-repeat pt-28 pb-48`}
// 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">
<SectionTitle
title={t('pages_product_categories_title')}
description={t('com_home_products_title')}
reverseColor
/>
<h4 className="pt-10 text-base font-extralight tracking-normal text-white">
{t('com_home_products_description')}
</h4>
</div>
</div>
<div className="relative top-[-100px] z-20 container mx-auto w-full">
{/* <div className="grid grid-cols-1 gap-8 rounded-4xl bg-gray-50 py-10 shadow-2xl md:grid-cols-2 lg:grid-cols-4">
{projectCategories.map((category, index) => (
<Link
href={'#'}
key={index}
// href={routes.products.route(index)}
>
<div
className={`flex flex-col items-center justify-center gap-4 p-6 text-center ${index ? 'border-s-[1px] border-gray-100' : ''}`}
>
<h3 className="text-xl font-bold text-gray-500">
{category.title}
</h3>
{/* <p className="text-lg font-light text-gray-400">
{t('com_products_category_types_count', {
count: category.typesCount,
})}
</p>
</div>
</Link>
))}
</div>*/}
</div>
</div>
);
}
+9 -8
View File
@@ -1,39 +1,40 @@
import images from '@/assets/images/images'; import images from '@/assets/images/images';
import Image from 'next/image'; import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import { IProjectCardProps } from './project';
const projects = [ const projects = [
{ {
title: 'Sustainable Practices Reducing Waste in Industrial Production', title: 'Sustainable Practices Reducing Waste in Industrial Production',
image: images.projectImg_1.src, imageSrc: images.projectImg_1.src,
link: '#', link: '#',
}, },
{ {
title: 'Advanced Robotics Revolutionizing Industrial Workflows', title: 'Advanced Robotics Revolutionizing Industrial Workflows',
image: images.projectImg_1.src, imageSrc: images.projectImg_1.src,
link: '#', link: '#',
}, },
{ {
title: 'Top Benefits of the Robotics in Manufacturing', title: 'Top Benefits of the Robotics in Manufacturing',
image: images.projectImg_1.src, imageSrc: images.projectImg_1.src,
link: '#', link: '#',
}, },
{ {
title: 'Leveraging Data Analytics for Smarter Production', title: 'Leveraging Data Analytics for Smarter Production',
image: images.projectImg_1.src, imageSrc: images.projectImg_1.src,
link: '#', link: '#',
}, },
{ {
title: 'Reducing Operational Costs Through Automation', title: 'Reducing Operational Costs Through Automation',
image: '/images/post5.jpg', imageSrc: '/images/post5.jpg',
link: '#', link: '#',
}, },
{ {
title: 'The Advantages of Customized Manufacturing Solutions', title: 'The Advantages of Customized Manufacturing Solutions',
image: '/images/post6.jpg', imageSrc: '/images/post6.jpg',
link: '#', link: '#',
}, },
]; ] as IProjectCardProps[];
export default function ProjectsGrid() { export default function ProjectsGrid() {
return ( return (
@@ -46,7 +47,7 @@ export default function ProjectsGrid() {
> >
<div className="relative aspect-[1.09] w-full overflow-hidden rounded-4xl"> <div className="relative aspect-[1.09] w-full overflow-hidden rounded-4xl">
<Image <Image
src={project.image} src={project.imageSrc}
alt={project.title} alt={project.title}
fill fill
className="h-auto w-full object-cover" className="h-auto w-full object-cover"
+5
View File
@@ -0,0 +1,5 @@
export interface IProjectCardProps {
imageSrc: string;
title: string;
link: string;
}
+1 -1
View File
@@ -20,7 +20,7 @@ const FormField: React.FC<FormFieldProps> = ({
name, name,
}) => { }) => {
const commonClass = const commonClass =
'w-full rounded-lg border border-gray-300 p-3 focus:ring-2 focus:ring-red-500 focus:outline-none'; 'w-full rounded-lg border border-gray-100 p-3 focus:outline-none';
if (type === 'textarea') { if (type === 'textarea') {
return ( return (
+18
View File
@@ -0,0 +1,18 @@
import api from "@/lib/axios";
interface payload {
first_name: string,
last_name: string,
email: string,
phone: string,
message: string,
}
export async function setContact(payload:payload) {
return api
.post('/contact', payload)
.then(({ data }) => {
return Promise.resolve();
})
.catch((error) => Promise.reject(error));
}
+40
View File
@@ -0,0 +1,40 @@
'use server';
import { IProjectCardProps } from '@/components/pages/project/project';
import api from '@/lib/axios';
import { IResponse } from '@/models/response';
import { cookies } from 'next/headers';
export async function getProjectCategories() {
const cookiesStore = await cookies();
return api
.get('/project_categories', {
headers: {
Cookie: cookiesStore.toString(),
},
})
.then(({ data }) => {
return Promise.resolve(data.data);
})
.catch((error) => Promise.reject(error));
}
export async function getProjects(
categoryId: string,
page = 1,
): Promise<IResponse<IProjectCardProps[]>> {
const cookiesStore = await cookies();
return api
.get(`/project_categories/${categoryId}/projects`, {
headers: {
Cookie: cookiesStore.toString(),
},
params: { page },
})
.then(({ data }) => {
return Promise.resolve(data);
})
.catch((error) => Promise.reject(error));
}