Add the Kaman Cable Next.js storefront with Meshkee catalog, blog, auth, and static-image slots.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-31 17:01:01 +03:30
co-authored by Cursor
commit 51fb9f6a26
84 changed files with 12999 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
import type { ReactNode } from "react";
import CallbackForm from "@/components/CallbackForm";
import { site, socials } from "@/data/site";
function InstagramIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden>
<rect x="3.5" y="3.5" width="17" height="17" rx="5" stroke="currentColor" strokeWidth="1.7" />
<circle cx="12" cy="12" r="4" stroke="currentColor" strokeWidth="1.7" />
<circle cx="17.4" cy="6.6" r="1" fill="currentColor" />
</svg>
);
}
function TelegramIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden>
<path
d="M20.5 4.5 3.8 11.2c-1.1.4-1.1 1.1-.2 1.4l4.3 1.3 1.7 5.2c.2.7.1.9.8.9.4 0 .6-.2.8-.4l2.4-2.3 4.5 3.3c.8.5 1.4.2 1.6-.8L21.7 5.7c.3-1.1-.4-1.6-1.2-1.2Z"
stroke="currentColor"
strokeWidth="1.4"
strokeLinejoin="round"
/>
</svg>
);
}
function LinkedinIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden>
<rect x="3.5" y="3.5" width="17" height="17" rx="2.5" stroke="currentColor" strokeWidth="1.7" />
<path d="M8 10.5V16.5" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" />
<circle cx="8" cy="8" r="0.9" fill="currentColor" />
<path
d="M12 16.5v-3.6c0-1.2.8-2 1.9-2s1.9.8 1.9 2v3.6"
stroke="currentColor"
strokeWidth="1.7"
strokeLinecap="round"
/>
</svg>
);
}
function EmailIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden>
<rect x="3.5" y="5.5" width="17" height="13" rx="2" stroke="currentColor" strokeWidth="1.7" />
<path d="M4.5 7.5 12 13l7.5-5.5" stroke="currentColor" strokeWidth="1.7" strokeLinejoin="round" />
</svg>
);
}
function PhoneIcon() {
return (
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden>
<path
d="M7.2 3.8h2.6l1.2 3-1.6 1.1a12.5 12.5 0 0 0 5.7 5.7l1.1-1.6 3 1.2v2.6c0 .7-.6 1.4-1.3 1.5-2 .3-6.3-.2-10.1-4S5.4 6.9 5.7 4.9c.1-.7.8-1.1 1.5-1.1Z"
stroke="currentColor"
strokeWidth="1.6"
strokeLinejoin="round"
/>
</svg>
);
}
const icons: Record<string, () => ReactNode> = {
instagram: InstagramIcon,
telegram: TelegramIcon,
linkedin: LinkedinIcon,
email: EmailIcon,
};
export default function ContactBar() {
return (
<section className="contact-bar" id="contact" aria-label="تماس با ما">
<div className="container contact-bar-frame">
<div className="contact-bar-inner">
<div className="contact-bar-phone">
<span className="contact-bar-kicker">تماس با ما</span>
<a href={`tel:${site.phone.replace(/-/g, "")}`} className="contact-bar-number">
<span dir="ltr">{site.phone}</span>
<PhoneIcon />
</a>
</div>
<div className="contact-socials">
{socials.map((item) => {
const Icon = icons[item.id];
return (
<a
key={item.id}
href={item.href}
className="contact-social"
target={item.href.startsWith("mailto:") ? undefined : "_blank"}
rel="noopener noreferrer"
aria-label={item.label}
title={item.label}
>
{Icon ? <Icon /> : item.labelEn}
</a>
);
})}
</div>
</div>
<div className="contact-bar-subscribe">
<p className="contact-bar-subscribe-text">شماره تماس خود را بگذارید، ما با شما تماس میگیریم.</p>
<CallbackForm />
</div>
</div>
</section>
);
}