Compare commits
11 Commits
e87a26d74c
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e71d774ccb | ||
|
|
49f5c0979a | ||
|
|
671344669c | ||
|
|
b9792e7eb5 | ||
|
|
638e5518e4 | ||
|
|
ce8d14c9b2 | ||
|
|
29e06be337 | ||
|
|
196f99d8dd | ||
|
|
ac7cd51600 | ||
|
|
21cb013cd8 | ||
|
|
de2554a2e7 |
27
app/[locale]/home/page.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import BackAnimatsiya from "@/components/backAnimatsiya/backAnimatsiya";
|
||||||
|
import {
|
||||||
|
AboutUs,
|
||||||
|
Banner,
|
||||||
|
Blog,
|
||||||
|
Line,
|
||||||
|
OurService,
|
||||||
|
Statistics,
|
||||||
|
Testimonial,
|
||||||
|
Video,
|
||||||
|
} from "@/components/pages/home";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<main className="bg-slate-950">
|
||||||
|
<Banner />
|
||||||
|
<Statistics />
|
||||||
|
<AboutUs />
|
||||||
|
<Line />
|
||||||
|
<Blog />
|
||||||
|
<Video />
|
||||||
|
<OurService />
|
||||||
|
{/* <BackAnimatsiya/> */}
|
||||||
|
{/* <Testimonial /> */}
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
6
app/[locale]/page.tsx
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { redirect } from 'next/navigation'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return redirect('/home')
|
||||||
|
}
|
||||||
141
app/globals.css
@@ -1,9 +1,60 @@
|
|||||||
@import 'tailwindcss';
|
@import "tailwindcss";
|
||||||
@import 'tw-animate-css';
|
@import "tw-animate-css";
|
||||||
|
|
||||||
@custom-variant dark (&:is(.dark *));
|
@layer {
|
||||||
|
@import url("https://fonts.googleapis.com/css2?family=Almarai:wght@300;400;700&display=swap");
|
||||||
|
@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap");
|
||||||
|
@import url("https://fonts.googleapis.com/css2?family=Unbounded:wght@200..900&display=swap");
|
||||||
|
}
|
||||||
|
|
||||||
|
@theme inline {
|
||||||
|
--color-background: var(--background);
|
||||||
|
--color-foreground: var(--foreground);
|
||||||
|
--font-sans: var(--font-geist-sans);
|
||||||
|
--font-mono: var(--font-geist-mono);
|
||||||
|
--font-roboto: "Roboto", sans-serif;
|
||||||
|
--font-almarai: "Almarai", sans-serif;
|
||||||
|
--font-unbounded:"Unbounded",sans-serif;
|
||||||
|
--color-sidebar-ring: var(--sidebar-ring);
|
||||||
|
--color-sidebar-border: var(--sidebar-border);
|
||||||
|
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||||
|
--color-sidebar-accent: var(--sidebar-accent);
|
||||||
|
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||||
|
--color-sidebar-primary: var(--sidebar-primary);
|
||||||
|
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||||
|
--color-sidebar: var(--sidebar);
|
||||||
|
--color-chart-5: var(--chart-5);
|
||||||
|
--color-chart-4: var(--chart-4);
|
||||||
|
--color-chart-3: var(--chart-3);
|
||||||
|
--color-chart-2: var(--chart-2);
|
||||||
|
--color-chart-1: var(--chart-1);
|
||||||
|
--color-ring: var(--ring);
|
||||||
|
--color-input: var(--input);
|
||||||
|
--color-border: var(--border);
|
||||||
|
--color-destructive: var(--destructive);
|
||||||
|
--color-accent-foreground: var(--accent-foreground);
|
||||||
|
--color-accent: var(--accent);
|
||||||
|
--color-muted-foreground: var(--muted-foreground);
|
||||||
|
--color-muted: var(--muted);
|
||||||
|
--color-secondary-foreground: var(--secondary-foreground);
|
||||||
|
--color-secondary: var(--secondary);
|
||||||
|
--color-primary-foreground: var(--primary-foreground);
|
||||||
|
--color-primary: var(--primary);
|
||||||
|
--color-popover-foreground: var(--popover-foreground);
|
||||||
|
--color-popover: var(--popover);
|
||||||
|
--color-card-foreground: var(--card-foreground);
|
||||||
|
--color-card: var(--card);
|
||||||
|
--radius-sm: calc(var(--radius) - 4px);
|
||||||
|
--radius-md: calc(var(--radius) - 2px);
|
||||||
|
--radius-lg: var(--radius);
|
||||||
|
--radius-xl: calc(var(--radius) + 4px);
|
||||||
|
--radius-2xl: calc(var(--radius) + 8px);
|
||||||
|
--radius-3xl: calc(var(--radius) + 12px);
|
||||||
|
--radius-4xl: calc(var(--radius) + 16px);
|
||||||
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
--radius: 0.625rem;
|
||||||
--background: oklch(1 0 0);
|
--background: oklch(1 0 0);
|
||||||
--foreground: oklch(0.145 0 0);
|
--foreground: oklch(0.145 0 0);
|
||||||
--card: oklch(1 0 0);
|
--card: oklch(1 0 0);
|
||||||
@@ -19,7 +70,6 @@
|
|||||||
--accent: oklch(0.97 0 0);
|
--accent: oklch(0.97 0 0);
|
||||||
--accent-foreground: oklch(0.205 0 0);
|
--accent-foreground: oklch(0.205 0 0);
|
||||||
--destructive: oklch(0.577 0.245 27.325);
|
--destructive: oklch(0.577 0.245 27.325);
|
||||||
--destructive-foreground: oklch(0.577 0.245 27.325);
|
|
||||||
--border: oklch(0.922 0 0);
|
--border: oklch(0.922 0 0);
|
||||||
--input: oklch(0.922 0 0);
|
--input: oklch(0.922 0 0);
|
||||||
--ring: oklch(0.708 0 0);
|
--ring: oklch(0.708 0 0);
|
||||||
@@ -28,7 +78,6 @@
|
|||||||
--chart-3: oklch(0.398 0.07 227.392);
|
--chart-3: oklch(0.398 0.07 227.392);
|
||||||
--chart-4: oklch(0.828 0.189 84.429);
|
--chart-4: oklch(0.828 0.189 84.429);
|
||||||
--chart-5: oklch(0.769 0.188 70.08);
|
--chart-5: oklch(0.769 0.188 70.08);
|
||||||
--radius: 0.625rem;
|
|
||||||
--sidebar: oklch(0.985 0 0);
|
--sidebar: oklch(0.985 0 0);
|
||||||
--sidebar-foreground: oklch(0.145 0 0);
|
--sidebar-foreground: oklch(0.145 0 0);
|
||||||
--sidebar-primary: oklch(0.205 0 0);
|
--sidebar-primary: oklch(0.205 0 0);
|
||||||
@@ -42,11 +91,11 @@
|
|||||||
.dark {
|
.dark {
|
||||||
--background: oklch(0.145 0 0);
|
--background: oklch(0.145 0 0);
|
||||||
--foreground: oklch(0.985 0 0);
|
--foreground: oklch(0.985 0 0);
|
||||||
--card: oklch(0.145 0 0);
|
--card: oklch(0.205 0 0);
|
||||||
--card-foreground: oklch(0.985 0 0);
|
--card-foreground: oklch(0.985 0 0);
|
||||||
--popover: oklch(0.145 0 0);
|
--popover: oklch(0.205 0 0);
|
||||||
--popover-foreground: oklch(0.985 0 0);
|
--popover-foreground: oklch(0.985 0 0);
|
||||||
--primary: oklch(0.985 0 0);
|
--primary: oklch(0.922 0 0);
|
||||||
--primary-foreground: oklch(0.205 0 0);
|
--primary-foreground: oklch(0.205 0 0);
|
||||||
--secondary: oklch(0.269 0 0);
|
--secondary: oklch(0.269 0 0);
|
||||||
--secondary-foreground: oklch(0.985 0 0);
|
--secondary-foreground: oklch(0.985 0 0);
|
||||||
@@ -54,11 +103,10 @@
|
|||||||
--muted-foreground: oklch(0.708 0 0);
|
--muted-foreground: oklch(0.708 0 0);
|
||||||
--accent: oklch(0.269 0 0);
|
--accent: oklch(0.269 0 0);
|
||||||
--accent-foreground: oklch(0.985 0 0);
|
--accent-foreground: oklch(0.985 0 0);
|
||||||
--destructive: oklch(0.396 0.141 25.723);
|
--destructive: oklch(0.704 0.191 22.216);
|
||||||
--destructive-foreground: oklch(0.637 0.237 25.331);
|
--border: oklch(1 0 0 / 10%);
|
||||||
--border: oklch(0.269 0 0);
|
--input: oklch(1 0 0 / 15%);
|
||||||
--input: oklch(0.269 0 0);
|
--ring: oklch(0.556 0 0);
|
||||||
--ring: oklch(0.439 0 0);
|
|
||||||
--chart-1: oklch(0.488 0.243 264.376);
|
--chart-1: oklch(0.488 0.243 264.376);
|
||||||
--chart-2: oklch(0.696 0.17 162.48);
|
--chart-2: oklch(0.696 0.17 162.48);
|
||||||
--chart-3: oklch(0.769 0.188 70.08);
|
--chart-3: oklch(0.769 0.188 70.08);
|
||||||
@@ -70,49 +118,8 @@
|
|||||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-accent: oklch(0.269 0 0);
|
--sidebar-accent: oklch(0.269 0 0);
|
||||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-border: oklch(0.269 0 0);
|
--sidebar-border: oklch(1 0 0 / 10%);
|
||||||
--sidebar-ring: oklch(0.439 0 0);
|
--sidebar-ring: oklch(0.556 0 0);
|
||||||
}
|
|
||||||
|
|
||||||
@theme inline {
|
|
||||||
--font-sans: 'Geist', 'Geist Fallback';
|
|
||||||
--font-mono: 'Geist Mono', 'Geist Mono Fallback';
|
|
||||||
--color-background: var(--background);
|
|
||||||
--color-foreground: var(--foreground);
|
|
||||||
--color-card: var(--card);
|
|
||||||
--color-card-foreground: var(--card-foreground);
|
|
||||||
--color-popover: var(--popover);
|
|
||||||
--color-popover-foreground: var(--popover-foreground);
|
|
||||||
--color-primary: var(--primary);
|
|
||||||
--color-primary-foreground: var(--primary-foreground);
|
|
||||||
--color-secondary: var(--secondary);
|
|
||||||
--color-secondary-foreground: var(--secondary-foreground);
|
|
||||||
--color-muted: var(--muted);
|
|
||||||
--color-muted-foreground: var(--muted-foreground);
|
|
||||||
--color-accent: var(--accent);
|
|
||||||
--color-accent-foreground: var(--accent-foreground);
|
|
||||||
--color-destructive: var(--destructive);
|
|
||||||
--color-destructive-foreground: var(--destructive-foreground);
|
|
||||||
--color-border: var(--border);
|
|
||||||
--color-input: var(--input);
|
|
||||||
--color-ring: var(--ring);
|
|
||||||
--color-chart-1: var(--chart-1);
|
|
||||||
--color-chart-2: var(--chart-2);
|
|
||||||
--color-chart-3: var(--chart-3);
|
|
||||||
--color-chart-4: var(--chart-4);
|
|
||||||
--color-chart-5: var(--chart-5);
|
|
||||||
--radius-sm: calc(var(--radius) - 4px);
|
|
||||||
--radius-md: calc(var(--radius) - 2px);
|
|
||||||
--radius-lg: var(--radius);
|
|
||||||
--radius-xl: calc(var(--radius) + 4px);
|
|
||||||
--color-sidebar: var(--sidebar);
|
|
||||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
||||||
--color-sidebar-primary: var(--sidebar-primary);
|
|
||||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
||||||
--color-sidebar-accent: var(--sidebar-accent);
|
|
||||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
||||||
--color-sidebar-border: var(--sidebar-border);
|
|
||||||
--color-sidebar-ring: var(--sidebar-ring);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
@@ -124,26 +131,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.loi{
|
body {
|
||||||
color:#a6040400;
|
background: #1e1d1c;
|
||||||
}
|
|
||||||
|
|
||||||
.gradient-text {
|
|
||||||
background: linear-gradient(
|
|
||||||
to bottom right,
|
|
||||||
#ffffff 0%,
|
|
||||||
#ffffff 50%,
|
|
||||||
rgba(255, 255, 255, 0.5) 100%
|
|
||||||
);
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
background-clip: text;
|
|
||||||
color: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
text gradient tailwindd classlari
|
|
||||||
|
|
||||||
bg-linear-to-br from-white via-white to-white/50
|
|
||||||
text-transparent bg-clip-text
|
|
||||||
*/
|
|
||||||
@@ -4,9 +4,19 @@ import { Geist, Geist_Mono } from "next/font/google";
|
|||||||
import { Analytics } from "@vercel/analytics/next";
|
import { Analytics } from "@vercel/analytics/next";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import { Footer, Navbar } from "@/components/layout";
|
import { Footer, Navbar } from "@/components/layout";
|
||||||
|
import { NextIntlClientProvider } from "next-intl";
|
||||||
|
import { getMessages } from "next-intl/server";
|
||||||
|
import BackAnimatsiya from "@/components/backAnimatsiya/backAnimatsiya";
|
||||||
|
|
||||||
const _geist = Geist({ subsets: ["latin"] });
|
const geistSans = Geist({
|
||||||
const _geistMono = Geist_Mono({ subsets: ["latin"] });
|
variable: "--font-geist-sans",
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
|
||||||
|
const geistMono = Geist_Mono({
|
||||||
|
variable: "--font-geist-mono",
|
||||||
|
subsets: ["latin"],
|
||||||
|
});
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "FireForce - Emergency Services",
|
title: "FireForce - Emergency Services",
|
||||||
@@ -32,18 +42,27 @@ export const metadata: Metadata = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default async function RootLayout({
|
||||||
children,
|
children,
|
||||||
|
params,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
params: any;
|
||||||
}>) {
|
}>) {
|
||||||
|
const { locale } = await params;
|
||||||
|
const messages: any = await getMessages();
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang={locale} suppressHydrationWarning>
|
||||||
<body className={`font-sans antialiased`}>
|
<body
|
||||||
<Navbar />
|
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||||
{children}
|
>
|
||||||
<Footer />
|
<NextIntlClientProvider messages={messages} locale={locale}>
|
||||||
<Analytics />
|
<BackAnimatsiya />
|
||||||
|
<Navbar />
|
||||||
|
{children}
|
||||||
|
<Footer />
|
||||||
|
<Analytics />
|
||||||
|
</NextIntlClientProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|||||||
24
app/page.tsx
@@ -1,25 +1,5 @@
|
|||||||
import {
|
import { redirect } from "next/navigation";
|
||||||
AboutUs,
|
|
||||||
Banner,
|
|
||||||
Blog,
|
|
||||||
Line,
|
|
||||||
OurService,
|
|
||||||
Statistics,
|
|
||||||
Testimonial,
|
|
||||||
Video,
|
|
||||||
} from "@/components/pages/home";
|
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return redirect('/uz/home')
|
||||||
<main className="bg-slate-950">
|
|
||||||
<Banner />
|
|
||||||
<Statistics />
|
|
||||||
<AboutUs />
|
|
||||||
<Video />
|
|
||||||
<OurService />
|
|
||||||
<Testimonial />
|
|
||||||
<Line />
|
|
||||||
<Blog />
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
23
components/Counter.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
"use client";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { animate, motion, useMotionValue, useTransform } from "framer-motion";
|
||||||
|
|
||||||
|
export function Counter({ countNum }: { countNum: number }) {
|
||||||
|
const count = useMotionValue(0);
|
||||||
|
const rounded = useTransform(count, (latest:any) => Math.round(latest));
|
||||||
|
const [displayValue, setDisplayValue] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const controls = animate(count, countNum, {
|
||||||
|
duration: 2,
|
||||||
|
ease: "easeOut",
|
||||||
|
onUpdate: (latest:any) => {
|
||||||
|
setDisplayValue(Math.round(latest));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => controls.stop();
|
||||||
|
}, [countNum]); // countNum dependency qo'shildi
|
||||||
|
|
||||||
|
return <motion.span>{displayValue}</motion.span>;
|
||||||
|
}
|
||||||
74
components/backAnimatsiya/back.css
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
@keyframes drawLine {
|
||||||
|
0% {
|
||||||
|
stroke-dashoffset: 500;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
10% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dashoffset: -500;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cls-1,
|
||||||
|
.cls-2,
|
||||||
|
.cls-3,
|
||||||
|
.cls-4,
|
||||||
|
.cls-5,
|
||||||
|
.cls-6,
|
||||||
|
.cls-7 {
|
||||||
|
fill: none;
|
||||||
|
stroke: currentColor;
|
||||||
|
stroke-width: 2px;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: round;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Har bir path uchun animatsiya */
|
||||||
|
.draw-path {
|
||||||
|
stroke-dasharray: 2000;
|
||||||
|
stroke-dashoffset: 2000;
|
||||||
|
animation: drawLine 8s ease-in-out infinite;
|
||||||
|
fill: none !important;
|
||||||
|
stroke: rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Har bir elementni ketma-ket chizish uchun delay */
|
||||||
|
.draw-path:nth-child(1) {
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draw-path:nth-child(2) {
|
||||||
|
animation-delay: 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draw-path:nth-child(3) {
|
||||||
|
animation-delay: 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draw-path:nth-child(4) {
|
||||||
|
animation-delay: 1.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draw-path:nth-child(5) {
|
||||||
|
animation-delay: 2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draw-path:nth-child(6) {
|
||||||
|
animation-delay: 2.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draw-path:nth-child(7) {
|
||||||
|
animation-delay: 3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draw-path:nth-child(8) {
|
||||||
|
animation-delay: 3.5s;
|
||||||
|
}
|
||||||
52
components/backAnimatsiya/backAnimatsiya.tsx
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import "./back.css";
|
||||||
|
|
||||||
|
export default function BackAnimatsiya() {
|
||||||
|
return (
|
||||||
|
<div className="fixed inset-0 w-full h-full flex items-center justify-center pointer-events-none z-0 opacity-100">
|
||||||
|
<svg
|
||||||
|
id="Layer_2"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 423.22 424.82"
|
||||||
|
className="w-full h-full"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
{/* Tailwind gradient uchun yangi linearGradient */}
|
||||||
|
<linearGradient id="tailwind-gradient" x1="0%" y1="100%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" stopColor="#979797" />
|
||||||
|
<stop offset="50%" stopColor="#e4e4e4" />
|
||||||
|
<stop offset="100%" stopColor="#9a9a9a" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g>
|
||||||
|
<polygon
|
||||||
|
className="draw-path"
|
||||||
|
points="352.86 365.08 347.11 365.08 347.11 381 289.38 381 289.38 365.08 283.63 365.08 283.63 381 204.78 381 204.78 365.08 199.03 365.08 199.03 381 141.32 381 141.32 365.08 135.57 365.08 135.57 381 77.87 381 77.87 365.08 71.86 365.08 71.85 381 17.21 381 17.21 386.74 72.11 386.74 72.11 424.82 74.04 424.82 74.04 386.74 350.94 386.74 350.94 424.82 352.86 424.82 352.86 386.74 406.02 386.74 406.02 381 352.86 381 352.86 365.08"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
className="draw-path"
|
||||||
|
d="m72.11,157.74v73.55l-41.42,23.89h3.83l37.58-21.68-.04,21.68h5.79v-24.99l57.7-33.27v58.26h5.75v-57.15l57.71-33.29v90.44h5.75v-90.43l39.43,22.77,39.43,22.77v44.89h5.74v-41.58l57.73,33.32v8.25h5.75v-95.41h-1.92v82.75l-61.56-35.55v-98.77l59.59-34.35-.97-1.66-58.62,33.81V0h-1.92v42.86h-88.43v115.23l-5.2,3-14.21,8.16-27.25,15.74-11.05,6.37v-73.53l36.14-20.85-.96-1.66-35.19,20.29v-35.03h-1.92v36.13l-65.36,37.7v-37.25h-1.92v38.35l-53.08,30.6.96,1.67,52.12-30.07ZM204.78,48.58h78.85v60.71l-78.85,45.48V48.58Zm0,108.41l78.85-45.49v92.14l-78.85-45.54v-1.11Zm-126.91,1.92l57.7-33.32v69.11l-57.7,33.26v-69.05Z"
|
||||||
|
/>
|
||||||
|
<g>
|
||||||
|
<rect className="draw-path" y="277.99" width="12.06" height="64.23" />
|
||||||
|
<path
|
||||||
|
className="draw-path"
|
||||||
|
d="m88.82,342.36c3.93-.65,7.51-1.73,10.75-3.23,3.24-1.5,6.01-3.46,8.32-5.89l1.31,8.97h7.76v-35.25h-39.45v9.72h27.58v1.03c0,3.12-.94,5.84-2.8,8.18-1.87,2.34-4.81,4.13-8.83,5.38-4.02,1.25-9.3,1.87-15.85,1.87-5.49,0-10.28-.73-14.4-2.2-4.11-1.46-7.32-3.8-9.63-7.01-2.31-3.21-3.46-7.46-3.46-12.76v-2.24c0-3.93.75-7.28,2.24-10.05,1.5-2.77,3.58-5.03,6.26-6.78,2.68-1.74,5.8-3.02,9.35-3.83,3.55-.81,7.39-1.21,11.5-1.21,3.37,0,6.56.2,9.58.61,3.02.41,5.75,1.11,8.18,2.1,2.43,1,4.35,2.38,5.75,4.16,1.4,1.78,2.1,3.97,2.1,6.59h11.78c0-4.05-.89-7.56-2.66-10.52-1.78-2.96-4.33-5.41-7.67-7.34-3.33-1.93-7.32-3.38-11.97-4.35-4.64-.97-9.83-1.45-15.57-1.45-8.6,0-15.99,1.25-22.16,3.74-6.17,2.49-10.89,6.22-14.16,11.17-3.27,4.95-4.91,11.08-4.91,18.37,0,11.16,3.23,19.48,9.68,24.96,6.45,5.49,16.16,8.23,29.12,8.23,4.24,0,8.32-.33,12.25-.98Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
className="draw-path"
|
||||||
|
d="m160.8,299.31c1.68,1.81,3.3,3.49,4.86,5.05l37.96,37.86h11.12v-64.23h-11.59v37.02c0,1.31.03,2.9.09,4.77.06,1.87.12,3.43.19,4.68h-.75c-.75-.87-1.67-1.87-2.76-2.99-1.09-1.12-2.15-2.23-3.18-3.32-1.03-1.09-1.92-1.98-2.66-2.66l-37.86-37.49h-11.5v64.23h11.59v-36.37c0-2.31-.02-4.46-.05-6.45-.03-1.99-.08-3.46-.14-4.39h.65c1,1.06,2.34,2.49,4.02,4.3Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
className="draw-path"
|
||||||
|
d="m242.6,277.99v35.34c0,6.11,1.26,11.42,3.79,15.94,2.52,4.52,6.36,7.99,11.5,10.42,5.14,2.43,11.64,3.65,19.49,3.65s14.33-1.21,19.45-3.65c5.11-2.43,8.93-5.9,11.45-10.42,2.52-4.52,3.79-9.83,3.79-15.94v-35.34h-12.06v34.97c0,6.48-1.96,11.47-5.89,14.96-3.93,3.49-9.5,5.23-16.73,5.23s-12.89-1.74-16.78-5.23c-3.9-3.49-5.84-8.48-5.84-14.96v-34.97h-12.15Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
className="draw-path"
|
||||||
|
d="m404.99,277.99l-17.2,37.02c-.5,1.12-1.11,2.51-1.82,4.16-.72,1.65-1.42,3.32-2.1,5-.69,1.68-1.31,3.18-1.87,4.49h-.56c-.62-1.5-1.3-3.12-2.01-4.86-.72-1.74-1.42-3.44-2.1-5.1-.69-1.65-1.25-2.94-1.68-3.88l-17.2-36.83h-18.51v64.23h11.59v-40.29c0-1.31-.02-2.67-.05-4.07-.03-1.4-.06-2.76-.09-4.07-.03-1.31-.08-2.4-.14-3.27h.75c.31.81.67,1.79,1.07,2.94.4,1.15.89,2.37,1.45,3.65.56,1.28,1.12,2.51,1.68,3.69l19.26,41.42h11.87l19.17-41.42c.43-.94.92-2.02,1.45-3.27.53-1.25,1.04-2.49,1.54-3.74.5-1.25.9-2.34,1.22-3.27h.75c-.06,1-.13,2.18-.19,3.55-.06,1.37-.11,2.74-.14,4.11-.03,1.37-.05,2.62-.05,3.74v40.29h12.15v-64.23h-18.23Z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
120
components/languageSwitcher.tsx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState, useTransition } from "react";
|
||||||
|
import { useRouter, usePathname } from "next/navigation";
|
||||||
|
import { Check, ChevronDown, Globe } from "lucide-react";
|
||||||
|
import { locales, localeFlags, localeNames, type Locale } from "@/i18n/config";
|
||||||
|
import { useLocale } from "next-intl";
|
||||||
|
|
||||||
|
export default function LanguageSelectRadix() {
|
||||||
|
const router = useRouter();
|
||||||
|
const pathname = usePathname();
|
||||||
|
const currentLocale = useLocale() as Locale;
|
||||||
|
const [isPending, startTransition] = useTransition();
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
const changeLanguage = (newLocale: Locale) => {
|
||||||
|
if (newLocale === currentLocale) {
|
||||||
|
setIsOpen(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
startTransition(() => {
|
||||||
|
// ✅ 1. Set cookie (middleware will sync this)
|
||||||
|
document.cookie = `NEXT_LOCALE=${newLocale}; path=/; max-age=31536000; SameSite=Lax`;
|
||||||
|
|
||||||
|
// ✅ 2. Build new path
|
||||||
|
const segments = pathname.split("/").filter(Boolean);
|
||||||
|
|
||||||
|
// Remove current locale if exists
|
||||||
|
const pathWithoutLocale =
|
||||||
|
segments[0] && locales.includes(segments[0] as Locale)
|
||||||
|
? segments.slice(1)
|
||||||
|
: segments;
|
||||||
|
|
||||||
|
// Add new locale
|
||||||
|
const newPath = `/${newLocale}${
|
||||||
|
pathWithoutLocale.length ? "/" + pathWithoutLocale.join("/") : ""
|
||||||
|
}`;
|
||||||
|
|
||||||
|
// ✅ 3. Navigate (middleware will handle the rest)
|
||||||
|
router.push(newPath);
|
||||||
|
|
||||||
|
// ✅ 4. Force refresh after navigation completes
|
||||||
|
setTimeout(() => {
|
||||||
|
router.refresh();
|
||||||
|
}, 100); // Small delay ensures navigation completes
|
||||||
|
});
|
||||||
|
|
||||||
|
setIsOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative">
|
||||||
|
{/* Trigger Button */}
|
||||||
|
<button
|
||||||
|
onClick={() => setIsOpen(!isOpen)}
|
||||||
|
disabled={isPending}
|
||||||
|
className="inline-flex items-center justify-between gap-2 px-2 py-1 border border-gray-300 hover:border-red-600
|
||||||
|
rounded-lg text-white text-sm font-medium shadow-sm hover:bg-red-600 disabled:opacity-50 disabled:cursor-not-allowed transition-all"
|
||||||
|
aria-label="Tilni tanlash"
|
||||||
|
aria-expanded={isOpen}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{isPending ? (
|
||||||
|
<Globe className="w-4 h-4 animate-spin" />
|
||||||
|
) : (
|
||||||
|
<span className="text-lg">{localeFlags[currentLocale]}</span>
|
||||||
|
)}
|
||||||
|
<span className="hidden md:inline font-medium">
|
||||||
|
{localeNames[currentLocale]}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<ChevronDown
|
||||||
|
className={`w-4 h-4 transition-transform duration-200 ${
|
||||||
|
isOpen ? "rotate-180" : ""
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Dropdown */}
|
||||||
|
{isOpen && (
|
||||||
|
<>
|
||||||
|
{/* Backdrop */}
|
||||||
|
<div
|
||||||
|
className="fixed inset-0 z-40"
|
||||||
|
onClick={() => setIsOpen(false)}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Menu */}
|
||||||
|
<div className="absolute right-0 mt-2 w-48 rounded-lg border border-gray-200 bg-white shadow-lg z-50 animate-in fade-in slide-in-from-top-2 duration-200">
|
||||||
|
<div className="p-1" role="menu">
|
||||||
|
{locales.map((lang) => (
|
||||||
|
<button
|
||||||
|
key={lang}
|
||||||
|
onClick={() => changeLanguage(lang)}
|
||||||
|
disabled={isPending}
|
||||||
|
role="menuitem"
|
||||||
|
className={`w-full flex items-center justify-between px-3 py-2 text-sm rounded-md transition-colors ${
|
||||||
|
currentLocale === lang
|
||||||
|
? "bg-blue-50 text-blue-700 font-medium"
|
||||||
|
: "hover:bg-gray-100 text-gray-700"
|
||||||
|
} disabled:opacity-50 disabled:cursor-not-allowed`}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-lg">{localeFlags[lang]}</span>
|
||||||
|
<span>{localeNames[lang]}</span>
|
||||||
|
</div>
|
||||||
|
{currentLocale === lang && (
|
||||||
|
<Check className="w-4 h-4 text-blue-700" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -4,8 +4,13 @@ import React from "react";
|
|||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Mail, Phone, MapPin } from "lucide-react";
|
import { Mail, Phone, MapPin } from "lucide-react";
|
||||||
|
import { useLocale, useTranslations } from "next-intl";
|
||||||
|
import Image from "next/image";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
export function Footer() {
|
export function Footer() {
|
||||||
|
const locale = useLocale();
|
||||||
|
const t = useTranslations();
|
||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
const [subscribed, setSubscribed] = useState(false);
|
const [subscribed, setSubscribed] = useState(false);
|
||||||
|
|
||||||
@@ -26,16 +31,16 @@ export function Footer() {
|
|||||||
"linear-gradient(to top right, #452811 0%, #000000 20%, #000000 40%, #000000 60%, #000000 80%, #000000 100%)",
|
"linear-gradient(to top right, #452811 0%, #000000 20%, #000000 40%, #000000 60%, #000000 80%, #000000 100%)",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Newsletter Section */}
|
{/* Newsletter Section for gitea */}
|
||||||
<div className=" absolute w-full -top-40 px-4 py-12 md:py-16">
|
<div className=" absolute w-full -top-40 px-4 py-12 md:py-16">
|
||||||
<div className="mx-auto max-w-6xl">
|
<div className="mx-auto max-w-6xl">
|
||||||
<div className="rounded-2xl bg-[#fa1d1d] px-6 py-8 md:flex lg:flex-row flex-col max-lg:gap-5 md:items-center lg:justify-between justify-center md:px-10 md:py-12">
|
<div className="rounded-2xl bg-[#fa1d1d] px-6 py-8 md:flex lg:flex-row flex-col max-lg:gap-5 md:items-center lg:justify-between justify-center md:px-10 md:py-12">
|
||||||
<div className="mb-8 md:mb-0">
|
<div className="mb-8 md:mb-0">
|
||||||
<h2 className="text-2xl font-bold text-white md:text-3xl">
|
<h2 className="font-unbounded text-2xl font-bold text-white md:text-3xl">
|
||||||
SUBSCRIBE OUR NEWSLETTER
|
{t("contactTitle")}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mt-2 text-gray-100">
|
<p className="font-almarai mt-2 text-gray-100">
|
||||||
Expect a friendly letter from us once a week. No spam.
|
{t("contactSubTitle")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -45,17 +50,17 @@ export function Footer() {
|
|||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="Enter your email address"
|
placeholder={t("enterPhone")}
|
||||||
value={email}
|
value={email}
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
className="flex-1 rounded-full bg-white px-6 py-3 text-gray-800 placeholder-gray-400 focus:outline-none md:w-64"
|
className="font-almarai flex-1 rounded-full bg-white px-6 py-3 text-gray-800 placeholder-gray-400 focus:outline-none md:w-64"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="rounded-full bg-gray-800 px-6 py-3 font-bold text-white transition hover:bg-gray-700"
|
className="font-almarai rounded-full bg-gray-800 px-6 py-3 font-bold text-white transition hover:bg-gray-700"
|
||||||
>
|
>
|
||||||
{subscribed ? "✓ Sent" : "SIGN UP"}
|
{subscribed ? "✓ Sent" : t("send")}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -69,91 +74,71 @@ export function Footer() {
|
|||||||
{/* Brand Section */}
|
{/* Brand Section */}
|
||||||
<div>
|
<div>
|
||||||
<div className="mb-4 flex items-center gap-2">
|
<div className="mb-4 flex items-center gap-2">
|
||||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-[#fa1d1d]">
|
<div className=" flex items-center justify-center">
|
||||||
<span className="text-lg font-bold text-white">⚡</span>
|
<Image
|
||||||
|
src="/images/IGNUM/PNG/1.@6x.png"
|
||||||
|
alt="logo image"
|
||||||
|
width={70}
|
||||||
|
height={70}
|
||||||
|
className=""
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xl font-bold text-white">FIREFORCE</span>
|
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm leading-relaxed text-gray-300">
|
<p className="font-almarai text-sm leading-relaxed text-gray-300">
|
||||||
They are seen as a beacon of hope, a figure who brings calm
|
{t("footer.description")}
|
||||||
amidst chaos and light in the darkest of moments.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Quick Links */}
|
{/* Quick Links */}
|
||||||
<div>
|
<div>
|
||||||
<h3 className="mb-6 text-lg font-bold text-white">QUICK LINK</h3>
|
<h3 className="font-unbounded uppercase mb-6 text-lg font-bold text-white">
|
||||||
|
{t("footer.quickLinks.title")}
|
||||||
|
</h3>
|
||||||
<ul className="space-y-3 text-gray-300">
|
<ul className="space-y-3 text-gray-300">
|
||||||
<li>
|
<li>
|
||||||
<a href="#home" className="transition hover:text-[#fa1d1d]">
|
<Link
|
||||||
Home
|
href={`/${locale}/home`}
|
||||||
</a>
|
className="font-almarai transition hover:text-[#fa1d1d]"
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#about" className="transition hover:text-[#fa1d1d]">
|
|
||||||
About
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="#services"
|
|
||||||
className="transition hover:text-[#fa1d1d]"
|
|
||||||
>
|
>
|
||||||
Services
|
{t("footer.quickLinks.home")}
|
||||||
</a>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<Link
|
||||||
href="#pricing"
|
href={`/${locale}/about`}
|
||||||
className="transition hover:text-[#fa1d1d]"
|
className="font-almarai transition hover:text-[#fa1d1d]"
|
||||||
>
|
>
|
||||||
Pricing
|
{t("footer.quickLinks.about")}
|
||||||
</a>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#blog" className="transition hover:text-[#fa1d1d]">
|
<Link
|
||||||
Blog
|
href={`/${locale}/services`}
|
||||||
</a>
|
className="font-almarai transition hover:text-[#fa1d1d]"
|
||||||
|
>
|
||||||
|
{t("footer.quickLinks.services")}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
href={`/${locale}/blog`}
|
||||||
|
className="font-almarai transition hover:text-[#fa1d1d]"
|
||||||
|
>
|
||||||
|
{t("footer.quickLinks.products")}
|
||||||
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Support */}
|
{/* Support */}
|
||||||
<div>
|
<div>
|
||||||
<h3 className="mb-6 text-lg font-bold text-white">SUPPORT</h3>
|
<h3 className="font-unbounded mb-6 text-lg font-bold text-white">
|
||||||
<ul className="space-y-3 text-gray-300">
|
{t("footer.support.title")}
|
||||||
|
</h3>
|
||||||
|
<ul className="font-almarai space-y-3 text-gray-300">
|
||||||
<li>
|
<li>
|
||||||
<a href="#help" className="transition hover:text-[#fa1d1d]">
|
<a href="#help" className="transition hover:text-[#fa1d1d]">
|
||||||
Help Center
|
{t("footer.support.contact")}
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="#disclaimer"
|
|
||||||
className="transition hover:text-[#fa1d1d]"
|
|
||||||
>
|
|
||||||
Disclaimer
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#faq" className="transition hover:text-[#fa1d1d]">
|
|
||||||
FAQ
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="#support"
|
|
||||||
className="transition hover:text-[#fa1d1d]"
|
|
||||||
>
|
|
||||||
Support
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="#contact"
|
|
||||||
className="transition hover:text-[#fa1d1d]"
|
|
||||||
>
|
|
||||||
Contact
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -161,12 +146,14 @@ export function Footer() {
|
|||||||
|
|
||||||
{/* Contact */}
|
{/* Contact */}
|
||||||
<div>
|
<div>
|
||||||
<h3 className="mb-6 text-lg font-bold text-white">CONTACT</h3>
|
<h3 className="font-unbounded uppercase mb-6 text-lg font-bold text-white">
|
||||||
<ul className="space-y-4 text-gray-300">
|
{t("footer.support.contact")}
|
||||||
|
</h3>
|
||||||
|
<ul className="font-almarai space-y-4 text-gray-300">
|
||||||
<li className="flex items-start gap-3">
|
<li className="flex items-start gap-3">
|
||||||
<Phone className="mt-1 h-5 w-5 shrink-0 text-white" />
|
<Phone className="mt-1 h-5 w-5 shrink-0 text-white" />
|
||||||
<a href="tel:+1234567890" className="hover:text-[#fa1d1d]">
|
<a href="tel:+998773722121" className="hover:text-[#fa1d1d]">
|
||||||
+123-456-7890
|
+998-77-372-21-21
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li className="flex items-start gap-3">
|
<li className="flex items-start gap-3">
|
||||||
@@ -191,13 +178,9 @@ export function Footer() {
|
|||||||
{/* Copyright Section */}
|
{/* Copyright Section */}
|
||||||
<div className="border-t border-gray-800 px-4 py-8">
|
<div className="border-t border-gray-800 px-4 py-8">
|
||||||
<div className="mx-auto max-w-6xl">
|
<div className="mx-auto max-w-6xl">
|
||||||
<div className="flex flex-col justify-between gap-4 text-sm text-gray-400 md:flex-row md:items-center">
|
<div className="font-almarai flex flex-col justify-between gap-4 text-sm text-gray-400 md:flex-row md:items-center">
|
||||||
<div>
|
<div>
|
||||||
Copyright © 2025 Fireforce. Built with
|
Copyright © 2025 Ignum Company.
|
||||||
<span className="text-white">
|
|
||||||
{" "}
|
|
||||||
Guniverse WordPress Blocks Addons
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-6">
|
<div className="flex gap-6">
|
||||||
<a href="#terms" className="hover:text-white">
|
<a href="#terms" className="hover:text-white">
|
||||||
|
|||||||
@@ -3,8 +3,13 @@ import { useEffect, useState } from "react";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { ChevronDown, Phone, Menu, X } from "lucide-react";
|
import { ChevronDown, Phone, Menu, X } from "lucide-react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import LanguageSelectRadix from "../languageSwitcher";
|
||||||
|
import { useLocale, useTranslations } from "next-intl";
|
||||||
|
import NavbarLogo from "./navbarLogo/navbarLogo";
|
||||||
|
|
||||||
export function Navbar() {
|
export function Navbar() {
|
||||||
|
const locale = useLocale();
|
||||||
|
const t = useTranslations();
|
||||||
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||||
const [scrolled, setScrolled] = useState(false);
|
const [scrolled, setScrolled] = useState(false);
|
||||||
@@ -34,16 +39,10 @@ export function Navbar() {
|
|||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div className="flex justify-between items-center h-20">
|
<div className="flex justify-between items-center h-20">
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<Link href="/" className="hover:cursor-pointer">
|
<Link href={`/${locale}/home`} className="hover:cursor-pointer">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div className="p-2 rounded-xl flex items-center justify-center">
|
<div className=" flex items-center justify-center">
|
||||||
<Image
|
<NavbarLogo/>
|
||||||
src="/images/IGNUM/PNG/1.@6x.png"
|
|
||||||
alt="logo image"
|
|
||||||
width={70}
|
|
||||||
height={70}
|
|
||||||
className=""
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -51,25 +50,25 @@ export function Navbar() {
|
|||||||
{/* Desktop Navigation Menu */}
|
{/* Desktop Navigation Menu */}
|
||||||
<div className="hidden h-full lg:flex items-center gap-8">
|
<div className="hidden h-full lg:flex items-center gap-8">
|
||||||
<Link
|
<Link
|
||||||
href="/"
|
href={`/${locale}/home`}
|
||||||
className="text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
className="font-unbounded uppercase text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
||||||
>
|
>
|
||||||
HOME
|
{t("navbar.home")}
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/about"
|
href={`/${locale}/about`}
|
||||||
className="text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
className="font-unbounded uppercase text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
||||||
>
|
>
|
||||||
ABOUT
|
{t("navbar.about")}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
{/* Pages Dropdown */}
|
{/* Pages Dropdown */}
|
||||||
<div className="relative group h-full">
|
<div className="relative group h-full">
|
||||||
<button
|
<button
|
||||||
className="text-white text-sm h-full font-semibold hover:text-red-500
|
className="font-unbounded uppercase text-white text-sm h-full font-semibold hover:text-red-500
|
||||||
transition-colors flex items-center gap-1"
|
transition-colors flex items-center gap-1"
|
||||||
>
|
>
|
||||||
PAGES
|
{t("navbar.pages")}
|
||||||
<ChevronDown
|
<ChevronDown
|
||||||
size={16}
|
size={16}
|
||||||
className="transition-transform group-hover:rotate-180"
|
className="transition-transform group-hover:rotate-180"
|
||||||
@@ -85,22 +84,22 @@ export function Navbar() {
|
|||||||
pointer-events-none group-hover:pointer-events-auto overflow-hidden"
|
pointer-events-none group-hover:pointer-events-auto overflow-hidden"
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
href="/faq"
|
href={`/${locale}/faq`}
|
||||||
className="block px-4 py-2 text-black text-sm hover:bg-red-600
|
className="font-unbounded uppercase block px-4 py-2 text-black text-sm hover:bg-red-600
|
||||||
hover:text-white transition-colors"
|
hover:text-white transition-colors"
|
||||||
>
|
>
|
||||||
FAQ
|
{t("navbar.faq")}
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/services"
|
href={`/${locale}/services`}
|
||||||
className="block px-4 py-2 text-black text-sm hover:bg-red-600
|
className="font-unbounded uppercase block px-4 py-2 text-black text-sm hover:bg-red-600
|
||||||
hover:text-white transition-colors"
|
hover:text-white transition-colors"
|
||||||
>
|
>
|
||||||
Services
|
{t("navbar.services")}
|
||||||
</Link>
|
</Link>
|
||||||
{/* <Link
|
{/* <Link
|
||||||
href="/blog"
|
href={`/${locale}/blog`}
|
||||||
className="block px-4 py-2 text-black text-sm hover:bg-red-600
|
className="font-unbounded uppercase block px-4 py-2 text-black text-sm hover:bg-red-600
|
||||||
hover:text-white transition-colors rounded-b-md"
|
hover:text-white transition-colors rounded-b-md"
|
||||||
>
|
>
|
||||||
Blog
|
Blog
|
||||||
@@ -109,39 +108,46 @@ export function Navbar() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
href="/products"
|
href={`/${locale}/products`}
|
||||||
className="text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
className="font-unbounded uppercase text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
||||||
>
|
>
|
||||||
PRODUCTS
|
{t("navbar.products")}
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/contact"
|
href={`/${locale}/contact`}
|
||||||
className="text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
className="font-unbounded uppercase text-white text-sm h-full flex items-center font-semibold hover:cursor-pointer hover:text-red-500 transition"
|
||||||
>
|
>
|
||||||
CONTACT
|
{t("navbar.contact")}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Emergency Call Button - Hidden on mobile */}
|
<div className="flex items-center gap-5">
|
||||||
<div className="hidden lg:flex items-center gap-3 bg-red-600 px-4 py-2 rounded-full">
|
{/* Language Switcher */}
|
||||||
<Phone size={20} className="text-white" />
|
<LanguageSelectRadix />
|
||||||
<div>
|
|
||||||
<div className="text-white text-xs font-semibold">
|
{/* Emergency Call Button - Hidden on mobile */}
|
||||||
Emergency Call!
|
<div className="hidden lg:flex items-center hover:cursor-pointer gap-3 px-4 py-2 rounded-full">
|
||||||
</div>
|
<span
|
||||||
<div className="text-white text-sm font-bold">
|
className="shrink-0 w-10 h-10 bg-red-600 rounded-full flex items-center justify-center
|
||||||
+123-456-7890
|
shadow-[0_0_0px_4px_rgba(239,68,68,0.1)]"
|
||||||
|
>
|
||||||
|
<Phone size={20} className="text-white" />
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<div className="text-white text-sm font-bold">
|
||||||
|
<div>+998-98-099-21-21</div> <div>+998-77-372-21-21</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Mobile Menu Button */}
|
{/* Mobile Menu Button */}
|
||||||
<button
|
<button
|
||||||
onClick={() => setIsMobileMenuOpen(true)}
|
onClick={() => setIsMobileMenuOpen(true)}
|
||||||
className="lg:hidden text-white p-2 hover:bg-red-600 rounded-md transition"
|
className="lg:hidden text-white p-2 hover:bg-red-600 rounded-md transition"
|
||||||
>
|
>
|
||||||
<Menu size={24} />
|
<Menu size={24} />
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@@ -164,14 +170,20 @@ export function Navbar() {
|
|||||||
>
|
>
|
||||||
{/* Mobile Menu Header */}
|
{/* Mobile Menu Header */}
|
||||||
<div className="flex justify-between items-center p-6 border-b border-gray-700">
|
<div className="flex justify-between items-center p-6 border-b border-gray-700">
|
||||||
<div className="flex items-center gap-2">
|
{/* Logo */}
|
||||||
<div className="w-8 h-8 bg-red-600 rounded-full flex items-center justify-center">
|
<Link href={`/${locale}/home`} className="hover:cursor-pointer">
|
||||||
<div className="w-6 h-6 bg-white rounded-full"></div>
|
<div className="font-unbounded uppercase flex flex-col items-center text-2xl gap-2 text-white font-bold">
|
||||||
|
<div className=" flex items-center justify-center">
|
||||||
|
<Image
|
||||||
|
src="/images/IGNUM/PNG/1.@6x.png"
|
||||||
|
alt="logo image"
|
||||||
|
width={50}
|
||||||
|
height={50}
|
||||||
|
className=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-white font-bold text-lg tracking-wider">
|
</Link>
|
||||||
FIREFORCE
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<button
|
<button
|
||||||
onClick={() => setIsMobileMenuOpen(false)}
|
onClick={() => setIsMobileMenuOpen(false)}
|
||||||
className="text-white p-2 hover:bg-red-600 rounded-md transition"
|
className="text-white p-2 hover:bg-red-600 rounded-md transition"
|
||||||
@@ -183,27 +195,27 @@ export function Navbar() {
|
|||||||
{/* Mobile Menu Links */}
|
{/* Mobile Menu Links */}
|
||||||
<div className="flex flex-col p-6 gap-4">
|
<div className="flex flex-col p-6 gap-4">
|
||||||
<Link
|
<Link
|
||||||
href="/"
|
href={`/${locale}/home`}
|
||||||
className="text-white text-base font-semibold hover:text-red-500 transition py-2"
|
className="font-unbounded uppercase text-white text-base font-semibold hover:text-red-500 transition py-2"
|
||||||
onClick={() => setIsMobileMenuOpen(false)}
|
onClick={() => setIsMobileMenuOpen(false)}
|
||||||
>
|
>
|
||||||
HOME
|
{t("navbar.home")}
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/about"
|
href={`/${locale}/about`}
|
||||||
className="text-white text-base font-semibold hover:text-red-500 transition py-2"
|
className="font-unbounded uppercase text-white text-base font-semibold hover:text-red-500 transition py-2"
|
||||||
onClick={() => setIsMobileMenuOpen(false)}
|
onClick={() => setIsMobileMenuOpen(false)}
|
||||||
>
|
>
|
||||||
ABOUT
|
{t("navbar.about")}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
{/* Mobile Pages Dropdown */}
|
{/* Mobile Pages Dropdown */}
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
|
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
|
||||||
className="text-white text-base font-semibold hover:text-red-500 transition flex items-center gap-1 py-2 w-full"
|
className="font-unbounded uppercase text-white text-base font-semibold hover:text-red-500 transition flex items-center gap-1 py-2 w-full"
|
||||||
>
|
>
|
||||||
PAGES
|
{t("navbar.pages")}
|
||||||
<ChevronDown
|
<ChevronDown
|
||||||
size={16}
|
size={16}
|
||||||
className={`transition-transform ${isDropdownOpen ? "rotate-180" : ""}`}
|
className={`transition-transform ${isDropdownOpen ? "rotate-180" : ""}`}
|
||||||
@@ -212,36 +224,36 @@ export function Navbar() {
|
|||||||
{isDropdownOpen && (
|
{isDropdownOpen && (
|
||||||
<div className="ml-4 mt-2 flex flex-col gap-2">
|
<div className="ml-4 mt-2 flex flex-col gap-2">
|
||||||
<Link
|
<Link
|
||||||
href="/faq"
|
href={`/${locale}/faq`}
|
||||||
className="text-white/80 text-sm hover:text-red-500 transition py-2"
|
className="font-unbounded uppercase text-white/80 text-sm hover:text-red-500 transition py-2"
|
||||||
onClick={() => setIsMobileMenuOpen(false)}
|
onClick={() => setIsMobileMenuOpen(false)}
|
||||||
>
|
>
|
||||||
FAQ
|
{t("navbar.faq")}
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/services"
|
href={`/${locale}/services`}
|
||||||
className="text-white/80 text-sm hover:text-red-500 transition py-2"
|
className="font-unbounded uppercase text-white/80 text-sm hover:text-red-500 transition py-2"
|
||||||
onClick={() => setIsMobileMenuOpen(false)}
|
onClick={() => setIsMobileMenuOpen(false)}
|
||||||
>
|
>
|
||||||
Services
|
{t("navbar.services")}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
href="/products"
|
href={`/${locale}/products`}
|
||||||
className="text-white text-base font-semibold hover:text-red-500 transition py-2"
|
className="font-unbounded uppercase text-white text-base font-semibold hover:text-red-500 transition py-2"
|
||||||
onClick={() => setIsMobileMenuOpen(false)}
|
onClick={() => setIsMobileMenuOpen(false)}
|
||||||
>
|
>
|
||||||
PRODUCTS
|
{t("navbar.products")}
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/contact"
|
href={`/${locale}/contact`}
|
||||||
className="text-white text-base font-semibold hover:text-red-500 transition py-2"
|
className="font-unbounded uppercase text-white text-base font-semibold hover:text-red-500 transition py-2"
|
||||||
onClick={() => setIsMobileMenuOpen(false)}
|
onClick={() => setIsMobileMenuOpen(false)}
|
||||||
>
|
>
|
||||||
CONTACT
|
{t("navbar.contact")}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
35
components/layout/navbarLogo/logo.css
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
.logo-path {
|
||||||
|
stroke-dasharray: 2000;
|
||||||
|
stroke-dashoffset: 2000;
|
||||||
|
animation: drawLogo 3s ease-in-out forwards;
|
||||||
|
fill: none !important;
|
||||||
|
stroke: url(#neon-gradient);
|
||||||
|
stroke-width: 2px;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: round;
|
||||||
|
filter: url(#neon-glow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ketma-ket chizish */
|
||||||
|
.logo-path:nth-child(1) { animation-delay: 0s; }
|
||||||
|
.logo-path:nth-child(2) { animation-delay: 0.3s; }
|
||||||
|
.logo-path:nth-child(3) { animation-delay: 0.6s; }
|
||||||
|
.logo-path:nth-child(4) { animation-delay: 0.9s; }
|
||||||
|
.logo-path:nth-child(5) { animation-delay: 1.2s; }
|
||||||
|
.logo-path:nth-child(6) { animation-delay: 1.5s; }
|
||||||
|
.logo-path:nth-child(7) { animation-delay: 1.8s; }
|
||||||
|
|
||||||
|
@keyframes drawLogo {
|
||||||
|
0% {
|
||||||
|
stroke-dashoffset: 2000;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
opacity: 1;
|
||||||
|
fill: url(#neon-gradient); /* Oxirida to'ldiriladi */
|
||||||
|
}
|
||||||
|
}
|
||||||
60
components/layout/navbarLogo/navbarLogo.tsx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import "./logo.css";
|
||||||
|
|
||||||
|
export default function NavbarLogo() {
|
||||||
|
return (
|
||||||
|
<div className="relative w-24 h-12">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 423.22 424.82"
|
||||||
|
className="w-full h-full"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
{/* Qizil neon gradient */}
|
||||||
|
<linearGradient id="neon-gradient" x1="0%" y1="100%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" stopColor="#979797" />
|
||||||
|
<stop offset="50%" stopColor="#e4e4e4" />
|
||||||
|
<stop offset="100%" stopColor="#9a9a9a" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
{/* Neon glow filter */}
|
||||||
|
<filter id="neon-glow">
|
||||||
|
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<g>
|
||||||
|
<polygon
|
||||||
|
className="logo-path"
|
||||||
|
points="352.86 365.08 347.11 365.08 347.11 381 289.38 381 289.38 365.08 283.63 365.08 283.63 381 204.78 381 204.78 365.08 199.03 365.08 199.03 381 141.32 381 141.32 365.08 135.57 365.08 135.57 381 77.87 381 77.87 365.08 71.86 365.08 71.85 381 17.21 381 17.21 386.74 72.11 386.74 72.11 424.82 74.04 424.82 74.04 386.74 350.94 386.74 350.94 424.82 352.86 424.82 352.86 386.74 406.02 386.74 406.02 381 352.86 381 352.86 365.08"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
className="logo-path"
|
||||||
|
d="m72.11,157.74v73.55l-41.42,23.89h3.83l37.58-21.68-.04,21.68h5.79v-24.99l57.7-33.27v58.26h5.75v-57.15l57.71-33.29v90.44h5.75v-90.43l39.43,22.77,39.43,22.77v44.89h5.74v-41.58l57.73,33.32v8.25h5.75v-95.41h-1.92v82.75l-61.56-35.55v-98.77l59.59-34.35-.97-1.66-58.62,33.81V0h-1.92v42.86h-88.43v115.23l-5.2,3-14.21,8.16-27.25,15.74-11.05,6.37v-73.53l36.14-20.85-.96-1.66-35.19,20.29v-35.03h-1.92v36.13l-65.36,37.7v-37.25h-1.92v38.35l-53.08,30.6.96,1.67,52.12-30.07ZM204.78,48.58h78.85v60.71l-78.85,45.48V48.58Zm0,108.41l78.85-45.49v92.14l-78.85-45.54v-1.11Zm-126.91,1.92l57.7-33.32v69.11l-57.7,33.26v-69.05Z"
|
||||||
|
/>
|
||||||
|
<g>
|
||||||
|
<rect className="logo-path" y="277.99" width="12.06" height="64.23" />
|
||||||
|
<path
|
||||||
|
className="logo-path"
|
||||||
|
d="m88.82,342.36c3.93-.65,7.51-1.73,10.75-3.23,3.24-1.5,6.01-3.46,8.32-5.89l1.31,8.97h7.76v-35.25h-39.45v9.72h27.58v1.03c0,3.12-.94,5.84-2.8,8.18-1.87,2.34-4.81,4.13-8.83,5.38-4.02,1.25-9.3,1.87-15.85,1.87-5.49,0-10.28-.73-14.4-2.2-4.11-1.46-7.32-3.8-9.63-7.01-2.31-3.21-3.46-7.46-3.46-12.76v-2.24c0-3.93.75-7.28,2.24-10.05,1.5-2.77,3.58-5.03,6.26-6.78,2.68-1.74,5.8-3.02,9.35-3.83,3.55-.81,7.39-1.21,11.5-1.21,3.37,0,6.56.2,9.58.61,3.02.41,5.75,1.11,8.18,2.1,2.43,1,4.35,2.38,5.75,4.16,1.4,1.78,2.1,3.97,2.1,6.59h11.78c0-4.05-.89-7.56-2.66-10.52-1.78-2.96-4.33-5.41-7.67-7.34-3.33-1.93-7.32-3.38-11.97-4.35-4.64-.97-9.83-1.45-15.57-1.45-8.6,0-15.99,1.25-22.16,3.74-6.17,2.49-10.89,6.22-14.16,11.17-3.27,4.95-4.91,11.08-4.91,18.37,0,11.16,3.23,19.48,9.68,24.96,6.45,5.49,16.16,8.23,29.12,8.23,4.24,0,8.32-.33,12.25-.98Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
className="logo-path"
|
||||||
|
d="m160.8,299.31c1.68,1.81,3.3,3.49,4.86,5.05l37.96,37.86h11.12v-64.23h-11.59v37.02c0,1.31.03,2.9.09,4.77.06,1.87.12,3.43.19,4.68h-.75c-.75-.87-1.67-1.87-2.76-2.99-1.09-1.12-2.15-2.23-3.18-3.32-1.03-1.09-1.92-1.98-2.66-2.66l-37.86-37.49h-11.5v64.23h11.59v-36.37c0-2.31-.02-4.46-.05-6.45-.03-1.99-.08-3.46-.14-4.39h.65c1,1.06,2.34,2.49,4.02,4.3Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
className="logo-path"
|
||||||
|
d="m242.6,277.99v35.34c0,6.11,1.26,11.42,3.79,15.94,2.52,4.52,6.36,7.99,11.5,10.42,5.14,2.43,11.64,3.65,19.49,3.65s14.33-1.21,19.45-3.65c5.11-2.43,8.93-5.9,11.45-10.42,2.52-4.52,3.79-9.83,3.79-15.94v-35.34h-12.06v34.97c0,6.48-1.96,11.47-5.89,14.96-3.93,3.49-9.5,5.23-16.73,5.23s-12.89-1.74-16.78-5.23c-3.9-3.49-5.84-8.48-5.84-14.96v-34.97h-12.15Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
className="logo-path"
|
||||||
|
d="m404.99,277.99l-17.2,37.02c-.5,1.12-1.11,2.51-1.82,4.16-.72,1.65-1.42,3.32-2.1,5-.69,1.68-1.31,3.18-1.87,4.49h-.56c-.62-1.5-1.3-3.12-2.01-4.86-.72-1.74-1.42-3.44-2.1-5.1-.69-1.65-1.25-2.94-1.68-3.88l-17.2-36.83h-18.51v64.23h11.59v-40.29c0-1.31-.02-2.67-.05-4.07-.03-1.4-.06-2.76-.09-4.07-.03-1.31-.08-2.4-.14-3.27h.75c.31.81.67,1.79,1.07,2.94.4,1.15.89,2.37,1.45,3.65.56,1.28,1.12,2.51,1.68,3.69l19.26,41.42h11.87l19.17-41.42c.43-.94.92-2.02,1.45-3.27.53-1.25,1.04-2.49,1.54-3.74.5-1.25.9-2.34,1.22-3.27h.75c-.06,1-.13,2.18-.19,3.55-.06,1.37-.11,2.74-.14,4.11-.03,1.37-.05,2.62-.05,3.74v40.29h12.15v-64.23h-18.23Z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
71
components/pageTransition/page-transition.css
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
.page-transition-overlay {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
pointer-events: none;
|
||||||
|
transition: background-color 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-transition-overlay.active {
|
||||||
|
background-color: rgba(0, 0, 0, 0.95);
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transition-svg {
|
||||||
|
width: 40vw;
|
||||||
|
height: 40vh;
|
||||||
|
max-width: 600px;
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.5);
|
||||||
|
transition: all 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-transition-overlay.active .transition-svg {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.transition-path {
|
||||||
|
stroke-dasharray: 2000;
|
||||||
|
stroke-dashoffset: 2000;
|
||||||
|
fill: none !important;
|
||||||
|
stroke: url(#transition-gradient);
|
||||||
|
stroke-width: 3px;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: round;
|
||||||
|
filter: url(#transition-glow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-transition-overlay.active .transition-path {
|
||||||
|
animation: drawTransition 1s ease-in-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transition-path:nth-child(1) { animation-delay: 0s; }
|
||||||
|
.transition-path:nth-child(2) { animation-delay: 0.2s; }
|
||||||
|
|
||||||
|
@keyframes drawTransition {
|
||||||
|
0% {
|
||||||
|
stroke-dashoffset: 2000;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content.transitioning {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
63
components/pageTransition/pageTransition.tsx
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
"use client";
|
||||||
|
import { usePathname } from "next/navigation";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import "./page-transition.css";
|
||||||
|
|
||||||
|
export default function PageTransition({ children }: { children: React.ReactNode }) {
|
||||||
|
const pathname = usePathname();
|
||||||
|
const [isTransitioning, setIsTransitioning] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsTransitioning(true);
|
||||||
|
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setIsTransitioning(false);
|
||||||
|
}, 1500); // Animatsiya davomiyligi
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [pathname]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* Transition overlay */}
|
||||||
|
<div className={`page-transition-overlay ${isTransitioning ? "active" : ""}`}>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 423.22 424.82"
|
||||||
|
className="transition-svg"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="transition-gradient" x1="0%" y1="100%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" stopColor="#ff0000" />
|
||||||
|
<stop offset="50%" stopColor="#ff4444" />
|
||||||
|
<stop offset="100%" stopColor="#ff0000" />
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<filter id="transition-glow">
|
||||||
|
<feGaussianBlur stdDeviation="5" result="coloredBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<g>
|
||||||
|
<polygon
|
||||||
|
className="transition-path"
|
||||||
|
points="352.86 365.08 347.11 365.08 347.11 381 289.38 381 289.38 365.08 283.63 365.08 283.63 381 204.78 381 204.78 365.08 199.03 365.08 199.03 381 141.32 381 141.32 365.08 135.57 365.08 135.57 381 77.87 381 77.87 365.08 71.86 365.08 71.85 381 17.21 381 17.21 386.74 72.11 386.74 72.11 424.82 74.04 424.82 74.04 386.74 350.94 386.74 350.94 424.82 352.86 424.82 352.86 386.74 406.02 386.74 406.02 381 352.86 381 352.86 365.08"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
className="transition-path"
|
||||||
|
d="m72.11,157.74v73.55l-41.42,23.89h3.83l37.58-21.68-.04,21.68h5.79v-24.99l57.7-33.27v58.26h5.75v-57.15l57.71-33.29v90.44h5.75v-90.43l39.43,22.77,39.43,22.77v44.89h5.74v-41.58l57.73,33.32v8.25h5.75v-95.41h-1.92v82.75l-61.56-35.55v-98.77l59.59-34.35-.97-1.66-58.62,33.81V0h-1.92v42.86h-88.43v115.23l-5.2,3-14.21,8.16-27.25,15.74-11.05,6.37v-73.53l36.14-20.85-.96-1.66-35.19,20.29v-35.03h-1.92v36.13l-65.36,37.7v-37.25h-1.92v38.35l-53.08,30.6.96,1.67,52.12-30.07ZM204.78,48.58h78.85v60.71l-78.85,45.48V48.58Zm0,108.41l78.85-45.49v92.14l-78.85-45.54v-1.11Zm-126.91,1.92l57.7-33.32v69.11l-57.7,33.26v-69.05Z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Page content */}
|
||||||
|
<div className={`page-content ${isTransitioning ? "transitioning" : ""}`}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function AboutBanner() {
|
export function AboutBanner() {
|
||||||
|
const t = useTranslations();
|
||||||
return (
|
return (
|
||||||
<section className="relative w-full lg:h-[60vh] h-screen min-h-100 overflow-hidden pt-10">
|
<section className="relative w-full lg:h-[60vh] h-screen min-h-100 overflow-hidden pt-10">
|
||||||
{/* Background Image */}
|
{/* Background Image */}
|
||||||
@@ -24,17 +26,21 @@ export function AboutBanner() {
|
|||||||
<div className="max-w-250 w-full mx-auto px-4">
|
<div className="max-w-250 w-full mx-auto px-4">
|
||||||
<div className="relative z-20 h-full flex max-lg:flex-col items-start justify-between gap-5 pt-30">
|
<div className="relative z-20 h-full flex max-lg:flex-col items-start justify-between gap-5 pt-30">
|
||||||
<div className="spacw-y-4 ">
|
<div className="spacw-y-4 ">
|
||||||
<DotAnimatsiya />
|
<div className="flex items-center gap-3">
|
||||||
|
<DotAnimatsiya />
|
||||||
|
<span className="font-almarai text-sm text-white font-semibold tracking-wide">
|
||||||
|
{t("about.banner.title")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<p
|
<p
|
||||||
className=" bg-linear-to-br from-white via-white to-black
|
className="font-unbounded uppercase bg-linear-to-br from-white via-white to-black
|
||||||
text-transparent bg-clip-text text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty"
|
text-transparent bg-clip-text text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty"
|
||||||
>
|
>
|
||||||
Fire Fighter <br /> At The Ready
|
{t("about.banner.subtitle")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="lg:w-[40%] text-gray-300 mt-20">
|
<div className="font-almarai lg:w-[40%] text-gray-300 mt-20">
|
||||||
It emphasizes that these firefighters are there not just as public
|
{t("about.banner.description")}
|
||||||
servants but as a vital part of the community.
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
import { useTranslations } from "next-intl";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
|
||||||
export function Story() {
|
export function Story() {
|
||||||
|
const t = useTranslations();
|
||||||
return (
|
return (
|
||||||
<div className="bg-[#1e1d1c] pb-0 relative z-10 max-[350px]:pb-30 ">
|
<div className="pb-0 relative z-10 max-[350px]:pb-30 ">
|
||||||
<div className="max-w-260 mx-auto px-4">
|
<div className="max-w-260 mx-auto px-4">
|
||||||
<section className="relative -top-30 rounded-xl w-full lg:h-[70vh] h-[80vh] min-h-150 sm:overflow-hidden shadow-2xl flex flex-col items-start justify-between">
|
<section className="relative -top-30 rounded-xl w-full lg:h-[70vh] h-[80vh] min-h-150 sm:overflow-hidden shadow-2xl flex flex-col items-start justify-between">
|
||||||
{/* Background Image */}
|
{/* Background Image */}
|
||||||
@@ -25,22 +27,14 @@ export function Story() {
|
|||||||
|
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
<div className="relative z-20 p-8 lg:p-12 max-w-130">
|
<div className="relative z-20 p-8 lg:p-12 max-w-130">
|
||||||
<h2 className="text-white text-4xl lg:text-5xl font-bold mb-6">
|
<h2 className="uppercase font-unbounded text-white text-4xl lg:text-5xl font-bold mb-6">
|
||||||
OUR STORY
|
{t("about.story.title")}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-gray-300 mb-4">
|
<p className="font-almarai text-gray-300 mb-4">
|
||||||
Our story is one of unwavering dedication, selflessness, and a{" "}
|
{t("about.story.description")}
|
||||||
<span className="text-white font-semibold">
|
|
||||||
deep commitment to the safety
|
|
||||||
</span>
|
|
||||||
and well-being of our communities.
|
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-400 mb-6">
|
<button className="font-almarai text-white flex items-center gap-2 hover:text-red-500 transition">
|
||||||
Aliquam lorem ante dapibus in viverra quis a tellus phasellus
|
{t("about.story.readMore")}
|
||||||
viverra nulla ut metus varius laoreet quisque rutrum.
|
|
||||||
</p>
|
|
||||||
<button className="text-white flex items-center gap-2 hover:text-red-500 transition">
|
|
||||||
READ MORE
|
|
||||||
<svg
|
<svg
|
||||||
className="w-4 h-4"
|
className="w-4 h-4"
|
||||||
fill="none"
|
fill="none"
|
||||||
@@ -74,14 +68,15 @@ export function Story() {
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<div className="space-y-1 text-white">
|
<div className="space-y-1 text-white">
|
||||||
<h2 className="text-xl font-semibold">FIREFORCE VISION</h2>
|
<h2 className="font-unbounded text-xl font-semibold">
|
||||||
<p>
|
{t("about.story.vision.title")}
|
||||||
Phasellus viverra nulla ut metus varius leo imperdiet laoreet.
|
</h2>
|
||||||
Quisque rutrum aenean augue vulputate eleifend.
|
<p className="font-almarai">
|
||||||
|
{t("about.story.vision.description")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex sm:flex-row flex-col sm:items-center items-start md:rounded-t-xl max-md:rounded-xl max-w-md w-full sm:p-7 p-2 bg-black sm:gap-5 gap-2">
|
<div className="flex sm:flex-row flex-col sm:items-center items-start md:rounded-t-xl max-md:rounded-xl max-w-md w-full sm:p-4 p-2 bg-black sm:gap-5 gap-2">
|
||||||
<span className="sm:rounded-xl rounded-lg bg-[#1e1d1c] sm:p-3 p-1 max-sm:w-15 max-sm:h-15">
|
<span className="sm:rounded-xl rounded-lg bg-[#1e1d1c] sm:p-3 p-1 max-sm:w-15 max-sm:h-15">
|
||||||
<Image
|
<Image
|
||||||
src="/images/about/fireforce-mission.png"
|
src="/images/about/fireforce-mission.png"
|
||||||
@@ -92,10 +87,11 @@ export function Story() {
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<div className="space-y-1 text-white">
|
<div className="space-y-1 text-white">
|
||||||
<h2 className="text-xl font-semibold">FIREFORCE VISION</h2>
|
<h2 className="font-unbounded text-xl font-semibold">
|
||||||
<p>
|
{t("about.story.mission.title")}
|
||||||
Phasellus viverra nulla ut metus varius leo imperdiet laoreet.
|
</h2>
|
||||||
Quisque rutrum aenean augue vulputate eleifend.
|
<p className="font-almarai">
|
||||||
|
{t("about.story.mission.description")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,13 +3,15 @@
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Check } from "lucide-react";
|
import { Check } from "lucide-react";
|
||||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function WhyChooseUs() {
|
export function WhyChooseUs() {
|
||||||
|
const t = useTranslations();
|
||||||
const features = [
|
const features = [
|
||||||
{ title: "Fast Response Team" },
|
{ title: t("about.whyChoose.features.fastResponse") },
|
||||||
{ title: "Experienced Firefighter" },
|
{ title: t("about.whyChoose.features.ready24") },
|
||||||
{ title: "Ready 24 Hours" },
|
{ title: t("about.whyChoose.features.experienced") },
|
||||||
{ title: "Fast Response Team" },
|
{ title: t("about.whyChoose.features.quality") },
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -21,24 +23,21 @@ export function WhyChooseUs() {
|
|||||||
<div>
|
<div>
|
||||||
<div className="mb-4 flex items-center gap-2">
|
<div className="mb-4 flex items-center gap-2">
|
||||||
<DotAnimatsiya />
|
<DotAnimatsiya />
|
||||||
<span className="text-sm font-semibold tracking-wider text-white">
|
<span className="font-almarai text-sm font-semibold tracking-wider text-white">
|
||||||
WHY CHOOSE US
|
{t("about.whyChoose.title")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<h2
|
<h2
|
||||||
className="bg-linear-to-br from-white via-white to-black
|
className="font-unbounded uppercase bg-linear-to-br from-white via-white to-black
|
||||||
text-transparent bg-clip-text text-4xl font-bold sm:text-5xl lg:text-6xl"
|
text-transparent bg-clip-text text-3xl font-bold sm:text-4xl lg:text-5xl"
|
||||||
>
|
>
|
||||||
WE ARE BEST
|
{t("about.whyChoose.subtitle")}
|
||||||
<br />
|
|
||||||
FIREFIGHTER
|
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Description */}
|
{/* Description */}
|
||||||
<p className="text-base leading-relaxed text-gray-400 sm:text-lg">
|
<p className="font-almarai text-base leading-relaxed text-gray-400 sm:text-lg">
|
||||||
Aliquam lorem ante dapibus in viverra quis a tellus phasellus
|
{t("about.whyChoose.description")}
|
||||||
viverra nulla ut metus varius laoreet quisque rutrum.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* Features Grid */}
|
{/* Features Grid */}
|
||||||
@@ -48,7 +47,7 @@ export function WhyChooseUs() {
|
|||||||
<div className="shrink-0">
|
<div className="shrink-0">
|
||||||
<Check className="h-5 w-5 text-red-600 sm:h-6 sm:w-6" />
|
<Check className="h-5 w-5 text-red-600 sm:h-6 sm:w-6" />
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm font-medium text-white sm:text-base">
|
<span className="font-almarai text-sm font-medium text-white sm:text-base">
|
||||||
{feature.title}
|
{feature.title}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -57,8 +56,8 @@ export function WhyChooseUs() {
|
|||||||
|
|
||||||
{/* CTA Button */}
|
{/* CTA Button */}
|
||||||
<div>
|
<div>
|
||||||
<button className="shadow-[0px_0px_2px_8px_#ff01015c] rounded-full bg-red-600 px-6 py-3 font-bold text-white transition-all hover:bg-red-700 sm:px-8 sm:py-4">
|
<button className="font-almarai shadow-[0px_0px_2px_8px_#ff01015c] rounded-full bg-red-600 px-6 py-3 font-bold text-white transition-all hover:bg-red-700 sm:px-8 sm:py-4">
|
||||||
CONTACT US
|
{t("about.whyChoose.contact")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -87,11 +86,8 @@ export function WhyChooseUs() {
|
|||||||
className="h-24 w-24 sm:h-20 sm:w-20"
|
className="h-24 w-24 sm:h-20 sm:w-20"
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-bold text-white sm:text-base">
|
<p className="font-almarai text-sm font-bold text-white sm:text-base">
|
||||||
BEST AWARD
|
{t("about.whyChoose.award")}
|
||||||
</p>
|
|
||||||
<p className="text-xs text-gray-400 sm:text-sm">
|
|
||||||
FIREFIGHTER 2025
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,23 +1,25 @@
|
|||||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
export default function ContactHeader() {
|
export default function ContactHeader() {
|
||||||
|
const t = useTranslations();
|
||||||
return (
|
return (
|
||||||
<div className="mb-8 text-center">
|
<div className="mb-8 text-center">
|
||||||
<div className="mb-4 flex items-center justify-center gap-2">
|
<div className="mb-4 flex items-center justify-center gap-2">
|
||||||
<DotAnimatsiya />
|
<DotAnimatsiya />
|
||||||
<span className="text-sm font-semibold tracking-wider text-white">
|
<span className="font-almarai text-sm font-semibold tracking-wider text-white">
|
||||||
CONTACT US
|
{t("contact.banner.title")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<h2
|
<h2
|
||||||
className="bg-linear-to-br from-white via-white to-black
|
className="uppercase font-unbounded bg-linear-to-br from-white via-white to-black
|
||||||
text-transparent bg-clip-text text-4xl font-bold tracking-wide md:text-5xl"
|
text-transparent bg-clip-text text-4xl font-bold tracking-wide md:text-5xl"
|
||||||
>
|
>
|
||||||
GET IN TOUCH
|
{t("contact.banner.subtitle")}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mt-3 text-sm text-gray-300 italic">
|
<p className="font-almarai mt-3 text-sm text-gray-300 italic">
|
||||||
We'd love to hear from you. Please fill out this form.
|
{t("contact.banner.description")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Check } from "lucide-react";
|
import { Check } from "lucide-react";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
interface FormData {
|
interface FormData {
|
||||||
@@ -22,6 +23,7 @@ interface FormErrors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Form() {
|
export default function Form() {
|
||||||
|
const t = useTranslations();
|
||||||
const [formData, setFormData] = useState<FormData>({
|
const [formData, setFormData] = useState<FormData>({
|
||||||
firstName: "",
|
firstName: "",
|
||||||
lastName: "",
|
lastName: "",
|
||||||
@@ -124,30 +126,31 @@ export default function Form() {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="firstName"
|
name="firstName"
|
||||||
placeholder="First Name"
|
placeholder={t("contact.form.placeholders.firstName")}
|
||||||
value={formData.firstName}
|
value={formData.firstName}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className={`w-full rounded-3xl border bg-white px-4 py-3 text-sm text-gray-700 placeholder-gray-400 outline-none transition focus:ring-2 focus:ring-red-500 ${
|
className={`font-almarai w-full rounded-3xl border bg-white px-4 py-3 text-sm
|
||||||
|
text-gray-700 placeholder-gray-400 outline-none transition focus:ring-2 focus:ring-red-500 ${
|
||||||
errors.firstName ? "border-red-500" : "border-transparent"
|
errors.firstName ? "border-red-500" : "border-transparent"
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
{errors.firstName && (
|
{errors.firstName && (
|
||||||
<p className="mt-1 text-xs text-red-500">{errors.firstName}</p>
|
<p className="font-almarai mt-1 text-xs text-red-500">{errors.firstName}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="lastName"
|
name="lastName"
|
||||||
placeholder="Last Name"
|
placeholder={t("contact.form.placeholders.lastName")}
|
||||||
value={formData.lastName}
|
value={formData.lastName}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className={`w-full rounded-3xl border bg-white px-4 py-3 text-sm text-gray-700 placeholder-gray-400 outline-none transition focus:ring-2 focus:ring-red-500 ${
|
className={`font-almarai w-full rounded-3xl border bg-white px-4 py-3 text-sm text-gray-700 placeholder-gray-400 outline-none transition focus:ring-2 focus:ring-red-500 ${
|
||||||
errors.lastName ? "border-red-500" : "border-transparent"
|
errors.lastName ? "border-red-500" : "border-transparent"
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
{errors.lastName && (
|
{errors.lastName && (
|
||||||
<p className="mt-1 text-xs text-red-500">{errors.lastName}</p>
|
<p className="font-almarai mt-1 text-xs text-red-500">{errors.lastName}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -158,30 +161,30 @@ export default function Form() {
|
|||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
name="email"
|
name="email"
|
||||||
placeholder="Your Email Address"
|
placeholder={t("contact.form.placeholders.email")}
|
||||||
value={formData.email}
|
value={formData.email}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className={`w-full rounded-3xl border bg-white px-4 py-3 text-sm text-gray-700 placeholder-gray-400 outline-none transition focus:ring-2 focus:ring-red-500 ${
|
className={`font-almarai w-full rounded-3xl border bg-white px-4 py-3 text-sm text-gray-700 placeholder-gray-400 outline-none transition focus:ring-2 focus:ring-red-500 ${
|
||||||
errors.email ? "border-red-500" : "border-transparent"
|
errors.email ? "border-red-500" : "border-transparent"
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
{errors.email && (
|
{errors.email && (
|
||||||
<p className="mt-1 text-xs text-red-500">{errors.email}</p>
|
<p className="font-almarai mt-1 text-xs text-red-500">{errors.email}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="subject"
|
name="subject"
|
||||||
placeholder="Subject"
|
placeholder={t("contact.form.placeholders.subject")}
|
||||||
value={formData.subject}
|
value={formData.subject}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className={`w-full rounded-3xl border bg-white px-4 py-3 text-sm text-gray-700 placeholder-gray-400 outline-none transition focus:ring-2 focus:ring-red-500 ${
|
className={`font-almarai w-full rounded-3xl border bg-white px-4 py-3 text-sm text-gray-700 placeholder-gray-400 outline-none transition focus:ring-2 focus:ring-red-500 ${
|
||||||
errors.subject ? "border-red-500" : "border-transparent"
|
errors.subject ? "border-red-500" : "border-transparent"
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
{errors.subject && (
|
{errors.subject && (
|
||||||
<p className="mt-1 text-xs text-red-500">{errors.subject}</p>
|
<p className="font-almarai mt-1 text-xs text-red-500">{errors.subject}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -190,16 +193,16 @@ export default function Form() {
|
|||||||
<div>
|
<div>
|
||||||
<textarea
|
<textarea
|
||||||
name="message"
|
name="message"
|
||||||
placeholder="Leave us a message"
|
placeholder={t("contact.form.placeholders.message")}
|
||||||
rows={8}
|
rows={8}
|
||||||
value={formData.message}
|
value={formData.message}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className={`w-full resize-none rounded-md border bg-white px-4 py-3 text-sm text-gray-700 placeholder-gray-400 outline-none transition focus:ring-2 focus:ring-red-500 ${
|
className={`font-almarai w-full resize-none rounded-md border bg-white px-4 py-3 text-sm text-gray-700 placeholder-gray-400 outline-none transition focus:ring-2 focus:ring-red-500 ${
|
||||||
errors.message ? "border-red-500" : "border-transparent"
|
errors.message ? "border-red-500" : "border-transparent"
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
{errors.message && (
|
{errors.message && (
|
||||||
<p className="mt-1 text-xs text-red-500">{errors.message}</p>
|
<p className="font-almarai mt-1 text-xs text-red-500">{errors.message}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -220,30 +223,30 @@ export default function Form() {
|
|||||||
<Check className="h-3 w-3 text-white" strokeWidth={3} />
|
<Check className="h-3 w-3 text-white" strokeWidth={3} />
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
<span className="text-sm text-gray-300">
|
<span className="font-almarai text-sm text-gray-300">
|
||||||
You agree to our friendly privacy policy
|
{t("contact.form.privacy")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
className="shadow-[0px_0px_2px_8px_#ff01015c] rounded-full bg-red-600 px-8 py-3 text-sm font-semibold uppercase tracking-wider text-white transition hover:cursor-pointer hover:scale-90 disabled:cursor-not-allowed disabled:opacity-50"
|
className="font-almarai shadow-[0px_0px_2px_8px_#ff01015c] rounded-full bg-red-600 px-8 py-3 text-sm font-semibold uppercase tracking-wider text-white transition hover:cursor-pointer hover:scale-90 disabled:cursor-not-allowed disabled:opacity-50"
|
||||||
>
|
>
|
||||||
{isSubmitting ? "Sending..." : "Send Message"}
|
{isSubmitting ? "Sending..." : t("contact.form.send")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{errors.agreeToPolicy && (
|
{errors.agreeToPolicy && (
|
||||||
<p className="text-xs text-red-500">{errors.agreeToPolicy}</p>
|
<p className="font-almarai text-xs text-red-500">{errors.agreeToPolicy}</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Status Messages */}
|
{/* Status Messages */}
|
||||||
{submitStatus === "success" && (
|
{submitStatus === "success" && (
|
||||||
<p className="text-center text-sm text-green-400">
|
<p className="font-almarai text-center text-sm text-green-400">
|
||||||
Message sent successfully!
|
Message sent successfully!
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{submitStatus === "error" && (
|
{submitStatus === "error" && (
|
||||||
<p className="text-center text-sm text-red-400">
|
<p className="font-almarai text-center text-sm text-red-400">
|
||||||
Failed to send message. Please try again.
|
Failed to send message. Please try again.
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -2,23 +2,25 @@ import Image from "next/image";
|
|||||||
import { Mail, MapPin, Phone, Check } from "lucide-react";
|
import { Mail, MapPin, Phone, Check } from "lucide-react";
|
||||||
import ContactHeader from "./contactHeader";
|
import ContactHeader from "./contactHeader";
|
||||||
import Form from "./form";
|
import Form from "./form";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function Contact() {
|
export function Contact() {
|
||||||
|
const t = useTranslations();
|
||||||
const contactInfo = [
|
const contactInfo = [
|
||||||
{
|
{
|
||||||
icon: Mail,
|
icon: Mail,
|
||||||
title: "EMAIL",
|
title:t("contact.form.email"),
|
||||||
detail: "support@fireforce",
|
detail: t("contact.form.emailAddress"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: MapPin,
|
icon: MapPin,
|
||||||
title: "OUR LOCATION",
|
title: t("contact.form.location"),
|
||||||
detail: "Jl. Dr. Ir. Soekarno No. 99x Tabanan - Bali",
|
detail: t("contact.form.address"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: Phone,
|
icon: Phone,
|
||||||
title: "PHONE",
|
title: t("contact.form.phone"),
|
||||||
detail: "+123-456-7890",
|
detail: "+998-77-372-21-21",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -38,7 +40,7 @@ export function Contact() {
|
|||||||
className="absolute inset-0"
|
className="absolute inset-0"
|
||||||
style={{
|
style={{
|
||||||
background:
|
background:
|
||||||
"radial-gradient(ellipse at bottom center, #d2610ab0 0%, #1e1d1ce3 70%)",
|
"radial-gradient(ellipse at bottom center, #d2610a 0%, #1e1d1ce9 70% , #1e1d1ce9 70%)",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -59,10 +61,10 @@ export function Contact() {
|
|||||||
<div className="mb-3 flex h-14 w-14 items-center justify-center rounded-xl bg-[#2c2b2a]">
|
<div className="mb-3 flex h-14 w-14 items-center justify-center rounded-xl bg-[#2c2b2a]">
|
||||||
<info.icon className="h-6 w-6 text-red-600" />
|
<info.icon className="h-6 w-6 text-red-600" />
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-sm font-bold tracking-wider text-white">
|
<h3 className="font-almarai text-sm font-bold tracking-wider text-white">
|
||||||
{info.title}
|
{info.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mt-1 text-sm text-gray-400">{info.detail}</p>
|
<p className="font-almarai mt-1 text-sm text-gray-400">{info.detail}</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,44 +1,73 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import FAQAccordion from "./faqAccardion";
|
import FAQAccordion from "./faqAccardion";
|
||||||
import { faqItems } from "@/lib/demoData";
|
import { faqItems } from "@/lib/demoData";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function Togle() {
|
export function Togle() {
|
||||||
|
const t = useTranslations();
|
||||||
|
const faqItems = [
|
||||||
|
{
|
||||||
|
id: "faq-1",
|
||||||
|
question: t("faq.question1.question"),
|
||||||
|
answer: t("faq.question1.answer"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "faq-2",
|
||||||
|
question: t("faq.question2.question"),
|
||||||
|
answer: t("faq.question2.answer"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "faq-3",
|
||||||
|
question: t("faq.question3.question"),
|
||||||
|
answer: t("faq.question3.answer"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "faq-4",
|
||||||
|
question: t("faq.question4.question"),
|
||||||
|
answer: t("faq.question4.answer"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "faq-5",
|
||||||
|
question: t("faq.question5.question"),
|
||||||
|
answer: t("faq.question5.answer"),
|
||||||
|
},
|
||||||
|
];
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-[#1e1d1c]">
|
<div className="min-h-screen bg-[#1e1d1c]">
|
||||||
<main className="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8">
|
<main className="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8">
|
||||||
{/* Header Section */}
|
{/* Header Section */}
|
||||||
<div className="mb-16 flex items-start justify-between gap-8 lg:gap-12">
|
<div className="mb-16 flex items-start justify-between gap-4 lg:gap-12">
|
||||||
<div className="flex items-center md:col-span-1">
|
<div className="flex items-center md:col-span-1">
|
||||||
<h1
|
<h1
|
||||||
className="bg-linear-to-br from-white via-white/50 to-black
|
className="font-unbounded uppercase bg-linear-to-br from-white via-white/50 to-black
|
||||||
text-transparent bg-clip-text text-3xl font-bold uppercase leading-tight sm:text-4xl md:text-5xl lg:text-6xl"
|
text-transparent bg-clip-text text-3xl font-bold leading-tight sm:text-4xl md:text-5xl lg:text-6xl"
|
||||||
>
|
>
|
||||||
About <br /> Work
|
{t("faq.banner.topic")}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* FAQ Section */}
|
{/* FAQ Section */}
|
||||||
<div className="md:col-span-2">
|
<div className="max-w-250 w-full">
|
||||||
<FAQAccordion items={faqItems} />
|
<FAQAccordion items={faqItems} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* ASK QUESTION */}
|
{/* ASK QUESTION */}
|
||||||
<div className="space-y-8 w-full mt-10 ">
|
<div className="space-y-8 w-full mt-10 ">
|
||||||
<h1
|
<h1
|
||||||
className="text-center bg-linear-to-br from-white via-white/50 to-black
|
className="font-unbounded uppercase text-center bg-linear-to-br from-white via-white/50 to-black
|
||||||
text-transparent bg-clip-text text-3xl font-bold uppercase leading-tight sm:text-4xl md:text-5xl lg:text-6xl"
|
text-transparent bg-clip-text text-3xl font-bold leading-tight sm:text-4xl md:text-5xl lg:text-6xl"
|
||||||
>
|
>
|
||||||
Still Have Question?
|
{t("faq.ask.question")}
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-center text-white/80 text-lg">
|
<p className="font-almarai text-center text-white/80 text-lg">
|
||||||
Nullam dictum felis eu pede mollis pretium integer tincidunt.
|
{t("faq.ask.subtitle")}
|
||||||
</p>
|
</p>
|
||||||
<div className="w-full flex items-center justify-center">
|
<div className="w-full flex items-center justify-center">
|
||||||
<Link
|
<Link
|
||||||
href={"/contact"}
|
href={"/contact"}
|
||||||
className="mx-auto shadow-[0px_0px_2px_8px_#ff01015c] bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-8 rounded-full transition duration-300 transform hover:scale-105 w-fit"
|
className="font-almarai mx-auto shadow-[0px_0px_2px_8px_#ff01015c] bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-8 rounded-full transition duration-300 transform hover:scale-105 w-fit"
|
||||||
>
|
>
|
||||||
ASK A QUESTION
|
{t("faq.ask.btn")}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default function FAQAccordion({ items }: FAQAccordionProps) {
|
|||||||
{items.map((item, index) => (
|
{items.map((item, index) => (
|
||||||
<Accordion.Item key={item.id} value={item.id} className="border-b border-slate-700 py-6">
|
<Accordion.Item key={item.id} value={item.id} className="border-b border-slate-700 py-6">
|
||||||
<Accordion.Trigger className="group flex w-full items-center justify-between text-left">
|
<Accordion.Trigger className="group flex w-full items-center justify-between text-left">
|
||||||
<h3 className="text-lg font-bold uppercase tracking-wide text-white transition-colors duration-300 group-hover:cursor-pointer md:text-xl">
|
<h3 className="font-almarai text-lg font-bold uppercase tracking-wide text-white transition-colors duration-300 group-hover:cursor-pointer md:text-xl">
|
||||||
{item.question}
|
{item.question}
|
||||||
</h3>
|
</h3>
|
||||||
<div className="ml-4 shrink-0">
|
<div className="ml-4 shrink-0">
|
||||||
@@ -31,7 +31,7 @@ export default function FAQAccordion({ items }: FAQAccordionProps) {
|
|||||||
</Accordion.Trigger>
|
</Accordion.Trigger>
|
||||||
|
|
||||||
<Accordion.Content className="overflow-hidden pt-4 text-gray-400 animate-in fade-in slide-in-from-top-2 duration-300 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=closed]:slide-out-to-top-2">
|
<Accordion.Content className="overflow-hidden pt-4 text-gray-400 animate-in fade-in slide-in-from-top-2 duration-300 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=closed]:slide-out-to-top-2">
|
||||||
<p className="leading-relaxed text-sm md:text-base">{item.answer}</p>
|
<p className="font-almarai leading-relaxed text-sm md:text-base">{item.answer}</p>
|
||||||
</Accordion.Content>
|
</Accordion.Content>
|
||||||
</Accordion.Item>
|
</Accordion.Item>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function FaqBanner() {
|
export function FaqBanner() {
|
||||||
|
const t = useTranslations();
|
||||||
return (
|
return (
|
||||||
<section className="relative w-full h-[55vh] min-h-100 overflow-hidden pt-10">
|
<section className="relative w-full h-[55vh] min-h-100 overflow-hidden pt-10">
|
||||||
{/* Background Image */}
|
{/* Background Image */}
|
||||||
@@ -24,12 +26,17 @@ export function FaqBanner() {
|
|||||||
<div className="max-w-250 w-full mx-auto px-4">
|
<div className="max-w-250 w-full mx-auto px-4">
|
||||||
<div className="relative z-20 h-full flex max-lg:flex-col items-start justify-between gap-5 pt-30">
|
<div className="relative z-20 h-full flex max-lg:flex-col items-start justify-between gap-5 pt-30">
|
||||||
<div className="spacw-y-4 ">
|
<div className="spacw-y-4 ">
|
||||||
<DotAnimatsiya />
|
<div className="flex items-center gap-3">
|
||||||
|
<DotAnimatsiya />
|
||||||
|
<span className="font-almarai text-sm text-white font-semibold tracking-wide">
|
||||||
|
{t("faq.banner.title")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<p
|
<p
|
||||||
className=" bg-linear-to-br from-white via-white to-black
|
className="font-unbounded uppercase bg-linear-to-br from-white via-white to-black
|
||||||
text-transparent bg-clip-text text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty"
|
text-transparent bg-clip-text text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty"
|
||||||
>
|
>
|
||||||
GENERAL <br /> QUESTIONS
|
{t("faq.banner.subtitle")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Flame, Building2, Ambulance } from "lucide-react";
|
import { Flame, Building2, Ambulance } from "lucide-react";
|
||||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
interface ServiceItem {
|
interface ServiceItem {
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
@@ -13,28 +14,25 @@ interface ServiceItem {
|
|||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const services: ServiceItem[] = [
|
|
||||||
{
|
|
||||||
icon: <Flame width={40} height={40} className="text-red-500" />,
|
|
||||||
title: "FIRE PREVENTION",
|
|
||||||
description:
|
|
||||||
"Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum aenean imperdiet augue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <Building2 width={40} height={40} className="text-red-500" />,
|
|
||||||
title: "ACTIVE ACCIDENTS",
|
|
||||||
description:
|
|
||||||
"Nullam dictum felis eu pede mollis pretium. Integer tincidunt cras dapibus vivamus consequat vitae.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <Ambulance width={40} height={40} className="text-red-500" />,
|
|
||||||
title: "AMBULANCE SERVICE",
|
|
||||||
description:
|
|
||||||
"Donec pede justo fringilla vel aliquet nec vulputate eget arcu enim justo rhoncus ut venenatis.",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export function AboutUs() {
|
export function AboutUs() {
|
||||||
|
const t = useTranslations();
|
||||||
|
const services: ServiceItem[] = [
|
||||||
|
{
|
||||||
|
icon: <Flame width={40} height={40} className="text-red-500" />,
|
||||||
|
title: t("home.about.prevention.title"),
|
||||||
|
description: t("home.about.prevention.description"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Building2 width={40} height={40} className="text-red-500" />,
|
||||||
|
title: t("home.about.accidents.title"),
|
||||||
|
description: t("home.about.accidents.description"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Ambulance width={40} height={40} className="text-red-500" />,
|
||||||
|
title: t("home.about.service.title"),
|
||||||
|
description: t("home.about.service.description"),
|
||||||
|
},
|
||||||
|
];
|
||||||
return (
|
return (
|
||||||
<section className="bg-[#1e1d1c] py-16 px-4 sm:py-20 sm:px-6 lg:px-8">
|
<section className="bg-[#1e1d1c] py-16 px-4 sm:py-20 sm:px-6 lg:px-8">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="max-w-7xl mx-auto">
|
||||||
@@ -45,17 +43,15 @@ export function AboutUs() {
|
|||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<DotAnimatsiya />
|
<DotAnimatsiya />
|
||||||
<span className="text-white font-bold text-sm tracking-wide">
|
<span className="font-almarai text-white font-bold text-sm tracking-wide">
|
||||||
ABOUT US
|
{t("home.about.title")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<h2
|
<h2
|
||||||
className="text-4xl bg-linear-to-br from-white via-white to-black
|
className="font-unbounded uppercase text-4xl bg-linear-to-br from-white via-white to-black
|
||||||
text-transparent bg-clip-text sm:text-5xl lg:text-6xl font-bold leading-tight"
|
text-transparent bg-clip-text sm:text-5xl lg:text-6xl font-bold leading-tight"
|
||||||
>
|
>
|
||||||
FIREFIGHTERS
|
{t("home.about.subtitle")}
|
||||||
<br />
|
|
||||||
AT THE READY
|
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -67,10 +63,10 @@ export function AboutUs() {
|
|||||||
{service.icon}
|
{service.icon}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-white font-bold text-base sm:text-lg mb-2">
|
<h3 className="uppercase font-unbounded text-white font-bold text-base sm:text-lg mb-2">
|
||||||
{service.title}
|
{service.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-gray-400 text-sm sm:text-base leading-relaxed">
|
<p className="font-almarai text-gray-400 text-sm sm:text-base leading-relaxed">
|
||||||
{service.description}
|
{service.description}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -80,8 +76,8 @@ export function AboutUs() {
|
|||||||
|
|
||||||
{/* Button */}
|
{/* Button */}
|
||||||
<div>
|
<div>
|
||||||
<Button className="bg-red-600 hover:bg-red-700 text-white font-bold px-8 py-3 rounded-full transition-colors duration-300 shadow-[0px_0px_2px_8px_#ff01015c]">
|
<Button className="font-almarai bg-red-600 hover:bg-red-700 text-white font-bold px-8 py-3 rounded-full transition-colors duration-300 shadow-[0px_0px_2px_8px_#ff01015c]">
|
||||||
ABOUT US
|
{t("home.about.title")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -112,10 +108,7 @@ export function AboutUs() {
|
|||||||
/>
|
/>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<p className="text-white font-bold text-sm sm:text-base">
|
<p className="text-white font-bold text-sm sm:text-base">
|
||||||
BEST AWARD
|
{t("home.about.award")}
|
||||||
</p>
|
|
||||||
<p className="text-white font-bold text-sm sm:text-base">
|
|
||||||
FIREFIGHTER 2025
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import { useTranslations } from "next-intl";
|
||||||
import DotAnimatsiya from "../../dot/DotAnimatsiya";
|
import DotAnimatsiya from "../../dot/DotAnimatsiya";
|
||||||
|
|
||||||
export function Banner() {
|
export function Banner() {
|
||||||
|
const t = useTranslations();
|
||||||
return (
|
return (
|
||||||
<section className="relative w-full lg:h-[86vh] h-screen min-h-150 overflow-hidden pt-20">
|
<section className="relative w-full lg:h-[86vh] h-screen min-h-150 overflow-hidden pt-20">
|
||||||
{/* Background Image */}
|
{/* Background Image */}
|
||||||
@@ -17,78 +19,77 @@ export function Banner() {
|
|||||||
<div
|
<div
|
||||||
className="absolute inset-0 z-10"
|
className="absolute inset-0 z-10"
|
||||||
style={{
|
style={{
|
||||||
background: `linear-gradient(to top right, #d2610ab0 0%, #1e1d1ce3 20%, #1e1d1ce3 100%)`,
|
background: `linear-gradient(to top right, #c75c08 0%, #1e1d1ce3 28%, #1e1d1ce3 100%)`,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Content Container */}
|
{/* Content Container */}
|
||||||
<div className="relative z-20 h-full flex items-end lg:mt-0 md:mt-[15vh] sm:mt-[5vh] mt-0">
|
<div className="relative z-20 h-full flex items-center lg:mt-0 sm:mt-[10vh] mt-[5vh]">
|
||||||
<div className="max-w-375 mx-auto px-4 sm:px-6 lg:px-8 w-full">
|
<div className="max-w-400 mx-auto px-4 sm:px-6 lg:px-8 w-full">
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12 items-center h-full">
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12 items-center h-full">
|
||||||
{/* Right side - Text Content */}
|
{/* Right side - Text Content */}
|
||||||
<div className="lg:hidden inline-block space-y-6 text-white">
|
<div className="lg:hidden inline-block space-y-6 text-white">
|
||||||
{/* Badge */}
|
{/* Badge */}
|
||||||
<div className="flex items-center gap-2 w-fit">
|
<div className="flex items-center gap-2 w-fit">
|
||||||
<DotAnimatsiya />
|
<DotAnimatsiya />
|
||||||
<span className="text-sm font-semibold tracking-wide">
|
<span className="text-sm font-semibold tracking-wide font-almarai">
|
||||||
WELCOME TO FIREFORCE
|
{t("home.banner.title1")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main Heading */}
|
{/* Main Heading */}
|
||||||
<h1
|
<h1
|
||||||
className="bg-linear-to-br from-white via-white to-black
|
className="bg-linear-to-br from-white via-white to-black
|
||||||
text-transparent bg-clip-text text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty"
|
text-transparent bg-clip-text text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty font-unbounded"
|
||||||
>
|
>
|
||||||
THE FIRE GUARDIAN
|
{t("home.banner.title2")}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
{/* Description */}
|
{/* Description */}
|
||||||
<p className="text-base sm:text-lg text-gray-300 leading-relaxed max-w-md">
|
<p className="text-base sm:text-lg text-gray-300 leading-relaxed max-w-md">
|
||||||
They are seen as a beacon of hope, a figure who brings calm
|
{t("home.banner.description")}
|
||||||
amidst chaos and light in the darkest of moments.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* CTA Button */}
|
{/* CTA Button */}
|
||||||
<button className="shadow-[0px_0px_2px_8px_#ff01015c] bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-8 rounded-full transition duration-300 transform hover:scale-105 w-fit">
|
<button className="shadow-[0px_0px_2px_8px_#ff01015c] bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-8 rounded-full transition duration-300 transform hover:scale-105 w-fit">
|
||||||
GET STARTED
|
{t("home.banner.cta")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Left side - Firefighters Image */}
|
{/* Left side - Firefighters Image */}
|
||||||
<div className="flex items-end justify-center">
|
<div className="flex items-end justify-center ">
|
||||||
<img
|
<img
|
||||||
src="/images/home/bannerHuman.png"
|
src="/images/homeBanner.png"
|
||||||
alt="Firefighters"
|
alt="Firefighters"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
className="w-full max-lg:w-[80vw] h-auto object-cover drop-shadow-2xl"
|
className="lg:w-150 w-100 lg:h-150 max-[300px]:w-[80vw] object-cover object-right rounded-xl drop-shadow-2xl"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right side - Text Content */}
|
{/* Right side - Text Content */}
|
||||||
<div className="lg:inline-block hidden space-y-6 text-white mb-20">
|
<div className="lg:inline-block hidden space-y-6 mb-20">
|
||||||
{/* Badge */}
|
{/* Badge */}
|
||||||
<div className="flex items-center gap-2 w-fit">
|
<div className="flex items-center gap-2 w-fit">
|
||||||
<DotAnimatsiya />
|
<DotAnimatsiya />
|
||||||
<span className="text-sm font-semibold tracking-wide">
|
<span className="text-sm font-semibold text-white tracking-wide font-almarai">
|
||||||
WELCOME TO FIREFORCE
|
{t("home.banner.title1")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main Heading */}
|
{/* Main Heading */}
|
||||||
<h1 className="gradient-text text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty">
|
<h1 className="font-unbounded uppercase text-4xl bg-linear-to-br from-white via-white to-black
|
||||||
THE FIRE GUARDIAN
|
text-transparent bg-clip-text sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty">
|
||||||
|
{t("home.banner.title2")}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
{/* Description */}
|
{/* Description */}
|
||||||
<p className="text-base sm:text-lg text-gray-300 leading-relaxed max-w-md">
|
<p className="font-almarai text-base sm:text-lg text-gray-300 leading-relaxed max-w-md">
|
||||||
They are seen as a beacon of hope, a figure who brings calm
|
{t("home.banner.description")}
|
||||||
amidst chaos and light in the darkest of moments.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* CTA Button */}
|
{/* CTA Button */}
|
||||||
<button className="shadow-[0px_0px_2px_8px_#ff01015c] bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-8 rounded-full transition duration-300 transform hover:scale-105 w-fit">
|
<button className="font-almarai shadow-[0px_0px_2px_8px_#ff01015c] bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-8 rounded-full transition duration-300 transform hover:scale-105 w-fit">
|
||||||
GET STARTED
|
{t("home.banner.cta")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,35 +1,38 @@
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { ChevronRight } from "lucide-react";
|
import { ChevronRight } from "lucide-react";
|
||||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
const blogPosts = [
|
import ProductCard from "../products/productCard";
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
image: "/images/img14.webp",
|
|
||||||
category: "Tips & Trick",
|
|
||||||
title: "BEHIND THE HELMET: LIFE AS A FIREFIGHTER",
|
|
||||||
author: "John Doe",
|
|
||||||
date: "July 24, 2025",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
image: "/images/img15.webp",
|
|
||||||
category: "Insight",
|
|
||||||
title: "FIREFIGHTING EQUIPMENT: TOOLS OF THE TRADE",
|
|
||||||
author: "John Doe",
|
|
||||||
date: "July 24, 2025",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
image: "/images/img16.webp",
|
|
||||||
category: "News",
|
|
||||||
title: "FIREFIGHTER TRAINING TAKES TO BECOME A HERO",
|
|
||||||
author: "John Doe",
|
|
||||||
date: "July 24, 2025",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export function Blog() {
|
export function Blog() {
|
||||||
|
const t = useTranslations();
|
||||||
|
const blogPosts = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
image: "/images/img14.webp",
|
||||||
|
category: "Tips & Trick",
|
||||||
|
title: t("home.blog.articles.article1"),
|
||||||
|
author: "John Doe",
|
||||||
|
date: "July 24, 2025",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
image: "/images/img15.webp",
|
||||||
|
category: "Insight",
|
||||||
|
title: t("home.blog.articles.article2"),
|
||||||
|
author: "John Doe",
|
||||||
|
date: "July 24, 2025",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
image: "/images/img16.webp",
|
||||||
|
category: "News",
|
||||||
|
title: t("home.blog.articles.article3"),
|
||||||
|
author: "John Doe",
|
||||||
|
date: "July 24, 2025",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="bg-[#1f1f1f] py-45">
|
<section className="bg-[#1f1f1f] py-45">
|
||||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||||
@@ -37,23 +40,23 @@ export function Blog() {
|
|||||||
<div className="mb-12 text-center">
|
<div className="mb-12 text-center">
|
||||||
<div className="mb-4 flex items-center justify-center gap-2">
|
<div className="mb-4 flex items-center justify-center gap-2">
|
||||||
<DotAnimatsiya />
|
<DotAnimatsiya />
|
||||||
<span className="text-sm font-semibold tracking-wider text-white uppercase">
|
<span className="font-almarai text-sm font-semibold tracking-wider text-white uppercase">
|
||||||
Blog & Articles
|
{t("products.banner.title")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<h2
|
<h2
|
||||||
className="bg-linear-to-br from-white via-white to-black
|
className="font-unbounded bg-linear-to-br from-white py-2 via-white to-black
|
||||||
text-transparent bg-clip-text text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl"
|
text-transparent bg-clip-text text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl"
|
||||||
>
|
>
|
||||||
LATEST BLOG & NEWS
|
{t("products.ourproducts")}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Blog Cards Grid */}
|
{/* Blog Cards Grid */}
|
||||||
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3 max-sm:place-items-center">
|
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3 max-sm:place-items-center">
|
||||||
{blogPosts.map((post) => (
|
{/* {blogPosts.map((post) => (
|
||||||
<article key={post.id} className="group">
|
<article key={post.id} className="group">
|
||||||
{/* Image Container */}
|
|
||||||
<div className="relative mb-6 aspect-4/2 md:aspect-4/3 overflow-hidden rounded-lg">
|
<div className="relative mb-6 aspect-4/2 md:aspect-4/3 overflow-hidden rounded-lg">
|
||||||
<Image
|
<Image
|
||||||
src={post.image || "/placeholder.svg"}
|
src={post.image || "/placeholder.svg"}
|
||||||
@@ -61,20 +64,19 @@ export function Blog() {
|
|||||||
fill
|
fill
|
||||||
className="object-cover transition-transform duration-300 group-hover:scale-105"
|
className="object-cover transition-transform duration-300 group-hover:scale-105"
|
||||||
/>
|
/>
|
||||||
{/* Category Badge */}
|
|
||||||
<div className="absolute bottom-4 left-4">
|
<div className="absolute bottom-4 left-4">
|
||||||
<span className="rounded bg-red-600 px-4 py-2 text-sm font-medium text-white">
|
<span className="font-almarai rounded bg-red-600 px-4 py-2 text-sm font-medium text-white">
|
||||||
{post.category}
|
{post.category}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Content */}
|
|
||||||
<div>
|
<div>
|
||||||
<h3 className="mb-3 text-lg font-bold leading-tight tracking-wide text-white uppercase md:text-xl">
|
<h3 className="font-unbounded uppercase mb-3 text-lg font-bold leading-tight tracking-wide text-white md:text-xl">
|
||||||
{post.title}
|
{post.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="mb-4 text-sm text-gray-400">
|
<p className="font-almarai mb-4 text-sm text-gray-400">
|
||||||
<span className="text-gray-500">by </span>
|
<span className="text-gray-500">by </span>
|
||||||
<span className="text-white">{post.author}</span>
|
<span className="text-white">{post.author}</span>
|
||||||
<span className="mx-2 text-gray-500">•</span>
|
<span className="mx-2 text-gray-500">•</span>
|
||||||
@@ -82,14 +84,26 @@ export function Blog() {
|
|||||||
</p>
|
</p>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="inline-flex items-center gap-1 text-sm font-semibold tracking-wider text-red-600 uppercase transition-colors hover:text-red-500"
|
className="font-almarai inline-flex items-center gap-1 text-sm font-semibold tracking-wider text-red-600 uppercase transition-colors hover:text-red-500"
|
||||||
>
|
>
|
||||||
Read More
|
{t("home.blog.readMore")}
|
||||||
<ChevronRight className="h-4 w-4" />
|
<ChevronRight className="h-4 w-4" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
))}
|
))} */}
|
||||||
|
{Array(3)
|
||||||
|
.fill(null)
|
||||||
|
.map((_, index) => (
|
||||||
|
<ProductCard
|
||||||
|
key={index}
|
||||||
|
title="Elektr yong'in detektori-Ypres ver.2"
|
||||||
|
name="P-0834404"
|
||||||
|
image="/images/products/products.webp"
|
||||||
|
slug="P_0834404"
|
||||||
|
status="full"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import { Phone } from "lucide-react";
|
import { Phone } from "lucide-react";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
|
||||||
export function Line() {
|
export function Line() {
|
||||||
|
const t = useTranslations();
|
||||||
return (
|
return (
|
||||||
<div className="bg-black py-10 px-4">
|
<div className="bg-black py-10 px-4">
|
||||||
<div className="max-w-280 w-full mx-auto relative py-10 flex items-center justify-between ">
|
<div className="max-w-280 w-full mx-auto relative py-10 flex items-center justify-between ">
|
||||||
<div className="text-white flex flex-col items-start justify-start gap-5 ">
|
<div className="text-white flex flex-col items-start justify-start gap-5 ">
|
||||||
<h2 className="lg:text-5xl sm:text-3xl text-2xl max-w-[80%] w-full font-semibold">
|
<h2 className="font-almarai lg:text-5xl sm:text-3xl text-2xl max-w-[80%] w-full font-semibold">
|
||||||
Ready for Action 24/7: Contact Us at
|
{t("home.contactLine.text")}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="flex items-center justify-center gap-4 font-semibold sm:text-xl text-lg">
|
<p className="flex items-center justify-center gap-4 font-semibold sm:text-xl text-lg">
|
||||||
<span
|
<span
|
||||||
|
|||||||
@@ -1,63 +1,64 @@
|
|||||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
import { ChevronRight } from "lucide-react";
|
import { ChevronRight } from "lucide-react";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
export function OurService() {
|
export function OurService() {
|
||||||
|
const t = useTranslations();
|
||||||
return (
|
return (
|
||||||
<div className="bg-[#1e1d1c] py-10 md:py-16 lg:py-20">
|
<div className="bg-[#1e1d1c] py-10 md:py-16 lg:py-20 mb-30">
|
||||||
<div className="max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="space-y-4 md:space-y-6">
|
<div className="space-y-4 md:space-y-6">
|
||||||
<div className="flex items-center justify-center gap-2 text-base sm:text-lg md:text-xl text-white font-bold">
|
<div className="font-almarai flex items-center justify-center gap-2 text-base sm:text-lg md:text-xl text-white font-bold">
|
||||||
<DotAnimatsiya />
|
<DotAnimatsiya />
|
||||||
OUR SERVICES
|
{t("home.services.title")}
|
||||||
</div>
|
</div>
|
||||||
<h1 className="text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl tracking-wider lg:tracking-[5px] font-bold bg-linear-to-br from-white via-white to-gray-400 text-transparent bg-clip-text text-center w-full">
|
<h1 className="uppercase font-unbounded text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl tracking-wider lg:tracking-[5px] font-bold bg-linear-to-br from-white via-white to-gray-400 text-transparent bg-clip-text text-center w-full">
|
||||||
FIREFIGHTER RESPONSIBILITIES
|
{t("home.services.subtitle")}
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-center text-sm sm:text-base md:text-lg text-gray-400 max-w-3xl mx-auto px-4">
|
<p className="font-almarai text-center text-sm sm:text-base md:text-lg text-gray-400 max-w-4xl mx-auto px-4">
|
||||||
Aliquam lorem ante dapibus in viverra quis feugiat a tellus
|
{t("home.services.description")}
|
||||||
phasellus viverra nulla ut metus varius laoreet quisque rutrum.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* cards */}
|
{/* cards */}
|
||||||
<div className="max-w-250 w-full mx-auto flex sm:flex-row flex-col items-center gap-5 my-10">
|
<div className="max-w-250 w-full mx-auto flex sm:flex-row flex-col items-center gap-5 my-10">
|
||||||
<div className="relative space-y-4 py-6 px-8 rounded-xl sm:w-[55%] w-full bg-[linear-gradient(to_bottom_right,#000000,#000000,#000000,#d2610a)]">
|
<div className="relative space-y-4 py-6 px-8 rounded-xl sm:w-[55%] w-full bg-[linear-gradient(to_bottom_right,#000000,#000000,#000000,#d2610a)]">
|
||||||
<p className="font-bold bg-linear-to-br from-white via-white to-black text-transparent bg-clip-text">
|
<p className="uppercase font-unbounded font-bold bg-linear-to-br from-white via-white to-black text-transparent bg-clip-text">
|
||||||
Operation Force
|
{t("home.services.services.operation.title")}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-400 max-w-80 w-full">
|
<p className="font-almarai text-gray-400 max-w-80 w-full">
|
||||||
Aliquam lorem ante dapibus in viverra feugiat phasellus.
|
{t("home.services.services.operation.description")}
|
||||||
</p>
|
</p>
|
||||||
<button className="text-[#dc2626] font-semibold flex items-center gap-2 text-sm">
|
<button className="font-almarai text-[#dc2626] font-semibold flex items-center gap-2 text-sm">
|
||||||
LEARN MORE <ChevronRight size={20} />
|
{t("home.services.learnmore")} <ChevronRight size={20} />
|
||||||
</button>
|
</button>
|
||||||
<Image
|
<Image
|
||||||
src="/images/home/gruop.png"
|
src="/images/home/gruop.png"
|
||||||
alt="images"
|
alt="images"
|
||||||
width={200}
|
width={200}
|
||||||
height={100}
|
height={100}
|
||||||
className="object-contain sm:absolute bottom-0 right-2 z-50"
|
className="object-contain sm:absolute bottom-0 right-2 z-10"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative overflow-hidden space-y-4 py-6 px-8 rounded-xl sm:w-[45%] w-full bg-[linear-gradient(to_bottom_right,#000000,#000000,#000000,#d2610a)]">
|
<div className="relative overflow-hidden space-y-4 py-6 px-8 rounded-xl sm:w-[45%] w-full bg-[linear-gradient(to_bottom_right,#000000,#000000,#000000,#d2610a)]">
|
||||||
<p className="font-bold bg-linear-to-br from-white via-white to-black text-transparent bg-clip-text">
|
<p className="uppercase font-unbounded font-bold bg-linear-to-br from-white via-white to-black text-transparent bg-clip-text">
|
||||||
Operation Force
|
{t("home.services.services.suppression.title")}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-400 max-w-70 w-full">
|
<p className="font-almarai text-gray-400 max-w-70 w-full">
|
||||||
Aliquam lorem ante dapibus in viverra feugiat phasellus.
|
{t("home.services.services.suppression.description")}
|
||||||
</p>
|
</p>
|
||||||
<button className="text-[#dc2626] font-semibold flex items-center gap-2 text-sm">
|
<button className="font-almarai text-[#dc2626] font-semibold flex items-center gap-2 text-sm">
|
||||||
LEARN MORE <ChevronRight size={20} />
|
{t("home.services.learnmore")} <ChevronRight size={20} />
|
||||||
</button>
|
</button>
|
||||||
<Image
|
<Image
|
||||||
src="/images/home/redShlang.png"
|
src="/images/home/redShlang.png"
|
||||||
alt="images"
|
alt="images"
|
||||||
width={200}
|
width={200}
|
||||||
height={100}
|
height={100}
|
||||||
className="object-contain sm:absolute -bottom-4 -right-4 z-50"
|
className="object-contain sm:absolute -bottom-4 -right-4 z-10"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -72,45 +73,45 @@ export function OurService() {
|
|||||||
className="object-contain mt-5"
|
className="object-contain mt-5"
|
||||||
/>
|
/>
|
||||||
<div className="space-y-4 py-6 px-8">
|
<div className="space-y-4 py-6 px-8">
|
||||||
<p className="font-bold bg-linear-to-br from-white via-white to-black text-transparent bg-clip-text">
|
<p className="uppercase font-unbounded font-bold bg-linear-to-br from-white via-white to-black text-transparent bg-clip-text">
|
||||||
Operation Force
|
{t("home.services.services.safety.title")}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-400 max-w-80 w-full">
|
<p className="font-almarai text-gray-400 max-w-80 w-full">
|
||||||
Aliquam lorem ante dapibus in viverra feugiat phasellus.
|
{t("home.services.services.safety.description")}
|
||||||
</p>
|
</p>
|
||||||
<button className="text-[#dc2626] font-semibold flex items-center gap-2 text-sm">
|
<button className="font-almarai text-[#dc2626] font-semibold flex items-center gap-2 text-sm">
|
||||||
LEARN MORE <ChevronRight size={20} />
|
{t("home.services.learnmore")} <ChevronRight size={20} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="sm:w-[60%] w-full">
|
<div className="sm:w-[60%] w-full">
|
||||||
<div className="relative overflow-hidden space-y-4 py-6 px-8 rounded-xl w-full bg-[linear-gradient(to_bottom_right,#000000,#000000,#000000,#d2610a)]">
|
<div className="relative overflow-hidden space-y-4 py-6 px-8 rounded-xl w-full bg-[linear-gradient(to_bottom_right,#000000,#000000,#000000,#d2610a)]">
|
||||||
<p className="font-bold bg-linear-to-br from-white via-white to-black text-transparent bg-clip-text">
|
<p className="uppercase font-unbounded font-bold bg-linear-to-br from-white via-white to-black text-transparent bg-clip-text">
|
||||||
Operation Force
|
{t("home.services.services.monitoring.title")}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-400 max-w-70 w-full">
|
<p className="font-almarai text-gray-400 max-w-70 w-full">
|
||||||
Aliquam lorem ante dapibus in viverra feugiat phasellus.
|
{t("home.services.services.monitoring.description")}
|
||||||
</p>
|
</p>
|
||||||
<button className="sm:mt-38 mt-0 text-[#dc2626] font-semibold flex items-center gap-2 text-sm">
|
<button className="font-almarai sm:mt-38 mt-0 text-[#dc2626] font-semibold flex items-center gap-2 text-sm">
|
||||||
LEARN MORE <ChevronRight size={20} />
|
{t("home.services.learnmore")} <ChevronRight size={20} />
|
||||||
</button>
|
</button>
|
||||||
<Image
|
<Image
|
||||||
src="/images/home/balon.png"
|
src="/images/home/balon.png"
|
||||||
alt="images"
|
alt="images"
|
||||||
width={200}
|
width={200}
|
||||||
height={100}
|
height={100}
|
||||||
className="object-contain sm:absolute -bottom-20 -right-4 max-sm:-mb-20 z-50"
|
className="object-contain sm:absolute -bottom-20 -right-4 max-sm:-mb-20 z-10"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="py-8 px-8 rounded-xl mt-5 w-full p-5 bg-[linear-gradient(to_top_right,#000000,#000000,#d2610a)] flex sm:flex-row flex-col gap-5 items-center justify-between">
|
<div className="py-8 px-8 rounded-xl mt-5 w-full p-5 bg-[linear-gradient(to_top_right,#000000,#000000,#d2610a)] flex sm:flex-row flex-col gap-5 items-center justify-between">
|
||||||
<h2 className="sm:text-3xl text-xl font-semibold font-armanai text-white">
|
<h2 className="font-unbounded sm:text-3xl text-xl font-semibold font-armanai text-white">
|
||||||
View more service
|
{t("home.services.viewMoreServices")}
|
||||||
</h2>
|
</h2>
|
||||||
<Link
|
<Link
|
||||||
href="/services"
|
href="/services"
|
||||||
className="shadow-[0px_0px_2px_6px_#a60404ad] bg-red-600 hover:bg-red-700 text-white font-bold sm:py-3 sm:px-8 px-8 py-2 rounded-full transition duration-300 transform hover:scale-105 w-fit"
|
className="font-almarai shadow-[0px_0px_2px_6px_#a60404ad] bg-red-600 hover:bg-red-700 text-white font-bold sm:py-3 sm:px-8 px-8 py-2 rounded-full transition duration-300 transform hover:scale-105 w-fit"
|
||||||
>
|
>
|
||||||
GET STARTED
|
{t("home.services.viewMore")}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,24 +1,28 @@
|
|||||||
|
import { Counter } from "@/components/Counter";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function Statistics() {
|
export function Statistics() {
|
||||||
|
const t = useTranslations();
|
||||||
const stats = [
|
const stats = [
|
||||||
{
|
{
|
||||||
number: '25',
|
number: "25",
|
||||||
symbol: '+',
|
symbol: "+",
|
||||||
label: 'Years Experience',
|
label: t("home.statistics.experience"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
number: '450',
|
number: "450",
|
||||||
symbol: '+',
|
symbol: "+",
|
||||||
label: 'Families Saved',
|
label: t("home.statistics.projectsCompleted"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
number: '99',
|
number: "99",
|
||||||
symbol: '+',
|
symbol: "+",
|
||||||
label: 'Trained Staff',
|
label: t("home.statistics.trainedSpecialists"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
number: '93',
|
number: "93",
|
||||||
symbol: '%',
|
symbol: "%",
|
||||||
label: 'Trusted Clients',
|
label: t("home.statistics.trustedClients"),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -27,17 +31,22 @@ export function Statistics() {
|
|||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 lg:gap-12">
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 lg:gap-12">
|
||||||
{stats.map((stat, index) => (
|
{stats.map((stat, index) => (
|
||||||
<div key={index} className="flex flex-col items-center justify-center py-10 sm:py-20 lg:py-15 border-b-red-600 border-b">
|
<div
|
||||||
|
key={index}
|
||||||
|
className="flex flex-col items-center justify-center py-10 sm:py-20 lg:py-15 border-b-red-600 border-b"
|
||||||
|
>
|
||||||
{/* Number and Symbol */}
|
{/* Number and Symbol */}
|
||||||
<div className="flex items-baseline gap-2">
|
<div className="flex items-baseline gap-2 font-almarai">
|
||||||
<span className="text-4xl sm:text-5xl lg:text-6xl font-bold text-white">
|
<span className="text-4xl sm:text-5xl lg:text-6xl font-bold text-white">
|
||||||
{stat.number}
|
<Counter countNum={Number(stat.number)} />
|
||||||
|
</span>
|
||||||
|
<span className="text-4xl sm:text-5xl lg:text-6xl font-bold text-red-600">
|
||||||
|
{stat.symbol}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-4xl sm:text-5xl lg:text-6xl font-bold text-red-600">{stat.symbol}</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Label */}
|
{/* Label */}
|
||||||
<p className="text-sm sm:text-base text-gray-300 mt-4 text-center font-medium">
|
<p className="font-almarai text-sm sm:text-base text-gray-300 mt-4 text-center font-medium">
|
||||||
{stat.label}
|
{stat.label}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,36 +5,7 @@ import { Autoplay } from "swiper/modules";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import "swiper/css";
|
import "swiper/css";
|
||||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
const testimonials = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
quote:
|
|
||||||
"I've witnessed Fireforce in action multiple times, and they never cease to amaze me with their dedication and professionalism. They are the backbone of our safety and security. Thank you, Fireforce!",
|
|
||||||
name: "JOHN SMITH",
|
|
||||||
role: "Manager",
|
|
||||||
avatar: "/images/home/avatar.jpg",
|
|
||||||
rating: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
quote:
|
|
||||||
"The team's response time and expertise saved our property from a devastating fire. Their bravery and commitment to protecting our community is truly remarkable. Highly recommend their services!",
|
|
||||||
name: "SARAH JOHNSON",
|
|
||||||
role: "Business Owner",
|
|
||||||
avatar: "/images/home/avatar.jpg",
|
|
||||||
rating: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
quote:
|
|
||||||
"Working alongside Fireforce has been an honor. Their training programs and emergency protocols are second to none. They set the standard for fire safety excellence in our region.",
|
|
||||||
name: "MICHAEL DAVIS",
|
|
||||||
role: "Safety Director",
|
|
||||||
avatar: "/images/home/avatar.jpg",
|
|
||||||
rating: 5,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
function StarRating({ rating }: { rating: number }) {
|
function StarRating({ rating }: { rating: number }) {
|
||||||
return (
|
return (
|
||||||
@@ -53,6 +24,33 @@ function StarRating({ rating }: { rating: number }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function Testimonial() {
|
export function Testimonial() {
|
||||||
|
const t = useTranslations();
|
||||||
|
const testimonials = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
quote:t("home.testimonials.clients.john.text"),
|
||||||
|
name: t("home.testimonials.clients.john.name"),
|
||||||
|
role: t("home.testimonials.clients.john.position"),
|
||||||
|
avatar: "/images/home/avatar.jpg",
|
||||||
|
rating: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
quote:t("home.testimonials.clients.sarah.text"),
|
||||||
|
name: t("home.testimonials.clients.sarah.name"),
|
||||||
|
role: t("home.testimonials.clients.sarah.position"),
|
||||||
|
avatar: "/images/home/avatar.jpg",
|
||||||
|
rating: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
quote:t("home.testimonials.clients.michael.text"),
|
||||||
|
name: t("home.testimonials.clients.michael.name"),
|
||||||
|
role: t("home.testimonials.clients.michael.position"),
|
||||||
|
avatar: "/images/home/avatar.jpg",
|
||||||
|
rating: 5,
|
||||||
|
},
|
||||||
|
];
|
||||||
return (
|
return (
|
||||||
<section className="w-full bg-[#1a1a1a]">
|
<section className="w-full bg-[#1a1a1a]">
|
||||||
<div className="flex flex-col lg:flex-row min-h-100 lg:min-h-125">
|
<div className="flex flex-col lg:flex-row min-h-100 lg:min-h-125">
|
||||||
@@ -87,8 +85,8 @@ export function Testimonial() {
|
|||||||
<div className="w-full max-w-xl mx-auto mb-5">
|
<div className="w-full max-w-xl mx-auto mb-5">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<DotAnimatsiya />
|
<DotAnimatsiya />
|
||||||
<span className="text-white font-semibold text-sm tracking-wider">
|
<span className="font-unbounded text-white font-semibold text-sm tracking-wider">
|
||||||
TESTIMONIALS
|
{t("home.testimonials.title")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -108,7 +106,7 @@ export function Testimonial() {
|
|||||||
<SwiperSlide key={testimonial.id}>
|
<SwiperSlide key={testimonial.id}>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* Quote */}
|
{/* Quote */}
|
||||||
<p className="text-white text-base sm:text-lg lg:text-xl leading-relaxed">
|
<p className="font-almarai text-white text-base sm:text-lg lg:text-xl leading-relaxed">
|
||||||
"{testimonial.quote}"
|
"{testimonial.quote}"
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -123,10 +121,10 @@ export function Testimonial() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4 className="text-white font-bold text-sm sm:text-base">
|
<h4 className="font-unbounded text-white font-bold text-sm sm:text-base">
|
||||||
{testimonial.name}
|
{testimonial.name}
|
||||||
</h4>
|
</h4>
|
||||||
<p className="text-red-600 text-xs sm:text-sm">
|
<p className="font-almarai text-red-600 text-xs sm:text-sm">
|
||||||
{testimonial.role}
|
{testimonial.role}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,15 +1,27 @@
|
|||||||
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
import HomeMarquee from "@/components/HomeMarquee";
|
import HomeMarquee from "@/components/HomeMarquee";
|
||||||
import { Play } from "lucide-react";
|
import { Play } from "lucide-react";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function Video() {
|
export function Video() {
|
||||||
|
const t = useTranslations();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className="bg-[#1e1d1c] bg-fixed max-sm:bg-center"
|
className="bg-[#1e1d1c] bg-fixed max-sm:bg-center"
|
||||||
style={{ backgroundImage: "url(/images/img7.jpg)" }}
|
style={{ backgroundImage: "url(/images/img7.jpg)" }}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-center bg-linear-to-t from-[#1e1d1c] to-[#1e1d1c02] h-80 w-full relative">
|
<div className="flex flex-col items-center justify-center bg-linear-to-t from-[#1e1d1c] to-[#1e1d1c02] h-80 w-full relative">
|
||||||
|
<div className="flex items-center gap-2 w-fit text-white ">
|
||||||
|
<DotAnimatsiya />
|
||||||
|
<span className="text-sm font-semibold tracking-wide font-almarai">
|
||||||
|
{t("rasmlar")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h1 className="font-unbounded uppercase text-4xl bg-linear-to-br from-white via-white to-black
|
||||||
|
text-transparent bg-clip-text sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty">
|
||||||
|
{t("fotogalereya")}
|
||||||
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function ProductBanner() {
|
export function ProductBanner() {
|
||||||
|
const t = useTranslations();
|
||||||
return (
|
return (
|
||||||
<section className="relative w-full h-[60vh] min-h-100 overflow-hidden pt-10">
|
<section className="relative w-full h-[60vh] min-h-100 overflow-hidden pt-10">
|
||||||
{/* Background Image */}
|
{/* Background Image */}
|
||||||
@@ -24,17 +26,21 @@ export function ProductBanner() {
|
|||||||
<div className="max-w-250 w-full mx-auto px-4">
|
<div className="max-w-250 w-full mx-auto px-4">
|
||||||
<div className="relative z-20 h-full flex max-lg:flex-col items-start justify-between gap-5 pt-30">
|
<div className="relative z-20 h-full flex max-lg:flex-col items-start justify-between gap-5 pt-30">
|
||||||
<div className="spacw-y-4 ">
|
<div className="spacw-y-4 ">
|
||||||
<DotAnimatsiya />
|
<div className="flex items-center gap-2 w-fit">
|
||||||
|
<DotAnimatsiya />
|
||||||
|
<span className="font-almarai text-white text-sm font-semibold tracking-wide">
|
||||||
|
{t("products.banner.title")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<p
|
<p
|
||||||
className=" bg-linear-to-br from-white via-white to-black
|
className="font-unbounded uppercase bg-linear-to-br from-white via-white to-black
|
||||||
text-transparent bg-clip-text text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty"
|
text-transparent bg-clip-text text-3xl sm:text-4xl lg:text-5xl font-bold leading-tight text-pretty"
|
||||||
>
|
>
|
||||||
Ignum technology <br /> At The Ready
|
{t("products.banner.subtitle")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="lg:w-[40%] text-gray-300 lg:mt-20 md:mt-10 sm:mt-5 ">
|
<div className="font-almarai lg:w-[40%] text-gray-300 lg:mt-20 md:mt-10 sm:mt-5 ">
|
||||||
It emphasizes that these firefighters are there not just as public
|
{t("products.banner.description")}
|
||||||
servants but as a vital part of the community.
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export default function ProductCard({
|
|||||||
<Link href={`/products/${slug}`}>
|
<Link href={`/products/${slug}`}>
|
||||||
<article className="group transition-all duration-300 hover:cursor-pointer max-sm:max-w-100 max-sm:mx-auto max-sm:w-full ">
|
<article className="group transition-all duration-300 hover:cursor-pointer max-sm:max-w-100 max-sm:mx-auto max-sm:w-full ">
|
||||||
{/* Image Container */}
|
{/* Image Container */}
|
||||||
<div className="relative rounded-2xl h-45 sm:h-55 md:h-65 lg:w-70 w-[90%] mx-auto overflow-hidden bg-white">
|
<div className="relative rounded-2xl h-45 sm:h-55 md:h-65 lg:w-[95%] w-[90%] mx-auto overflow-hidden bg-white">
|
||||||
<Image
|
<Image
|
||||||
src={image || "/placeholder.svg"}
|
src={image || "/placeholder.svg"}
|
||||||
alt={title}
|
alt={title}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function ServiceBanner() {
|
export function ServiceBanner() {
|
||||||
|
const t = useTranslations();
|
||||||
return (
|
return (
|
||||||
<section className="relative w-full h-[60vh] min-h-100 overflow-hidden pt-10">
|
<section className="relative w-full h-[60vh] min-h-100 overflow-hidden pt-10">
|
||||||
{/* Background Image */}
|
{/* Background Image */}
|
||||||
@@ -24,17 +26,21 @@ export function ServiceBanner() {
|
|||||||
<div className="max-w-250 w-full mx-auto px-4">
|
<div className="max-w-250 w-full mx-auto px-4">
|
||||||
<div className="relative z-20 h-full flex max-lg:flex-col items-start justify-between gap-5 pt-30">
|
<div className="relative z-20 h-full flex max-lg:flex-col items-start justify-between gap-5 pt-30">
|
||||||
<div className="spacw-y-4 ">
|
<div className="spacw-y-4 ">
|
||||||
<DotAnimatsiya />
|
<div className="flex items-center gap-3">
|
||||||
|
<DotAnimatsiya />
|
||||||
|
<span className="font-almarai text-sm text-white font-semibold tracking-wide">
|
||||||
|
{t("services.banner.title")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<p
|
<p
|
||||||
className=" bg-linear-to-br from-white via-white to-black
|
className="font-unbounded uppercase bg-linear-to-br from-white via-white to-black
|
||||||
text-transparent bg-clip-text text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty"
|
text-transparent bg-clip-text text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty"
|
||||||
>
|
>
|
||||||
GENERAL <br /> QUESTIONS
|
{t("services.banner.subtitle")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="lg:w-[40%] text-gray-300 mt-10 text-lg">
|
<div className="font-almarai lg:w-[40%] text-gray-300 mt-10 text-lg">
|
||||||
Always Ready, Always On Time: Rescuing Lives” represents an
|
{t("services.banner.description")}
|
||||||
unwavering commitment to emergency.
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,36 @@
|
|||||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||||
import FAQAccordion from "../faq/faqAccardion";
|
import FAQAccordion from "../faq/faqAccardion";
|
||||||
import { faqItems } from "@/lib/demoData";
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function ServiceFaq() {
|
export function ServiceFaq() {
|
||||||
|
const t = useTranslations();
|
||||||
|
const faqItems = [
|
||||||
|
{
|
||||||
|
id: "faq-1",
|
||||||
|
question: t("faq.question1.question"),
|
||||||
|
answer: t("faq.question1.answer"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "faq-2",
|
||||||
|
question: t("faq.question2.question"),
|
||||||
|
answer: t("faq.question2.answer"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "faq-3",
|
||||||
|
question: t("faq.question3.question"),
|
||||||
|
answer: t("faq.question3.answer"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "faq-4",
|
||||||
|
question: t("faq.question4.question"),
|
||||||
|
answer: t("faq.question4.answer"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "faq-5",
|
||||||
|
question: t("faq.question5.question"),
|
||||||
|
answer: t("faq.question5.answer"),
|
||||||
|
},
|
||||||
|
];
|
||||||
return (
|
return (
|
||||||
<div className="bg-[#1e1d1c] py-20 pb-50 space-y-8">
|
<div className="bg-[#1e1d1c] py-20 pb-50 space-y-8">
|
||||||
{/* header */}
|
{/* header */}
|
||||||
|
|||||||
16
i18n/config.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export const locales = ["uz", "ru", "en"] as const
|
||||||
|
export type Locale = (typeof locales)[number]
|
||||||
|
|
||||||
|
export const defaultLocale: Locale = "uz"
|
||||||
|
|
||||||
|
export const localeNames: Record<Locale, string> = {
|
||||||
|
uz: "O'zbekcha",
|
||||||
|
ru: "Русский",
|
||||||
|
en: "English",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const localeFlags: Record<Locale, string> = {
|
||||||
|
uz: "🇺🇿",
|
||||||
|
ru: "🇷🇺",
|
||||||
|
en: "🇬🇧",
|
||||||
|
}
|
||||||
25
i18n/request.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// i18n/request.ts
|
||||||
|
import { getRequestConfig } from 'next-intl/server';
|
||||||
|
import { headers } from 'next/headers';
|
||||||
|
|
||||||
|
const LOCALES = ["uz", "ru", "en"] as const;
|
||||||
|
const DEFAULT_LOCALE = "uz";
|
||||||
|
|
||||||
|
type Locale = typeof LOCALES[number];
|
||||||
|
|
||||||
|
export default getRequestConfig(async () => {
|
||||||
|
const headersList = await headers();
|
||||||
|
|
||||||
|
// ✅ Middleware allaqachon locale'ni set qilgan
|
||||||
|
const locale = headersList.get('x-locale') || DEFAULT_LOCALE;
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
const validLocale = LOCALES.includes(locale as Locale)
|
||||||
|
? locale
|
||||||
|
: DEFAULT_LOCALE;
|
||||||
|
|
||||||
|
return {
|
||||||
|
locale: validLocale,
|
||||||
|
messages: (await import(`../messages/${validLocale}.json`)).default,
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
export const DATA = [
|
export const DATA = [
|
||||||
{
|
{
|
||||||
name: "P-0834405",
|
name: "P-0834405",
|
||||||
|
|||||||
23
lib/i18n-utils.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { Locale } from "@/i18n/config"
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
|
|
||||||
|
export function useChangeLocale() {
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const changeLocale = (locale: Locale) => {
|
||||||
|
document.cookie = `NEXT_LOCALE=${locale}; path=/; max-age=31536000`
|
||||||
|
router.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
return changeLocale
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLocaleFromCookie(): Locale {
|
||||||
|
if (typeof document === "undefined") return "uz"
|
||||||
|
|
||||||
|
const cookie = document.cookie.split("; ").find((row) => row.startsWith("NEXT_LOCALE="))
|
||||||
|
|
||||||
|
return (cookie?.split("=")[1] as Locale) || "uz"
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"home": {
|
"home": {
|
||||||
"banner": {
|
"banner": {
|
||||||
"title1": "Welcome to Ignum",
|
"title1": "Welcome to Ignum",
|
||||||
"title2": "Fire Protection Guardian",
|
"title2": "FIRE PROTECTION GUARDIAN",
|
||||||
"description": "We are seen as a beacon of hope, a figure that brings calm amidst chaos and light in the darkest of moments.",
|
"description": "We are seen as a beacon of hope, a figure that brings calm amidst chaos and light in the darkest of moments.",
|
||||||
"cta": "Get Started"
|
"cta": "Get Started"
|
||||||
},
|
},
|
||||||
@@ -150,7 +150,8 @@
|
|||||||
"title": "Products",
|
"title": "Products",
|
||||||
"subtitle": "Ignum Technology Ready",
|
"subtitle": "Ignum Technology Ready",
|
||||||
"description": "We not only supply equipment but become a successful partner for every client."
|
"description": "We not only supply equipment but become a successful partner for every client."
|
||||||
}
|
},
|
||||||
|
"ourproducts": "Our Products"
|
||||||
},
|
},
|
||||||
"faq": {
|
"faq": {
|
||||||
"banner": {
|
"banner": {
|
||||||
@@ -158,28 +159,31 @@
|
|||||||
"subtitle": "General Questions",
|
"subtitle": "General Questions",
|
||||||
"topic": "ABOUT WORK"
|
"topic": "ABOUT WORK"
|
||||||
},
|
},
|
||||||
"questions": [
|
"question1": {
|
||||||
{
|
"question": "How to choose a fire alarm system?",
|
||||||
"question": "How to choose a fire alarm system?",
|
"answer": "Depending on the area, type and features of the facility, our specialists will offer you the most optimal solution. You can get a free consultation."
|
||||||
"answer": "Depending on the area, type and features of the facility, our specialists will offer you the most optimal solution. You can get a free consultation."
|
},
|
||||||
},
|
"question2": {
|
||||||
{
|
"question": "How long does equipment installation take?",
|
||||||
"question": "How long does equipment installation take?",
|
"answer": "Installation time depends on the project scope. Usually, 1-3 days for small facilities, 1-2 weeks for large facilities."
|
||||||
"answer": "Installation time depends on the project scope. Usually, 1-3 days for small facilities, 1-2 weeks for large facilities."
|
},
|
||||||
},
|
"question3": {
|
||||||
{
|
"question": "How is maintenance carried out?",
|
||||||
"question": "How is maintenance carried out?",
|
"answer": "We offer regular maintenance and 24/7 emergency service. Preventive inspections are conducted every six months."
|
||||||
"answer": "We offer regular maintenance and 24/7 emergency service. Preventive inspections are conducted every six months."
|
},
|
||||||
},
|
"question4": {
|
||||||
{
|
"question": "What is the warranty period?",
|
||||||
"question": "What is the warranty period?",
|
"answer": "All our equipment comes with a 2-year warranty and 10-year maintenance guarantee."
|
||||||
"answer": "All our equipment comes with a 2-year warranty and 10-year maintenance guarantee."
|
},
|
||||||
},
|
"question5": {
|
||||||
{
|
"question": "For which facilities are they suitable?",
|
||||||
"question": "For which facilities are they suitable?",
|
"answer": "We have suitable solutions for office buildings, warehouses, industrial plants, shopping malls, residential buildings and all types of public places."
|
||||||
"answer": "We have suitable solutions for office buildings, warehouses, industrial plants, shopping malls, residential buildings and all types of public places."
|
},
|
||||||
}
|
"ask": {
|
||||||
]
|
"question": "Do you still have questions?",
|
||||||
|
"subtitle": "Contact us and our specialists will answer you",
|
||||||
|
"btn": "Ask Question"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"banner": {
|
"banner": {
|
||||||
@@ -213,5 +217,11 @@
|
|||||||
"contact": "Contact",
|
"contact": "Contact",
|
||||||
"help": "Help"
|
"help": "Help"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
"rasmlar": "Images",
|
||||||
|
"fotogalereya": "Photo Gallery",
|
||||||
|
"contactTitle": "Send us your phone number",
|
||||||
|
"contactSubTitle": "Our staff will contact you",
|
||||||
|
"enterPhone": "Enter your phone number",
|
||||||
|
"send": "Send"
|
||||||
|
}
|
||||||
@@ -150,7 +150,8 @@
|
|||||||
"title": "Продукты",
|
"title": "Продукты",
|
||||||
"subtitle": "Технология Ignum Готова",
|
"subtitle": "Технология Ignum Готова",
|
||||||
"description": "Мы не просто поставляем оборудование, мы становимся успешным партнером для каждого клиента."
|
"description": "Мы не просто поставляем оборудование, мы становимся успешным партнером для каждого клиента."
|
||||||
}
|
},
|
||||||
|
"ourproducts": "Наши продукты"
|
||||||
},
|
},
|
||||||
"faq": {
|
"faq": {
|
||||||
"banner": {
|
"banner": {
|
||||||
@@ -158,28 +159,31 @@
|
|||||||
"subtitle": "Общие Вопросы",
|
"subtitle": "Общие Вопросы",
|
||||||
"topic": "О РАБОТЕ"
|
"topic": "О РАБОТЕ"
|
||||||
},
|
},
|
||||||
"questions": [
|
"question1": {
|
||||||
{
|
"question": "Как выбрать систему пожарной сигнализации?",
|
||||||
"question": "Как выбрать систему пожарной сигнализации?",
|
"answer": "В зависимости от площади, типа и особенностей объекта наши специалисты предложат вам наиболее оптимальное решение. Вы можете получить бесплатную консультацию."
|
||||||
"answer": "В зависимости от площади, типа и особенностей объекта наши специалисты предложат вам наиболее оптимальное решение. Вы можете получить бесплатную консультацию."
|
},
|
||||||
},
|
"question2": {
|
||||||
{
|
"question": "Сколько времени занимает установка оборудования?",
|
||||||
"question": "Сколько времени занимает установка оборудования?",
|
"answer": "Время установки зависит от объема проекта. Обычно для небольших объектов требуется 1-3 дня, для крупных объектов - 1-2 недели."
|
||||||
"answer": "Время установки зависит от объема проекта. Обычно для небольших объектов требуется 1-3 дня, для крупных объектов - 1-2 недели."
|
},
|
||||||
},
|
"question3": {
|
||||||
{
|
"question": "Как проводится техническое обслуживание?",
|
||||||
"question": "Как проводится техническое обслуживание?",
|
"answer": "Мы предлагаем регулярное техническое обслуживание и экстренную службу 24/7. Профилактические проверки проводятся каждые шесть месяцев."
|
||||||
"answer": "Мы предлагаем регулярное техническое обслуживание и экстренную службу 24/7. Профилактические проверки проводятся каждые шесть месяцев."
|
},
|
||||||
},
|
"question4": {
|
||||||
{
|
"question": "Какой срок гарантии?",
|
||||||
"question": "Какой срок гарантии?",
|
"answer": "На все наше оборудование предоставляется 2-летняя гарантия и 10-летняя гарантия на техническое обслуживание."
|
||||||
"answer": "На все наше оборудование предоставляется 2-летняя гарантия и 10-летняя гарантия на техническое обслуживание."
|
},
|
||||||
},
|
"question5": {
|
||||||
{
|
"question": "Для каких объектов подходят?",
|
||||||
"question": "Для каких объектов подходят?",
|
"answer": "У нас есть подходящие решения для офисных зданий, складов, промышленных предприятий, торговых центров, жилых зданий и всех видов общественных мест."
|
||||||
"answer": "У нас есть подходящие решения для офисных зданий, складов, промышленных предприятий, торговых центров, жилых зданий и всех видов общественных мест."
|
},
|
||||||
}
|
"ask": {
|
||||||
]
|
"question": "Остались вопросы?",
|
||||||
|
"subtitle": "Свяжитесь с нами, и наши специалисты ответят вам",
|
||||||
|
"btn": "Задать вопрос"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"banner": {
|
"banner": {
|
||||||
@@ -213,5 +217,11 @@
|
|||||||
"contact": "Контакты",
|
"contact": "Контакты",
|
||||||
"help": "Помощь"
|
"help": "Помощь"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
"rasmlar": "Изображения",
|
||||||
|
"fotogalereya": "Фотогалерея",
|
||||||
|
"contactTitle": "Отправьте нам свой номер",
|
||||||
|
"contactSubTitle": "Наши сотрудники свяжутся с вами",
|
||||||
|
"enterPhone": "Введите ваш номер телефона",
|
||||||
|
"send": "Отправить"
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"home": {
|
"home": {
|
||||||
"banner": {
|
"banner": {
|
||||||
"title1": "Ignum-ga xush kelibsiz",
|
"title1": "Ignum-ga xush kelibsiz",
|
||||||
"title2": "Yong'inga Qarshi Himoya",
|
"title2": "YONG'INGA QARSHI HIMOYA",
|
||||||
"description": "Biz umid nuri, tartibsizlik davrida tinchlik va eng qiyin vaziyatlarda ishonchli himoya manbai sifatida ko'rilamiz.",
|
"description": "Biz umid nuri, tartibsizlik davrida tinchlik va eng qiyin vaziyatlarda ishonchli himoya manbai sifatida ko'rilamiz.",
|
||||||
"cta": "Boshlash"
|
"cta": "Boshlash"
|
||||||
},
|
},
|
||||||
@@ -14,17 +14,17 @@
|
|||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "Biz haqimizda",
|
"title": "Biz haqimizda",
|
||||||
"subtitle": "Yong'inga Qarshi Tizimlar Tayyor",
|
"subtitle": "YONG'INGA QARSHI TIZIMLAR TAYYOR",
|
||||||
"prevention": {
|
"prevention": {
|
||||||
"title": "Yong'inni Oldini Olish Tizimlari",
|
"title": "YONG'INDI OLDINI OLISH TIZIMLARI",
|
||||||
"description": "Biz eng ilg'or yong'in oldini olish texnologiyalarini taklif etamiz. Har bir detal xavfsizlik va ishonchlilikni ta'minlash uchun ishlab chiqilgan."
|
"description": "Biz eng ilg'or yong'in oldini olish texnologiyalarini taklif etamiz. Har bir detal xavfsizlik va ishonchlilikni ta'minlash uchun ishlab chiqilgan."
|
||||||
},
|
},
|
||||||
"accidents": {
|
"accidents": {
|
||||||
"title": "Favqulodda Holatlar",
|
"title": "FAVQULODDA HOLATLAR",
|
||||||
"description": "Har qanday vaziyatga tezkor va samarali javob berish uchun mo'ljallangan avtomatik o'chirish tizimlari. Xavfsizlik - bizning birinchi ustuvorligimiz."
|
"description": "Har qanday vaziyatga tezkor va samarali javob berish uchun mo'ljallangan avtomatik o'chirish tizimlari. Xavfsizlik - bizning birinchi ustuvorligimiz."
|
||||||
},
|
},
|
||||||
"service": {
|
"service": {
|
||||||
"title": "Texnik Xizmat",
|
"title": "TEXNIK XIZMAT",
|
||||||
"description": "Muntazam texnik xizmat ko'rsatish va ta'mirlash xizmatlari. Tizimlaringiz har doim ish holatida bo'lishini kafolatlaymiz."
|
"description": "Muntazam texnik xizmat ko'rsatish va ta'mirlash xizmatlari. Tizimlaringiz har doim ish holatida bo'lishini kafolatlaymiz."
|
||||||
},
|
},
|
||||||
"award": "Eng Yaxshi Yong'in Himoyasi 2025"
|
"award": "Eng Yaxshi Yong'in Himoyasi 2025"
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"viewMoreServices": "Ko'proq Xizmatlar",
|
"viewMoreServices": "Ko'proq Xizmatlar",
|
||||||
"viewMore": "Ko'proq"
|
"viewMore": "Ko'proq ko'rish"
|
||||||
},
|
},
|
||||||
"testimonials": {
|
"testimonials": {
|
||||||
"title": "Mijozlar Fikrlari",
|
"title": "Mijozlar Fikrlari",
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
},
|
},
|
||||||
"blog": {
|
"blog": {
|
||||||
"title": "Blog & Maqolalar",
|
"title": "Blog & Maqolalar",
|
||||||
"subtitle": "SO'NGI BLOG & YANGILIKLAR",
|
"subtitle": "BLOG & SO'NGI YANGILIKLAR",
|
||||||
"articles": {
|
"articles": {
|
||||||
"article1": "YONG'IN HIMOYASI TIZIMLARI: QANDAY ISHLAYDI?",
|
"article1": "YONG'IN HIMOYASI TIZIMLARI: QANDAY ISHLAYDI?",
|
||||||
"article2": "YANGI TEXNOLOGIYALAR: AQLLI O'CHIRISH TIZIMLARI",
|
"article2": "YANGI TEXNOLOGIYALAR: AQLLI O'CHIRISH TIZIMLARI",
|
||||||
@@ -150,7 +150,8 @@
|
|||||||
"title": "Mahsulotlar",
|
"title": "Mahsulotlar",
|
||||||
"subtitle": "Ignum Texnologiyasi Tayyor",
|
"subtitle": "Ignum Texnologiyasi Tayyor",
|
||||||
"description": "Biz nafaqat uskunalar yetkazib beramiz, balki har bir mijozning muvaffaqiyatli hamkoriga aylanamiz."
|
"description": "Biz nafaqat uskunalar yetkazib beramiz, balki har bir mijozning muvaffaqiyatli hamkoriga aylanamiz."
|
||||||
}
|
},
|
||||||
|
"ourproducts": "Bizning mahsulotlarimiz"
|
||||||
},
|
},
|
||||||
"faq": {
|
"faq": {
|
||||||
"banner": {
|
"banner": {
|
||||||
@@ -158,28 +159,31 @@
|
|||||||
"subtitle": "Umumiy Savollar",
|
"subtitle": "Umumiy Savollar",
|
||||||
"topic": "ISH HAQIDA"
|
"topic": "ISH HAQIDA"
|
||||||
},
|
},
|
||||||
"questions": [
|
"question1": {
|
||||||
{
|
"question": "Yong'in signalizatsiya tizimini qanday tanlash kerak?",
|
||||||
"question": "Yong'in signalizatsiya tizimini qanday tanlash kerak?",
|
"answer": "Ob'ektning maydoni, turi va xususiyatlariga qarab mutaxassislarimiz sizga eng optimal yechimni taklif qiladilar. Bepul konsultatsiya olishingiz mumkin."
|
||||||
"answer": "Ob'ektning maydoni, turi va xususiyatlariga qarab mutaxassislarimiz sizga eng optimal yechimni taklif qiladilar. Bepul konsultatsiya olishingiz mumkin."
|
},
|
||||||
},
|
"question2": {
|
||||||
{
|
"question": "Uskunalarni o'rnatish qancha vaqt oladi?",
|
||||||
"question": "Uskunalarni o'rnatish qancha vaqt oladi?",
|
"answer": "O'rnatish vaqti loyiha hajmiga bog'liq. Odatda, kichik ob'ektlar uchun 1-3 kun, yirik ob'ektlar uchun 1-2 hafta kerak bo'ladi."
|
||||||
"answer": "O'rnatish vaqti loyiha hajmiga bog'liq. Odatda, kichik ob'ektlar uchun 1-3 kun, yirik ob'ektlar uchun 1-2 hafta kerak bo'ladi."
|
},
|
||||||
},
|
"question3": {
|
||||||
{
|
"question": "Texnik xizmat ko'rsatish qanday amalga oshiriladi?",
|
||||||
"question": "Texnik xizmat ko'rsatish qanday amalga oshiriladi?",
|
"answer": "Biz muntazam texnik xizmat ko'rsatish va 24/7 favqulodda xizmatni taklif etamiz. Har olti oyda bir marta profilaktik tekshiruvlar o'tkaziladi."
|
||||||
"answer": "Biz muntazam texnik xizmat ko'rsatish va 24/7 favqulodda xizmatni taklif etamiz. Har olti oyda bir marta profilaktik tekshiruvlar o'tkaziladi."
|
},
|
||||||
},
|
"question4": {
|
||||||
{
|
"question": "Kafolatiy muddati qancha?",
|
||||||
"question": "Kafolatiy muddati qancha?",
|
"answer": "Barcha uskunalarimiz uchun 2 yillik kafolat va 10 yillik texnik xizmat ko'rsatish kafolati beriladi."
|
||||||
"answer": "Barcha uskunalarimiz uchun 2 yillik kafolat va 10 yillik texnik xizmat ko'rsatish kafolati beriladi."
|
},
|
||||||
},
|
"question5": {
|
||||||
{
|
"question": "Qanday ob'ektlar uchun mos?",
|
||||||
"question": "Qanday ob'ektlar uchun mos?",
|
"answer": "Ofis binalari, omborxonalar, sanoat korxonalari, savdo markazlari, turar-joy binolari va barcha turdagi jamoat joylari uchun mos yechimlarimiz mavjud."
|
||||||
"answer": "Ofis binalari, omborxonalar, sanoat korxonalari, savdo markazlari, turar-joy binolari va barcha turdagi jamoat joylari uchun mos yechimlarimiz mavjud."
|
},
|
||||||
}
|
"ask": {
|
||||||
]
|
"question": "Hali ham savolingiz bormi?",
|
||||||
|
"subtitle": "Bizga bo'glaning va bizni hodilarimiz sizga javob berishadi",
|
||||||
|
"btn": "Savollingizni yo'llang"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"banner": {
|
"banner": {
|
||||||
@@ -213,5 +217,11 @@
|
|||||||
"contact": "Aloqa",
|
"contact": "Aloqa",
|
||||||
"help": "Yordam"
|
"help": "Yordam"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
"rasmlar": "Rasmlar",
|
||||||
|
"fotogalereya": "Fotogalereya",
|
||||||
|
"contactTitle": "Bizga raqamingizni yuboring",
|
||||||
|
"contactSubTitle": "Xodimlarimiz siz bilan bog'lanishadi",
|
||||||
|
"enterPhone":"Telefon raqamingiz kiriting",
|
||||||
|
"send":"Yuborish"
|
||||||
|
}
|
||||||
136
middleware.ts
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { match as matchLocale } from "@formatjs/intl-localematcher";
|
||||||
|
import Negotiator from "negotiator";
|
||||||
|
const PUBLIC_PAGES = ["/login", "/register"];
|
||||||
|
|
||||||
|
const LOCALES = ["uz", "ru", "en"];
|
||||||
|
const DEFAULT_LOCALE = "uz";
|
||||||
|
|
||||||
|
type Locale = (typeof LOCALES)[number];
|
||||||
|
|
||||||
|
function getLocaleFromPathname(pathname: string): Locale | null {
|
||||||
|
const segments = pathname.split("/").filter(Boolean);
|
||||||
|
const firstSegment = segments[0];
|
||||||
|
|
||||||
|
if (firstSegment && LOCALES.includes(firstSegment as Locale)) {
|
||||||
|
return firstSegment as Locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocaleFromCookie(request: NextRequest): Locale | null {
|
||||||
|
const cookieLocale = request.cookies.get("NEXT_LOCALE")?.value;
|
||||||
|
|
||||||
|
if (cookieLocale && LOCALES.includes(cookieLocale as Locale)) {
|
||||||
|
return cookieLocale as Locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocaleFromHeaders(request: NextRequest): Locale {
|
||||||
|
const negotiatorHeaders: Record<string, string> = {};
|
||||||
|
request.headers.forEach((value, key) => {
|
||||||
|
negotiatorHeaders[key] = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const languages = new Negotiator({ headers: negotiatorHeaders }).languages();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return matchLocale(
|
||||||
|
languages,
|
||||||
|
LOCALES as unknown as string[],
|
||||||
|
DEFAULT_LOCALE
|
||||||
|
) as Locale;
|
||||||
|
} catch {
|
||||||
|
return DEFAULT_LOCALE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function middleware(request: NextRequest) {
|
||||||
|
const { pathname, search } = request.nextUrl;
|
||||||
|
|
||||||
|
// Skip public files and API routes
|
||||||
|
if (
|
||||||
|
pathname.includes(".") ||
|
||||||
|
pathname.startsWith("/api") ||
|
||||||
|
pathname.startsWith("/_next")
|
||||||
|
) {
|
||||||
|
return NextResponse.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Check URL locale
|
||||||
|
const localeFromPath = getLocaleFromPathname(pathname);
|
||||||
|
|
||||||
|
// 2. Check cookie locale
|
||||||
|
const localeFromCookie = getLocaleFromCookie(request);
|
||||||
|
|
||||||
|
// 3. Check browser locale
|
||||||
|
const localeFromBrowser = getLocaleFromHeaders(request);
|
||||||
|
|
||||||
|
// Priority: URL > Cookie > Browser
|
||||||
|
const preferredLocale =
|
||||||
|
localeFromPath || localeFromCookie || localeFromBrowser;
|
||||||
|
|
||||||
|
// Faqat kerakli sahifalarni redirect qilamiz
|
||||||
|
const isPublicPage = PUBLIC_PAGES.some((page) => pathname === page);
|
||||||
|
|
||||||
|
if (isPublicPage) {
|
||||||
|
const url = request.nextUrl.clone();
|
||||||
|
url.pathname = `/${DEFAULT_LOCALE}/verify-otp`;
|
||||||
|
url.search = search; // ?code=1111&phone=...
|
||||||
|
|
||||||
|
return NextResponse.redirect(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If URL has no locale, redirect with preferred locale
|
||||||
|
if (!localeFromPath) {
|
||||||
|
const newUrl = new URL(`/${preferredLocale}/${pathname}`, request.url);
|
||||||
|
return NextResponse.redirect(newUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If URL locale differs from cookie, update cookie
|
||||||
|
if (localeFromPath !== localeFromCookie) {
|
||||||
|
const response = NextResponse.next();
|
||||||
|
|
||||||
|
// ✅ Set cookie on server side
|
||||||
|
response.cookies.set("NEXT_LOCALE", localeFromPath, {
|
||||||
|
path: "/",
|
||||||
|
maxAge: 31536000, // 1 year
|
||||||
|
sameSite: "lax",
|
||||||
|
});
|
||||||
|
|
||||||
|
// ✅ Pass locale to request headers for server components
|
||||||
|
const requestHeaders = new Headers(request.headers);
|
||||||
|
requestHeaders.set("x-locale", localeFromPath);
|
||||||
|
requestHeaders.set("x-pathname", pathname);
|
||||||
|
|
||||||
|
return NextResponse.next({
|
||||||
|
request: {
|
||||||
|
headers: requestHeaders,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal flow - just pass locale in headers
|
||||||
|
const response = NextResponse.next();
|
||||||
|
const requestHeaders = new Headers(request.headers);
|
||||||
|
requestHeaders.set("x-locale", localeFromPath);
|
||||||
|
requestHeaders.set("x-pathname", pathname);
|
||||||
|
|
||||||
|
return NextResponse.next({
|
||||||
|
request: {
|
||||||
|
headers: requestHeaders,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
matcher: [
|
||||||
|
// Match all pathnames except for
|
||||||
|
// - … if they start with `/api`, `/_next` or `/_vercel`
|
||||||
|
// - … the ones containing a dot (e.g. `favicon.ico`)
|
||||||
|
'/((?!api|_next|_vercel|.*\\..*).*)',
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -1,11 +1,23 @@
|
|||||||
|
import createNextIntlPlugin from 'next-intl/plugin'
|
||||||
|
|
||||||
|
const withNextIntl = createNextIntlPlugin('./i18n/request.ts')
|
||||||
|
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
|
eslint: {
|
||||||
|
ignoreDuringBuilds: true,
|
||||||
|
},
|
||||||
typescript: {
|
typescript: {
|
||||||
ignoreBuildErrors: true,
|
ignoreBuildErrors: true,
|
||||||
},
|
},
|
||||||
images: {
|
images: {
|
||||||
unoptimized: true,
|
unoptimized: true,
|
||||||
},
|
},
|
||||||
|
webpack: (config) => {
|
||||||
|
config.resolve.alias.canvas = false;
|
||||||
|
|
||||||
|
return config;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default nextConfig
|
export default withNextIntl(nextConfig)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"start": "next start"
|
"start": "next start"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@formatjs/intl-localematcher": "^0.8.0",
|
||||||
"@hookform/resolvers": "^3.10.0",
|
"@hookform/resolvers": "^3.10.0",
|
||||||
"@radix-ui/react-accordion": "1.2.2",
|
"@radix-ui/react-accordion": "1.2.2",
|
||||||
"@radix-ui/react-alert-dialog": "1.1.4",
|
"@radix-ui/react-alert-dialog": "1.1.4",
|
||||||
@@ -44,9 +45,12 @@
|
|||||||
"cmdk": "1.0.4",
|
"cmdk": "1.0.4",
|
||||||
"date-fns": "4.1.0",
|
"date-fns": "4.1.0",
|
||||||
"embla-carousel-react": "8.5.1",
|
"embla-carousel-react": "8.5.1",
|
||||||
|
"framer-motion": "^12.29.2",
|
||||||
"input-otp": "1.4.1",
|
"input-otp": "1.4.1",
|
||||||
"lucide-react": "^0.454.0",
|
"lucide-react": "^0.454.0",
|
||||||
|
"negotiator": "^1.0.0",
|
||||||
"next": "16.0.10",
|
"next": "16.0.10",
|
||||||
|
"next-intl": "^4.7.0",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"react": "19.2.0",
|
"react": "19.2.0",
|
||||||
"react-day-picker": "9.8.0",
|
"react-day-picker": "9.8.0",
|
||||||
@@ -64,6 +68,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4.1.9",
|
"@tailwindcss/postcss": "^4.1.9",
|
||||||
|
"@types/negotiator": "^0.6.4",
|
||||||
"@types/node": "^22",
|
"@types/node": "^22",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
|
|||||||
486
pnpm-lock.yaml
generated
@@ -8,6 +8,9 @@ importers:
|
|||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@formatjs/intl-localematcher':
|
||||||
|
specifier: ^0.8.0
|
||||||
|
version: 0.8.0
|
||||||
'@hookform/resolvers':
|
'@hookform/resolvers':
|
||||||
specifier: ^3.10.0
|
specifier: ^3.10.0
|
||||||
version: 3.10.0(react-hook-form@7.71.1(react@19.2.0))
|
version: 3.10.0(react-hook-form@7.71.1(react@19.2.0))
|
||||||
@@ -113,15 +116,24 @@ importers:
|
|||||||
embla-carousel-react:
|
embla-carousel-react:
|
||||||
specifier: 8.5.1
|
specifier: 8.5.1
|
||||||
version: 8.5.1(react@19.2.0)
|
version: 8.5.1(react@19.2.0)
|
||||||
|
framer-motion:
|
||||||
|
specifier: ^12.29.2
|
||||||
|
version: 12.29.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
input-otp:
|
input-otp:
|
||||||
specifier: 1.4.1
|
specifier: 1.4.1
|
||||||
version: 1.4.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
version: 1.4.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
lucide-react:
|
lucide-react:
|
||||||
specifier: ^0.454.0
|
specifier: ^0.454.0
|
||||||
version: 0.454.0(react@19.2.0)
|
version: 0.454.0(react@19.2.0)
|
||||||
|
negotiator:
|
||||||
|
specifier: ^1.0.0
|
||||||
|
version: 1.0.0
|
||||||
next:
|
next:
|
||||||
specifier: 16.0.10
|
specifier: 16.0.10
|
||||||
version: 16.0.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
version: 16.0.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
next-intl:
|
||||||
|
specifier: ^4.7.0
|
||||||
|
version: 4.7.0(next@16.0.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
|
||||||
next-themes:
|
next-themes:
|
||||||
specifier: ^0.4.6
|
specifier: ^0.4.6
|
||||||
version: 0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
version: 0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
@@ -168,6 +180,9 @@ importers:
|
|||||||
'@tailwindcss/postcss':
|
'@tailwindcss/postcss':
|
||||||
specifier: ^4.1.9
|
specifier: ^4.1.9
|
||||||
version: 4.1.18
|
version: 4.1.18
|
||||||
|
'@types/negotiator':
|
||||||
|
specifier: ^0.6.4
|
||||||
|
version: 0.6.4
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22
|
specifier: ^22
|
||||||
version: 22.19.7
|
version: 22.19.7
|
||||||
@@ -221,6 +236,30 @@ packages:
|
|||||||
'@floating-ui/utils@0.2.10':
|
'@floating-ui/utils@0.2.10':
|
||||||
resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
|
resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
|
||||||
|
|
||||||
|
'@formatjs/ecma402-abstract@2.3.6':
|
||||||
|
resolution: {integrity: sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==}
|
||||||
|
|
||||||
|
'@formatjs/fast-memoize@2.2.7':
|
||||||
|
resolution: {integrity: sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==}
|
||||||
|
|
||||||
|
'@formatjs/fast-memoize@3.1.0':
|
||||||
|
resolution: {integrity: sha512-b5mvSWCI+XVKiz5WhnBCY3RJ4ZwfjAidU0yVlKa3d3MSgKmH1hC3tBGEAtYyN5mqL7N0G5x0BOUYyO8CEupWgg==}
|
||||||
|
|
||||||
|
'@formatjs/icu-messageformat-parser@2.11.4':
|
||||||
|
resolution: {integrity: sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==}
|
||||||
|
|
||||||
|
'@formatjs/icu-skeleton-parser@1.8.16':
|
||||||
|
resolution: {integrity: sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==}
|
||||||
|
|
||||||
|
'@formatjs/intl-localematcher@0.5.10':
|
||||||
|
resolution: {integrity: sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==}
|
||||||
|
|
||||||
|
'@formatjs/intl-localematcher@0.6.2':
|
||||||
|
resolution: {integrity: sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==}
|
||||||
|
|
||||||
|
'@formatjs/intl-localematcher@0.8.0':
|
||||||
|
resolution: {integrity: sha512-zgMYWdUlmEZpX2Io+v3LHrfq9xZ6khpQVf9UAw2xYWhGerGgI9XgH1HvL/A34jWiruUJpYlP5pk4g8nIcaDrXQ==}
|
||||||
|
|
||||||
'@hookform/resolvers@3.10.0':
|
'@hookform/resolvers@3.10.0':
|
||||||
resolution: {integrity: sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==}
|
resolution: {integrity: sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -430,6 +469,88 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
|
'@parcel/watcher-android-arm64@2.5.6':
|
||||||
|
resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [android]
|
||||||
|
|
||||||
|
'@parcel/watcher-darwin-arm64@2.5.6':
|
||||||
|
resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@parcel/watcher-darwin-x64@2.5.6':
|
||||||
|
resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@parcel/watcher-freebsd-x64@2.5.6':
|
||||||
|
resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [freebsd]
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-arm-glibc@2.5.6':
|
||||||
|
resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-arm-musl@2.5.6':
|
||||||
|
resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-arm64-glibc@2.5.6':
|
||||||
|
resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-arm64-musl@2.5.6':
|
||||||
|
resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-x64-glibc@2.5.6':
|
||||||
|
resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-x64-musl@2.5.6':
|
||||||
|
resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@parcel/watcher-win32-arm64@2.5.6':
|
||||||
|
resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@parcel/watcher-win32-ia32@2.5.6':
|
||||||
|
resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [ia32]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@parcel/watcher-win32-x64@2.5.6':
|
||||||
|
resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@parcel/watcher@2.5.6':
|
||||||
|
resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
|
||||||
'@radix-ui/number@1.1.0':
|
'@radix-ui/number@1.1.0':
|
||||||
resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==}
|
resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==}
|
||||||
|
|
||||||
@@ -1086,9 +1207,87 @@ packages:
|
|||||||
'@radix-ui/rect@1.1.0':
|
'@radix-ui/rect@1.1.0':
|
||||||
resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==}
|
resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==}
|
||||||
|
|
||||||
|
'@schummar/icu-type-parser@1.21.5':
|
||||||
|
resolution: {integrity: sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==}
|
||||||
|
|
||||||
|
'@swc/core-darwin-arm64@1.15.10':
|
||||||
|
resolution: {integrity: sha512-U72pGqmJYbjrLhMndIemZ7u9Q9owcJczGxwtfJlz/WwMaGYAV/g4nkGiUVk/+QSX8sFCAjanovcU1IUsP2YulA==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@swc/core-darwin-x64@1.15.10':
|
||||||
|
resolution: {integrity: sha512-NZpDXtwHH083L40xdyj1sY31MIwLgOxKfZEAGCI8xHXdHa+GWvEiVdGiu4qhkJctoHFzAEc7ZX3GN5phuJcPuQ==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@swc/core-linux-arm-gnueabihf@1.15.10':
|
||||||
|
resolution: {integrity: sha512-ioieF5iuRziUF1HkH1gg1r93e055dAdeBAPGAk40VjqpL5/igPJ/WxFHGvc6WMLhUubSJI4S0AiZAAhEAp1jDg==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@swc/core-linux-arm64-gnu@1.15.10':
|
||||||
|
resolution: {integrity: sha512-tD6BClOrxSsNus9cJL7Gxdv7z7Y2hlyvZd9l0NQz+YXzmTWqnfzLpg16ovEI7gknH2AgDBB5ywOsqu8hUgSeEQ==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@swc/core-linux-arm64-musl@1.15.10':
|
||||||
|
resolution: {integrity: sha512-4uAHO3nbfbrTcmO/9YcVweTQdx5fN3l7ewwl5AEK4yoC4wXmoBTEPHAVdKNe4r9+xrTgd4BgyPsy0409OjjlMw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@swc/core-linux-x64-gnu@1.15.10':
|
||||||
|
resolution: {integrity: sha512-W0h9ONNw1pVIA0cN7wtboOSTl4Jk3tHq+w2cMPQudu9/+3xoCxpFb9ZdehwCAk29IsvdWzGzY6P7dDVTyFwoqg==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@swc/core-linux-x64-musl@1.15.10':
|
||||||
|
resolution: {integrity: sha512-XQNZlLZB62S8nAbw7pqoqwy91Ldy2RpaMRqdRN3T+tAg6Xg6FywXRKCsLh6IQOadr4p1+lGnqM/Wn35z5a/0Vw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@swc/core-win32-arm64-msvc@1.15.10':
|
||||||
|
resolution: {integrity: sha512-qnAGrRv5Nj/DATxAmCnJQRXXQqnJwR0trxLndhoHoxGci9MuguNIjWahS0gw8YZFjgTinbTxOwzatkoySihnmw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@swc/core-win32-ia32-msvc@1.15.10':
|
||||||
|
resolution: {integrity: sha512-i4X/q8QSvzVlaRtv1xfnfl+hVKpCfiJ+9th484rh937fiEZKxZGf51C+uO0lfKDP1FfnT6C1yBYwHy7FLBVXFw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
cpu: [ia32]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@swc/core-win32-x64-msvc@1.15.10':
|
||||||
|
resolution: {integrity: sha512-HvY8XUFuoTXn6lSccDLYFlXv1SU/PzYi4PyUqGT++WfTnbw/68N/7BdUZqglGRwiSqr0qhYt/EhmBpULj0J9rA==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@swc/core@1.15.10':
|
||||||
|
resolution: {integrity: sha512-udNofxftduMUEv7nqahl2nvodCiCDQ4Ge0ebzsEm6P8s0RC2tBM0Hqx0nNF5J/6t9uagFJyWIDjXy3IIWMHDJw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
peerDependencies:
|
||||||
|
'@swc/helpers': '>=0.5.17'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@swc/helpers':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@swc/counter@0.1.3':
|
||||||
|
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
|
||||||
|
|
||||||
'@swc/helpers@0.5.15':
|
'@swc/helpers@0.5.15':
|
||||||
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
|
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
|
||||||
|
|
||||||
|
'@swc/types@0.1.25':
|
||||||
|
resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==}
|
||||||
|
|
||||||
'@tailwindcss/node@4.1.18':
|
'@tailwindcss/node@4.1.18':
|
||||||
resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==}
|
resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==}
|
||||||
|
|
||||||
@@ -1204,6 +1403,9 @@ packages:
|
|||||||
'@types/d3-timer@3.0.2':
|
'@types/d3-timer@3.0.2':
|
||||||
resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
|
resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
|
||||||
|
|
||||||
|
'@types/negotiator@0.6.4':
|
||||||
|
resolution: {integrity: sha512-elf6BsTq+AkyNsb2h5cGNst2Mc7dPliVoAPm1fXglC/BM3f2pFA40BaSSv3E5lyHteEawVKLP+8TwiY1DMNb3A==}
|
||||||
|
|
||||||
'@types/node@22.19.7':
|
'@types/node@22.19.7':
|
||||||
resolution: {integrity: sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==}
|
resolution: {integrity: sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==}
|
||||||
|
|
||||||
@@ -1321,6 +1523,9 @@ packages:
|
|||||||
decimal.js-light@2.5.1:
|
decimal.js-light@2.5.1:
|
||||||
resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==}
|
resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==}
|
||||||
|
|
||||||
|
decimal.js@10.6.0:
|
||||||
|
resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}
|
||||||
|
|
||||||
detect-libc@2.1.2:
|
detect-libc@2.1.2:
|
||||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1365,6 +1570,20 @@ packages:
|
|||||||
fraction.js@5.3.4:
|
fraction.js@5.3.4:
|
||||||
resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
|
resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
|
||||||
|
|
||||||
|
framer-motion@12.29.2:
|
||||||
|
resolution: {integrity: sha512-lSNRzBJk4wuIy0emYQ/nfZ7eWhqud2umPKw2QAQki6uKhZPKm2hRQHeQoHTG9MIvfobb+A/LbEWPJU794ZUKrg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@emotion/is-prop-valid': '*'
|
||||||
|
react: ^18.0.0 || ^19.0.0
|
||||||
|
react-dom: ^18.0.0 || ^19.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@emotion/is-prop-valid':
|
||||||
|
optional: true
|
||||||
|
react:
|
||||||
|
optional: true
|
||||||
|
react-dom:
|
||||||
|
optional: true
|
||||||
|
|
||||||
get-nonce@1.0.1:
|
get-nonce@1.0.1:
|
||||||
resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
|
resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -1382,6 +1601,17 @@ packages:
|
|||||||
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
intl-messageformat@10.7.18:
|
||||||
|
resolution: {integrity: sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==}
|
||||||
|
|
||||||
|
is-extglob@2.1.1:
|
||||||
|
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
is-glob@4.0.3:
|
||||||
|
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
jiti@2.6.1:
|
jiti@2.6.1:
|
||||||
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -1474,11 +1704,34 @@ packages:
|
|||||||
magic-string@0.30.21:
|
magic-string@0.30.21:
|
||||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||||
|
|
||||||
|
motion-dom@12.29.2:
|
||||||
|
resolution: {integrity: sha512-/k+NuycVV8pykxyiTCoFzIVLA95Nb1BFIVvfSu9L50/6K6qNeAYtkxXILy/LRutt7AzaYDc2myj0wkCVVYAPPA==}
|
||||||
|
|
||||||
|
motion-utils@12.29.2:
|
||||||
|
resolution: {integrity: sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A==}
|
||||||
|
|
||||||
nanoid@3.3.11:
|
nanoid@3.3.11:
|
||||||
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
|
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
negotiator@1.0.0:
|
||||||
|
resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
|
||||||
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
|
next-intl-swc-plugin-extractor@4.7.0:
|
||||||
|
resolution: {integrity: sha512-iAqflu2FWdQMWhwB0B2z52X7LmEpvnMNJXqVERZQ7bK5p9iqQLu70ur6Ka6NfiXLxfb+AeAkUX5qIciQOg+87A==}
|
||||||
|
|
||||||
|
next-intl@4.7.0:
|
||||||
|
resolution: {integrity: sha512-gvROzcNr/HM0jTzQlKWQxUNk8jrZ0bREz+bht3wNbv+uzlZ5Kn3J+m+viosub18QJ72S08UJnVK50PXWcUvwpQ==}
|
||||||
|
peerDependencies:
|
||||||
|
next: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
|
||||||
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0
|
||||||
|
typescript: ^5.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
typescript:
|
||||||
|
optional: true
|
||||||
|
|
||||||
next-themes@0.4.6:
|
next-themes@0.4.6:
|
||||||
resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==}
|
resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1506,6 +1759,9 @@ packages:
|
|||||||
sass:
|
sass:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
node-addon-api@7.1.1:
|
||||||
|
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
|
||||||
|
|
||||||
node-releases@2.0.27:
|
node-releases@2.0.27:
|
||||||
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
|
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
|
||||||
|
|
||||||
@@ -1516,6 +1772,13 @@ packages:
|
|||||||
picocolors@1.1.1:
|
picocolors@1.1.1:
|
||||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||||
|
|
||||||
|
picomatch@4.0.3:
|
||||||
|
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
po-parser@2.1.1:
|
||||||
|
resolution: {integrity: sha512-ECF4zHLbUItpUgE3OTtLKlPjeBN+fKEczj2zYjDfCGOzicNs0GK3Vg2IoAYwx7LH/XYw43fZQP6xnZ4TkNxSLQ==}
|
||||||
|
|
||||||
postcss-value-parser@4.2.0:
|
postcss-value-parser@4.2.0:
|
||||||
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
|
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
|
||||||
|
|
||||||
@@ -1711,6 +1974,11 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
use-intl@4.7.0:
|
||||||
|
resolution: {integrity: sha512-jyd8nSErVRRsSlUa+SDobKHo9IiWs5fjcPl9VBUnzUyEQpVM5mwJCgw8eUiylhvBpLQzUGox1KN0XlRivSID9A==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0
|
||||||
|
|
||||||
use-sidecar@1.1.3:
|
use-sidecar@1.1.3:
|
||||||
resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
|
resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -1768,6 +2036,45 @@ snapshots:
|
|||||||
|
|
||||||
'@floating-ui/utils@0.2.10': {}
|
'@floating-ui/utils@0.2.10': {}
|
||||||
|
|
||||||
|
'@formatjs/ecma402-abstract@2.3.6':
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/fast-memoize': 2.2.7
|
||||||
|
'@formatjs/intl-localematcher': 0.6.2
|
||||||
|
decimal.js: 10.6.0
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@formatjs/fast-memoize@2.2.7':
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@formatjs/fast-memoize@3.1.0':
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@formatjs/icu-messageformat-parser@2.11.4':
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/ecma402-abstract': 2.3.6
|
||||||
|
'@formatjs/icu-skeleton-parser': 1.8.16
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@formatjs/icu-skeleton-parser@1.8.16':
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/ecma402-abstract': 2.3.6
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@formatjs/intl-localematcher@0.5.10':
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@formatjs/intl-localematcher@0.6.2':
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@formatjs/intl-localematcher@0.8.0':
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/fast-memoize': 3.1.0
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
'@hookform/resolvers@3.10.0(react-hook-form@7.71.1(react@19.2.0))':
|
'@hookform/resolvers@3.10.0(react-hook-form@7.71.1(react@19.2.0))':
|
||||||
dependencies:
|
dependencies:
|
||||||
react-hook-form: 7.71.1(react@19.2.0)
|
react-hook-form: 7.71.1(react@19.2.0)
|
||||||
@@ -1914,6 +2221,66 @@ snapshots:
|
|||||||
'@next/swc-win32-x64-msvc@16.0.10':
|
'@next/swc-win32-x64-msvc@16.0.10':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-android-arm64@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-darwin-arm64@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-darwin-x64@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-freebsd-x64@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-arm-glibc@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-arm-musl@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-arm64-glibc@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-arm64-musl@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-x64-glibc@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-linux-x64-musl@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-win32-arm64@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-win32-ia32@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher-win32-x64@2.5.6':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@parcel/watcher@2.5.6':
|
||||||
|
dependencies:
|
||||||
|
detect-libc: 2.1.2
|
||||||
|
is-glob: 4.0.3
|
||||||
|
node-addon-api: 7.1.1
|
||||||
|
picomatch: 4.0.3
|
||||||
|
optionalDependencies:
|
||||||
|
'@parcel/watcher-android-arm64': 2.5.6
|
||||||
|
'@parcel/watcher-darwin-arm64': 2.5.6
|
||||||
|
'@parcel/watcher-darwin-x64': 2.5.6
|
||||||
|
'@parcel/watcher-freebsd-x64': 2.5.6
|
||||||
|
'@parcel/watcher-linux-arm-glibc': 2.5.6
|
||||||
|
'@parcel/watcher-linux-arm-musl': 2.5.6
|
||||||
|
'@parcel/watcher-linux-arm64-glibc': 2.5.6
|
||||||
|
'@parcel/watcher-linux-arm64-musl': 2.5.6
|
||||||
|
'@parcel/watcher-linux-x64-glibc': 2.5.6
|
||||||
|
'@parcel/watcher-linux-x64-musl': 2.5.6
|
||||||
|
'@parcel/watcher-win32-arm64': 2.5.6
|
||||||
|
'@parcel/watcher-win32-ia32': 2.5.6
|
||||||
|
'@parcel/watcher-win32-x64': 2.5.6
|
||||||
|
|
||||||
'@radix-ui/number@1.1.0': {}
|
'@radix-ui/number@1.1.0': {}
|
||||||
|
|
||||||
'@radix-ui/primitive@1.1.1': {}
|
'@radix-ui/primitive@1.1.1': {}
|
||||||
@@ -2606,10 +2973,64 @@ snapshots:
|
|||||||
|
|
||||||
'@radix-ui/rect@1.1.0': {}
|
'@radix-ui/rect@1.1.0': {}
|
||||||
|
|
||||||
|
'@schummar/icu-type-parser@1.21.5': {}
|
||||||
|
|
||||||
|
'@swc/core-darwin-arm64@1.15.10':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@swc/core-darwin-x64@1.15.10':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@swc/core-linux-arm-gnueabihf@1.15.10':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@swc/core-linux-arm64-gnu@1.15.10':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@swc/core-linux-arm64-musl@1.15.10':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@swc/core-linux-x64-gnu@1.15.10':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@swc/core-linux-x64-musl@1.15.10':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@swc/core-win32-arm64-msvc@1.15.10':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@swc/core-win32-ia32-msvc@1.15.10':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@swc/core-win32-x64-msvc@1.15.10':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@swc/core@1.15.10':
|
||||||
|
dependencies:
|
||||||
|
'@swc/counter': 0.1.3
|
||||||
|
'@swc/types': 0.1.25
|
||||||
|
optionalDependencies:
|
||||||
|
'@swc/core-darwin-arm64': 1.15.10
|
||||||
|
'@swc/core-darwin-x64': 1.15.10
|
||||||
|
'@swc/core-linux-arm-gnueabihf': 1.15.10
|
||||||
|
'@swc/core-linux-arm64-gnu': 1.15.10
|
||||||
|
'@swc/core-linux-arm64-musl': 1.15.10
|
||||||
|
'@swc/core-linux-x64-gnu': 1.15.10
|
||||||
|
'@swc/core-linux-x64-musl': 1.15.10
|
||||||
|
'@swc/core-win32-arm64-msvc': 1.15.10
|
||||||
|
'@swc/core-win32-ia32-msvc': 1.15.10
|
||||||
|
'@swc/core-win32-x64-msvc': 1.15.10
|
||||||
|
|
||||||
|
'@swc/counter@0.1.3': {}
|
||||||
|
|
||||||
'@swc/helpers@0.5.15':
|
'@swc/helpers@0.5.15':
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@swc/types@0.1.25':
|
||||||
|
dependencies:
|
||||||
|
'@swc/counter': 0.1.3
|
||||||
|
|
||||||
'@tailwindcss/node@4.1.18':
|
'@tailwindcss/node@4.1.18':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/remapping': 2.3.5
|
'@jridgewell/remapping': 2.3.5
|
||||||
@@ -2703,6 +3124,8 @@ snapshots:
|
|||||||
|
|
||||||
'@types/d3-timer@3.0.2': {}
|
'@types/d3-timer@3.0.2': {}
|
||||||
|
|
||||||
|
'@types/negotiator@0.6.4': {}
|
||||||
|
|
||||||
'@types/node@22.19.7':
|
'@types/node@22.19.7':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.21.0
|
undici-types: 6.21.0
|
||||||
@@ -2813,6 +3236,8 @@ snapshots:
|
|||||||
|
|
||||||
decimal.js-light@2.5.1: {}
|
decimal.js-light@2.5.1: {}
|
||||||
|
|
||||||
|
decimal.js@10.6.0: {}
|
||||||
|
|
||||||
detect-libc@2.1.2: {}
|
detect-libc@2.1.2: {}
|
||||||
|
|
||||||
detect-node-es@1.1.0: {}
|
detect-node-es@1.1.0: {}
|
||||||
@@ -2849,6 +3274,15 @@ snapshots:
|
|||||||
|
|
||||||
fraction.js@5.3.4: {}
|
fraction.js@5.3.4: {}
|
||||||
|
|
||||||
|
framer-motion@12.29.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
|
||||||
|
dependencies:
|
||||||
|
motion-dom: 12.29.2
|
||||||
|
motion-utils: 12.29.2
|
||||||
|
tslib: 2.8.1
|
||||||
|
optionalDependencies:
|
||||||
|
react: 19.2.0
|
||||||
|
react-dom: 19.2.0(react@19.2.0)
|
||||||
|
|
||||||
get-nonce@1.0.1: {}
|
get-nonce@1.0.1: {}
|
||||||
|
|
||||||
graceful-fs@4.2.11: {}
|
graceful-fs@4.2.11: {}
|
||||||
@@ -2860,6 +3294,19 @@ snapshots:
|
|||||||
|
|
||||||
internmap@2.0.3: {}
|
internmap@2.0.3: {}
|
||||||
|
|
||||||
|
intl-messageformat@10.7.18:
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/ecma402-abstract': 2.3.6
|
||||||
|
'@formatjs/fast-memoize': 2.2.7
|
||||||
|
'@formatjs/icu-messageformat-parser': 2.11.4
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
is-extglob@2.1.1: {}
|
||||||
|
|
||||||
|
is-glob@4.0.3:
|
||||||
|
dependencies:
|
||||||
|
is-extglob: 2.1.1
|
||||||
|
|
||||||
jiti@2.6.1: {}
|
jiti@2.6.1: {}
|
||||||
|
|
||||||
js-tokens@4.0.0: {}
|
js-tokens@4.0.0: {}
|
||||||
@@ -2927,8 +3374,34 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/sourcemap-codec': 1.5.5
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
|
||||||
|
motion-dom@12.29.2:
|
||||||
|
dependencies:
|
||||||
|
motion-utils: 12.29.2
|
||||||
|
|
||||||
|
motion-utils@12.29.2: {}
|
||||||
|
|
||||||
nanoid@3.3.11: {}
|
nanoid@3.3.11: {}
|
||||||
|
|
||||||
|
negotiator@1.0.0: {}
|
||||||
|
|
||||||
|
next-intl-swc-plugin-extractor@4.7.0: {}
|
||||||
|
|
||||||
|
next-intl@4.7.0(next@16.0.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)(typescript@5.9.3):
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/intl-localematcher': 0.5.10
|
||||||
|
'@parcel/watcher': 2.5.6
|
||||||
|
'@swc/core': 1.15.10
|
||||||
|
negotiator: 1.0.0
|
||||||
|
next: 16.0.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
next-intl-swc-plugin-extractor: 4.7.0
|
||||||
|
po-parser: 2.1.1
|
||||||
|
react: 19.2.0
|
||||||
|
use-intl: 4.7.0(react@19.2.0)
|
||||||
|
optionalDependencies:
|
||||||
|
typescript: 5.9.3
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@swc/helpers'
|
||||||
|
|
||||||
next-themes@0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
|
next-themes@0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.2.0
|
react: 19.2.0
|
||||||
@@ -2957,12 +3430,18 @@ snapshots:
|
|||||||
- '@babel/core'
|
- '@babel/core'
|
||||||
- babel-plugin-macros
|
- babel-plugin-macros
|
||||||
|
|
||||||
|
node-addon-api@7.1.1: {}
|
||||||
|
|
||||||
node-releases@2.0.27: {}
|
node-releases@2.0.27: {}
|
||||||
|
|
||||||
object-assign@4.1.1: {}
|
object-assign@4.1.1: {}
|
||||||
|
|
||||||
picocolors@1.1.1: {}
|
picocolors@1.1.1: {}
|
||||||
|
|
||||||
|
picomatch@4.0.3: {}
|
||||||
|
|
||||||
|
po-parser@2.1.1: {}
|
||||||
|
|
||||||
postcss-value-parser@4.2.0: {}
|
postcss-value-parser@4.2.0: {}
|
||||||
|
|
||||||
postcss@8.4.31:
|
postcss@8.4.31:
|
||||||
@@ -3162,6 +3641,13 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 19.2.9
|
'@types/react': 19.2.9
|
||||||
|
|
||||||
|
use-intl@4.7.0(react@19.2.0):
|
||||||
|
dependencies:
|
||||||
|
'@formatjs/fast-memoize': 2.2.7
|
||||||
|
'@schummar/icu-type-parser': 1.21.5
|
||||||
|
intl-messageformat: 10.7.18
|
||||||
|
react: 19.2.0
|
||||||
|
|
||||||
use-sidecar@1.1.3(@types/react@19.2.9)(react@19.2.0):
|
use-sidecar@1.1.3(@types/react@19.2.9)(react@19.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
detect-node-es: 1.1.0
|
detect-node-es: 1.1.0
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 585 B |
|
Before Width: | Height: | Size: 566 B |
@@ -1,26 +0,0 @@
|
|||||||
<svg width="180" height="180" viewBox="0 0 180 180" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<style>
|
|
||||||
@media (prefers-color-scheme: light) {
|
|
||||||
.background { fill: black; }
|
|
||||||
.foreground { fill: white; }
|
|
||||||
}
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
.background { fill: white; }
|
|
||||||
.foreground { fill: black; }
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<g clip-path="url(#clip0_7960_43945)">
|
|
||||||
<rect class="background" width="180" height="180" rx="37" />
|
|
||||||
<g style="transform: scale(95%); transform-origin: center">
|
|
||||||
<path class="foreground"
|
|
||||||
d="M101.141 53H136.632C151.023 53 162.689 64.6662 162.689 79.0573V112.904H148.112V79.0573C148.112 78.7105 148.098 78.3662 148.072 78.0251L112.581 112.898C112.701 112.902 112.821 112.904 112.941 112.904H148.112V126.672H112.941C98.5504 126.672 86.5638 114.891 86.5638 100.5V66.7434H101.141V100.5C101.141 101.15 101.191 101.792 101.289 102.422L137.56 66.7816C137.255 66.7563 136.945 66.7434 136.632 66.7434H101.141V53Z" />
|
|
||||||
<path class="foreground"
|
|
||||||
d="M65.2926 124.136L14 66.7372H34.6355L64.7495 100.436V66.7372H80.1365V118.47C80.1365 126.278 70.4953 129.958 65.2926 124.136Z" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_7960_43945">
|
|
||||||
<rect width="180" height="180" fill="white" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB |
24
public/images/IGNUM/SVG/1._6x.svg
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="2540.000000pt" height="2550.000000pt" viewBox="0 0 2540.000000 2550.000000"
|
||||||
|
preserveAspectRatio="xMidYMid meet">
|
||||||
|
|
||||||
|
<g transform="translate(0.000000,2550.000000) scale(0.100000,-0.100000)"
|
||||||
|
fill="#000000" stroke="none">
|
||||||
|
<path d="M4495 8870 c-501 -26 -925 -130 -1278 -313 l-120 -61 248 -241 248
|
||||||
|
-240 96 46 c331 162 833 235 1361 200 420 -28 715 -99 924 -223 104 -61 224
|
||||||
|
-185 270 -278 38 -79 66 -186 66 -257 l0 -43 160 0 c88 0 160 2 160 4 0 3
|
||||||
|
-323 317 -718 699 l-719 694 -94 7 c-180 11 -445 14 -604 6z"/>
|
||||||
|
<path d="M4662 7025 c3 -45 4 -47 258 -290 l255 -245 567 0 568 0 0 -75 c0
|
||||||
|
-251 -130 -498 -333 -633 l-38 -25 93 -94 c51 -52 141 -139 200 -194 l106
|
||||||
|
-100 66 62 c37 34 69 59 72 56 3 -3 15 -70 26 -149 l20 -143 116 -117 117
|
||||||
|
-118 132 0 133 0 0 1055 0 1055 -1181 0 -1180 0 3 -45z"/>
|
||||||
|
<path d="M8690 5221 l0 -261 265 0 c146 0 265 2 265 4 0 2 -119 119 -265 261
|
||||||
|
l-265 257 0 -261z"/>
|
||||||
|
<path d="M8140 3105 l0 -475 -1089 0 -1089 0 174 -170 175 -170 1681 0 1681 0
|
||||||
|
-174 170 -174 169 -422 1 -423 0 0 408 0 407 -74 68 -75 67 -95 0 -96 0 0
|
||||||
|
-475z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
public/images/homeBanner.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 568 B |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="215" height="48" fill="none"><path fill="#000" d="M57.588 9.6h6L73.828 38h-5.2l-2.36-6.88h-11.36L52.548 38h-5.2l10.24-28.4Zm7.16 17.16-4.16-12.16-4.16 12.16h8.32Zm23.694-2.24c-.186-1.307-.706-2.32-1.56-3.04-.853-.72-1.866-1.08-3.04-1.08-1.68 0-2.986.613-3.92 1.84-.906 1.227-1.36 2.947-1.36 5.16s.454 3.933 1.36 5.16c.934 1.227 2.24 1.84 3.92 1.84 1.254 0 2.307-.373 3.16-1.12.854-.773 1.387-1.867 1.6-3.28l5.12.24c-.186 1.68-.733 3.147-1.64 4.4-.906 1.227-2.08 2.173-3.52 2.84-1.413.667-2.986 1-4.72 1-2.08 0-3.906-.453-5.48-1.36-1.546-.907-2.76-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84 0-2.24.427-4.187 1.28-5.84.88-1.68 2.094-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.68 0 3.227.32 4.64.96 1.414.64 2.56 1.56 3.44 2.76.907 1.2 1.454 2.6 1.64 4.2l-5.12.28Zm11.486-7.72.12 3.4c.534-1.227 1.307-2.173 2.32-2.84 1.04-.693 2.267-1.04 3.68-1.04 1.494 0 2.76.387 3.8 1.16 1.067.747 1.827 1.813 2.28 3.2.507-1.44 1.294-2.52 2.36-3.24 1.094-.747 2.414-1.12 3.96-1.12 1.414 0 2.64.307 3.68.92s1.84 1.52 2.4 2.72c.56 1.2.84 2.667.84 4.4V38h-4.96V25.92c0-1.813-.293-3.187-.88-4.12-.56-.96-1.413-1.44-2.56-1.44-.906 0-1.68.213-2.32.64-.64.427-1.133 1.053-1.48 1.88-.32.827-.48 1.84-.48 3.04V38h-4.56V25.92c0-1.2-.133-2.213-.4-3.04-.24-.827-.626-1.453-1.16-1.88-.506-.427-1.133-.64-1.88-.64-.906 0-1.68.227-2.32.68-.64.427-1.133 1.053-1.48 1.88-.32.827-.48 1.827-.48 3V38h-4.96V16.8h4.48Zm26.723 10.6c0-2.24.427-4.187 1.28-5.84.854-1.68 2.067-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.84 0 3.494.413 4.96 1.24 1.467.827 2.64 2.08 3.52 3.76.88 1.653 1.347 3.693 1.4 6.12v1.32h-15.08c.107 1.813.614 3.227 1.52 4.24.907.987 2.134 1.48 3.68 1.48.987 0 1.88-.253 2.68-.76a4.803 4.803 0 0 0 1.84-2.2l5.08.36c-.64 2.027-1.84 3.64-3.6 4.84-1.733 1.173-3.733 1.76-6 1.76-2.08 0-3.906-.453-5.48-1.36-1.573-.907-2.786-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84Zm15.16-2.04c-.213-1.733-.76-3.013-1.64-3.84-.853-.827-1.893-1.24-3.12-1.24-1.44 0-2.6.453-3.48 1.36-.88.88-1.44 2.12-1.68 3.72h9.92ZM163.139 9.6V38h-5.04V9.6h5.04Zm8.322 7.2.24 5.88-.64-.36c.32-2.053 1.094-3.56 2.32-4.52 1.254-.987 2.787-1.48 4.6-1.48 2.32 0 4.107.733 5.36 2.2 1.254 1.44 1.88 3.387 1.88 5.84V38h-4.96V25.92c0-1.253-.12-2.28-.36-3.08-.24-.8-.64-1.413-1.2-1.84-.533-.427-1.253-.64-2.16-.64-1.44 0-2.573.48-3.4 1.44-.8.933-1.2 2.307-1.2 4.12V38h-4.96V16.8h4.48Zm30.003 7.72c-.186-1.307-.706-2.32-1.56-3.04-.853-.72-1.866-1.08-3.04-1.08-1.68 0-2.986.613-3.92 1.84-.906 1.227-1.36 2.947-1.36 5.16s.454 3.933 1.36 5.16c.934 1.227 2.24 1.84 3.92 1.84 1.254 0 2.307-.373 3.16-1.12.854-.773 1.387-1.867 1.6-3.28l5.12.24c-.186 1.68-.733 3.147-1.64 4.4-.906 1.227-2.08 2.173-3.52 2.84-1.413.667-2.986 1-4.72 1-2.08 0-3.906-.453-5.48-1.36-1.546-.907-2.76-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84 0-2.24.427-4.187 1.28-5.84.88-1.68 2.094-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.68 0 3.227.32 4.64.96 1.414.64 2.56 1.56 3.44 2.76.907 1.2 1.454 2.6 1.64 4.2l-5.12.28Zm11.443 8.16V38h-5.6v-5.32h5.6Z"/><path fill="#171717" fill-rule="evenodd" d="m7.839 40.783 16.03-28.054L20 6 0 40.783h7.839Zm8.214 0H40L27.99 19.894l-4.02 7.032 3.976 6.914H20.02l-3.967 6.943Z" clip-rule="evenodd"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |