loading and catalog card

This commit is contained in:
nabijonovdavronbek619@gmail.com
2026-02-02 18:22:53 +05:00
parent 63b363b142
commit ca3e28779e
9 changed files with 267 additions and 24 deletions

View File

@@ -135,4 +135,6 @@ body {
background: #1e1d1c;
}
.loio{
color:#8b1515, #c91d1d
}

View File

@@ -8,6 +8,8 @@ import { NextIntlClientProvider } from "next-intl";
import { getMessages } from "next-intl/server";
import BackAnimatsiya from "@/components/backAnimatsiya/backAnimatsiya";
import { PriceModal } from "@/components/priceContact";
import PageTransition from "@/components/pageTransition/pageTransition";
import { InitialLoading } from "@/components/initialLoading/initialLoading";
const geistSans = Geist({
variable: "--font-geist-sans",
@@ -57,12 +59,13 @@ export default async function RootLayout({
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
<InitialLoading />
<NextIntlClientProvider messages={messages} locale={locale}>
<BackAnimatsiya />
<Navbar />
{children}
<Footer />
<PriceModal />
<PriceModal />
<Analytics />
</NextIntlClientProvider>
</body>

View File

@@ -0,0 +1,117 @@
.initial-loading {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: linear-gradient(135deg, #0c0c0c 0%, #151313 100%);
z-index: 99999;
display: flex;
align-items: center;
justify-content: center;
opacity: 1;
transition: opacity 0.6s ease-out;
}
.initial-loading.fade-out {
opacity: 0;
pointer-events: none;
}
.initial-loading-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 2rem;
}
.initial-svg {
width: 250px;
height: 250px;
animation: initialFloat 2s ease-in-out infinite, initialScale 1.5s ease-in-out infinite;
}
.initial-path {
fill: url(#initial-gradient);
filter: url(#initial-glow);
stroke: #ffffff;
stroke-width: 2;
animation: pathPulse 1.5s ease-in-out infinite;
}
/* Loading dots animation */
.initial-loading-text {
text-align: center;
}
.loading-dots {
display: flex;
gap: 8px;
justify-content: center;
}
.loading-dots span {
width: 12px;
height: 12px;
background: #ff0000;
border-radius: 50%;
animation: dotBounce 1.4s ease-in-out infinite;
}
.loading-dots span:nth-child(1) {
animation-delay: 0s;
}
.loading-dots span:nth-child(2) {
animation-delay: 0.2s;
}
.loading-dots span:nth-child(3) {
animation-delay: 0.4s;
}
/* Animations */
@keyframes initialFloat {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-30px);
}
}
@keyframes initialScale {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
@keyframes pathPulse {
0%, 100% {
opacity: 1;
stroke-width: 2;
}
50% {
opacity: 0.7;
stroke-width: 3;
}
}
@keyframes dotBounce {
0%, 80%, 100% {
transform: scale(0);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
}
/* Smooth scroll prevention */
body:has(.initial-loading:not(.fade-out)) {
overflow: hidden;
}

View File

@@ -0,0 +1,106 @@
"use client";
import { useState, useEffect } from "react";
import "./initialLoading.css";
export function InitialLoading() {
const [isLoading, setIsLoading] = useState(true);
const [isVisible, setIsVisible] = useState(true);
useEffect(() => {
// Faqat birinchi yuklanishda ishga tushadi
const hasVisited = sessionStorage.getItem("hasVisited");
if (hasVisited) {
// Agar oldin tashrif buyurilgan bo'lsa, darhol yashirish
setIsLoading(false);
setIsVisible(false);
return;
}
// Birinchi tashrif
const loadingTimer = setTimeout(() => {
setIsLoading(false);
// Fade out animatsiyasi
const hideTimer = setTimeout(() => {
setIsVisible(false);
sessionStorage.setItem("hasVisited", "true");
}, 1000); // Fade out duration
return () => clearTimeout(hideTimer);
}, 1500); // Loading duration
return () => clearTimeout(loadingTimer);
}, []);
// Agar ko'rinmas bo'lsa, hech narsa render qilmaymiz
if (!isVisible) return null;
return (
<div className={`initial-loading ${!isLoading ? "fade-out" : ""}`}>
<div className="initial-loading-content">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 423.22 424.82"
className="w-full h-full"
>
<defs>
{/* Qizil neon gradient for github*/}
<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>
{/* Loading dots */}
<div className="initial-loading-text">
<div className="loading-dots">
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
</div>
);
}

View File

@@ -2,7 +2,7 @@ import "./logo.css";
export default function NavbarLogo() {
return (
<div className="relative w-24 h-12">
<div className="relative w-24 h-20">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 423.22 424.82"

View File

@@ -3,19 +3,35 @@ import { usePathname } from "next/navigation";
import { useEffect, useState } from "react";
import "./page-transition.css";
export default function PageTransition({ children }: { children: React.ReactNode }) {
export default function PageTransition({
children
}: {
children: React.ReactNode
}) {
const pathname = usePathname();
const [displayPath, setDisplayPath] = useState(pathname);
const [isTransitioning, setIsTransitioning] = useState(false);
useEffect(() => {
setIsTransitioning(true);
const timer = setTimeout(() => {
setIsTransitioning(false);
}, 1500); // Animatsiya davomiyligi
if (pathname !== displayPath) {
// Start exit animation
setIsTransitioning(true);
return () => clearTimeout(timer);
}, [pathname]);
const exitTimer = setTimeout(() => {
// Update path (triggers content change)
setDisplayPath(pathname);
// Start enter animation
const enterTimer = setTimeout(() => {
setIsTransitioning(false);
}, 800); // Enter animation duration
return () => clearTimeout(enterTimer);
}, 800); // Exit animation duration
return () => clearTimeout(exitTimer);
}
}, [pathname, displayPath]);
return (
<>
@@ -32,7 +48,6 @@ export default function PageTransition({ children }: { children: React.ReactNode
<stop offset="50%" stopColor="#ff4444" />
<stop offset="100%" stopColor="#ff0000" />
</linearGradient>
<filter id="transition-glow">
<feGaussianBlur stdDeviation="5" result="coloredBlur"/>
<feMerge>
@@ -53,7 +68,7 @@ export default function PageTransition({ children }: { children: React.ReactNode
</g>
</svg>
</div>
{/* Page content */}
<div className={`page-content ${isTransitioning ? "transitioning" : ""}`}>
{children}

View File

@@ -69,20 +69,20 @@ export default function CatalogCard({
return (
<Link
href={`/${locale}/products?category=${id}`}
className="group relative h-[450px] w-full overflow-hidden rounded-2xl bg-linear-to-br from-[#444242] to-black border border-white/10 transition-all duration-500 hover:border-red-500/50 hover:-translate-y-1"
className="group relative h-112.5 w-full overflow-hidden rounded-2xl bg-[#17161679] from-[#444242] to-black border hover:border-red-700 border-white/10 transition-all duration-500 hover:-translate-y-1"
>
{/* Background glow effect */}
<div className="absolute inset-0 bg-gradient-to-t from-red-600/20 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
<div className="absolute inset-0 bg-linear-to-t from-red-600/20 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
{/* Decorative corner accent */}
<div className="absolute top-0 right-0 w-24 h-24 bg-gradient-to-br from-red-500/20 to-transparent rounded-bl-full opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
<div className="absolute top-0 right-0 w-24 h-24 bg-linear-to-br from-red-500/20 to-transparent rounded-bl-full opacity-0 group-hover:opacity-00 transition-opacity duration-500" />
{/* Content container */}
<div className="relative h-full flex flex-col p-6">
{/* Title section */}
<div className="mb-4">
<div className="flex items-start justify-between mb-2">
<h3 className="text-2xl font-unbounded font-bold text-white leading-tight group-hover:text-red-400 transition-colors duration-300">
<h3 className="text-2xl font-unbounded font-bold text-white leading-tight transition-colors duration-300">
{title}
</h3>
<div className="shrink-0 w-8 h-8 rounded-full bg-white/10 flex items-center justify-center group-hover:bg-red-500 transition-all duration-300 group-hover:scale-110">
@@ -97,9 +97,9 @@ export default function CatalogCard({
</div>
{/* Image container with elegant frame */}
<div className="relative flex-1 rounded-xl overflow-hidden bg-gradient-to-br from-[#444242] to-gray-900/50 border border-white/5 group-hover:border-white/20 transition-all duration-500">
<div className="relative flex-1 rounded-xl overflow-hidden bg-linear-to-br from-[#444242] to-gray-900/50 border border-white/5 group-hover:border-white/20 transition-all duration-500">
{/* Animated gradient overlay */}
<div className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent z-10" />
<div className="absolute inset-0 bg-linear-to-t from-black/60 via-transparent to-transparent z-10" />
{/* Image */}
<div className="relative w-full h-full">
@@ -118,7 +118,7 @@ export default function CatalogCard({
</div>
{/* Bottom accent bar */}
<div className="mt-4 h-1 w-0 bg-gradient-to-r from-red-500 to-red-600 group-hover:w-full transition-all duration-500 rounded-full" />
<div className="mt-4 h-1 w-0 bg-linear-to-r from-red-500 to-red-600 group-hover:w-full transition-all duration-500 rounded-full" />
</div>
{/* Subtle noise texture overlay */}

View File

@@ -14,7 +14,7 @@
},
"about": {
"title": "About us",
"subtitle": "Fire Protection Systems Ready",
"subtitle": "Fire Protection Systems",
"prevention": {
"title": "Fire Prevention Systems",
"description": "We offer the most advanced fire prevention technologies. Every detail is designed to ensure safety and reliability."

View File

@@ -3,7 +3,7 @@
"banner": {
"title1": "Ignum-ga xush kelibsiz",
"title2": "YONG'INGA QARSHI HIMOYA",
"description": "Biz umid nuri, tartibsizlik davrida tinchlik va eng qiyin vaziyatlarda ishonchli himoya manbai sifatida ko'rilamiz.",
"description": "Biz yongin xavfsizligi tizimlarini ornatish va sertifikatlangan himoya vositalari savdosi boyicha professional xizmatlar korsatamiz.",
"cta": "Boshlash"
},
"statistics": {
@@ -14,7 +14,7 @@
},
"about": {
"title": "Biz haqimizda",
"subtitle": "YONG'INGA QARSHI TIZIMLAR TAYYOR",
"subtitle": "YONG'INGA QARSHI TIZIMLAR",
"prevention": {
"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."
@@ -177,7 +177,7 @@
"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": "Kafolat muddati qancha?",
"answer": "Barcha uskunalarimiz uchun 2 yillik kafolat va 10 yillik texnik xizmat ko'rsatish kafolati beriladi."
},
"question5": {