new web sayt

This commit is contained in:
nabijonovdavronbek619@gmail.com
2025-11-25 21:06:55 +05:00
parent bef940d9d8
commit f9d27ec11d
29 changed files with 3978 additions and 55 deletions

26
app/[locale]/layout.tsx Normal file
View File

@@ -0,0 +1,26 @@
import { ReactNode } from "react";
import { notFound } from "next/navigation";
import { locales } from "@/i18n.config";
export function generateStaticParams() {
return locales.map((locale) => ({ locale }));
}
interface LocaleLayoutProps {
children: ReactNode;
params: Promise<{
locale: string;
}>;
}
async function LocaleLayout({ children, params }: LocaleLayoutProps) {
const { locale } = await params;
if (!locales.includes(locale as any)) {
notFound();
}
return <>{children}</>;
}
export default LocaleLayout;

36
app/[locale]/page.tsx Normal file
View File

@@ -0,0 +1,36 @@
"use client";
import { Navbar } from "@/components/Navbar";
import { ShowCase } from "@/components/ShowCase";
import { About } from "@/components/About";
import { ProductsGrid } from "@/components/ProductsGrid";
import { FAQ } from "@/components/FAQ";
import { ContactForm } from "@/components/ContactForm";
import { Footer } from "@/components/Footer";
const HERO_IMAGES = [
"/images/hero-pump-1.jpg",
"/images/hero-pump-2.jpg",
"/images/hero-pump-3.jpg",
"/images/hero-pump-4.jpg",
"/images/hero-pump-5.jpg",
];
export default function Home() {
return (
<main>
<Navbar />
<ShowCase
titleKey="hero.title"
subtitleKey="hero.subtitle"
ctaLabelKey="hero.cta"
images={HERO_IMAGES}
/>
<About />
<ProductsGrid />
<FAQ />
<ContactForm />
<Footer />
</main>
);
}

75
app/api/contact/route.ts Normal file
View File

@@ -0,0 +1,75 @@
import { NextResponse } from "next/server";
import axios from "axios";
export async function POST(req: Request) {
try {
const body = await req.json();
const { name, phone, message, productSlug, lang } = body;
// Validation
if (!phone || typeof phone !== "string" || phone.trim() === "") {
return NextResponse.json(
{ error: "Phone number is required" },
{ status: 400 }
);
}
// Get Telegram credentials from environment
const token = process.env.TELEGRAM_BOT_TOKEN;
const chatId = process.env.TELEGRAM_CHAT_ID;
if (!token || !chatId) {
console.error("Telegram credentials not configured");
return NextResponse.json(
{ error: "Server not properly configured" },
{ status: 500 }
);
}
// Format message for Telegram
const telegramMessage = `
📨 New Contact Message
👤 Name: ${name || "—"}
📱 Phone: ${phone}
📝 Message: ${message || "—"}
🔧 Product: ${productSlug || "—"}
🌐 Language: ${lang || "—"}
---
Sent from firma.uz
`.trim();
// Send to Telegram
try {
await axios.post(
`https://api.telegram.org/bot${token}/sendMessage`,
{
chat_id: chatId,
text: telegramMessage,
parse_mode: "HTML",
},
{
timeout: 10000,
}
);
return NextResponse.json(
{
ok: true,
message: "Message sent successfully",
},
{ status: 200 }
);
} catch (telegramError) {
console.error("Telegram API error:", telegramError);
return NextResponse.json(
{ error: "Failed to send message via Telegram" },
{ status: 500 }
);
}
} catch (error) {
console.error("Contact API error:", error);
return NextResponse.json({ error: "Invalid request" }, { status: 400 });
}
}

View File

@@ -1,5 +1,8 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import { ReactNode } from "react";
import { NextIntlClientProvider } from "next-intl";
import { getMessages } from "next-intl/server";
import "./globals.css";
const geistSans = Geist({
@@ -13,22 +16,33 @@ const geistMono = Geist_Mono({
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
title: "Firma - Industrial Equipment & Pumps",
description:
"Premium industrial pumps and equipment supplier with 10+ years of experience",
};
export default function RootLayout({
async function RootLayout({
children,
params,
}: Readonly<{
children: React.ReactNode;
children: ReactNode;
params: Promise<Record<string, any>>;
}>) {
const resolvedParams = await params;
const locale = resolvedParams.locale || "uz";
const messages = await getMessages();
return (
<html lang="en">
<html lang={locale}>
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
);
}
export default RootLayout;