feat: update Dockerfile, add category pages, fonts and product images
Rebuild Docker setup with simplified nginx-only Dockerfile (build runs on host). Add category detail pages, IRANSans font files, product images, and update all landing sections. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
e31ef5a21f
commit
bb7f1e3378
+1
-5
@@ -2,12 +2,8 @@ node_modules
|
|||||||
.nuxt
|
.nuxt
|
||||||
.output
|
.output
|
||||||
.git
|
.git
|
||||||
.gitignore
|
|
||||||
app
|
|
||||||
server
|
|
||||||
shared
|
|
||||||
public
|
|
||||||
*.md
|
*.md
|
||||||
_dev.log
|
_dev.log
|
||||||
.env*
|
.env*
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
|
logo.png
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ node_modules/
|
|||||||
.output/
|
.output/
|
||||||
.data/
|
.data/
|
||||||
dist
|
dist
|
||||||
# out/ عمداً در git نگه داشته میشود (بیلد محلی → دیپلوی با Docker)
|
out/
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
FROM docker.arvancloud.ir/nginx:latest
|
# Static export is built on the host (`npm run build` → ./out)
|
||||||
|
# This image only serves the pre-built files via nginx.
|
||||||
|
FROM docker.arvancloud.ir/nginx:alpine
|
||||||
|
|
||||||
# خروجی static export (npm run build → پوشه out)
|
|
||||||
COPY out /usr/share/nginx/html
|
COPY out /usr/share/nginx/html
|
||||||
|
|
||||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|||||||
+47
-21
@@ -1,20 +1,46 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
/* ---- local fonts (replaces next/font/local) ----
|
/* ---- local fonts ---- */
|
||||||
Same family names, fallback faces and metric overrides that next/font generated, so text
|
|
||||||
(including Persian glyphs inside font-mono, which fall back to the size-adjusted Arial face)
|
|
||||||
renders exactly as before. */
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "vazirmatn";
|
font-family: "IRANSans";
|
||||||
src: url("/fonts/Vazirmatn-Variable.woff2") format("woff2");
|
src: url("/fonts/IRANSansWeb_UltraLight.woff2") format("woff2");
|
||||||
font-weight: 100 900;
|
font-weight: 200;
|
||||||
|
font-style: normal;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "vazirmatn Fallback";
|
font-family: "IRANSans";
|
||||||
|
src: url("/fonts/IRANSansWeb_Light.woff2") format("woff2");
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "IRANSans";
|
||||||
|
src: url("/fonts/IRANSansWeb.woff2") format("woff2");
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "IRANSans";
|
||||||
|
src: url("/fonts/IRANSansWeb_Medium.woff2") format("woff2");
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "IRANSans";
|
||||||
|
src: url("/fonts/IRANSansWeb_Bold.woff2") format("woff2");
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "IRANSans Fallback";
|
||||||
src: local("Arial");
|
src: local("Arial");
|
||||||
ascent-override: 102.54%;
|
ascent-override: 100%;
|
||||||
descent-override: 53.71%;
|
descent-override: 35%;
|
||||||
line-gap-override: 0%;
|
line-gap-override: 0%;
|
||||||
size-adjust: 100%;
|
size-adjust: 100%;
|
||||||
}
|
}
|
||||||
@@ -49,23 +75,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--font-vazirmatn: "vazirmatn", "vazirmatn Fallback", Tahoma, system-ui, sans-serif;
|
--font-iransans: "IRANSans", "IRANSans Fallback", Tahoma, system-ui, sans-serif;
|
||||||
--font-ibm-plex-mono: "ibmPlexMono", "ibmPlexMono Fallback", ui-monospace, monospace;
|
--font-ibm-plex-mono: "ibmPlexMono", "ibmPlexMono Fallback", ui-monospace, monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@theme {
|
@theme {
|
||||||
--font-sans: var(--font-vazirmatn), ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; /* font variables defined in :root above */
|
--font-sans: var(--font-iransans), ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
|
||||||
--font-mono: var(--font-ibm-plex-mono), "Vazirmatn", ui-monospace, monospace; /* font variables defined in :root above */
|
--font-mono: var(--font-ibm-plex-mono), "IRANSans", ui-monospace, monospace;
|
||||||
|
|
||||||
--color-bg: #0a0a0c;
|
--color-bg: #0b1224;
|
||||||
--color-panel: #121216;
|
--color-panel: #101a32;
|
||||||
--color-panel-2: #17171c;
|
--color-panel-2: #152040;
|
||||||
--color-ink: #edede6;
|
--color-ink: #edede6;
|
||||||
--color-muted: #8e8e96;
|
--color-muted: #8e9ab0;
|
||||||
--color-accent: #ff5a00;
|
--color-accent: #ff5a00;
|
||||||
--color-accent-soft: #ff7a2a;
|
--color-accent-soft: #ff7a2a;
|
||||||
--color-hazard: #ffb800;
|
--color-hazard: #ffb800;
|
||||||
--color-line: #232329;
|
--color-line: #1e2d4d;
|
||||||
|
|
||||||
--animate-marquee: marquee 32s linear infinite;
|
--animate-marquee: marquee 32s linear infinite;
|
||||||
--animate-spin-slow: spin-slow 18s linear infinite;
|
--animate-spin-slow: spin-slow 18s linear infinite;
|
||||||
@@ -162,7 +188,7 @@ body {
|
|||||||
background: var(--color-bg);
|
background: var(--color-bg);
|
||||||
}
|
}
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background: #2c2c33;
|
background: #253558;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 2px solid var(--color-bg);
|
border: 2px solid var(--color-bg);
|
||||||
}
|
}
|
||||||
@@ -175,7 +201,7 @@ body {
|
|||||||
background-image: repeating-linear-gradient(
|
background-image: repeating-linear-gradient(
|
||||||
-45deg,
|
-45deg,
|
||||||
#ffb800 0 14px,
|
#ffb800 0 14px,
|
||||||
#0a0a0c 14px 28px
|
#0b1224 14px 28px
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +240,6 @@ body {
|
|||||||
background-image: repeating-linear-gradient(
|
background-image: repeating-linear-gradient(
|
||||||
45deg,
|
45deg,
|
||||||
#ffb800 0 10px,
|
#ffb800 0 10px,
|
||||||
#0a0a0c 10px 20px
|
#0b1224 10px 20px
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { AtSign, Globe, Phone, Send } from "lucide-vue-next";
|
import { AtSign, Globe, Phone, Send } from "lucide-vue-next";
|
||||||
|
import { CATEGORIES } from "#shared/data/categories";
|
||||||
import Logo from "~/components/ui/Logo.vue";
|
import Logo from "~/components/ui/Logo.vue";
|
||||||
|
|
||||||
const QUICK_LINKS = [
|
const QUICK_LINKS = [
|
||||||
{ href: "#home", label: "خانه" },
|
{ href: "/#home", label: "خانه" },
|
||||||
{ href: "#products", label: "محصولات" },
|
{ href: "/#products", label: "محصولات" },
|
||||||
{ href: "#about", label: "درباره ما" },
|
{ href: "/#about", label: "درباره ما" },
|
||||||
{ href: "#services", label: "خدمات" },
|
{ href: "/#services", label: "خدمات" },
|
||||||
{ href: "#standards", label: "استانداردها" },
|
{ href: "/#standards", label: "استانداردها" },
|
||||||
{ href: "#industries", label: "صنایع" },
|
{ href: "/#industries", label: "صنایع" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const PRODUCT_LINKS = [
|
const PRODUCT_LINKS = CATEGORIES.map((c) => ({
|
||||||
"کلاه ایمنی",
|
label: c.name,
|
||||||
"دستکش ضدبرش",
|
href: `/categories/${c.slug}`,
|
||||||
"کفش ایمنی",
|
}));
|
||||||
"عینک ایمنی",
|
|
||||||
"هارنس ضدسقوط",
|
|
||||||
"لباس کار بازتابنده",
|
|
||||||
];
|
|
||||||
|
|
||||||
const SOCIALS = [
|
const SOCIALS = [
|
||||||
{ icon: Globe, label: "وبسایت" },
|
{ icon: Globe, label: "وبسایت" },
|
||||||
@@ -32,7 +29,7 @@ const SOCIALS = [
|
|||||||
<footer class="relative overflow-hidden border-t border-line">
|
<footer class="relative overflow-hidden border-t border-line">
|
||||||
<div class="hazard h-2.5" />
|
<div class="hazard h-2.5" />
|
||||||
|
|
||||||
<div class="mx-auto max-w-7xl px-5 md:px-8">
|
<div class="mx-auto max-w-[1480px] px-5 md:px-8">
|
||||||
<div class="grid gap-12 py-16 md:grid-cols-12 md:py-20">
|
<div class="grid gap-12 py-16 md:grid-cols-12 md:py-20">
|
||||||
<!-- brand -->
|
<!-- brand -->
|
||||||
<div class="md:col-span-5">
|
<div class="md:col-span-5">
|
||||||
@@ -45,7 +42,7 @@ const SOCIALS = [
|
|||||||
<a
|
<a
|
||||||
v-for="s in SOCIALS"
|
v-for="s in SOCIALS"
|
||||||
:key="s.label"
|
:key="s.label"
|
||||||
href="#contact"
|
href="/#contact"
|
||||||
:aria-label="s.label"
|
:aria-label="s.label"
|
||||||
class="flex size-10 items-center justify-center rounded-lg border border-line text-muted transition-all duration-300 hover:border-accent hover:bg-accent hover:text-bg"
|
class="flex size-10 items-center justify-center rounded-lg border border-line text-muted transition-all duration-300 hover:border-accent hover:bg-accent hover:text-bg"
|
||||||
>
|
>
|
||||||
@@ -70,10 +67,10 @@ const SOCIALS = [
|
|||||||
<div class="md:col-span-2">
|
<div class="md:col-span-2">
|
||||||
<div class="font-mono text-xs tracking-[0.25em] text-accent">// محصولات</div>
|
<div class="font-mono text-xs tracking-[0.25em] text-accent">// محصولات</div>
|
||||||
<ul class="mt-5 space-y-3">
|
<ul class="mt-5 space-y-3">
|
||||||
<li v-for="p in PRODUCT_LINKS" :key="p">
|
<li v-for="p in PRODUCT_LINKS" :key="p.href">
|
||||||
<a href="#products" class="text-sm text-muted transition-colors hover:text-ink">
|
<NuxtLink :to="p.href" class="text-sm text-muted transition-colors hover:text-ink">
|
||||||
{{ p }}
|
{{ p.label }}
|
||||||
</a>
|
</NuxtLink>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -88,7 +85,7 @@ const SOCIALS = [
|
|||||||
خیابان فر، کوچه دوم، پلاک ۱۲
|
خیابان فر، کوچه دوم، پلاک ۱۲
|
||||||
</p>
|
</p>
|
||||||
<p class="font-mono tracking-wider" dir="ltr">۰۲۱ - ۹۱ ۰۰ ۸۸ ۰۰</p>
|
<p class="font-mono tracking-wider" dir="ltr">۰۲۱ - ۹۱ ۰۰ ۸۸ ۰۰</p>
|
||||||
<p class="font-mono tracking-wider" dir="ltr">info@ariaiman.ir</p>
|
<p class="font-mono tracking-wider" dir="ltr">info@imenpishgaman.ir</p>
|
||||||
<p class="pt-2 text-xs leading-6">
|
<p class="pt-2 text-xs leading-6">
|
||||||
شنبه تا پنجشنبه — ۸:۰۰ تا ۱۷:۰۰
|
شنبه تا پنجشنبه — ۸:۰۰ تا ۱۷:۰۰
|
||||||
<br />
|
<br />
|
||||||
@@ -101,14 +98,14 @@ const SOCIALS = [
|
|||||||
<!-- giant wordmark -->
|
<!-- giant wordmark -->
|
||||||
<div aria-hidden="true" class="pointer-events-none select-none pb-6">
|
<div aria-hidden="true" class="pointer-events-none select-none pb-6">
|
||||||
<div class="text-outline text-center text-[17vw] font-black leading-[0.85] md:text-[11vw]">
|
<div class="text-outline text-center text-[17vw] font-black leading-[0.85] md:text-[11vw]">
|
||||||
آریا ایمن
|
ایمن پیشگامان
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex flex-wrap items-center justify-between gap-4 border-t border-line py-6 text-xs text-muted"
|
class="flex flex-wrap items-center justify-between gap-4 border-t border-line py-6 text-xs text-muted"
|
||||||
>
|
>
|
||||||
<div>© ۱۴۰۴ آریا ایمن — تمامی حقوق محفوظ است.</div>
|
<div>© ۱۴۰۴ ایمن پیشگامان — تمامی حقوق محفوظ است.</div>
|
||||||
<div class="font-mono text-[10px] tracking-[0.25em]">
|
<div class="font-mono text-[10px] tracking-[0.25em]">
|
||||||
ISO 9001:2015 — CE CERTIFIED PPE SUPPLIER
|
ISO 9001:2015 — CE CERTIFIED PPE SUPPLIER
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import { Menu, Phone, X } from "lucide-vue-next";
|
|||||||
import Logo from "~/components/ui/Logo.vue";
|
import Logo from "~/components/ui/Logo.vue";
|
||||||
|
|
||||||
const LINKS = [
|
const LINKS = [
|
||||||
{ href: "#home", label: "خانه" },
|
{ href: "/#home", label: "خانه" },
|
||||||
{ href: "#products", label: "محصولات" },
|
{ href: "/#products", label: "محصولات" },
|
||||||
{ href: "#about", label: "درباره ما" },
|
{ href: "/#about", label: "درباره ما" },
|
||||||
{ href: "#services", label: "خدمات" },
|
{ href: "/#services", label: "خدمات" },
|
||||||
{ href: "#standards", label: "استانداردها" },
|
{ href: "/#standards", label: "استانداردها" },
|
||||||
{ href: "#industries", label: "صنایع" },
|
{ href: "/#industries", label: "صنایع" },
|
||||||
{ href: "#contact", label: "تماس" },
|
{ href: "/#contact", label: "تماس" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const ui = useUiStore();
|
const ui = useUiStore();
|
||||||
@@ -37,7 +37,7 @@ onBeforeUnmount(() => {
|
|||||||
scrolled ? 'border-b border-line bg-bg/85 py-3 backdrop-blur-xl' : 'py-5'
|
scrolled ? 'border-b border-line bg-bg/85 py-3 backdrop-blur-xl' : 'py-5'
|
||||||
}`"
|
}`"
|
||||||
>
|
>
|
||||||
<div class="mx-auto flex max-w-7xl items-center justify-between px-5 md:px-8">
|
<div class="mx-auto flex max-w-[1480px] items-center justify-between px-5 md:px-8">
|
||||||
<Logo />
|
<Logo />
|
||||||
|
|
||||||
<nav class="hidden items-center gap-7 lg:flex">
|
<nav class="hidden items-center gap-7 lg:flex">
|
||||||
@@ -65,7 +65,7 @@ onBeforeUnmount(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="#contact"
|
href="/#contact"
|
||||||
class="hidden items-center gap-2 rounded-full bg-accent px-5 py-2.5 text-sm font-bold text-bg transition-all duration-300 hover:bg-accent-soft hover:shadow-[0_0_30px_rgba(255,90,0,0.4)] md:flex"
|
class="hidden items-center gap-2 rounded-full bg-accent px-5 py-2.5 text-sm font-bold text-bg transition-all duration-300 hover:bg-accent-soft hover:shadow-[0_0_30px_rgba(255,90,0,0.4)] md:flex"
|
||||||
>
|
>
|
||||||
<Phone class="size-4" />
|
<Phone class="size-4" />
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const step = computed(
|
|||||||
<ShieldCheck class="size-7" />
|
<ShieldCheck class="size-7" />
|
||||||
</span>
|
</span>
|
||||||
<span class="font-mono text-xs tracking-[0.35em] text-muted">
|
<span class="font-mono text-xs tracking-[0.35em] text-muted">
|
||||||
ARIA IMEN CO.
|
IMEN PISHGAMAN CO.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import Reveal from "~/components/ui/Reveal.vue";
|
|||||||
import SectionHead from "~/components/ui/SectionHead.vue";
|
import SectionHead from "~/components/ui/SectionHead.vue";
|
||||||
|
|
||||||
const TIMELINE = [
|
const TIMELINE = [
|
||||||
{ year: "۱۳۸۶", text: "تأسیس آریا ایمن در تهران با تمرکز بر تجهیزات حفاظت فردی" },
|
{ year: "۱۳۸۶", text: "تأسیس ایمن پیشگامان در تهران با تمرکز بر تجهیزات حفاظت فردی" },
|
||||||
{ year: "۱۳۹۲", text: "توسعه شبکه توزیع به تمام ۳۱ استان کشور" },
|
{ year: "۱۳۹۲", text: "توسعه شبکه توزیع به تمام ۳۱ استان کشور" },
|
||||||
{ year: "۱۳۹۸", text: "راهاندازی آزمایشگاه کنترل کیفیت و تست تجهیزات" },
|
{ year: "۱۳۹۸", text: "راهاندازی آزمایشگاه کنترل کیفیت و تست تجهیزات" },
|
||||||
{ year: "۱۴۰۲", text: "افتتاح مرکز تخصصی آموزش و بازرسی HSE" },
|
{ year: "۱۴۰۲", text: "افتتاح مرکز تخصصی آموزش و بازرسی HSE" },
|
||||||
@@ -25,14 +25,14 @@ const FEATURES = [
|
|||||||
>
|
>
|
||||||
<div class="absolute inset-0 bg-grid-fine opacity-50" />
|
<div class="absolute inset-0 bg-grid-fine opacity-50" />
|
||||||
|
|
||||||
<div class="relative mx-auto max-w-7xl px-5 md:px-8">
|
<div class="relative mx-auto max-w-[1480px] px-5 md:px-8">
|
||||||
<div class="grid items-center gap-14 lg:grid-cols-2">
|
<div class="grid items-center gap-14 lg:grid-cols-2">
|
||||||
<!-- ---- image ---- -->
|
<!-- ---- image ---- -->
|
||||||
<Reveal class="relative order-2 lg:order-1" :delay="0.1">
|
<Reveal class="relative order-2 lg:order-1" :delay="0.1">
|
||||||
<div class="relative overflow-hidden rounded-2xl border border-line">
|
<div class="relative overflow-hidden rounded-2xl border border-line">
|
||||||
<img
|
<img
|
||||||
src="/images/about.jpg"
|
src="/images/about.jpg"
|
||||||
alt="انبار تجهیزات ایمنی آریا ایمن"
|
alt="انبار تجهیزات ایمنی ایمن پیشگامان"
|
||||||
width="800"
|
width="800"
|
||||||
height="600"
|
height="600"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const INFO = [
|
|||||||
value: "تهران، خیابان کارگر شمالی، خیابان فر، کوچه دوم، پلاک ۱۲",
|
value: "تهران، خیابان کارگر شمالی، خیابان فر، کوچه دوم، پلاک ۱۲",
|
||||||
},
|
},
|
||||||
{ icon: Phone, label: "تلفن تماس", value: "۰۲۱ - ۹۱ ۰۰ ۸۸ ۰۰", ltr: true },
|
{ icon: Phone, label: "تلفن تماس", value: "۰۲۱ - ۹۱ ۰۰ ۸۸ ۰۰", ltr: true },
|
||||||
{ icon: Mail, label: "ایمیل", value: "info@ariaiman.ir", ltr: true },
|
{ icon: Mail, label: "ایمیل", value: "info@imenpishgaman.ir", ltr: true },
|
||||||
{ icon: Clock, label: "ساعات کاری", value: "شنبه تا پنجشنبه — ۸:۰۰ تا ۱۷:۰۰" },
|
{ icon: Clock, label: "ساعات کاری", value: "شنبه تا پنجشنبه — ۸:۰۰ تا ۱۷:۰۰" },
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ const contact = useContactStore();
|
|||||||
>
|
>
|
||||||
<div class="absolute inset-0 bg-grid-fine opacity-40" />
|
<div class="absolute inset-0 bg-grid-fine opacity-40" />
|
||||||
|
|
||||||
<div class="relative mx-auto max-w-7xl px-5 md:px-8">
|
<div class="relative mx-auto max-w-[1480px] px-5 md:px-8">
|
||||||
<div class="grid gap-14 lg:grid-cols-2">
|
<div class="grid gap-14 lg:grid-cols-2">
|
||||||
<!-- ---- info ---- -->
|
<!-- ---- info ---- -->
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ const MINI_STATS = [
|
|||||||
|
|
||||||
<!-- ---- content ---- -->
|
<!-- ---- content ---- -->
|
||||||
<div
|
<div
|
||||||
class="relative z-10 mx-auto flex w-full max-w-7xl flex-1 items-center px-5 pb-24 pt-36 md:px-8"
|
class="relative z-10 mx-auto flex w-full max-w-[1480px] flex-1 items-center px-5 pb-24 pt-36 md:px-8"
|
||||||
>
|
>
|
||||||
<div class="grid w-full items-center gap-12 lg:grid-cols-12">
|
<div class="grid w-full items-center gap-12 lg:grid-cols-12">
|
||||||
<div class="lg:col-span-7">
|
<div class="lg:col-span-7">
|
||||||
@@ -72,7 +72,7 @@ const MINI_STATS = [
|
|||||||
<p
|
<p
|
||||||
class="animate-fade-up-3 mt-7 max-w-xl text-base leading-9 text-ink/70 md:text-lg md:leading-10"
|
class="animate-fade-up-3 mt-7 max-w-xl text-base leading-9 text-ink/70 md:text-lg md:leading-10"
|
||||||
>
|
>
|
||||||
آریا ایمن با بیش از ۱۸ سال تجربه، تأمینکننده تخصصی تجهیزات ایمنی و
|
ایمن پیشگامان با بیش از ۱۸ سال تجربه، تأمینکننده تخصصی تجهیزات ایمنی و
|
||||||
حفاظت فردی برای سازمانهایی است که جان انسانها را جدی میگیرند؛ از
|
حفاظت فردی برای سازمانهایی است که جان انسانها را جدی میگیرند؛ از
|
||||||
کلاه ایمنی تا هارنس نجات، از مشاوره تا بازرسی و آموزش.
|
کلاه ایمنی تا هارنس نجات، از مشاوره تا بازرسی و آموزش.
|
||||||
</p>
|
</p>
|
||||||
@@ -121,7 +121,7 @@ const MINI_STATS = [
|
|||||||
</defs>
|
</defs>
|
||||||
<text font-size="9" letter-spacing="2.6" class="fill-ink/60 font-mono">
|
<text font-size="9" letter-spacing="2.6" class="fill-ink/60 font-mono">
|
||||||
<textPath href="#badge-circle">
|
<textPath href="#badge-circle">
|
||||||
ARIA IMEN SAFETY • ISO 9001 • CE CERTIFIED • EST 2007 •
|
IMEN PISHGAMAN SAFETY • ISO 9001 • CE CERTIFIED • EST 2007 •
|
||||||
</textPath>
|
</textPath>
|
||||||
</text>
|
</text>
|
||||||
</svg>
|
</svg>
|
||||||
@@ -156,7 +156,7 @@ const MINI_STATS = [
|
|||||||
</div>
|
</div>
|
||||||
<div class="my-4 h-px bg-line" />
|
<div class="my-4 h-px bg-line" />
|
||||||
<div class="font-mono text-[11px] leading-6 text-muted">
|
<div class="font-mono text-[11px] leading-6 text-muted">
|
||||||
سیستم پایش حرفهای آریا ایمن<span class="animate-blink text-accent">▍</span>
|
سیستم پایش حرفهای ایمن پیشگامان<span class="animate-blink text-accent">▍</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -173,7 +173,7 @@ const MINI_STATS = [
|
|||||||
|
|
||||||
<!-- ---- bottom bar ---- -->
|
<!-- ---- bottom bar ---- -->
|
||||||
<div class="animate-fade-up-8 relative z-10 border-t border-ink/10 backdrop-blur-sm">
|
<div class="animate-fade-up-8 relative z-10 border-t border-ink/10 backdrop-blur-sm">
|
||||||
<div class="mx-auto grid max-w-7xl grid-cols-1 gap-px bg-ink/10 sm:grid-cols-3">
|
<div class="mx-auto grid max-w-[1480px] grid-cols-1 gap-px bg-ink/10 sm:grid-cols-3">
|
||||||
<div
|
<div
|
||||||
v-for="s in MINI_STATS"
|
v-for="s in MINI_STATS"
|
||||||
:key="s.label"
|
:key="s.label"
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ const onMove = (e: MouseEvent) => {
|
|||||||
class="relative border-t border-line py-24 md:py-32"
|
class="relative border-t border-line py-24 md:py-32"
|
||||||
@mousemove="onMove"
|
@mousemove="onMove"
|
||||||
>
|
>
|
||||||
<div class="mx-auto max-w-7xl px-5 md:px-8">
|
<div class="mx-auto max-w-[1480px] px-5 md:px-8">
|
||||||
<SectionHead
|
<SectionHead
|
||||||
heading-id="industries-title"
|
heading-id="industries-title"
|
||||||
tag="۰۵ — صنایع"
|
tag="۰۵ — صنایع"
|
||||||
|
|||||||
@@ -1,69 +1,20 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { AnimatePresence, motion } from "motion-v";
|
|
||||||
import { ArrowLeft, BadgeCheck, PackageCheck, ShieldCheck } from "lucide-vue-next";
|
import { ArrowLeft, BadgeCheck, PackageCheck, ShieldCheck } from "lucide-vue-next";
|
||||||
|
import { CATEGORIES } from "#shared/data/categories";
|
||||||
import Reveal from "~/components/ui/Reveal.vue";
|
import Reveal from "~/components/ui/Reveal.vue";
|
||||||
import SectionHead from "~/components/ui/SectionHead.vue";
|
import SectionHead from "~/components/ui/SectionHead.vue";
|
||||||
|
|
||||||
type Product = {
|
const CATEGORY_IMAGES: Record<string, string> = {
|
||||||
code: string;
|
workwear: "/images/products/vest.jpg",
|
||||||
name: string;
|
"safety-footwear": "/images/products/shoes.jpg",
|
||||||
en: string;
|
"protective-gloves": "/images/products/gloves.jpg",
|
||||||
desc: string;
|
"safety-helmets": "/images/products/helmet.jpg",
|
||||||
img: string;
|
"eye-protection": "/images/products/goggles.jpg",
|
||||||
specs: string[];
|
"hearing-protection": "/images/products/hearing.jpg",
|
||||||
|
"respiratory-protection": "/images/products/respiratory.jpg",
|
||||||
|
"traffic-equipment": "/images/products/traffic.jpg",
|
||||||
};
|
};
|
||||||
|
|
||||||
const PRODUCTS: Product[] = [
|
|
||||||
{
|
|
||||||
code: "AP-101",
|
|
||||||
name: "کلاه ایمنی",
|
|
||||||
en: "SAFETY HELMET",
|
|
||||||
img: "/images/products/helmet.jpg",
|
|
||||||
desc: "کلاههای ایمنی با بدنه HDPE مقاوم به ضربه و ترتیهبند ضدتعریق؛ با قابلیت نصب هدفون و شیشه محافظ صورت برای محیطهای ساختمانی و صنعتی.",
|
|
||||||
specs: ["EN 397", "مقاوم به ضربه ۵۰ ژول", "بدنه HDPE"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
code: "AP-205",
|
|
||||||
name: "دستکش ضدبرش",
|
|
||||||
en: "CUT-RESISTANT GLOVE",
|
|
||||||
img: "/images/products/gloves.jpg",
|
|
||||||
desc: "دستکشهای سطح ۵ ضدبرش با پوشش نیتریل؛ طراحیشده برای کار با ورق فلز، شیشه و ابزار برنده با چسبندگی عالی در محیط خشک و چرب.",
|
|
||||||
specs: ["EN 388 — 4X43C", "سطح ۵ ضدبرش", "پوشش نیتریل"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
code: "AP-310",
|
|
||||||
name: "کفش ایمنی",
|
|
||||||
en: "SAFETY BOOTS",
|
|
||||||
img: "/images/products/shoes.jpg",
|
|
||||||
desc: "کفشهای ایمنی با پنجه فولادی و کف مقاوم در برابر سوراخشدگی و روغن؛ راحتی تمامروز برای شیفتهای طولانی در سایت.",
|
|
||||||
specs: ["EN ISO 20345", "پنجه فولادی", "کف ضدروغن"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
code: "AP-412",
|
|
||||||
name: "عینک ایمنی",
|
|
||||||
en: "SAFETY GOGGLES",
|
|
||||||
img: "/images/products/goggles.jpg",
|
|
||||||
desc: "عینکهای محافظ ضدخش با پوشش UV400 و تهویه ضدمه؛ سازگار با عینک طبی برای کارهای جوشکاری، سنگزنی و محیطهای شیمیایی.",
|
|
||||||
specs: ["EN 166", "عدسی ضدخش", "پوشش UV400"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
code: "AP-508",
|
|
||||||
name: "هارنس ضدسقوط",
|
|
||||||
en: "FULL BODY HARNESS",
|
|
||||||
img: "/images/products/harness.jpg",
|
|
||||||
desc: "هارنس تمامبدنی با دو شیر پیچی و نوارهای دوختهشده با نخ نارنجی سیگنال؛ تستشده برای کار در ارتفاع با ظرفیت ۱۰۰ کیلوگرم.",
|
|
||||||
specs: ["EN 361", "ظرفیت ۱۰۰ کیلوگرم", "شیر دوگانه"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
code: "AP-615",
|
|
||||||
name: "لباس کار بازتابنده",
|
|
||||||
en: "HI-VIS WORKWEAR",
|
|
||||||
img: "/images/products/vest.jpg",
|
|
||||||
desc: "جلیقهها و لباسهای کار بازتابنده کلاس ۲ با نوارهای ۳M؛ دیدهشدن کامل پرسنل در شب، مه و محیطهای پرتردد خودرویی.",
|
|
||||||
specs: ["EN ISO 20471", "کلاس ۲", "نوار ۳M"],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const TRUST = [
|
const TRUST = [
|
||||||
{
|
{
|
||||||
icon: BadgeCheck,
|
icon: BadgeCheck,
|
||||||
@@ -87,12 +38,12 @@ const active = ref(0);
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section id="products" aria-labelledby="products-title" class="relative py-24 md:py-32">
|
<section id="products" aria-labelledby="products-title" class="relative py-24 md:py-32">
|
||||||
<div class="mx-auto max-w-7xl px-5 md:px-8">
|
<div class="mx-auto max-w-[1480px] px-5 md:px-8">
|
||||||
<div class="flex flex-wrap items-end justify-between gap-6">
|
<div class="flex flex-wrap items-end justify-between gap-6">
|
||||||
<SectionHead
|
<SectionHead
|
||||||
heading-id="products-title"
|
heading-id="products-title"
|
||||||
tag="۰۱ — محصولات"
|
tag="۰۱ — محصولات"
|
||||||
desc="هر محصول پیش از عرضه، زیر ذرهبین کنترل کیفیت و تطبیق با استانداردهای جهانی قرار میگیرد. روی هر پنل کلیک کنید."
|
desc="هر محصول پیش از عرضه، زیر ذرهبین کنترل کیفیت و تطبیق با استانداردهای جهانی قرار میگیرد."
|
||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
خط اول دفاع،
|
خط اول دفاع،
|
||||||
@@ -102,7 +53,7 @@ const active = ref(0);
|
|||||||
</SectionHead>
|
</SectionHead>
|
||||||
<Reveal :delay="0.2" class="hidden md:block">
|
<Reveal :delay="0.2" class="hidden md:block">
|
||||||
<a
|
<a
|
||||||
href="#contact"
|
href="/#contact"
|
||||||
class="group inline-flex items-center gap-2 rounded-full border border-line px-6 py-3 text-sm text-muted transition-colors hover:border-accent hover:text-accent"
|
class="group inline-flex items-center gap-2 rounded-full border border-line px-6 py-3 text-sm text-muted transition-colors hover:border-accent hover:text-accent"
|
||||||
>
|
>
|
||||||
دریافت کاتالوگ کامل
|
دریافت کاتالوگ کامل
|
||||||
@@ -112,29 +63,70 @@ const active = ref(0);
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mx-auto mt-14 max-w-7xl px-5 md:px-8">
|
<!-- ---- mobile: card grid ---- -->
|
||||||
<div class="flex flex-col gap-2 md:h-[74vh] md:min-h-[580px] md:flex-row">
|
<div class="mx-auto mt-14 max-w-[1480px] px-5 md:hidden">
|
||||||
<div
|
<div class="grid grid-cols-2 gap-3">
|
||||||
v-for="(p, i) in PRODUCTS"
|
<Reveal v-for="(cat, i) in CATEGORIES" :key="cat.code" :delay="i * 0.05">
|
||||||
:key="p.code"
|
<NuxtLink
|
||||||
|
:to="`/categories/${cat.slug}`"
|
||||||
|
class="group relative block aspect-[3/4] overflow-hidden rounded-xl border border-line transition-colors duration-300 active:border-accent/60"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
v-if="CATEGORY_IMAGES[cat.slug]"
|
||||||
|
:src="CATEGORY_IMAGES[cat.slug]"
|
||||||
|
:alt="cat.name"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
class="absolute inset-0 size-full object-cover transition-transform duration-500 group-active:scale-105"
|
||||||
|
/>
|
||||||
|
<div v-else class="absolute inset-0 bg-panel" />
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-t from-bg via-bg/50 to-transparent" />
|
||||||
|
|
||||||
|
<div class="absolute inset-x-0 top-0 flex items-center justify-between p-3">
|
||||||
|
<span class="font-mono text-[9px] tracking-widest text-ink/50">{{ cat.code }}</span>
|
||||||
|
<span class="font-mono text-[10px] text-accent">
|
||||||
|
{{ faNum(String(i + 1).padStart(2, "0")) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="absolute inset-x-0 bottom-0 p-3">
|
||||||
|
<h3 class="text-sm font-black leading-6">{{ cat.name }}</h3>
|
||||||
|
<p class="mt-0.5 font-mono text-[8px] tracking-[0.15em] text-muted">{{ cat.en }}</p>
|
||||||
|
</div>
|
||||||
|
</NuxtLink>
|
||||||
|
</Reveal>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ---- desktop: accordion panels ---- -->
|
||||||
|
<div class="mx-auto mt-14 hidden max-w-[1480px] px-8 md:block">
|
||||||
|
<div class="flex h-[74vh] min-h-[580px] flex-row gap-2">
|
||||||
|
<NuxtLink
|
||||||
|
v-for="(cat, i) in CATEGORIES"
|
||||||
|
:key="cat.code"
|
||||||
|
:to="`/categories/${cat.slug}`"
|
||||||
data-hover
|
data-hover
|
||||||
:class="`group relative cursor-pointer overflow-hidden rounded-xl border transition-all duration-700 ease-[cubic-bezier(0.22,1,0.36,1)] ${
|
:class="`group relative cursor-pointer overflow-hidden rounded-xl border transition-all duration-500 ease-[cubic-bezier(0.22,1,0.36,1)] ${
|
||||||
active === i
|
active === i
|
||||||
? 'h-[500px] flex-[3.4] border-accent/60 md:h-auto'
|
? 'flex-[3.4] border-accent/60'
|
||||||
: 'h-24 flex-[1] border-line hover:border-ink/30 md:h-auto'
|
: 'flex-[1] border-line hover:border-ink/30'
|
||||||
}`"
|
}`"
|
||||||
@mouseenter="active = i"
|
@mouseenter="active = i"
|
||||||
@click="active = i"
|
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="p.img"
|
v-if="CATEGORY_IMAGES[cat.slug]"
|
||||||
:alt="p.name"
|
:src="CATEGORY_IMAGES[cat.slug]"
|
||||||
|
:alt="cat.name"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
decoding="async"
|
decoding="async"
|
||||||
:class="`absolute inset-0 size-full object-cover transition-all duration-700 ${
|
:class="`absolute inset-0 size-full object-cover transition-all duration-700 ${
|
||||||
active === i ? 'scale-100 grayscale-0' : 'scale-110 grayscale group-hover:grayscale-0'
|
active === i ? 'scale-100 grayscale-0' : 'scale-110 grayscale group-hover:grayscale-0'
|
||||||
}`"
|
}`"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="absolute inset-0 bg-panel"
|
||||||
|
/>
|
||||||
<div
|
<div
|
||||||
:class="`absolute inset-0 transition-opacity duration-700 ${
|
:class="`absolute inset-0 transition-opacity duration-700 ${
|
||||||
active === i
|
active === i
|
||||||
@@ -144,7 +136,7 @@ const active = ref(0);
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="absolute inset-x-0 top-0 flex items-center justify-between p-5">
|
<div class="absolute inset-x-0 top-0 flex items-center justify-between p-5">
|
||||||
<span class="font-mono text-[10px] tracking-widest text-ink/60">{{ p.code }}</span>
|
<span class="font-mono text-[10px] tracking-widest text-ink/60">{{ cat.code }}</span>
|
||||||
<span
|
<span
|
||||||
:class="`font-mono text-xs transition-colors duration-500 ${
|
:class="`font-mono text-xs transition-colors duration-500 ${
|
||||||
active === i ? 'text-accent' : 'text-ink/40'
|
active === i ? 'text-accent' : 'text-ink/40'
|
||||||
@@ -154,42 +146,22 @@ const active = ref(0);
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="absolute inset-x-0 bottom-0 p-5 md:p-6">
|
<div class="absolute inset-x-0 bottom-0 p-6">
|
||||||
<h3
|
<h3
|
||||||
:class="`font-black transition-all duration-500 ${
|
:class="`font-black transition-all duration-500 ${
|
||||||
active === i ? 'text-2xl' : 'text-base md:text-sm'
|
active === i ? 'text-2xl' : 'text-sm'
|
||||||
}`"
|
}`"
|
||||||
>
|
>
|
||||||
{{ p.name }}
|
{{ cat.name }}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="mt-1 font-mono text-[10px] tracking-[0.2em] text-muted">{{ p.en }}</p>
|
<p class="mt-1 font-mono text-[10px] tracking-[0.2em] text-muted">{{ cat.en }}</p>
|
||||||
<AnimatePresence>
|
|
||||||
<motion.div
|
|
||||||
v-if="active === i"
|
|
||||||
:initial="{ opacity: 0, y: 18 }"
|
|
||||||
:animate="{ opacity: 1, y: 0 }"
|
|
||||||
:exit="{ opacity: 0, y: 10 }"
|
|
||||||
:transition="{ duration: 0.45, delay: 0.12, ease: EASE }"
|
|
||||||
>
|
|
||||||
<p class="mt-4 max-w-md text-sm leading-8 text-ink/75">{{ p.desc }}</p>
|
|
||||||
<div class="mt-4 flex flex-wrap gap-2">
|
|
||||||
<span
|
|
||||||
v-for="s in p.specs"
|
|
||||||
:key="s"
|
|
||||||
class="rounded-full border border-accent/40 bg-accent/10 px-3 py-1 font-mono text-[10px] text-accent"
|
|
||||||
>
|
|
||||||
{{ s }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</motion.div>
|
|
||||||
</AnimatePresence>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="mx-auto mt-10 grid max-w-7xl gap-px overflow-hidden rounded-xl border border-line bg-line md:grid-cols-3"
|
class="mx-auto mt-10 grid max-w-[1480px] gap-px overflow-hidden rounded-xl border border-line bg-line md:grid-cols-3"
|
||||||
>
|
>
|
||||||
<Reveal v-for="(t, i) in TRUST" :key="t.title" :delay="i * 0.08">
|
<Reveal v-for="(t, i) in TRUST" :key="t.title" :delay="i * 0.08">
|
||||||
<div class="flex h-full items-center gap-4 bg-panel/60 p-6">
|
<div class="flex h-full items-center gap-4 bg-panel/60 p-6">
|
||||||
|
|||||||
@@ -58,11 +58,11 @@ const open = ref(0);
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section id="services" aria-labelledby="services-title" class="border-t border-line py-24 md:py-32">
|
<section id="services" aria-labelledby="services-title" class="border-t border-line py-24 md:py-32">
|
||||||
<div class="mx-auto max-w-7xl px-5 md:px-8">
|
<div class="mx-auto max-w-[1480px] px-5 md:px-8">
|
||||||
<SectionHead
|
<SectionHead
|
||||||
heading-id="services-title"
|
heading-id="services-title"
|
||||||
tag="۰۳ — خدمات"
|
tag="۰۳ — خدمات"
|
||||||
desc="ما در آریا ایمن، تجهیزات را تحویل میدهیم و کنار شما میمانیم؛ از نخستین ارزیابی ریسک تا آخرین تست دورهای."
|
desc="ما در ایمن پیشگامان، تجهیزات را تحویل میدهیم و کنار شما میمانیم؛ از نخستین ارزیابی ریسک تا آخرین تست دورهای."
|
||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
فراتر از تأمین؛
|
فراتر از تأمین؛
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const STANDARDS = [
|
|||||||
CE
|
CE
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative mx-auto max-w-7xl px-5 md:px-8">
|
<div class="relative mx-auto max-w-[1480px] px-5 md:px-8">
|
||||||
<div class="grid items-center gap-14 lg:grid-cols-12">
|
<div class="grid items-center gap-14 lg:grid-cols-12">
|
||||||
<div class="lg:col-span-5">
|
<div class="lg:col-span-5">
|
||||||
<SectionHead
|
<SectionHead
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const STATS = [
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="relative" aria-label="آمار و دستاوردهای آریا ایمن">
|
<section class="relative" aria-label="آمار و دستاوردهای ایمن پیشگامان">
|
||||||
<div class="grid grid-cols-2 gap-px border-y border-line bg-line lg:grid-cols-4">
|
<div class="grid grid-cols-2 gap-px border-y border-line bg-line lg:grid-cols-4">
|
||||||
<div
|
<div
|
||||||
v-for="(s, i) in STATS"
|
v-for="(s, i) in STATS"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import SectionHead from "~/components/ui/SectionHead.vue";
|
|||||||
|
|
||||||
const QUOTES = [
|
const QUOTES = [
|
||||||
{
|
{
|
||||||
text: "آریا ایمن فقط تأمینکننده نیست؛ شریک ایمنی ماست. بازرسیهای دورهای و آموزشهای میدانیشان نرخ حوادث سایت را به کمترین رقم تاریخ مجموعه رساند.",
|
text: "ایمن پیشگامان فقط تأمینکننده نیست؛ شریک ایمنی ماست. بازرسیهای دورهای و آموزشهای میدانیشان نرخ حوادث سایت را به کمترین رقم تاریخ مجموعه رساند.",
|
||||||
name: "مهندس رضا کاظمی",
|
name: "مهندس رضا کاظمی",
|
||||||
role: "مدیر HSE — مجتمع پتروشیمی خلیج فارس",
|
role: "مدیر HSE — مجتمع پتروشیمی خلیج فارس",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ImageOff } from "lucide-vue-next";
|
||||||
|
|
||||||
|
withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
label?: string;
|
||||||
|
aspectClass?: string;
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
label: "تصویر محصول",
|
||||||
|
aspectClass: "aspect-[4/3]",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
:class="`flex flex-col items-center justify-center border border-dashed border-line bg-panel ${aspectClass}`"
|
||||||
|
>
|
||||||
|
<ImageOff class="size-10 text-muted/30" />
|
||||||
|
<span class="mt-2 font-mono text-[10px] tracking-wider text-muted/40">{{ label }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -1,19 +1,24 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ShieldCheck } from "lucide-vue-next";
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a href="#home" class="flex items-center gap-3" aria-label="آریا ایمن">
|
<NuxtLink to="/" class="flex items-center gap-3" aria-label="ایمن پیشگامان">
|
||||||
<span
|
<span
|
||||||
class="flex size-10 items-center justify-center rounded-xl bg-accent text-bg shadow-[0_0_28px_rgba(255,90,0,0.35)]"
|
class="flex size-10 items-center justify-center rounded-xl bg-white shadow-[0_0_28px_rgba(10,30,92,0.45)]"
|
||||||
>
|
>
|
||||||
<ShieldCheck class="size-6" />
|
<img
|
||||||
|
src="/images/logo.png"
|
||||||
|
alt="ایمن پیشگامان"
|
||||||
|
width="28"
|
||||||
|
height="28"
|
||||||
|
class="size-7 object-contain"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span class="leading-tight">
|
<span class="leading-tight">
|
||||||
<span class="block text-lg font-black">آریا ایمن</span>
|
<span class="block text-lg font-black">ایمن پیشگامان</span>
|
||||||
<span class="block font-mono text-[9px] tracking-[0.32em] text-muted">
|
<span class="block font-mono text-[9px] tracking-[0.32em] text-muted">
|
||||||
ARIA IMEN CO.
|
IMEN PISHGAMAN CO.
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</NuxtLink>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ArrowRight, Phone } from "lucide-vue-next";
|
||||||
|
import { absUrl } from "#shared/config/site";
|
||||||
|
import { CATEGORIES, findCategory } from "#shared/data/categories";
|
||||||
|
import { categoryPageSchema } from "#shared/seo/schema";
|
||||||
|
import AppShell from "~/components/layout/AppShell.vue";
|
||||||
|
import Footer from "~/components/layout/Footer.vue";
|
||||||
|
import SectionHead from "~/components/ui/SectionHead.vue";
|
||||||
|
import Reveal from "~/components/ui/Reveal.vue";
|
||||||
|
|
||||||
|
const CATEGORY_IMAGES: Record<string, string> = {
|
||||||
|
workwear: "/images/products/vest.jpg",
|
||||||
|
"safety-footwear": "/images/products/shoes.jpg",
|
||||||
|
"protective-gloves": "/images/products/gloves.jpg",
|
||||||
|
"safety-helmets": "/images/products/helmet.jpg",
|
||||||
|
"eye-protection": "/images/products/goggles.jpg",
|
||||||
|
"hearing-protection": "/images/products/hearing.jpg",
|
||||||
|
"respiratory-protection": "/images/products/respiratory.jpg",
|
||||||
|
"traffic-equipment": "/images/products/traffic.jpg",
|
||||||
|
};
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const slug = route.params.slug as string;
|
||||||
|
const category = findCategory(slug);
|
||||||
|
|
||||||
|
if (!category) {
|
||||||
|
throw createError({ statusCode: 404, statusMessage: "دستهبندی یافت نشد" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const categoryIndex = CATEGORIES.findIndex((c) => c.slug === slug);
|
||||||
|
const canonical = absUrl(`/categories/${slug}`);
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: `${category.name} | ایمن پیشگامان`,
|
||||||
|
link: [{ rel: "canonical", href: canonical }],
|
||||||
|
});
|
||||||
|
useSeoMeta({
|
||||||
|
description: category.fullDesc,
|
||||||
|
robots: "index, follow",
|
||||||
|
ogUrl: canonical,
|
||||||
|
ogTitle: `${category.name} | ایمن پیشگامان`,
|
||||||
|
ogDescription: category.fullDesc,
|
||||||
|
});
|
||||||
|
useJsonLd(categoryPageSchema(category), `category-${slug}`);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<AppShell>
|
||||||
|
<main>
|
||||||
|
<!-- ---- hero banner ---- -->
|
||||||
|
<section class="relative overflow-hidden pt-32 pb-20 md:pt-40 md:pb-28">
|
||||||
|
<div class="absolute inset-0">
|
||||||
|
<img
|
||||||
|
v-if="CATEGORY_IMAGES[slug]"
|
||||||
|
:src="CATEGORY_IMAGES[slug]"
|
||||||
|
:alt="category.name"
|
||||||
|
class="absolute inset-0 size-full object-cover"
|
||||||
|
fetchpriority="high"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-l from-bg via-bg/85 to-bg/40" />
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-t from-bg via-bg/50 to-bg/30" />
|
||||||
|
<div class="absolute inset-0 bg-grid opacity-40" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tape-v absolute bottom-0 end-0 z-10 h-32 w-1.5 opacity-70" />
|
||||||
|
|
||||||
|
<div class="relative z-10 mx-auto max-w-[1480px] px-5 md:px-8">
|
||||||
|
<Reveal>
|
||||||
|
<nav class="flex items-center gap-2 text-sm text-muted" aria-label="مسیر">
|
||||||
|
<NuxtLink to="/" class="transition-colors hover:text-accent">خانه</NuxtLink>
|
||||||
|
<span class="text-line">/</span>
|
||||||
|
<NuxtLink to="/#products" class="transition-colors hover:text-accent">
|
||||||
|
محصولات
|
||||||
|
</NuxtLink>
|
||||||
|
<span class="text-line">/</span>
|
||||||
|
<span class="text-ink">{{ category.name }}</span>
|
||||||
|
</nav>
|
||||||
|
</Reveal>
|
||||||
|
|
||||||
|
<div class="mt-8">
|
||||||
|
<SectionHead
|
||||||
|
:tag="`${faNum(String(categoryIndex + 1).padStart(2, '0'))} — محصولات`"
|
||||||
|
:desc="category.fullDesc"
|
||||||
|
>
|
||||||
|
<template #title>{{ category.name }}</template>
|
||||||
|
</SectionHead>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Reveal :delay="0.2">
|
||||||
|
<div class="mt-8 flex flex-wrap items-center gap-4">
|
||||||
|
<span
|
||||||
|
class="rounded-full border border-accent/40 bg-accent/10 px-4 py-1.5 font-mono text-xs text-accent backdrop-blur"
|
||||||
|
>
|
||||||
|
{{ faNum(category.products.length) }} محصول
|
||||||
|
</span>
|
||||||
|
<span class="font-mono text-xs tracking-[0.25em] text-muted/60">
|
||||||
|
{{ category.en }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Reveal>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- ---- products grid ---- -->
|
||||||
|
<section class="relative py-16 md:py-24">
|
||||||
|
<div class="absolute inset-0 bg-grid-fine opacity-30" />
|
||||||
|
<div class="relative mx-auto max-w-[1480px] px-5 md:px-8">
|
||||||
|
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
|
<Reveal v-for="(product, i) in category.products" :key="product.code" :delay="i * 0.06">
|
||||||
|
<div
|
||||||
|
class="group h-full overflow-hidden rounded-xl border border-line bg-panel/80 backdrop-blur transition-all duration-500 hover:border-accent/40 hover:shadow-[0_8px_40px_rgba(255,90,0,0.08)]"
|
||||||
|
>
|
||||||
|
<div class="relative aspect-[4/3] overflow-hidden">
|
||||||
|
<img
|
||||||
|
:src="CATEGORY_IMAGES[slug]"
|
||||||
|
:alt="product.name"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
class="size-full object-cover transition-transform duration-700 group-hover:scale-105"
|
||||||
|
/>
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-t from-bg/60 to-transparent" />
|
||||||
|
<div class="absolute inset-x-0 top-0 flex items-center justify-between p-4">
|
||||||
|
<span class="rounded-full bg-bg/60 px-3 py-1 font-mono text-[10px] tracking-widest text-ink/70 backdrop-blur">
|
||||||
|
{{ product.code }}
|
||||||
|
</span>
|
||||||
|
<span class="font-mono text-xs text-accent">
|
||||||
|
{{ faNum(String(i + 1).padStart(2, "0")) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-5 md:p-6">
|
||||||
|
<h3 class="text-xl font-black">{{ product.name }}</h3>
|
||||||
|
<p class="mt-1 font-mono text-[10px] tracking-[0.2em] text-muted">
|
||||||
|
{{ product.en }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="mt-3 text-sm leading-8 text-muted">{{ product.desc }}</p>
|
||||||
|
|
||||||
|
<div class="mt-4 flex flex-wrap gap-2">
|
||||||
|
<span
|
||||||
|
v-for="s in product.specs"
|
||||||
|
:key="s"
|
||||||
|
class="rounded-full border border-accent/40 bg-accent/10 px-3 py-1 font-mono text-[10px] text-accent"
|
||||||
|
>
|
||||||
|
{{ s }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="product.variants?.length" class="mt-4">
|
||||||
|
<div class="mb-2 text-xs text-muted">مدلها / رنگها:</div>
|
||||||
|
<div class="flex flex-wrap gap-1.5">
|
||||||
|
<span
|
||||||
|
v-for="v in product.variants"
|
||||||
|
:key="v"
|
||||||
|
class="rounded-md border border-line bg-panel-2 px-2.5 py-1 text-[11px] text-ink/70"
|
||||||
|
>
|
||||||
|
{{ v }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Reveal>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- ---- bottom CTA ---- -->
|
||||||
|
<section class="border-t border-line py-12 md:py-16">
|
||||||
|
<div class="mx-auto flex max-w-[1480px] flex-wrap items-center justify-between gap-6 px-5 md:px-8">
|
||||||
|
<NuxtLink
|
||||||
|
to="/#products"
|
||||||
|
class="group inline-flex items-center gap-2 text-muted transition-colors hover:text-accent"
|
||||||
|
>
|
||||||
|
<ArrowRight class="size-4 transition-transform group-hover:translate-x-1" />
|
||||||
|
بازگشت به دستهبندیها
|
||||||
|
</NuxtLink>
|
||||||
|
<a
|
||||||
|
href="/#contact"
|
||||||
|
class="inline-flex items-center gap-2 rounded-full bg-accent px-6 py-3 text-sm font-bold text-bg transition-all hover:bg-accent-soft hover:shadow-[0_8px_45px_rgba(255,90,0,0.5)]"
|
||||||
|
>
|
||||||
|
<Phone class="size-4" />
|
||||||
|
درخواست قیمت
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</AppShell>
|
||||||
|
</template>
|
||||||
+17
-2
@@ -1,6 +1,7 @@
|
|||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
import tailwindcss from "@tailwindcss/vite";
|
import tailwindcss from "@tailwindcss/vite";
|
||||||
import { siteConfig } from "./shared/config/site";
|
import { siteConfig } from "./shared/config/site";
|
||||||
|
import { categorySlugs } from "./shared/data/categories";
|
||||||
|
|
||||||
/** Unmatched path rendered through error.vue at build time and saved as out/404.html */
|
/** Unmatched path rendered through error.vue at build time and saved as out/404.html */
|
||||||
const NOT_FOUND_ROUTE = "/__not-found";
|
const NOT_FOUND_ROUTE = "/__not-found";
|
||||||
@@ -23,7 +24,14 @@ export default defineNuxtConfig({
|
|||||||
link: [
|
link: [
|
||||||
{
|
{
|
||||||
rel: "preload",
|
rel: "preload",
|
||||||
href: "/fonts/Vazirmatn-Variable.woff2",
|
href: "/fonts/IRANSansWeb.woff2",
|
||||||
|
as: "font",
|
||||||
|
type: "font/woff2",
|
||||||
|
crossorigin: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rel: "preload",
|
||||||
|
href: "/fonts/IRANSansWeb_Bold.woff2",
|
||||||
as: "font",
|
as: "font",
|
||||||
type: "font/woff2",
|
type: "font/woff2",
|
||||||
crossorigin: "",
|
crossorigin: "",
|
||||||
@@ -51,7 +59,14 @@ export default defineNuxtConfig({
|
|||||||
output: { publicDir: fileURLToPath(new URL("./out", import.meta.url)) },
|
output: { publicDir: fileURLToPath(new URL("./out", import.meta.url)) },
|
||||||
prerender: {
|
prerender: {
|
||||||
crawlLinks: false,
|
crawlLinks: false,
|
||||||
routes: ["/", "/robots.txt", "/sitemap.xml", "/manifest.webmanifest", NOT_FOUND_ROUTE],
|
routes: [
|
||||||
|
"/",
|
||||||
|
"/robots.txt",
|
||||||
|
"/sitemap.xml",
|
||||||
|
"/manifest.webmanifest",
|
||||||
|
NOT_FOUND_ROUTE,
|
||||||
|
...categorySlugs.map((s) => `/categories/${s}`),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
hooks: {
|
hooks: {
|
||||||
// Nuxt's own /404.html is an empty SPA shell. Replace it with a server-rendered error.vue
|
// Nuxt's own /404.html is an empty SPA shell. Replace it with a server-rendered error.vue
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 279 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
@@ -1,6 +1,15 @@
|
|||||||
import { absUrl } from "../../shared/config/site";
|
import { absUrl } from "../../shared/config/site";
|
||||||
|
import { categorySlugs } from "../../shared/data/categories";
|
||||||
|
|
||||||
const pages = ["/"];
|
interface SitemapEntry {
|
||||||
|
loc: string;
|
||||||
|
priority: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pages: SitemapEntry[] = [
|
||||||
|
{ loc: "/", priority: "1" },
|
||||||
|
...categorySlugs.map((s) => ({ loc: `/categories/${s}`, priority: "0.8" })),
|
||||||
|
];
|
||||||
|
|
||||||
export default defineEventHandler((event) => {
|
export default defineEventHandler((event) => {
|
||||||
setHeader(event, "Content-Type", "application/xml; charset=utf-8");
|
setHeader(event, "Content-Type", "application/xml; charset=utf-8");
|
||||||
@@ -8,7 +17,7 @@ export default defineEventHandler((event) => {
|
|||||||
const urls = pages
|
const urls = pages
|
||||||
.map(
|
.map(
|
||||||
(p) =>
|
(p) =>
|
||||||
`<url>\n<loc>${absUrl(p)}</loc>\n<lastmod>${lastmod}</lastmod>\n<changefreq>monthly</changefreq>\n<priority>1</priority>\n</url>`,
|
`<url>\n<loc>${absUrl(p.loc)}</loc>\n<lastmod>${lastmod}</lastmod>\n<changefreq>monthly</changefreq>\n<priority>${p.priority}</priority>\n</url>`,
|
||||||
)
|
)
|
||||||
.join("\n");
|
.join("\n");
|
||||||
return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${urls}\n</urlset>\n`;
|
return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${urls}\n</urlset>\n`;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
export const siteConfig = {
|
export const siteConfig = {
|
||||||
name: "آریا ایمن",
|
name: "ایمن پیشگامان",
|
||||||
nameEn: "Aria Imen Safety",
|
nameEn: "Imen Pishgaman Safety",
|
||||||
url: "https://ariaiman.ir", // TODO: replace with the real production domain before deploy
|
url: "https://imenpishgaman.ir", // TODO: replace with the real production domain before deploy
|
||||||
locale: "fa_IR",
|
locale: "fa_IR",
|
||||||
lang: "fa",
|
lang: "fa",
|
||||||
dir: "rtl" as const,
|
dir: "rtl" as const,
|
||||||
title: "آریا ایمن | تجهیزات ایمنی و حفاظت فردی صنعتی",
|
title: "ایمن پیشگامان | تجهیزات ایمنی و حفاظت فردی صنعتی",
|
||||||
description:
|
description:
|
||||||
"آریا ایمن — تأمینکننده تخصصی تجهیزات حفاظت فردی (PPE)، بازرسی، آموزش و راهکارهای ایمنی صنعتی برای سازمانهایی که جان انسانها را جدی میگیرند.",
|
"ایمن پیشگامان — تأمینکننده تخصصی تجهیزات حفاظت فردی (PPE)، بازرسی، آموزش و راهکارهای ایمنی صنعتی برای سازمانهایی که جان انسانها را جدی میگیرند.",
|
||||||
// TODO: replace with a dedicated 1200×630 social image when available
|
// TODO: replace with a dedicated 1200×630 social image when available
|
||||||
ogImage: {
|
ogImage: {
|
||||||
src: "/images/hero.jpg",
|
src: "/images/hero.jpg",
|
||||||
@@ -28,7 +28,7 @@ export const siteConfig = {
|
|||||||
contact: {
|
contact: {
|
||||||
phone: "+98-21-91008800",
|
phone: "+98-21-91008800",
|
||||||
phoneDisplay: "۰۲۱ - ۹۱ ۰۰ ۸۸ ۰۰",
|
phoneDisplay: "۰۲۱ - ۹۱ ۰۰ ۸۸ ۰۰",
|
||||||
email: "info@ariaiman.ir",
|
email: "info@imenpishgaman.ir",
|
||||||
address: {
|
address: {
|
||||||
streetAddress: "خیابان کارگر شمالی، خیابان فر، کوچه دوم، پلاک ۱۲",
|
streetAddress: "خیابان کارگر شمالی، خیابان فر، کوچه دوم، پلاک ۱۲",
|
||||||
addressLocality: "تهران",
|
addressLocality: "تهران",
|
||||||
|
|||||||
@@ -0,0 +1,458 @@
|
|||||||
|
export interface Product {
|
||||||
|
code: string;
|
||||||
|
name: string;
|
||||||
|
en: string;
|
||||||
|
desc: string;
|
||||||
|
specs: string[];
|
||||||
|
variants?: string[];
|
||||||
|
image?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Category {
|
||||||
|
slug: string;
|
||||||
|
code: string;
|
||||||
|
name: string;
|
||||||
|
en: string;
|
||||||
|
shortDesc: string;
|
||||||
|
fullDesc: string;
|
||||||
|
icon: string;
|
||||||
|
products: Product[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CATEGORIES: readonly Category[] = [
|
||||||
|
{
|
||||||
|
slug: "workwear",
|
||||||
|
code: "IP-C01",
|
||||||
|
name: "پوشاک کار و البسه صنعتی",
|
||||||
|
en: "INDUSTRIAL WORKWEAR",
|
||||||
|
shortDesc:
|
||||||
|
"لباسکار صنعتی با پارچه فلامنت کجراه اعلا، دوخت سه سوزنه و آستر عرقگیر؛ مناسب محیطهای کارگاهی و صنعتی.",
|
||||||
|
fullDesc:
|
||||||
|
"مجموعه کامل پوشاک کار صنعتی شامل کاپشن و شلوار مهندسی، لباس جوشکاری، پیشبند دوبنده و تیشرت کار. تمامی مدلها با پارچه فلامنت کجراه اعلا و کتان مقاوم، دوخت صنعتی سه سوزنه پیوسته برای جلوگیری از شکافتگی درزها و آستر عرقگیر اختصاصی تولید میشوند. موجود در سایزهای M تا 4XL.",
|
||||||
|
icon: "Shirt",
|
||||||
|
products: [
|
||||||
|
{
|
||||||
|
code: "IP-W01",
|
||||||
|
name: "لباسکار مدل آلفا",
|
||||||
|
en: "ALPHA WORKWEAR",
|
||||||
|
desc: "کاپشن و شلوار مهندسی با جیبهای پاکتی و زیپدار، نوار مغزی تزئینی و طراحی ارگونومیک برای تیمهای فنی و مهندسی.",
|
||||||
|
specs: ["فلامنت کجراه اعلا", "دوخت سه سوزنه", "آستر عرقگیر", "سایز M تا 4XL"],
|
||||||
|
variants: [
|
||||||
|
"طوسی/آبی",
|
||||||
|
"مشکی/قرمز",
|
||||||
|
"مشکی/زرد",
|
||||||
|
"کرم/سرمهای",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-W02",
|
||||||
|
name: "لباسکار مدل اورجینال",
|
||||||
|
en: "ORIGINAL WORKWEAR",
|
||||||
|
desc: "کاپشن و شلوار استاندارد با دوام بالا، مناسب کادر فنی کارخانجات و خطوط تولید با ترکیبهای صنعتی دورنگ.",
|
||||||
|
specs: ["کتان مقاوم", "دوخت سه سوزنه", "آستر عرقگیر", "سایز M تا 4XL"],
|
||||||
|
variants: ["ترکیبهای صنعتی دورنگ"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-W03",
|
||||||
|
name: "لباسکار مدل بوفالو",
|
||||||
|
en: "BUFFALO WORKWEAR",
|
||||||
|
desc: "طراحی اسپرت با برشهای تقویتی روی شانه و بازو، زیپ مخفی محافظدار؛ مناسب محیطهای صنعتی فعال.",
|
||||||
|
specs: ["فلامنت کجراه اعلا", "زیپ مخفی محافظدار", "برش تقویتی شانه", "سایز M تا 4XL"],
|
||||||
|
variants: [
|
||||||
|
"سرمهای/زرد",
|
||||||
|
"طوسی/قرمز",
|
||||||
|
"طوسی/خردلی",
|
||||||
|
"آبی/مشکی",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-W04",
|
||||||
|
name: "لباسکار ست ورک",
|
||||||
|
en: "SET WORK",
|
||||||
|
desc: "ست اداری/کارگاهی با انعطاف بالا جهت فعالیتهای فنی و تعمیراتی؛ قابل استفاده در محیطهای ستادی و عملیاتی.",
|
||||||
|
specs: ["کتان مقاوم", "دوخت سه سوزنه", "طراحی منعطف", "سایز M تا 4XL"],
|
||||||
|
variants: ["ترکیبهای چندگانه کارگاهی"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-W05",
|
||||||
|
name: "لباسکار جوشکاری",
|
||||||
|
en: "WELDING WORKWEAR",
|
||||||
|
desc: "متریال سنگین کتان یا چرم جهت مقاومت در برابر پاشش جرقههای مذاب؛ طراحیشده برای جوشکاران صنعتی.",
|
||||||
|
specs: ["مقاوم به جرقه مذاب", "کتان سنگین / چرم", "دوخت صنعتی", "سایز M تا 4XL"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-W06",
|
||||||
|
name: "پیشبند دوبنده",
|
||||||
|
en: "BIB OVERALLS",
|
||||||
|
desc: "آزادی عمل کامل کتف و شانه با جیبهای چندمنظوره ابزار بر روی پیشسینه؛ ایدهآل برای کارهای تعمیراتی و مونتاژ.",
|
||||||
|
specs: ["آزادی حرکت شانه", "جیب ابزار پیشسینه", "دوخت سه سوزنه", "سایز M تا 4XL"],
|
||||||
|
variants: ["سرمهای", "خاکستری"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-W07",
|
||||||
|
name: "تیشرت صنعتی",
|
||||||
|
en: "INDUSTRIAL T-SHIRT",
|
||||||
|
desc: "تیشرت یقهدار جودون / پنبهای مناسب فصول گرم و زیرپوش کاپشن کارگاهی در سولههای سرپوشیده.",
|
||||||
|
specs: ["پنبه / جودون", "یقهدار", "مناسب فصول گرم", "سایز M تا 4XL"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: "safety-footwear",
|
||||||
|
code: "IP-C02",
|
||||||
|
name: "پایپوش و کفش ایمنی",
|
||||||
|
en: "SAFETY FOOTWEAR",
|
||||||
|
shortDesc:
|
||||||
|
"کفشهای ایمنی مهندسی، کارگری، اداری و زنانه به همراه چکمه صنعتی؛ مجهز به سرپنجه ایمنی و زیره ضد لغزش.",
|
||||||
|
fullDesc:
|
||||||
|
"مجموعه کامل پایپوش ایمنی شامل کفشهای اداری، مهندسی، کارگری و زنانه به همراه چکمههای صنعتی. هر مدل متناسب با شرایط محیط کار طراحی شده و مجهز به سرپنجه ایمنی مقاوم، زیره تخصصی ضد لغزش و مواد مقاوم در برابر سایش و مواد شیمیایی.",
|
||||||
|
icon: "Footprints",
|
||||||
|
products: [
|
||||||
|
{
|
||||||
|
code: "IP-F01",
|
||||||
|
name: "کفش اداری ایمنی",
|
||||||
|
en: "OFFICE SAFETY SHOE",
|
||||||
|
desc: "طراحی شکیل و رسمی برای محیطهای اداری و ستادی؛ وزن سبک، زیره مقاوم و راحتی در استفاده طولانیمدت.",
|
||||||
|
specs: ["طراحی رسمی", "وزن سبک", "زیره مقاوم", "راحتی طولانیمدت"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-F02",
|
||||||
|
name: "کفش ایمنی مهندسی",
|
||||||
|
en: "ENGINEERING SAFETY BOOT",
|
||||||
|
desc: "مجهز به سرپنجه ایمنی مقاوم و زیره تخصصی ضد لغزش؛ مناسب محیطهای صنعتی و کارگاهی ناظران و مهندسان.",
|
||||||
|
specs: ["سرپنجه ایمنی", "Anti-Slip", "مقاوم به سایش", "زیره تخصصی"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-F03",
|
||||||
|
name: "کفش ایمنی کارگری",
|
||||||
|
en: "WORKER SAFETY BOOT",
|
||||||
|
desc: "مقاومت بالا در برابر سایش فیزیکی و تماس با مواد شیمیایی سبک؛ مناسب کارگاههای تولیدی، انبارها و پروژههای ساختمانی.",
|
||||||
|
specs: ["مقاوم به سایش", "مقاوم شیمیایی", "سرپنجه فولادی", "زیره ضد لغزش"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-F04",
|
||||||
|
name: "کفش ایمنی زنانه",
|
||||||
|
en: "WOMEN'S SAFETY SHOE",
|
||||||
|
desc: "قالب اختصاصی ارگونومیک برای بانوان شاغل در خطوط تولید و کارگاهها؛ وزن سبک و مقاوم در برابر لغزش و سایش.",
|
||||||
|
specs: ["قالب ارگونومیک زنانه", "وزن سبک", "ضد لغزش", "مقاوم به سایش"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-F05",
|
||||||
|
name: "چکمه صنعتی",
|
||||||
|
en: "INDUSTRIAL BOOT",
|
||||||
|
desc: "کاملاً نفوذناپذیر در برابر آب و مواد شیمیایی؛ زیره آجدار عمیق برای محیطهای مرطوب، آبروها و تماس با گل.",
|
||||||
|
specs: ["نفوذناپذیر", "مقاوم شیمیایی", "زیره آجدار عمیق", "ساق بلند"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: "protective-gloves",
|
||||||
|
code: "IP-C03",
|
||||||
|
name: "دستکشهای حفاظتی",
|
||||||
|
en: "PROTECTIVE GLOVES",
|
||||||
|
shortDesc:
|
||||||
|
"دستکشهای ضد برش، چرم، ضد اسید، ضد حلال و آرگون از برندهای استادکار، گیلان، فاکس و کالکان.",
|
||||||
|
fullDesc:
|
||||||
|
"دستکشهای حفاظت فردی شامل مدلهای ضد برش، چرم گاوی، ضد اسید، ضد حلال و آرگون. تأمین از برندهای معتبر استادکار، گیلان، فاکس و کالکان. هر مدل متناسب با نوع خطر محیط کار طراحی شده و مشخصات فنی دقیقی دارد.",
|
||||||
|
icon: "Hand",
|
||||||
|
products: [
|
||||||
|
{
|
||||||
|
code: "IP-G01",
|
||||||
|
name: "دستکش ضد برش",
|
||||||
|
en: "CUT-RESISTANT GLOVE",
|
||||||
|
desc: "کف مواد نیتریل، لاتکس یا PU بر روی الیاف مقاوم؛ مقاومت برشی بالا، مناسب فلزکاری، برشکاری و صنایع سنگین. قابل شستشو و چندبار مصرف.",
|
||||||
|
specs: ["پوشش نیتریل / لاتکس / PU", "مقاومت برشی بالا", "قابل شستشو", "چندبار مصرف"],
|
||||||
|
variants: ["استادکار", "گیلان", "فاکس", "کالکان"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-G02",
|
||||||
|
name: "دستکش چرم",
|
||||||
|
en: "LEATHER GLOVE",
|
||||||
|
desc: "چرم گاوی یا اشپالت ضخیم با مقاومت مکانیکی بالا در برابر سایش، جرقه و اجسام تیز و زبر.",
|
||||||
|
specs: ["چرم گاوی / اشپالت", "مقاومت مکانیکی بالا", "مقاوم به جرقه", "مقاوم به سایش"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-G03",
|
||||||
|
name: "دستکش ضد اسید",
|
||||||
|
en: "ACID-RESISTANT GLOVE",
|
||||||
|
desc: "لایههای ضخیم PVC یا نئوپرن برای محافظت کامل دست و ساعد در برابر انواع اسیدها، بازها و قلیاها.",
|
||||||
|
specs: ["PVC / نئوپرن", "محافظت دست و ساعد", "مقاوم به اسید و باز", "ساق بلند"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-G04",
|
||||||
|
name: "دستکش ضد حلال",
|
||||||
|
en: "SOLVENT-RESISTANT GLOVE",
|
||||||
|
desc: "نیتریل خالص و لاستیکهای مقاوم با مقاومت شیمیایی بالا در تماس با حلالها، تینر و مشتقات نفتی.",
|
||||||
|
specs: ["نیتریل خالص", "مقاوم شیمیایی", "مقاوم به تینر", "مقاوم به مشتقات نفتی"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-G05",
|
||||||
|
name: "دستکش آرگون",
|
||||||
|
en: "ARGON WELDING GLOVE",
|
||||||
|
desc: "چرم سبک و لطیف بزی با ساق بلند؛ نرمی و حس لامسه بالا برای جوشکاری ظریف آرگون (TIG) و مقاومت حرارتی.",
|
||||||
|
specs: ["چرم بزی سبک", "ساق بلند", "حس لامسه بالا", "مقاوم حرارتی"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: "safety-helmets",
|
||||||
|
code: "IP-C04",
|
||||||
|
name: "کلاه ایمنی",
|
||||||
|
en: "SAFETY HELMETS",
|
||||||
|
shortDesc:
|
||||||
|
"کلاههای مهندسی، کارگری، کار در ارتفاع، ضد حرارت، کپ و عایق برق با تنوع رنگی استاندارد HSE.",
|
||||||
|
fullDesc:
|
||||||
|
"انواع کلاه ایمنی صنعتی شامل مدلهای مهندسی، کارگری، کار در ارتفاع، ضد حرارت، کپ ضربهگیر نقابدار و عایق برق. با پوشش تنوع رنگی استاندارد HSE (سفید، زرد، آبی، قرمز، سبز)، یراق و رگلاژ داخلی قابل تنظیم و پوسته ضربهگیر مقاوم.",
|
||||||
|
icon: "HardHat",
|
||||||
|
products: [
|
||||||
|
{
|
||||||
|
code: "IP-H01",
|
||||||
|
name: "کلاه ایمنی مهندسی",
|
||||||
|
en: "ENGINEERING HELMET",
|
||||||
|
desc: "کلاه ایمنی مهندسی با پوسته HDPE مقاوم به ضربه، رگلاژ داخلی قابل تنظیم و قابلیت نصب هدفون و شیلد صورت.",
|
||||||
|
specs: ["پوسته HDPE", "رگلاژ قابل تنظیم", "قابلیت نصب لوازم جانبی", "رنگبندی HSE"],
|
||||||
|
variants: ["سفید", "زرد", "آبی", "قرمز", "سبز"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-H02",
|
||||||
|
name: "کلاه ایمنی کارگری",
|
||||||
|
en: "WORKER HELMET",
|
||||||
|
desc: "کلاه ایمنی استاندارد برای خطوط تولید و محیطهای کارگاهی؛ سبک و مقاوم با تهویه مناسب.",
|
||||||
|
specs: ["سبک و مقاوم", "تهویه مناسب", "تسمه چانه", "پوسته ضربهگیر"],
|
||||||
|
variants: ["سفید", "زرد", "آبی", "قرمز"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-H03",
|
||||||
|
name: "کلاه ایمنی ارتفاع",
|
||||||
|
en: "HEIGHT SAFETY HELMET",
|
||||||
|
desc: "کلاه ایمنی ویژه کار در ارتفاع با تسمه چانهبند مستحکم و سیستم نگهداری چندنقطهای برای داربستبندی و پروژههای عمرانی.",
|
||||||
|
specs: ["چانهبند مستحکم", "نگهداری چندنقطهای", "مقاوم به سقوط اجسام", "سبکوزن"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-H04",
|
||||||
|
name: "کلاه ضد حرارت",
|
||||||
|
en: "HEAT-RESISTANT HELMET",
|
||||||
|
desc: "مقاوم در برابر دماهای بالا و پاشش مواد مذاب؛ مناسب محیطهای ذوب، ریختهگری و کورههای صنعتی.",
|
||||||
|
specs: ["مقاوم حرارتی", "مقاوم به مواد مذاب", "پوسته تقویتشده", "عایق حرارتی"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-H05",
|
||||||
|
name: "کلاه کپ ایمنی",
|
||||||
|
en: "SAFETY CAP",
|
||||||
|
desc: "کلاه ایمنی نقابدار ضربهگیر با ظاهر شبیه کلاه معمولی؛ مناسب محیطهایی با ریسک برخورد سر ولی نیاز به ظاهر رسمی.",
|
||||||
|
specs: ["نقابدار", "ضربهگیر داخلی", "ظاهر رسمی", "سبکوزن"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-H06",
|
||||||
|
name: "کلاه عایق برق",
|
||||||
|
en: "ELECTRICALLY INSULATED HELMET",
|
||||||
|
desc: "عایق در برابر جریان الکتریکی، مناسب تأسیسات برق فشار قوی و کار با تجهیزات الکتریکی صنعتی.",
|
||||||
|
specs: ["عایق الکتریکی", "فشار قوی", "پوسته ABS / HDPE", "رگلاژ قابل تنظیم"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: "eye-protection",
|
||||||
|
code: "IP-C05",
|
||||||
|
name: "عینک ایمنی و صنعتی",
|
||||||
|
en: "EYE PROTECTION",
|
||||||
|
shortDesc:
|
||||||
|
"عینکهای مهندسی فریمدار، گاگلهای محافظتی و شیلدهای صورت با ویژگیهای ضد ضربه، ضد خش و UV.",
|
||||||
|
fullDesc:
|
||||||
|
"عینکهای ایمنی صنعتی شامل مدلهای مهندسی فریمدار، گاگلهای محافظتی کشدار کارگاهی و آزمایشگاهی و شیلدهای دودی و شفاف. مجهز به ویژگیهای ضد ضربه، ضد خش (Anti-Scratch)، ضد بخار (Anti-Fog) و فیلتر اشعه UV با قابلیت تنظیم فریم و دستهها.",
|
||||||
|
icon: "Glasses",
|
||||||
|
products: [
|
||||||
|
{
|
||||||
|
code: "IP-E01",
|
||||||
|
name: "عینک مهندسی فریمدار",
|
||||||
|
en: "FRAMED SAFETY GLASSES",
|
||||||
|
desc: "عینک ایمنی فریمدار با لنز ضد ضربه و پوشش UV400؛ سازگار با عینک طبی و قابلیت تنظیم فریم و دستهها.",
|
||||||
|
specs: ["ضد ضربه", "Anti-Scratch", "UV400", "قابل تنظیم"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-E02",
|
||||||
|
name: "گاگل محافظتی",
|
||||||
|
en: "PROTECTIVE GOGGLES",
|
||||||
|
desc: "گاگل محافظتی کشدار با تهویه ضد بخار؛ مناسب سنگزنی، تراشکاری و محیطهای شیمیایی و آزمایشگاهی.",
|
||||||
|
specs: ["Anti-Fog", "ضد ضربه", "تهویه مناسب", "کشدار ارگونومیک"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-E03",
|
||||||
|
name: "شیلد محافظ صورت",
|
||||||
|
en: "FACE SHIELD",
|
||||||
|
desc: "شیلد محافظ تمام صورت با لنز شفاف یا دودی؛ محافظت کامل صورت در برابر پاشش مواد، براده و ذرات.",
|
||||||
|
specs: ["محافظت تمام صورت", "لنز شفاف / دودی", "ضد ضربه", "سبکوزن"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: "hearing-protection",
|
||||||
|
code: "IP-C06",
|
||||||
|
name: "حفاظت شنوایی",
|
||||||
|
en: "HEARING PROTECTION",
|
||||||
|
shortDesc:
|
||||||
|
"ایرماف روگوشی با کاهش ۲۸ دسیبل و ایرپلاگهای اسفنجی و سیلیکونی برای محیطهای پرسروصدا.",
|
||||||
|
fullDesc:
|
||||||
|
"تجهیزات حفاظت شنوایی شامل ایرماف (محافظ روگوشی) با کاهش تراز صدا تا ۲۸ دسیبل و ایرپلاگ (داخلگوشی) در مدلهای اسفنجی فرمگیر و پلهای سیلیکونی. مناسب محیطهای با آلودگی صوتی بالای ۸۵ دسیبل، کمپرسورخانهها و خطوط تولید سنگین.",
|
||||||
|
icon: "Ear",
|
||||||
|
products: [
|
||||||
|
{
|
||||||
|
code: "IP-HP01",
|
||||||
|
name: "ایرماف محافظ",
|
||||||
|
en: "PROTECTIVE EARMUFF",
|
||||||
|
desc: "محافظ روگوشی با کاهش تراز صدا تا ۲۸ دسیبل؛ هدبند قابل تنظیم، سبک و بالشتکهای نرم جهت شیفتهای کاری طولانی.",
|
||||||
|
specs: ["کاهش ۲۸ دسیبل", "هدبند قابل تنظیم", "بالشتک نرم", "سبکوزن"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-HP02",
|
||||||
|
name: "ایرپلاگ",
|
||||||
|
en: "EARPLUG",
|
||||||
|
desc: "محافظت در برابر نویزهای تیز محیطی؛ مدلهای اسفنجی فرمگیر و پلهای سیلیکونی بنددار، یکبار مصرف و چندبار مصرف.",
|
||||||
|
specs: ["اسفنجی فرمگیر", "سیلیکونی پلهای", "بنددار", "یکبار / چندبار مصرف"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: "respiratory-protection",
|
||||||
|
code: "IP-C07",
|
||||||
|
name: "حفاظت تنفسی",
|
||||||
|
en: "RESPIRATORY PROTECTION",
|
||||||
|
shortDesc:
|
||||||
|
"ماسکهای نیمصورت، تمامصورت، شیمیایی، P2/P3 و فیلتردار برای محافظت در برابر گازها و ذرات.",
|
||||||
|
fullDesc:
|
||||||
|
"تجهیزات حفاظت تنفسی شامل ماسکهای نیمصورت، تمامصورت، شیمیایی با کارتریج تخصصی، ماسکهای فیلتردار P2/P3 برای ذرات میکرونی، ماسکهای با فیلتر تعویضی اقتصادی و ماسکهای سهلایه بهداشتی. مناسب کار با حلالهای فرار، غبارهای معدنی، رنگپاشی و خطوط شیمیایی.",
|
||||||
|
icon: "ShieldPlus",
|
||||||
|
products: [
|
||||||
|
{
|
||||||
|
code: "IP-R01",
|
||||||
|
name: "ماسک نیمصورت",
|
||||||
|
en: "HALF-FACE RESPIRATOR",
|
||||||
|
desc: "مناسب فضاهای صنعتی با آلودگی و گازهای با غلظت متوسط؛ سبک و راحت برای استفاده طولانیمدت.",
|
||||||
|
specs: ["پوشش بینی و دهان", "فیلتر قابل تعویض", "بند قابل تنظیم", "سبکوزن"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-R02",
|
||||||
|
name: "ماسک تمامصورت",
|
||||||
|
en: "FULL-FACE RESPIRATOR",
|
||||||
|
desc: "پوشش همزمان چشم و تنفس جهت کار با مواد سمی و بخارات خورنده پرخطر؛ شیشه ضد ضربه و ضد بخار.",
|
||||||
|
specs: ["محافظت چشم و تنفس", "شیشه ضد ضربه", "Anti-Fog", "فیلتر چندمنظوره"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-R03",
|
||||||
|
name: "ماسک شیمیایی",
|
||||||
|
en: "CHEMICAL RESPIRATOR",
|
||||||
|
desc: "مجهز به کارتریجهای تخصصی فیلتراسیون بخارات آلی و گازهای اسیدی؛ مناسب صنایع شیمیایی و پتروشیمی.",
|
||||||
|
specs: ["کارتریج تخصصی", "فیلتر بخارات آلی", "فیلتر گازهای اسیدی", "آببندی کامل"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-R04",
|
||||||
|
name: "ماسک فیلتردار P2/P3",
|
||||||
|
en: "P2/P3 PARTICULATE MASK",
|
||||||
|
desc: "محافظت اختصاصی در برابر ذرات میکرونی، گردوغبار و میستهای مایع؛ مناسب معادن و محیطهای پرگردوغبار.",
|
||||||
|
specs: ["فیلتر P2 / P3", "ذرات میکرونی", "گردوغبار و میست", "سوپاپ بازدمی"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-R05",
|
||||||
|
name: "ماسک با فیلتر تعویضی",
|
||||||
|
en: "REPLACEABLE FILTER MASK",
|
||||||
|
desc: "قابلیت تعویض مدیا و استفاده اقتصادی طولانیمدت؛ مناسب مصارف روزمره صنعتی.",
|
||||||
|
specs: ["فیلتر تعویضی", "اقتصادی", "استفاده طولانیمدت", "آببندی مطمئن"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-R06",
|
||||||
|
name: "ماسک سهلایه بهداشتی",
|
||||||
|
en: "THREE-LAYER MASK",
|
||||||
|
desc: "مناسب مراجعات روزمره و فضاهای عمومی با غلظت پایین آلودگی؛ سبک و یکبار مصرف.",
|
||||||
|
specs: ["سهلایه", "یکبار مصرف", "سبکوزن", "بهداشتی"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slug: "traffic-equipment",
|
||||||
|
code: "IP-C08",
|
||||||
|
name: "تجهیزات ترافیکی و ایمنی محیطی",
|
||||||
|
en: "TRAFFIC & SITE SAFETY",
|
||||||
|
shortDesc:
|
||||||
|
"مخروط، نیوجرسی، استوانه، سرعتگیر، آینه محدب و سایر تجهیزات ایمنسازی محوطه صنعتی.",
|
||||||
|
fullDesc:
|
||||||
|
"تجهیزات ترافیکی و ایمنی محیطی شامل مخروط ترافیکی، نیوجرسی پلاستیکی، استوانه و بولارد، چراغ و تابلوهای هشداردهنده، باتوم ترافیکی، نوارهای خطر، سرعتگیر لاستیکی، آینههای محدب، محافظ گوشه ستون و گلمیخ خورشیدی. مناسب ایمنسازی محوطه کارخانه، انبارها، رمپها و پارکینگها.",
|
||||||
|
icon: "TriangleAlert",
|
||||||
|
products: [
|
||||||
|
{
|
||||||
|
code: "IP-T01",
|
||||||
|
name: "مخروط ترافیکی",
|
||||||
|
en: "TRAFFIC CONE",
|
||||||
|
desc: "PVC انعطافپذیر با شبرنگهای استاندارد روز و شب؛ مقاوم در برابر واژگونی و ضربه خودرو.",
|
||||||
|
specs: ["PVC انعطافپذیر", "شبرنگ استاندارد", "مقاوم به واژگونی", "قابل رؤیت شبانه"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-T02",
|
||||||
|
name: "نیوجرسی پلاستیکی",
|
||||||
|
en: "NEW JERSEY BARRIER",
|
||||||
|
desc: "بدنه پلیاتیلنی مدولار قابل اتصال با قابلیت پرشوندگی با آب یا ماسه جهت تثبیت و ایجاد حائل.",
|
||||||
|
specs: ["پلیاتیلن مدولار", "قابل اتصال", "پرشدنی با آب/ماسه", "مقاوم UV"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-T03",
|
||||||
|
name: "استوانه ترافیکی",
|
||||||
|
en: "TRAFFIC BOLLARD",
|
||||||
|
desc: "پلیاورتان ارتجاعی انعطافپذیر پس از ضربه؛ مجهز به حلقههای شبرنگ هشدار برای تفکیک مسیر.",
|
||||||
|
specs: ["پلیاورتان ارتجاعی", "بازگشت پس از ضربه", "شبرنگ هشدار", "نصب آسان"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-T04",
|
||||||
|
name: "چراغ و تابلوی هشدار",
|
||||||
|
en: "WARNING LIGHT & SIGN",
|
||||||
|
desc: "چراغهای چشمکزن سولار، تابلوی دستی ایست/حرکت و تابلوهای علائم هشداردهنده ترافیکی.",
|
||||||
|
specs: ["سولار / باتری", "LED چشمکزن", "تابلوی Stop/Go", "علائم استاندارد"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-T05",
|
||||||
|
name: "باتوم ترافیکی",
|
||||||
|
en: "TRAFFIC BATON",
|
||||||
|
desc: "باتوم LED دار دستی جهت هدایت ترافیک در شب و محیطهای کمنور؛ سبک و ارگونومیک.",
|
||||||
|
specs: ["LED داخلی", "قابل رؤیت شبانه", "سبکوزن", "ارگونومیک"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-T06",
|
||||||
|
name: "نوار خطر",
|
||||||
|
en: "CAUTION TAPE",
|
||||||
|
desc: "نوار شطرنجی و خطکشی زرد/قرمز هشدار محوطه گودبرداری و مناطق خطرناک با رولهای بازتابنده نور.",
|
||||||
|
specs: ["زرد / قرمز هشدار", "بازتابنده نور", "رول بلند", "مقاوم به پارگی"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-T07",
|
||||||
|
name: "سرعتگیر لاستیکی",
|
||||||
|
en: "RUBBER SPEED BUMP",
|
||||||
|
desc: "قطعات لاستیکی سنگین مدولار با مقاومت وزنی بالا و المانهای بازتابش شبانه؛ نصب آسان.",
|
||||||
|
specs: ["لاستیکی مدولار", "مقاومت وزنی بالا", "بازتاب شبانه", "نصب پیچی"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-T08",
|
||||||
|
name: "آینه محدب ترافیکی",
|
||||||
|
en: "CONVEX TRAFFIC MIRROR",
|
||||||
|
desc: "آینه نشکن فریمدار و کلاهدار جهت پوشش نقاط کور پیچها، تقاطعها و درب انبار.",
|
||||||
|
specs: ["نشکن", "فریمدار و کلاهدار", "پوشش نقاط کور", "مقاوم به آب و باد"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-T09",
|
||||||
|
name: "محافظ گوشه ستون",
|
||||||
|
en: "CORNER GUARD",
|
||||||
|
desc: "ضربهگیر لاستیکی شبرنگدار جهت نصب روی ستونها برای ممانعت از آسیب لیفتراک و خودروهای سنگین.",
|
||||||
|
specs: ["لاستیکی ضربهگیر", "شبرنگدار", "نصب دیواری", "محافظ ستون"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "IP-T10",
|
||||||
|
name: "گلمیخ ترافیکی خورشیدی",
|
||||||
|
en: "SOLAR ROAD STUD",
|
||||||
|
desc: "بدنه آلومینیومی مستحکم مجهز به پنل خورشیدی و LED جهت تعیین مسیر و خطکشی شبانه.",
|
||||||
|
specs: ["آلومینیوم مستحکم", "پنل خورشیدی", "LED", "مقاوم به عبور خودرو"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export const findCategory = (slug: string): Category | undefined =>
|
||||||
|
CATEGORIES.find((c) => c.slug === slug);
|
||||||
|
|
||||||
|
export const categorySlugs: readonly string[] = CATEGORIES.map((c) => c.slug);
|
||||||
@@ -63,6 +63,37 @@ export const serviceSchema = (opts: {
|
|||||||
provider: { "@id": `${s.url}/#organization` },
|
provider: { "@id": `${s.url}/#organization` },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const categoryPageSchema = (category: {
|
||||||
|
name: string;
|
||||||
|
en: string;
|
||||||
|
fullDesc: string;
|
||||||
|
slug: string;
|
||||||
|
products: { name: string; desc: string }[];
|
||||||
|
}) =>
|
||||||
|
clean({
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "CollectionPage",
|
||||||
|
"@id": `${s.url}/categories/${category.slug}`,
|
||||||
|
name: category.name,
|
||||||
|
description: category.fullDesc,
|
||||||
|
url: abs(`/categories/${category.slug}`),
|
||||||
|
isPartOf: { "@id": `${s.url}/#website` },
|
||||||
|
provider: { "@id": `${s.url}/#organization` },
|
||||||
|
mainEntity: {
|
||||||
|
"@type": "ItemList",
|
||||||
|
numberOfItems: category.products.length,
|
||||||
|
itemListElement: category.products.map((p, i) => ({
|
||||||
|
"@type": "ListItem",
|
||||||
|
position: i + 1,
|
||||||
|
item: {
|
||||||
|
"@type": "Product",
|
||||||
|
name: p.name,
|
||||||
|
description: p.desc,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/** Serialize JSON-LD safely for an inline <script> (escape "<"). */
|
/** Serialize JSON-LD safely for an inline <script> (escape "<"). */
|
||||||
export const toJsonLd = (data: Json) =>
|
export const toJsonLd = (data: Json) =>
|
||||||
JSON.stringify(data).replace(/</g, "\\u003c");
|
JSON.stringify(data).replace(/</g, "\\u003c");
|
||||||
|
|||||||
Reference in New Issue
Block a user