feat: add accessory detail and index pages with dynamic routing and metadata
CI/CD / test-and-build (push) Waiting to run
CI/CD / deploy (push) Blocked by required conditions

This commit is contained in:
Najjar\NajjarV02
2026-05-21 16:22:05 +04:00
parent 5271914b16
commit 2d32a1e722
10 changed files with 1124 additions and 51 deletions
+274 -36
View File
@@ -1,68 +1,306 @@
import type { Metadata } from 'next';
import Link from 'next/link';
import ChevronRight from 'lucide-react/dist/esm/icons/chevron-right';
import { Navbar } from '@/components/Navbar';
import { FooterAndContact } from '@/components/FooterAndContact';
import { CatalogClient } from './CatalogClient';
import { AccessoriesShowcase } from '@/components/robotics/AccessoriesShowcase';
import { RoboticsSplineShowcase } from '@/components/sections/robotics-spline-showcase';
import { CTAButton } from '@/components/ui/CTAButton';
import { ROBOTS } from '@/data/robots';
import { ACCESSORIES } from '@/data/accessories';
export const metadata: Metadata = {
title: 'Robots Catalog YS Lootah Robotics Dubai',
title: 'Robots Catalog · Unitree & Pudu in UAE | YS Lootah Robotics',
description:
'Explore selected humanoid, quadruped, industrial, service, delivery, hospitality, and cleaning robots — plus dexterous hands, arms, sensors, and accessories — from Unitree and Pudu available in the UAE through YS Lootah Robotics.',
alternates: { canonical: '/robots/' },
};
const unitreeCount = ROBOTS.filter((r) => r.brand === 'unitree').length;
const puduCount = ROBOTS.filter((r) => r.brand === 'pudu').length;
const HERO_STATS: { value: string; label: string }[] = [
{ value: String(ROBOTS.length), label: 'Robot models' },
{ value: String(ACCESSORIES.length), label: 'Accessories' },
{ value: String(unitreeCount), label: 'Unitree' },
{ value: String(puduCount), label: 'Pudu' },
];
export default function RobotsPage() {
return (
<>
<Navbar />
<main>
<div style={{ paddingTop: 'clamp(5rem, 8vw, 7rem)' }}>
<RoboticsSplineShowcase />
</div>
<div
className="container-wide"
style={{
display: 'flex',
flexDirection: 'column',
gap: 'clamp(2.5rem, 5vw, 4rem)',
paddingTop: 'clamp(3rem, 6vw, 5rem)',
paddingBottom: 'clamp(4rem, 8vw, 6rem)',
}}
>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', maxWidth: 760 }}>
<span className="eyebrow">Catalog · Filter & Browse</span>
<h2 style={{ margin: 0, fontSize: 'clamp(1.6rem, 3.6vw, 2.4rem)', fontWeight: 400, lineHeight: 1.1, letterSpacing: '-0.02em' }}>
<span className="text-gradient" style={{ fontWeight: 500 }}>
{ROBOTS.length} robots across the UAE portfolio.
</span>
</h2>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: 'clamp(0.95rem, 2vw, 1.05rem)', lineHeight: 1.7 }}>
Filter by brand or category, then request a UAE quotation or book a live demo at our Dubai showroom.
</p>
</div>
<main className="rb-main">
<div className="container-wide rb-stack">
{/* BREADCRUMBS */}
<nav aria-label="Breadcrumb" className="rb-crumbs">
<ol>
<li><Link href="/">Home</Link></li>
<li aria-hidden><ChevronRight size={12} /></li>
<li aria-current="page">Robots</li>
</ol>
</nav>
<CatalogClient />
{/* HERO */}
<section className="rb-hero" aria-labelledby="rb-hero-title">
<div className="rb-hero-glow" aria-hidden />
<div className="rb-hero-glow-b" aria-hidden />
<div className="rb-hero-grid" aria-hidden />
<section id="accessories" style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem', scrollMarginTop: 'clamp(80px, 12vh, 120px)' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.85rem', maxWidth: 760 }}>
<div className="rb-hero-inner">
<div className="rb-hero-copy">
<span className="eyebrow rb-hero-eyebrow">
<span className="rb-dot" />
Catalog · UAE Portfolio · Dubai
</span>
<h1 id="rb-hero-title" className="rb-hero-title">
<span className="text-gradient">
{ROBOTS.length} robots + {ACCESSORIES.length} accessories.
</span>
</h1>
<p className="rb-hero-sub">
Selected Unitree and Pudu Robotics platforms — humanoid, quadruped, industrial, delivery, service, and cleaning — plus dexterous hands, arms, sensors, and building IoT modules. Available in the UAE through YS Lootah Robotics.
</p>
<div className="rb-hero-actions">
<CTAButton href="#catalog" variant="primary" size="lg" arrow="right">
Browse the Catalog
</CTAButton>
<CTAButton href="/book-demo/" variant="secondary" size="lg" arrow="right">
Book a Live Demo
</CTAButton>
</div>
<ul className="rb-jump" role="list" aria-label="Quick links">
<li><a href="#catalog">Robots</a></li>
<li><a href="#accessories">Accessories</a></li>
<li><Link href="/configure/">Configure G1</Link></li>
<li><Link href="/brands/">Brands</Link></li>
</ul>
</div>
<aside className="rb-hero-stats" aria-label="Catalog stats">
{HERO_STATS.map((s) => (
<div key={s.label} className="rb-stat">
<span className="rb-stat-value">{s.value}</span>
<span className="rb-stat-label">{s.label}</span>
</div>
))}
</aside>
</div>
</section>
{/* CATALOG */}
<section id="catalog" className="rb-catalog">
<header className="rb-section-head">
<span className="eyebrow">Filter &amp; Browse</span>
<h2>
<span className="text-gradient">{ROBOTS.length} robots across the UAE portfolio.</span>
</h2>
<p>Filter by brand or category, then request a UAE quotation or book a live demo at our Dubai showroom.</p>
</header>
<CatalogClient />
</section>
{/* ACCESSORIES */}
<section id="accessories" className="rb-accessories">
<header className="rb-section-head">
<span className="eyebrow">Add-ons · Accessories</span>
<h2 style={{ margin: 0, fontSize: 'clamp(1.5rem, 3.4vw, 2.2rem)', fontWeight: 400, lineHeight: 1.1, letterSpacing: '-0.02em' }}>
<span className="text-gradient" style={{ fontWeight: 500 }}>
<h2>
<span className="text-gradient">
{ACCESSORIES.length} accessories — dexterous hands, arms, sensors, IoT modules.
</span>
</h2>
<p style={{ margin: 0, color: '#DEE0F0', fontSize: 'clamp(0.92rem, 2vw, 1.02rem)', lineHeight: 1.65 }}>
Robot platforms get their full capability from accessories. Browse Unitree dexterous hands and arms, perception sensors, and Pudu dispatch, docking, modular attachments, and building IoT modules.
</p>
</div>
<p>Robot platforms get their full capability from accessories. Each one has its own detail page with features, compatibility, and inquiry form.</p>
</header>
<AccessoriesShowcase />
</section>
</div>
</main>
<FooterAndContact />
<style>{`
.rb-main {
padding-top: clamp(5rem, 9vw, 7rem);
padding-bottom: clamp(3rem, 6vw, 5rem);
}
.rb-stack {
display: flex;
flex-direction: column;
gap: clamp(2.5rem, 5vw, 4rem);
}
/* BREADCRUMBS */
.rb-crumbs ol {
list-style: none; margin: 0; padding: 0;
display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase;
color: #8891C7;
}
.rb-crumbs a { color: #8891C7; text-decoration: none; transition: color 0.25s; }
.rb-crumbs a:hover { color: #FFFFFF; }
.rb-crumbs li[aria-current="page"] { color: #FFFFFF; }
.rb-crumbs li[aria-hidden] { display: inline-flex; align-items: center; color: #4a4f63; }
/* HERO */
.rb-hero {
position: relative; overflow: hidden;
border-radius: 26px;
border: 1px solid rgba(74, 102, 216, 0.20);
background:
radial-gradient(ellipse 70% 100% at 0% 0%, rgba(58, 85, 196, 0.20), transparent 55%),
radial-gradient(ellipse 60% 80% at 100% 100%, rgba(136, 145, 199, 0.16), transparent 60%),
linear-gradient(135deg, rgba(14, 13, 22, 0.95), rgba(6, 6, 10, 0.97));
box-shadow: 0 30px 90px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.rb-hero-glow {
position: absolute; width: 580px; height: 580px; border-radius: 999px;
top: -220px; right: -180px;
background: radial-gradient(circle, rgba(120, 140, 255, 0.34), transparent 70%);
filter: blur(120px); opacity: 0.55; pointer-events: none;
}
.rb-hero-glow-b {
position: absolute; width: 460px; height: 460px; border-radius: 999px;
bottom: -200px; left: -150px;
background: radial-gradient(circle, rgba(74, 102, 216, 0.30), transparent 70%);
filter: blur(110px); opacity: 0.45; pointer-events: none;
}
.rb-hero-grid {
position: absolute; inset: 0;
background:
linear-gradient(rgba(74, 102, 216, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(74, 102, 216, 0.05) 1px, transparent 1px);
background-size: 56px 56px;
mask-image: radial-gradient(ellipse 70% 90% at 30% 40%, #000 25%, transparent 80%);
-webkit-mask-image: radial-gradient(ellipse 70% 90% at 30% 40%, #000 25%, transparent 80%);
pointer-events: none;
}
.rb-hero-inner {
position: relative; z-index: 1;
display: grid; grid-template-columns: minmax(0, 1fr);
gap: clamp(1.75rem, 3.5vw, 2.75rem);
padding: clamp(1.8rem, 4vw, 3.25rem);
align-items: center;
}
.rb-hero-copy { display: flex; flex-direction: column; gap: 1rem; max-width: 680px; min-width: 0; }
.rb-hero-eyebrow {
display: inline-flex; align-items: center; gap: 0.55rem;
width: fit-content;
}
.rb-dot {
width: 7px; height: 7px; border-radius: 999px; background: #DEE0F0;
box-shadow: 0 0 14px rgba(222, 224, 240, 0.85);
}
.rb-hero-title {
margin: 0;
font-size: clamp(2rem, 5vw, 3.2rem);
font-weight: 300; letter-spacing: -0.03em; line-height: 1.05;
color: #FFFFFF;
}
.rb-hero-title :global(.text-gradient) { font-weight: 500; }
.rb-hero-sub {
margin: 0; color: #DEE0F0;
font-size: clamp(0.95rem, 1.8vw, 1.08rem);
line-height: 1.65;
max-width: 600px;
}
.rb-hero-actions {
display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0.5rem;
}
.rb-jump {
list-style: none; margin: 0.5rem 0 0; padding: 0;
display: flex; flex-wrap: wrap; gap: 0.4rem;
}
.rb-jump li a {
display: inline-flex; align-items: center;
padding: 0.45rem 0.85rem;
border-radius: 999px;
border: 1px solid rgba(222, 224, 240, 0.14);
background: rgba(20, 19, 26, 0.6);
color: #DEE0F0;
font-size: 0.7rem; font-weight: 700;
letter-spacing: 0.12em; text-transform: uppercase;
text-decoration: none;
transition: all 0.25s ease;
}
.rb-jump li a:hover {
color: #FFFFFF;
border-color: rgba(74, 102, 216, 0.5);
background: rgba(28, 27, 38, 0.7);
}
/* HERO STATS */
.rb-hero-stats {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.6rem;
}
.rb-stat {
position: relative;
display: flex; flex-direction: column; gap: 0.3rem;
padding: 0.95rem 1rem;
border-radius: 16px;
border: 1px solid rgba(120, 140, 255, 0.22);
background:
linear-gradient(135deg, rgba(80, 110, 255, 0.12), rgba(255, 255, 255, 0.03));
overflow: hidden;
min-height: 86px;
transition: border-color 0.3s, transform 0.3s, box-shadow 0.3s;
}
.rb-stat::before {
content: ''; position: absolute;
top: 0; right: 14px; width: 24px; height: 1px;
background: linear-gradient(90deg, transparent, rgba(180, 195, 255, 0.55));
}
.rb-stat:hover {
border-color: rgba(120, 140, 255, 0.45);
transform: translateY(-1px);
box-shadow: 0 10px 22px rgba(0, 0, 0, 0.38), 0 0 18px rgba(74, 102, 216, 0.18);
}
.rb-stat-value {
font-size: clamp(1.55rem, 2.6vw, 2rem);
font-weight: 500; letter-spacing: -0.025em; line-height: 1;
background: linear-gradient(180deg, #FFFFFF, #B5BDDB);
-webkit-background-clip: text; background-clip: text; color: transparent;
}
.rb-stat-label {
font-size: 0.64rem; letter-spacing: 0.22em;
text-transform: uppercase; font-weight: 700; color: #A6B2D8;
}
@media (min-width: 920px) {
.rb-hero-inner { grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); }
}
/* SECTION HEADERS */
.rb-catalog,
.rb-accessories {
display: flex; flex-direction: column; gap: clamp(1.25rem, 2.5vw, 1.75rem);
scroll-margin-top: clamp(80px, 12vh, 120px);
}
.rb-section-head {
display: flex; flex-direction: column; gap: 0.6rem;
max-width: 760px;
}
.rb-section-head h2 {
margin: 0;
font-size: clamp(1.5rem, 3vw, 2.1rem);
font-weight: 400; letter-spacing: -0.02em; line-height: 1.15;
color: #FFFFFF;
}
.rb-section-head h2 :global(.text-gradient) { font-weight: 500; }
.rb-section-head p {
margin: 0; color: #DEE0F0;
font-size: clamp(0.92rem, 2vw, 1.02rem);
line-height: 1.65;
}
@media (max-width: 520px) {
.rb-hero-actions .cta-btn { width: 100%; justify-content: space-between; }
}
`}</style>
</>
);
}