@aws505/sheetsite 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +185 -40
- package/dist/components/index.js +932 -60
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +916 -60
- package/dist/components/index.mjs.map +1 -1
- package/dist/index.js +195 -62
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +185 -62
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/index.ts +15 -0
- package/src/components/layout/Header.tsx +1 -0
- package/src/components/sections/BeforeAfter.tsx +345 -0
- package/src/components/sections/FAQ.tsx +3 -3
- package/src/components/sections/Gallery.tsx +104 -4
- package/src/components/sections/Hero.tsx +19 -3
- package/src/components/sections/Menu.tsx +312 -0
- package/src/components/sections/Services.tsx +3 -3
- package/src/components/sections/Testimonials.tsx +1 -1
- package/src/components/sections/TrustBadges.tsx +283 -0
- package/src/components/ui/AnimatedSection.tsx +136 -0
- package/src/components/ui/FloatingClaimBanner.tsx +160 -0
package/dist/components/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
9
|
var __export = (target, all) => {
|
|
8
10
|
for (var name in all)
|
|
@@ -16,11 +18,21 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
18
|
}
|
|
17
19
|
return to;
|
|
18
20
|
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
19
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
30
|
|
|
21
31
|
// src/components/index.ts
|
|
22
32
|
var components_exports = {};
|
|
23
33
|
__export(components_exports, {
|
|
34
|
+
AnimatedSection: () => AnimatedSection,
|
|
35
|
+
BeforeAfter: () => BeforeAfter,
|
|
24
36
|
BriefcaseIcon: () => BriefcaseIcon,
|
|
25
37
|
Button: () => Button,
|
|
26
38
|
ButtonLink: () => ButtonLink,
|
|
@@ -36,6 +48,7 @@ __export(components_exports, {
|
|
|
36
48
|
ClockIcon: () => ClockIcon,
|
|
37
49
|
FAQ: () => FAQ,
|
|
38
50
|
FacebookIcon: () => FacebookIcon,
|
|
51
|
+
FloatingClaimBanner: () => FloatingClaimBanner,
|
|
39
52
|
Footer: () => Footer,
|
|
40
53
|
Gallery: () => Gallery,
|
|
41
54
|
Header: () => Header,
|
|
@@ -46,13 +59,16 @@ __export(components_exports, {
|
|
|
46
59
|
InstagramIcon: () => InstagramIcon,
|
|
47
60
|
MailIcon: () => MailIcon,
|
|
48
61
|
MapPinIcon: () => MapPinIcon,
|
|
62
|
+
Menu: () => Menu,
|
|
49
63
|
MenuIcon: () => MenuIcon,
|
|
50
64
|
PhoneIcon: () => PhoneIcon,
|
|
51
65
|
ScissorsIcon: () => ScissorsIcon,
|
|
52
66
|
Services: () => Services,
|
|
53
67
|
SparklesIcon: () => SparklesIcon,
|
|
68
|
+
StaggerContainer: () => StaggerContainer,
|
|
54
69
|
StarIcon: () => StarIcon,
|
|
55
70
|
Testimonials: () => Testimonials,
|
|
71
|
+
TrustBadges: () => TrustBadges,
|
|
56
72
|
UtensilsIcon: () => UtensilsIcon,
|
|
57
73
|
WrenchIcon: () => WrenchIcon,
|
|
58
74
|
XIcon: () => XIcon,
|
|
@@ -536,6 +552,7 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
|
536
552
|
var defaultNavigation = [
|
|
537
553
|
{ label: "Home", href: "/" },
|
|
538
554
|
{ label: "Services", href: "/#services" },
|
|
555
|
+
{ label: "Gallery", href: "/#gallery" },
|
|
539
556
|
{ label: "Hours", href: "/#hours" },
|
|
540
557
|
{ label: "Reviews", href: "/#reviews" },
|
|
541
558
|
{ label: "FAQ", href: "/#faq" }
|
|
@@ -794,6 +811,15 @@ function Footer({
|
|
|
794
811
|
|
|
795
812
|
// src/components/sections/Hero.tsx
|
|
796
813
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
814
|
+
var defaultTrustSignals = {
|
|
815
|
+
salon: ["Expert Stylists", "Walk-Ins Welcome", "Quality Products"],
|
|
816
|
+
restaurant: ["Fresh Ingredients", "Family Recipes", "Friendly Service"],
|
|
817
|
+
repair: ["Certified Technicians", "Honest Estimates", "Quality Parts"],
|
|
818
|
+
tailor: ["Expert Craftsmanship", "Perfect Fit Guaranteed", "Quick Turnaround"],
|
|
819
|
+
professional: ["Quality Work", "Fair Prices", "Fast Service"],
|
|
820
|
+
retail: ["Quality Products", "Great Selection", "Friendly Service"],
|
|
821
|
+
default: ["Quality Work", "Fair Prices", "Fast Service"]
|
|
822
|
+
};
|
|
797
823
|
function Hero({
|
|
798
824
|
business,
|
|
799
825
|
variant = "centered",
|
|
@@ -802,8 +828,11 @@ function Hero({
|
|
|
802
828
|
todayHours,
|
|
803
829
|
backgroundImage,
|
|
804
830
|
overlay = true,
|
|
805
|
-
className = ""
|
|
831
|
+
className = "",
|
|
832
|
+
trustSignals
|
|
806
833
|
}) {
|
|
834
|
+
const businessType = business.type || "default";
|
|
835
|
+
const signals = trustSignals || defaultTrustSignals[businessType] || defaultTrustSignals.default;
|
|
807
836
|
const bgStyle = backgroundImage ? { backgroundImage: `url(${backgroundImage})` } : void 0;
|
|
808
837
|
const handleCallClick = () => {
|
|
809
838
|
if (business.phone) {
|
|
@@ -883,8 +912,8 @@ function Hero({
|
|
|
883
912
|
) }),
|
|
884
913
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "text-4xl md:text-5xl lg:text-6xl font-bold text-white mb-4", children: business.name }),
|
|
885
914
|
business.tagline && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "text-xl md:text-2xl text-white/90 mb-6", children: business.tagline }),
|
|
886
|
-
business.aboutShort && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className:
|
|
887
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className:
|
|
915
|
+
business.aboutShort && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: `text-lg text-white/80 mb-8 max-w-xl ${variant === "centered" ? "mx-auto" : ""}`, children: business.aboutShort }),
|
|
916
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `flex flex-wrap gap-4 mb-8 ${variant === "centered" ? "justify-center" : ""}`, children: signals.map((signal) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center text-white/90", children: [
|
|
888
917
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "w-5 h-5 text-accent-400 mr-2", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
889
918
|
"path",
|
|
890
919
|
{
|
|
@@ -958,7 +987,7 @@ function Services({
|
|
|
958
987
|
4: "md:grid-cols-2 lg:grid-cols-4"
|
|
959
988
|
};
|
|
960
989
|
if (variant === "list") {
|
|
961
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("section", { id, className: `py-16 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
990
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("section", { id, className: `py-16 scroll-mt-20 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
962
991
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SectionHeader, { title, subtitle }),
|
|
963
992
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "max-w-3xl mx-auto divide-y divide-gray-200", children: displayedServices.map((service) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
964
993
|
ServiceListItem,
|
|
@@ -972,7 +1001,7 @@ function Services({
|
|
|
972
1001
|
] }) });
|
|
973
1002
|
}
|
|
974
1003
|
if (variant === "minimal") {
|
|
975
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("section", { id, className: `py-16 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1004
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("section", { id, className: `py-16 scroll-mt-20 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
976
1005
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SectionHeader, { title, subtitle }),
|
|
977
1006
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `grid gap-6 ${gridCols[columns]}`, children: displayedServices.map((service) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
978
1007
|
ServiceMinimalCard,
|
|
@@ -984,7 +1013,7 @@ function Services({
|
|
|
984
1013
|
)) })
|
|
985
1014
|
] }) });
|
|
986
1015
|
}
|
|
987
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("section", { id, className: `py-16 bg-gray-50 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1016
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("section", { id, className: `py-16 scroll-mt-20 bg-gray-50 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
988
1017
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SectionHeader, { title, subtitle }),
|
|
989
1018
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `grid gap-6 ${gridCols[columns]}`, children: displayedServices.map((service) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
990
1019
|
ServiceCard,
|
|
@@ -1067,7 +1096,7 @@ function Testimonials({
|
|
|
1067
1096
|
2: "md:grid-cols-2 max-w-4xl mx-auto",
|
|
1068
1097
|
3: "md:grid-cols-2 lg:grid-cols-3"
|
|
1069
1098
|
};
|
|
1070
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("section", { id, className: `py-16 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1099
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("section", { id, className: `py-16 scroll-mt-20 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1071
1100
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "text-center mb-12", children: [
|
|
1072
1101
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { className: "text-3xl md:text-4xl font-bold text-gray-900 mb-4", children: title }),
|
|
1073
1102
|
subtitle && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-lg text-gray-600 max-w-2xl mx-auto", children: subtitle })
|
|
@@ -1187,18 +1216,18 @@ function FAQ({
|
|
|
1187
1216
|
}
|
|
1188
1217
|
};
|
|
1189
1218
|
if (variant === "cards") {
|
|
1190
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("section", { id, className: `py-16 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1219
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("section", { id, className: `py-16 scroll-mt-20 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1191
1220
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SectionHeader2, { title, subtitle }),
|
|
1192
1221
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "grid md:grid-cols-2 gap-6 max-w-4xl mx-auto", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FAQCard, { item }, item.id || item.question)) })
|
|
1193
1222
|
] }) });
|
|
1194
1223
|
}
|
|
1195
1224
|
if (variant === "simple") {
|
|
1196
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("section", { id, className: `py-16 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("section", { id, className: `py-16 scroll-mt-20 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1197
1226
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SectionHeader2, { title, subtitle }),
|
|
1198
1227
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "max-w-3xl mx-auto space-y-8", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FAQSimple, { item }, item.id || item.question)) })
|
|
1199
1228
|
] }) });
|
|
1200
1229
|
}
|
|
1201
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("section", { id, className: `py-16 bg-gray-50 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("section", { id, className: `py-16 scroll-mt-20 bg-gray-50 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1202
1231
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SectionHeader2, { title, subtitle }),
|
|
1203
1232
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "max-w-3xl mx-auto", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1204
1233
|
FAQAccordionItem,
|
|
@@ -1410,53 +1439,694 @@ function Gallery({
|
|
|
1410
1439
|
columns = 3,
|
|
1411
1440
|
variant = "grid",
|
|
1412
1441
|
showCaptions = true,
|
|
1442
|
+
enableLightbox = true,
|
|
1413
1443
|
limit,
|
|
1414
|
-
className = ""
|
|
1444
|
+
className = "",
|
|
1445
|
+
id = "gallery"
|
|
1415
1446
|
}) {
|
|
1416
1447
|
const displayedItems = limit ? items.slice(0, limit) : items;
|
|
1417
1448
|
const [failedImages, setFailedImages] = (0, import_react3.useState)(/* @__PURE__ */ new Set());
|
|
1418
|
-
const
|
|
1419
|
-
|
|
1449
|
+
const [lightboxIndex, setLightboxIndex] = (0, import_react3.useState)(null);
|
|
1450
|
+
const handleImageError = (id2) => {
|
|
1451
|
+
setFailedImages((prev) => new Set(prev).add(id2));
|
|
1420
1452
|
};
|
|
1421
1453
|
const gridCols = {
|
|
1422
1454
|
2: "grid-cols-1 sm:grid-cols-2",
|
|
1423
1455
|
3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
|
|
1424
1456
|
4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4"
|
|
1425
1457
|
};
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1458
|
+
const openLightbox = (index) => {
|
|
1459
|
+
if (enableLightbox) {
|
|
1460
|
+
setLightboxIndex(index);
|
|
1461
|
+
}
|
|
1462
|
+
};
|
|
1463
|
+
const closeLightbox = () => setLightboxIndex(null);
|
|
1464
|
+
const goToPrevious = () => {
|
|
1465
|
+
if (lightboxIndex !== null) {
|
|
1466
|
+
setLightboxIndex(lightboxIndex === 0 ? displayedItems.length - 1 : lightboxIndex - 1);
|
|
1467
|
+
}
|
|
1468
|
+
};
|
|
1469
|
+
const goToNext = () => {
|
|
1470
|
+
if (lightboxIndex !== null) {
|
|
1471
|
+
setLightboxIndex(lightboxIndex === displayedItems.length - 1 ? 0 : lightboxIndex + 1);
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("section", { id, className: `py-16 scroll-mt-20 ${className}`, children: [
|
|
1475
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1476
|
+
(title || subtitle) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "text-center mb-12", children: [
|
|
1477
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", { className: "text-3xl md:text-4xl font-bold text-gray-900 mb-4", children: title }),
|
|
1478
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-lg text-gray-600 max-w-2xl mx-auto", children: subtitle })
|
|
1479
|
+
] }),
|
|
1480
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `grid gap-4 ${gridCols[columns]}`, children: displayedItems.map((item, index) => {
|
|
1481
|
+
const itemId = item.id || item.imageUrl;
|
|
1482
|
+
const hasFailed = failedImages.has(itemId);
|
|
1483
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1484
|
+
"div",
|
|
1485
|
+
{
|
|
1486
|
+
className: `group relative aspect-square overflow-hidden rounded-lg bg-gray-100 ${enableLightbox ? "cursor-pointer" : ""}`,
|
|
1487
|
+
onClick: () => openLightbox(index),
|
|
1488
|
+
role: enableLightbox ? "button" : void 0,
|
|
1489
|
+
tabIndex: enableLightbox ? 0 : void 0,
|
|
1490
|
+
onKeyDown: enableLightbox ? (e) => e.key === "Enter" && openLightbox(index) : void 0,
|
|
1491
|
+
children: hasFailed ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "absolute inset-0 flex items-center justify-center text-gray-400", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Image unavailable" }) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1492
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1493
|
+
"img",
|
|
1494
|
+
{
|
|
1495
|
+
src: item.imageUrl,
|
|
1496
|
+
alt: item.alt || "",
|
|
1497
|
+
loading: "lazy",
|
|
1498
|
+
className: "w-full h-full object-cover transition-transform duration-300 group-hover:scale-105",
|
|
1499
|
+
onError: () => handleImageError(itemId)
|
|
1500
|
+
}
|
|
1501
|
+
),
|
|
1502
|
+
enableLightbox && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "absolute inset-0 bg-black/30 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-10 h-10 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7" }) }) }),
|
|
1503
|
+
showCaptions && item.caption && !enableLightbox && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "absolute inset-0 bg-gradient-to-t from-black/60 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "absolute bottom-0 left-0 right-0 p-4", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-white text-sm", children: item.caption }) }) })
|
|
1504
|
+
] })
|
|
1505
|
+
},
|
|
1506
|
+
itemId
|
|
1507
|
+
);
|
|
1508
|
+
}) })
|
|
1430
1509
|
] }),
|
|
1431
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1510
|
+
enableLightbox && lightboxIndex !== null && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1511
|
+
"div",
|
|
1512
|
+
{
|
|
1513
|
+
className: "fixed inset-0 z-50 bg-black/90 flex items-center justify-center",
|
|
1514
|
+
onClick: closeLightbox,
|
|
1515
|
+
children: [
|
|
1516
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1517
|
+
"button",
|
|
1518
|
+
{
|
|
1519
|
+
onClick: closeLightbox,
|
|
1520
|
+
className: "absolute top-4 right-4 text-white hover:text-gray-300 transition-colors z-10",
|
|
1521
|
+
"aria-label": "Close lightbox",
|
|
1522
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-8 h-8", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
1523
|
+
}
|
|
1524
|
+
),
|
|
1525
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1526
|
+
"button",
|
|
1527
|
+
{
|
|
1528
|
+
onClick: (e) => {
|
|
1529
|
+
e.stopPropagation();
|
|
1530
|
+
goToPrevious();
|
|
1531
|
+
},
|
|
1532
|
+
className: "absolute left-4 top-1/2 -translate-y-1/2 text-white hover:text-gray-300 transition-colors z-10",
|
|
1533
|
+
"aria-label": "Previous image",
|
|
1534
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-10 h-10", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
1535
|
+
}
|
|
1536
|
+
),
|
|
1537
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1538
|
+
"button",
|
|
1539
|
+
{
|
|
1540
|
+
onClick: (e) => {
|
|
1541
|
+
e.stopPropagation();
|
|
1542
|
+
goToNext();
|
|
1543
|
+
},
|
|
1544
|
+
className: "absolute right-4 top-1/2 -translate-y-1/2 text-white hover:text-gray-300 transition-colors z-10",
|
|
1545
|
+
"aria-label": "Next image",
|
|
1546
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-10 h-10", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
1547
|
+
}
|
|
1548
|
+
),
|
|
1549
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1550
|
+
"div",
|
|
1551
|
+
{
|
|
1552
|
+
className: "max-w-5xl max-h-[85vh] mx-4",
|
|
1553
|
+
onClick: (e) => e.stopPropagation(),
|
|
1554
|
+
children: [
|
|
1555
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1556
|
+
"img",
|
|
1557
|
+
{
|
|
1558
|
+
src: displayedItems[lightboxIndex].imageUrl,
|
|
1559
|
+
alt: displayedItems[lightboxIndex].alt || "",
|
|
1560
|
+
className: "max-w-full max-h-[85vh] object-contain"
|
|
1561
|
+
}
|
|
1562
|
+
),
|
|
1563
|
+
showCaptions && displayedItems[lightboxIndex].caption && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-white text-center mt-4 text-lg", children: displayedItems[lightboxIndex].caption })
|
|
1564
|
+
]
|
|
1565
|
+
}
|
|
1566
|
+
),
|
|
1567
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "absolute bottom-4 left-1/2 -translate-x-1/2 text-white text-sm", children: [
|
|
1568
|
+
lightboxIndex + 1,
|
|
1569
|
+
" / ",
|
|
1570
|
+
displayedItems.length
|
|
1450
1571
|
] })
|
|
1572
|
+
]
|
|
1573
|
+
}
|
|
1574
|
+
)
|
|
1575
|
+
] });
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
// src/components/sections/Menu.tsx
|
|
1579
|
+
var import_react4 = require("react");
|
|
1580
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1581
|
+
function Menu({
|
|
1582
|
+
items,
|
|
1583
|
+
title = "Our Menu",
|
|
1584
|
+
subtitle,
|
|
1585
|
+
showCategories = true,
|
|
1586
|
+
showImages = true,
|
|
1587
|
+
showDietary = true,
|
|
1588
|
+
variant = "cards",
|
|
1589
|
+
columns = 2,
|
|
1590
|
+
className = "",
|
|
1591
|
+
id = "menu"
|
|
1592
|
+
}) {
|
|
1593
|
+
const categories = showCategories ? [...new Set(items.filter((item) => item.category).map((item) => item.category))] : [];
|
|
1594
|
+
const [activeCategory, setActiveCategory] = (0, import_react4.useState)(
|
|
1595
|
+
categories.length > 0 ? categories[0] : null
|
|
1596
|
+
);
|
|
1597
|
+
const displayedItems = activeCategory ? items.filter((item) => item.category === activeCategory) : items;
|
|
1598
|
+
const sortedItems = [...displayedItems].sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0));
|
|
1599
|
+
const gridCols = {
|
|
1600
|
+
1: "max-w-2xl mx-auto",
|
|
1601
|
+
2: "md:grid-cols-2",
|
|
1602
|
+
3: "md:grid-cols-2 lg:grid-cols-3"
|
|
1603
|
+
};
|
|
1604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("section", { id, className: `py-16 scroll-mt-20 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1605
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "text-center mb-12", children: [
|
|
1606
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "text-3xl md:text-4xl font-bold text-gray-900 mb-4", children: title }),
|
|
1607
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-lg text-gray-600 max-w-2xl mx-auto", children: subtitle })
|
|
1608
|
+
] }),
|
|
1609
|
+
showCategories && categories.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex flex-wrap justify-center gap-2 mb-8", children: categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1610
|
+
"button",
|
|
1611
|
+
{
|
|
1612
|
+
onClick: () => setActiveCategory(category),
|
|
1613
|
+
className: `px-4 py-2 rounded-full text-sm font-medium transition-colors ${activeCategory === category ? "bg-primary-600 text-white" : "bg-gray-100 text-gray-700 hover:bg-gray-200"}`,
|
|
1614
|
+
children: category
|
|
1615
|
+
},
|
|
1616
|
+
category
|
|
1617
|
+
)) }),
|
|
1618
|
+
variant === "list" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "max-w-3xl mx-auto divide-y divide-gray-200", children: sortedItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1619
|
+
MenuListItem,
|
|
1620
|
+
{
|
|
1621
|
+
item,
|
|
1622
|
+
showImage: showImages,
|
|
1623
|
+
showDietary
|
|
1624
|
+
},
|
|
1625
|
+
item.id || item.name
|
|
1626
|
+
)) }) : variant === "compact" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `grid gap-4 ${gridCols[columns]}`, children: sortedItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1627
|
+
MenuCompactItem,
|
|
1628
|
+
{
|
|
1629
|
+
item,
|
|
1630
|
+
showDietary
|
|
1631
|
+
},
|
|
1632
|
+
item.id || item.name
|
|
1633
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `grid gap-6 ${gridCols[columns]}`, children: sortedItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1634
|
+
MenuCard,
|
|
1635
|
+
{
|
|
1636
|
+
item,
|
|
1637
|
+
showImage: showImages,
|
|
1638
|
+
showDietary
|
|
1639
|
+
},
|
|
1640
|
+
item.id || item.name
|
|
1641
|
+
)) })
|
|
1642
|
+
] }) });
|
|
1643
|
+
}
|
|
1644
|
+
function MenuCard({
|
|
1645
|
+
item,
|
|
1646
|
+
showImage,
|
|
1647
|
+
showDietary
|
|
1648
|
+
}) {
|
|
1649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow", children: [
|
|
1650
|
+
showImage && item.imageUrl && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "aspect-video relative overflow-hidden", children: [
|
|
1651
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1652
|
+
"img",
|
|
1653
|
+
{
|
|
1654
|
+
src: item.imageUrl,
|
|
1655
|
+
alt: item.name,
|
|
1656
|
+
className: "w-full h-full object-cover"
|
|
1657
|
+
}
|
|
1658
|
+
),
|
|
1659
|
+
item.featured && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "absolute top-2 left-2 px-2 py-1 bg-primary-600 text-white text-xs font-medium rounded", children: "Featured" })
|
|
1660
|
+
] }),
|
|
1661
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "p-4", children: [
|
|
1662
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex justify-between items-start mb-2", children: [
|
|
1663
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "text-lg font-semibold text-gray-900", children: item.name }),
|
|
1664
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PriceDisplay, { item })
|
|
1665
|
+
] }),
|
|
1666
|
+
item.description && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-gray-600 text-sm mb-3", children: item.description }),
|
|
1667
|
+
showDietary && item.dietary && item.dietary.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DietaryBadges, { dietary: item.dietary }),
|
|
1668
|
+
!item.available && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "inline-block mt-2 px-2 py-1 bg-gray-100 text-gray-500 text-xs rounded", children: "Currently unavailable" })
|
|
1669
|
+
] })
|
|
1670
|
+
] });
|
|
1671
|
+
}
|
|
1672
|
+
function MenuListItem({
|
|
1673
|
+
item,
|
|
1674
|
+
showImage,
|
|
1675
|
+
showDietary
|
|
1676
|
+
}) {
|
|
1677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "py-4 flex gap-4", children: [
|
|
1678
|
+
showImage && item.imageUrl && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "w-20 h-20 flex-shrink-0 rounded-lg overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1679
|
+
"img",
|
|
1680
|
+
{
|
|
1681
|
+
src: item.imageUrl,
|
|
1682
|
+
alt: item.name,
|
|
1683
|
+
className: "w-full h-full object-cover"
|
|
1684
|
+
}
|
|
1685
|
+
) }),
|
|
1686
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex justify-between items-start", children: [
|
|
1687
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
|
|
1688
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("h3", { className: "text-lg font-semibold text-gray-900", children: [
|
|
1689
|
+
item.name,
|
|
1690
|
+
item.featured && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ml-2 px-2 py-0.5 bg-primary-100 text-primary-700 text-xs font-medium rounded", children: "Popular" })
|
|
1691
|
+
] }),
|
|
1692
|
+
item.description && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-gray-600 text-sm mt-1", children: item.description }),
|
|
1693
|
+
showDietary && item.dietary && item.dietary.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-2", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DietaryBadges, { dietary: item.dietary }) })
|
|
1694
|
+
] }),
|
|
1695
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PriceDisplay, { item })
|
|
1696
|
+
] }) })
|
|
1697
|
+
] });
|
|
1698
|
+
}
|
|
1699
|
+
function MenuCompactItem({
|
|
1700
|
+
item,
|
|
1701
|
+
showDietary
|
|
1702
|
+
}) {
|
|
1703
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex justify-between items-center py-2 border-b border-gray-100 last:border-0", children: [
|
|
1704
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1705
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-medium text-gray-900", children: item.name }),
|
|
1706
|
+
item.featured && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "w-2 h-2 bg-primary-500 rounded-full", title: "Popular" }),
|
|
1707
|
+
showDietary && item.dietary && item.dietary.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-xs text-gray-500", children: [
|
|
1708
|
+
"(",
|
|
1709
|
+
item.dietary.join(", "),
|
|
1710
|
+
")"
|
|
1711
|
+
] })
|
|
1712
|
+
] }),
|
|
1713
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PriceDisplay, { item, compact: true })
|
|
1714
|
+
] });
|
|
1715
|
+
}
|
|
1716
|
+
function PriceDisplay({ item, compact = false }) {
|
|
1717
|
+
if (item.priceNote) {
|
|
1718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: `text-primary-600 font-medium ${compact ? "text-sm" : ""}`, children: item.priceNote });
|
|
1719
|
+
}
|
|
1720
|
+
if (item.price) {
|
|
1721
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: `text-primary-600 font-medium ${compact ? "text-sm" : ""}`, children: [
|
|
1722
|
+
"$",
|
|
1723
|
+
item.price.toFixed(2)
|
|
1724
|
+
] });
|
|
1725
|
+
}
|
|
1726
|
+
return null;
|
|
1727
|
+
}
|
|
1728
|
+
function DietaryBadges({ dietary }) {
|
|
1729
|
+
const dietaryIcons = {
|
|
1730
|
+
vegetarian: "V",
|
|
1731
|
+
vegan: "VG",
|
|
1732
|
+
"gluten-free": "GF",
|
|
1733
|
+
"dairy-free": "DF",
|
|
1734
|
+
"nut-free": "NF",
|
|
1735
|
+
spicy: "\u{1F336}",
|
|
1736
|
+
halal: "H",
|
|
1737
|
+
kosher: "K"
|
|
1738
|
+
};
|
|
1739
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex flex-wrap gap-1", children: dietary.map((diet) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1740
|
+
"span",
|
|
1741
|
+
{
|
|
1742
|
+
className: "px-1.5 py-0.5 bg-green-100 text-green-700 text-xs font-medium rounded",
|
|
1743
|
+
title: diet,
|
|
1744
|
+
children: dietaryIcons[diet.toLowerCase()] || diet
|
|
1745
|
+
},
|
|
1746
|
+
diet
|
|
1747
|
+
)) });
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
// src/components/sections/TrustBadges.tsx
|
|
1751
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1752
|
+
function TrustBadges({
|
|
1753
|
+
badges,
|
|
1754
|
+
title = "Certifications & Affiliations",
|
|
1755
|
+
subtitle,
|
|
1756
|
+
variant = "grid",
|
|
1757
|
+
columns = 4,
|
|
1758
|
+
showDescriptions = false,
|
|
1759
|
+
className = "",
|
|
1760
|
+
id = "certifications"
|
|
1761
|
+
}) {
|
|
1762
|
+
const sortedBadges = [...badges].sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0));
|
|
1763
|
+
const gridCols = {
|
|
1764
|
+
3: "grid-cols-2 sm:grid-cols-3",
|
|
1765
|
+
4: "grid-cols-2 sm:grid-cols-4",
|
|
1766
|
+
5: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-5",
|
|
1767
|
+
6: "grid-cols-3 sm:grid-cols-6"
|
|
1768
|
+
};
|
|
1769
|
+
if (variant === "inline") {
|
|
1770
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("section", { id, className: `py-12 scroll-mt-20 bg-gray-50 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1771
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-center text-sm text-gray-500 mb-6", children: title }),
|
|
1772
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex flex-wrap justify-center items-center gap-8 md:gap-12", children: sortedBadges.map((badge) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(InlineBadge, { badge }, badge.id || badge.name)) })
|
|
1773
|
+
] }) });
|
|
1774
|
+
}
|
|
1775
|
+
if (variant === "cards") {
|
|
1776
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("section", { id, className: `py-16 scroll-mt-20 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1777
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "text-center mb-12", children: [
|
|
1778
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { className: "text-3xl md:text-4xl font-bold text-gray-900 mb-4", children: title }),
|
|
1779
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-lg text-gray-600 max-w-2xl mx-auto", children: subtitle })
|
|
1780
|
+
] }),
|
|
1781
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: `grid gap-6 ${gridCols[columns]}`, children: sortedBadges.map((badge) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1782
|
+
CardBadge,
|
|
1783
|
+
{
|
|
1784
|
+
badge,
|
|
1785
|
+
showDescription: showDescriptions
|
|
1451
1786
|
},
|
|
1452
|
-
|
|
1453
|
-
)
|
|
1454
|
-
}) })
|
|
1787
|
+
badge.id || badge.name
|
|
1788
|
+
)) })
|
|
1789
|
+
] }) });
|
|
1790
|
+
}
|
|
1791
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("section", { id, className: `py-16 scroll-mt-20 bg-gray-50 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1792
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "text-center mb-12", children: [
|
|
1793
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { className: "text-3xl md:text-4xl font-bold text-gray-900 mb-4", children: title }),
|
|
1794
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-lg text-gray-600 max-w-2xl mx-auto", children: subtitle })
|
|
1795
|
+
] }),
|
|
1796
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: `grid gap-8 ${gridCols[columns]}`, children: sortedBadges.map((badge) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1797
|
+
GridBadge,
|
|
1798
|
+
{
|
|
1799
|
+
badge,
|
|
1800
|
+
showDescription: showDescriptions
|
|
1801
|
+
},
|
|
1802
|
+
badge.id || badge.name
|
|
1803
|
+
)) })
|
|
1455
1804
|
] }) });
|
|
1456
1805
|
}
|
|
1806
|
+
function InlineBadge({ badge }) {
|
|
1807
|
+
const Wrapper = badge.link ? "a" : "div";
|
|
1808
|
+
const wrapperProps = badge.link ? { href: badge.link, target: "_blank", rel: "noopener noreferrer" } : {};
|
|
1809
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1810
|
+
Wrapper,
|
|
1811
|
+
{
|
|
1812
|
+
...wrapperProps,
|
|
1813
|
+
className: "flex items-center opacity-70 hover:opacity-100 transition-opacity",
|
|
1814
|
+
title: badge.name,
|
|
1815
|
+
children: badge.imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1816
|
+
"img",
|
|
1817
|
+
{
|
|
1818
|
+
src: badge.imageUrl,
|
|
1819
|
+
alt: badge.name,
|
|
1820
|
+
className: "h-10 md:h-12 w-auto object-contain grayscale hover:grayscale-0 transition-all"
|
|
1821
|
+
}
|
|
1822
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 text-gray-600", children: [
|
|
1823
|
+
badge.icon && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(BadgeIcon, { icon: badge.icon, className: "w-8 h-8" }),
|
|
1824
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm font-medium", children: badge.name })
|
|
1825
|
+
] })
|
|
1826
|
+
}
|
|
1827
|
+
);
|
|
1828
|
+
}
|
|
1829
|
+
function GridBadge({
|
|
1830
|
+
badge,
|
|
1831
|
+
showDescription
|
|
1832
|
+
}) {
|
|
1833
|
+
const Wrapper = badge.link ? "a" : "div";
|
|
1834
|
+
const wrapperProps = badge.link ? { href: badge.link, target: "_blank", rel: "noopener noreferrer" } : {};
|
|
1835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1836
|
+
Wrapper,
|
|
1837
|
+
{
|
|
1838
|
+
...wrapperProps,
|
|
1839
|
+
className: "flex flex-col items-center text-center group",
|
|
1840
|
+
children: [
|
|
1841
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "w-20 h-20 mb-3 flex items-center justify-center", children: badge.imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1842
|
+
"img",
|
|
1843
|
+
{
|
|
1844
|
+
src: badge.imageUrl,
|
|
1845
|
+
alt: badge.name,
|
|
1846
|
+
className: "max-w-full max-h-full object-contain group-hover:scale-110 transition-transform"
|
|
1847
|
+
}
|
|
1848
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1849
|
+
BadgeIcon,
|
|
1850
|
+
{
|
|
1851
|
+
icon: badge.icon || "certificate",
|
|
1852
|
+
className: "w-16 h-16 text-primary-600 group-hover:scale-110 transition-transform"
|
|
1853
|
+
}
|
|
1854
|
+
) }),
|
|
1855
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "font-semibold text-gray-900 text-sm", children: badge.name }),
|
|
1856
|
+
badge.year && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-xs text-gray-500", children: [
|
|
1857
|
+
"Since ",
|
|
1858
|
+
badge.year
|
|
1859
|
+
] }),
|
|
1860
|
+
showDescription && badge.description && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm text-gray-600 mt-2", children: badge.description })
|
|
1861
|
+
]
|
|
1862
|
+
}
|
|
1863
|
+
);
|
|
1864
|
+
}
|
|
1865
|
+
function CardBadge({
|
|
1866
|
+
badge,
|
|
1867
|
+
showDescription
|
|
1868
|
+
}) {
|
|
1869
|
+
const Wrapper = badge.link ? "a" : "div";
|
|
1870
|
+
const wrapperProps = badge.link ? { href: badge.link, target: "_blank", rel: "noopener noreferrer" } : {};
|
|
1871
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1872
|
+
Wrapper,
|
|
1873
|
+
{
|
|
1874
|
+
...wrapperProps,
|
|
1875
|
+
className: "bg-white rounded-lg shadow p-6 flex flex-col items-center text-center hover:shadow-md transition-shadow",
|
|
1876
|
+
children: [
|
|
1877
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "w-16 h-16 mb-4 flex items-center justify-center", children: badge.imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1878
|
+
"img",
|
|
1879
|
+
{
|
|
1880
|
+
src: badge.imageUrl,
|
|
1881
|
+
alt: badge.name,
|
|
1882
|
+
className: "max-w-full max-h-full object-contain"
|
|
1883
|
+
}
|
|
1884
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(BadgeIcon, { icon: badge.icon || "certificate", className: "w-12 h-12 text-primary-600" }) }),
|
|
1885
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "font-semibold text-gray-900", children: badge.name }),
|
|
1886
|
+
badge.year && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-xs text-gray-500 mt-1", children: [
|
|
1887
|
+
"Since ",
|
|
1888
|
+
badge.year
|
|
1889
|
+
] }),
|
|
1890
|
+
showDescription && badge.description && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm text-gray-600 mt-2", children: badge.description })
|
|
1891
|
+
]
|
|
1892
|
+
}
|
|
1893
|
+
);
|
|
1894
|
+
}
|
|
1895
|
+
function BadgeIcon({ icon, className = "" }) {
|
|
1896
|
+
const icons = {
|
|
1897
|
+
certificate: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z" }) }),
|
|
1898
|
+
shield: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" }) }),
|
|
1899
|
+
star: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" }) }),
|
|
1900
|
+
award: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" }) }),
|
|
1901
|
+
check: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
1902
|
+
verified: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z" }) })
|
|
1903
|
+
};
|
|
1904
|
+
return icons[icon] || icons.certificate;
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
// src/components/sections/BeforeAfter.tsx
|
|
1908
|
+
var import_react5 = require("react");
|
|
1909
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1910
|
+
function BeforeAfter({
|
|
1911
|
+
items,
|
|
1912
|
+
title = "Our Work",
|
|
1913
|
+
subtitle = "See the transformation",
|
|
1914
|
+
columns = 2,
|
|
1915
|
+
variant = "slider",
|
|
1916
|
+
showCategories = true,
|
|
1917
|
+
className = "",
|
|
1918
|
+
id = "portfolio"
|
|
1919
|
+
}) {
|
|
1920
|
+
const categories = showCategories ? [...new Set(items.filter((item) => item.category).map((item) => item.category))] : [];
|
|
1921
|
+
const [activeCategory, setActiveCategory] = (0, import_react5.useState)(null);
|
|
1922
|
+
const displayedItems = activeCategory ? items.filter((item) => item.category === activeCategory) : items;
|
|
1923
|
+
const sortedItems = [...displayedItems].sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0));
|
|
1924
|
+
const gridCols = {
|
|
1925
|
+
1: "max-w-2xl mx-auto",
|
|
1926
|
+
2: "md:grid-cols-2",
|
|
1927
|
+
3: "md:grid-cols-2 lg:grid-cols-3"
|
|
1928
|
+
};
|
|
1929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("section", { id, className: `py-16 scroll-mt-20 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "container mx-auto px-4", children: [
|
|
1930
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "text-center mb-12", children: [
|
|
1931
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", { className: "text-3xl md:text-4xl font-bold text-gray-900 mb-4", children: title }),
|
|
1932
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-lg text-gray-600 max-w-2xl mx-auto", children: subtitle })
|
|
1933
|
+
] }),
|
|
1934
|
+
showCategories && categories.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap justify-center gap-2 mb-8", children: [
|
|
1935
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1936
|
+
"button",
|
|
1937
|
+
{
|
|
1938
|
+
onClick: () => setActiveCategory(null),
|
|
1939
|
+
className: `px-4 py-2 rounded-full text-sm font-medium transition-colors ${activeCategory === null ? "bg-primary-600 text-white" : "bg-gray-100 text-gray-700 hover:bg-gray-200"}`,
|
|
1940
|
+
children: "All"
|
|
1941
|
+
}
|
|
1942
|
+
),
|
|
1943
|
+
categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1944
|
+
"button",
|
|
1945
|
+
{
|
|
1946
|
+
onClick: () => setActiveCategory(category),
|
|
1947
|
+
className: `px-4 py-2 rounded-full text-sm font-medium transition-colors ${activeCategory === category ? "bg-primary-600 text-white" : "bg-gray-100 text-gray-700 hover:bg-gray-200"}`,
|
|
1948
|
+
children: category
|
|
1949
|
+
},
|
|
1950
|
+
category
|
|
1951
|
+
))
|
|
1952
|
+
] }),
|
|
1953
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: `grid gap-8 ${gridCols[columns]}`, children: sortedItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1954
|
+
BeforeAfterCard,
|
|
1955
|
+
{
|
|
1956
|
+
item,
|
|
1957
|
+
variant
|
|
1958
|
+
},
|
|
1959
|
+
item.id || `${item.beforeImageUrl}-${item.afterImageUrl}`
|
|
1960
|
+
)) })
|
|
1961
|
+
] }) });
|
|
1962
|
+
}
|
|
1963
|
+
function BeforeAfterCard({
|
|
1964
|
+
item,
|
|
1965
|
+
variant
|
|
1966
|
+
}) {
|
|
1967
|
+
if (variant === "side-by-side") {
|
|
1968
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SideBySideCard, { item });
|
|
1969
|
+
}
|
|
1970
|
+
if (variant === "stacked") {
|
|
1971
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(StackedCard, { item });
|
|
1972
|
+
}
|
|
1973
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SliderCard, { item });
|
|
1974
|
+
}
|
|
1975
|
+
function SliderCard({ item }) {
|
|
1976
|
+
const [sliderPosition, setSliderPosition] = (0, import_react5.useState)(50);
|
|
1977
|
+
const containerRef = (0, import_react5.useRef)(null);
|
|
1978
|
+
const isDragging = (0, import_react5.useRef)(false);
|
|
1979
|
+
const handleMove = (0, import_react5.useCallback)((clientX) => {
|
|
1980
|
+
if (!containerRef.current) return;
|
|
1981
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
1982
|
+
const x = clientX - rect.left;
|
|
1983
|
+
const percentage = Math.max(0, Math.min(100, x / rect.width * 100));
|
|
1984
|
+
setSliderPosition(percentage);
|
|
1985
|
+
}, []);
|
|
1986
|
+
const handleMouseDown = () => {
|
|
1987
|
+
isDragging.current = true;
|
|
1988
|
+
};
|
|
1989
|
+
const handleMouseUp = () => {
|
|
1990
|
+
isDragging.current = false;
|
|
1991
|
+
};
|
|
1992
|
+
const handleMouseMove = (e) => {
|
|
1993
|
+
if (isDragging.current) {
|
|
1994
|
+
handleMove(e.clientX);
|
|
1995
|
+
}
|
|
1996
|
+
};
|
|
1997
|
+
const handleTouchMove = (e) => {
|
|
1998
|
+
handleMove(e.touches[0].clientX);
|
|
1999
|
+
};
|
|
2000
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "bg-white rounded-lg shadow-md overflow-hidden", children: [
|
|
2001
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2002
|
+
"div",
|
|
2003
|
+
{
|
|
2004
|
+
ref: containerRef,
|
|
2005
|
+
className: "relative aspect-[4/3] cursor-ew-resize select-none overflow-hidden",
|
|
2006
|
+
onMouseDown: handleMouseDown,
|
|
2007
|
+
onMouseUp: handleMouseUp,
|
|
2008
|
+
onMouseLeave: handleMouseUp,
|
|
2009
|
+
onMouseMove: handleMouseMove,
|
|
2010
|
+
onTouchMove: handleTouchMove,
|
|
2011
|
+
children: [
|
|
2012
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2013
|
+
"img",
|
|
2014
|
+
{
|
|
2015
|
+
src: item.afterImageUrl,
|
|
2016
|
+
alt: item.afterAlt || "After",
|
|
2017
|
+
className: "absolute inset-0 w-full h-full object-cover"
|
|
2018
|
+
}
|
|
2019
|
+
),
|
|
2020
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2021
|
+
"div",
|
|
2022
|
+
{
|
|
2023
|
+
className: "absolute inset-0 overflow-hidden",
|
|
2024
|
+
style: { width: `${sliderPosition}%` },
|
|
2025
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2026
|
+
"img",
|
|
2027
|
+
{
|
|
2028
|
+
src: item.beforeImageUrl,
|
|
2029
|
+
alt: item.beforeAlt || "Before",
|
|
2030
|
+
className: "absolute inset-0 w-full h-full object-cover",
|
|
2031
|
+
style: { width: containerRef.current?.offsetWidth || "100%" }
|
|
2032
|
+
}
|
|
2033
|
+
)
|
|
2034
|
+
}
|
|
2035
|
+
),
|
|
2036
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2037
|
+
"div",
|
|
2038
|
+
{
|
|
2039
|
+
className: "absolute top-0 bottom-0 w-1 bg-white shadow-lg cursor-ew-resize",
|
|
2040
|
+
style: { left: `${sliderPosition}%`, transform: "translateX(-50%)" },
|
|
2041
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-10 h-10 bg-white rounded-full shadow-lg flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { className: "w-6 h-6 text-gray-600", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 9l4-4 4 4m0 6l-4 4-4-4" }) }) })
|
|
2042
|
+
}
|
|
2043
|
+
),
|
|
2044
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "absolute bottom-4 left-4 px-2 py-1 bg-black/60 text-white text-xs rounded", children: "Before" }),
|
|
2045
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "absolute bottom-4 right-4 px-2 py-1 bg-black/60 text-white text-xs rounded", children: "After" })
|
|
2046
|
+
]
|
|
2047
|
+
}
|
|
2048
|
+
),
|
|
2049
|
+
(item.title || item.description) && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "p-4", children: [
|
|
2050
|
+
item.title && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { className: "text-lg font-semibold text-gray-900 mb-1", children: item.title }),
|
|
2051
|
+
item.description && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-gray-600 text-sm", children: item.description })
|
|
2052
|
+
] })
|
|
2053
|
+
] });
|
|
2054
|
+
}
|
|
2055
|
+
function SideBySideCard({ item }) {
|
|
2056
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "bg-white rounded-lg shadow-md overflow-hidden", children: [
|
|
2057
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "grid grid-cols-2", children: [
|
|
2058
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "relative aspect-square", children: [
|
|
2059
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2060
|
+
"img",
|
|
2061
|
+
{
|
|
2062
|
+
src: item.beforeImageUrl,
|
|
2063
|
+
alt: item.beforeAlt || "Before",
|
|
2064
|
+
className: "w-full h-full object-cover"
|
|
2065
|
+
}
|
|
2066
|
+
),
|
|
2067
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "absolute bottom-2 left-2 px-2 py-1 bg-black/60 text-white text-xs rounded", children: "Before" })
|
|
2068
|
+
] }),
|
|
2069
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "relative aspect-square", children: [
|
|
2070
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2071
|
+
"img",
|
|
2072
|
+
{
|
|
2073
|
+
src: item.afterImageUrl,
|
|
2074
|
+
alt: item.afterAlt || "After",
|
|
2075
|
+
className: "w-full h-full object-cover"
|
|
2076
|
+
}
|
|
2077
|
+
),
|
|
2078
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "absolute bottom-2 right-2 px-2 py-1 bg-black/60 text-white text-xs rounded", children: "After" })
|
|
2079
|
+
] })
|
|
2080
|
+
] }),
|
|
2081
|
+
(item.title || item.description) && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "p-4", children: [
|
|
2082
|
+
item.title && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { className: "text-lg font-semibold text-gray-900 mb-1", children: item.title }),
|
|
2083
|
+
item.description && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-gray-600 text-sm", children: item.description })
|
|
2084
|
+
] })
|
|
2085
|
+
] });
|
|
2086
|
+
}
|
|
2087
|
+
function StackedCard({ item }) {
|
|
2088
|
+
const [showAfter, setShowAfter] = (0, import_react5.useState)(false);
|
|
2089
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "bg-white rounded-lg shadow-md overflow-hidden", children: [
|
|
2090
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2091
|
+
"div",
|
|
2092
|
+
{
|
|
2093
|
+
className: "relative aspect-[4/3] cursor-pointer",
|
|
2094
|
+
onMouseEnter: () => setShowAfter(true),
|
|
2095
|
+
onMouseLeave: () => setShowAfter(false),
|
|
2096
|
+
onClick: () => setShowAfter(!showAfter),
|
|
2097
|
+
children: [
|
|
2098
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2099
|
+
"img",
|
|
2100
|
+
{
|
|
2101
|
+
src: item.beforeImageUrl,
|
|
2102
|
+
alt: item.beforeAlt || "Before",
|
|
2103
|
+
className: `absolute inset-0 w-full h-full object-cover transition-opacity duration-300 ${showAfter ? "opacity-0" : "opacity-100"}`
|
|
2104
|
+
}
|
|
2105
|
+
),
|
|
2106
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2107
|
+
"img",
|
|
2108
|
+
{
|
|
2109
|
+
src: item.afterImageUrl,
|
|
2110
|
+
alt: item.afterAlt || "After",
|
|
2111
|
+
className: `absolute inset-0 w-full h-full object-cover transition-opacity duration-300 ${showAfter ? "opacity-100" : "opacity-0"}`
|
|
2112
|
+
}
|
|
2113
|
+
),
|
|
2114
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "absolute bottom-4 left-1/2 -translate-x-1/2 px-3 py-1 bg-black/60 text-white text-sm rounded", children: [
|
|
2115
|
+
showAfter ? "After" : "Before",
|
|
2116
|
+
" (hover to toggle)"
|
|
2117
|
+
] })
|
|
2118
|
+
]
|
|
2119
|
+
}
|
|
2120
|
+
),
|
|
2121
|
+
(item.title || item.description) && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "p-4", children: [
|
|
2122
|
+
item.title && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { className: "text-lg font-semibold text-gray-900 mb-1", children: item.title }),
|
|
2123
|
+
item.description && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-gray-600 text-sm", children: item.description })
|
|
2124
|
+
] })
|
|
2125
|
+
] });
|
|
2126
|
+
}
|
|
1457
2127
|
|
|
1458
2128
|
// src/components/ui/Button.tsx
|
|
1459
|
-
var
|
|
2129
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1460
2130
|
function getButtonClasses(props) {
|
|
1461
2131
|
const { variant = "primary", size = "md", fullWidth, disabled } = props;
|
|
1462
2132
|
const baseClasses = [
|
|
@@ -1498,16 +2168,16 @@ function Button({
|
|
|
1498
2168
|
...props
|
|
1499
2169
|
}) {
|
|
1500
2170
|
const classes = getButtonClasses({ variant, size, fullWidth, disabled: disabled || loading });
|
|
1501
|
-
return /* @__PURE__ */ (0,
|
|
2171
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1502
2172
|
"button",
|
|
1503
2173
|
{
|
|
1504
2174
|
className: `${classes} ${className}`,
|
|
1505
2175
|
disabled: disabled || loading,
|
|
1506
2176
|
...props,
|
|
1507
|
-
children: loading ? /* @__PURE__ */ (0,
|
|
1508
|
-
leftIcon && /* @__PURE__ */ (0,
|
|
2177
|
+
children: loading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LoadingSpinner, { size }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
2178
|
+
leftIcon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "mr-2", children: leftIcon }),
|
|
1509
2179
|
children,
|
|
1510
|
-
rightIcon && /* @__PURE__ */ (0,
|
|
2180
|
+
rightIcon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ml-2", children: rightIcon })
|
|
1511
2181
|
] })
|
|
1512
2182
|
}
|
|
1513
2183
|
);
|
|
@@ -1518,7 +2188,7 @@ function LoadingSpinner({ size }) {
|
|
|
1518
2188
|
md: "w-5 h-5",
|
|
1519
2189
|
lg: "w-6 h-6"
|
|
1520
2190
|
};
|
|
1521
|
-
return /* @__PURE__ */ (0,
|
|
2191
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1522
2192
|
"svg",
|
|
1523
2193
|
{
|
|
1524
2194
|
className: `animate-spin ${sizeClasses[size || "md"]}`,
|
|
@@ -1526,7 +2196,7 @@ function LoadingSpinner({ size }) {
|
|
|
1526
2196
|
fill: "none",
|
|
1527
2197
|
viewBox: "0 0 24 24",
|
|
1528
2198
|
children: [
|
|
1529
|
-
/* @__PURE__ */ (0,
|
|
2199
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1530
2200
|
"circle",
|
|
1531
2201
|
{
|
|
1532
2202
|
className: "opacity-25",
|
|
@@ -1537,7 +2207,7 @@ function LoadingSpinner({ size }) {
|
|
|
1537
2207
|
strokeWidth: "4"
|
|
1538
2208
|
}
|
|
1539
2209
|
),
|
|
1540
|
-
/* @__PURE__ */ (0,
|
|
2210
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1541
2211
|
"path",
|
|
1542
2212
|
{
|
|
1543
2213
|
className: "opacity-75",
|
|
@@ -1560,15 +2230,15 @@ function ButtonLink({
|
|
|
1560
2230
|
...props
|
|
1561
2231
|
}) {
|
|
1562
2232
|
const classes = getButtonClasses({ variant, size, fullWidth, disabled: false });
|
|
1563
|
-
return /* @__PURE__ */ (0,
|
|
1564
|
-
leftIcon && /* @__PURE__ */ (0,
|
|
2233
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("a", { className: `${classes} ${className}`, ...props, children: [
|
|
2234
|
+
leftIcon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "mr-2", children: leftIcon }),
|
|
1565
2235
|
children,
|
|
1566
|
-
rightIcon && /* @__PURE__ */ (0,
|
|
2236
|
+
rightIcon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ml-2", children: rightIcon })
|
|
1567
2237
|
] });
|
|
1568
2238
|
}
|
|
1569
2239
|
|
|
1570
2240
|
// src/components/ui/Card.tsx
|
|
1571
|
-
var
|
|
2241
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1572
2242
|
function getCardClasses(props) {
|
|
1573
2243
|
const { variant = "default", padding = "md", hover = false } = props;
|
|
1574
2244
|
const baseClasses = ["rounded-lg", "overflow-hidden"];
|
|
@@ -1601,7 +2271,7 @@ function Card({
|
|
|
1601
2271
|
...props
|
|
1602
2272
|
}) {
|
|
1603
2273
|
const classes = getCardClasses({ variant, padding, hover });
|
|
1604
|
-
return /* @__PURE__ */ (0,
|
|
2274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: `${classes} ${className}`, ...props, children });
|
|
1605
2275
|
}
|
|
1606
2276
|
function CardHeader({
|
|
1607
2277
|
title,
|
|
@@ -1611,13 +2281,13 @@ function CardHeader({
|
|
|
1611
2281
|
className = "",
|
|
1612
2282
|
...props
|
|
1613
2283
|
}) {
|
|
1614
|
-
return /* @__PURE__ */ (0,
|
|
1615
|
-
/* @__PURE__ */ (0,
|
|
1616
|
-
title && /* @__PURE__ */ (0,
|
|
1617
|
-
subtitle && /* @__PURE__ */ (0,
|
|
2284
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `flex items-start justify-between ${className}`, ...props, children: [
|
|
2285
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
2286
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "text-lg font-semibold text-gray-900", children: title }),
|
|
2287
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "mt-1 text-sm text-gray-500", children: subtitle }),
|
|
1618
2288
|
children
|
|
1619
2289
|
] }),
|
|
1620
|
-
action && /* @__PURE__ */ (0,
|
|
2290
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex-shrink-0 ml-4", children: action })
|
|
1621
2291
|
] });
|
|
1622
2292
|
}
|
|
1623
2293
|
function CardBody({
|
|
@@ -1625,14 +2295,14 @@ function CardBody({
|
|
|
1625
2295
|
className = "",
|
|
1626
2296
|
...props
|
|
1627
2297
|
}) {
|
|
1628
|
-
return /* @__PURE__ */ (0,
|
|
2298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: `mt-4 ${className}`, ...props, children });
|
|
1629
2299
|
}
|
|
1630
2300
|
function CardFooter({
|
|
1631
2301
|
children,
|
|
1632
2302
|
className = "",
|
|
1633
2303
|
...props
|
|
1634
2304
|
}) {
|
|
1635
|
-
return /* @__PURE__ */ (0,
|
|
2305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: `mt-4 pt-4 border-t border-gray-100 ${className}`, ...props, children });
|
|
1636
2306
|
}
|
|
1637
2307
|
function CardImage({
|
|
1638
2308
|
aspectRatio = "video",
|
|
@@ -1646,7 +2316,7 @@ function CardImage({
|
|
|
1646
2316
|
wide: "aspect-[2/1]",
|
|
1647
2317
|
auto: ""
|
|
1648
2318
|
};
|
|
1649
|
-
return /* @__PURE__ */ (0,
|
|
2319
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: `-m-5 mb-4 ${aspectClasses[aspectRatio]} overflow-hidden`, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1650
2320
|
"img",
|
|
1651
2321
|
{
|
|
1652
2322
|
className: `w-full h-full object-cover ${className}`,
|
|
@@ -1655,8 +2325,206 @@ function CardImage({
|
|
|
1655
2325
|
}
|
|
1656
2326
|
) });
|
|
1657
2327
|
}
|
|
2328
|
+
|
|
2329
|
+
// src/components/ui/AnimatedSection.tsx
|
|
2330
|
+
var import_react6 = __toESM(require("react"));
|
|
2331
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2332
|
+
function AnimatedSection({
|
|
2333
|
+
children,
|
|
2334
|
+
animation = "fade-up",
|
|
2335
|
+
delay = 0,
|
|
2336
|
+
duration = 600,
|
|
2337
|
+
threshold = 0.1,
|
|
2338
|
+
once = true,
|
|
2339
|
+
className = "",
|
|
2340
|
+
as: Component = "div"
|
|
2341
|
+
}) {
|
|
2342
|
+
const ref = (0, import_react6.useRef)(null);
|
|
2343
|
+
const [isVisible, setIsVisible] = (0, import_react6.useState)(false);
|
|
2344
|
+
(0, import_react6.useEffect)(() => {
|
|
2345
|
+
const observer = new IntersectionObserver(
|
|
2346
|
+
([entry]) => {
|
|
2347
|
+
if (entry.isIntersecting) {
|
|
2348
|
+
setIsVisible(true);
|
|
2349
|
+
if (once && ref.current) {
|
|
2350
|
+
observer.unobserve(ref.current);
|
|
2351
|
+
}
|
|
2352
|
+
} else if (!once) {
|
|
2353
|
+
setIsVisible(false);
|
|
2354
|
+
}
|
|
2355
|
+
},
|
|
2356
|
+
{ threshold }
|
|
2357
|
+
);
|
|
2358
|
+
if (ref.current) {
|
|
2359
|
+
observer.observe(ref.current);
|
|
2360
|
+
}
|
|
2361
|
+
return () => {
|
|
2362
|
+
if (ref.current) {
|
|
2363
|
+
observer.unobserve(ref.current);
|
|
2364
|
+
}
|
|
2365
|
+
};
|
|
2366
|
+
}, [threshold, once]);
|
|
2367
|
+
const getAnimationStyles = () => {
|
|
2368
|
+
const baseStyles = {
|
|
2369
|
+
transition: `opacity ${duration}ms ease-out, transform ${duration}ms ease-out`,
|
|
2370
|
+
transitionDelay: `${delay}ms`
|
|
2371
|
+
};
|
|
2372
|
+
if (!isVisible) {
|
|
2373
|
+
switch (animation) {
|
|
2374
|
+
case "fade-up":
|
|
2375
|
+
return { ...baseStyles, opacity: 0, transform: "translateY(30px)" };
|
|
2376
|
+
case "fade-down":
|
|
2377
|
+
return { ...baseStyles, opacity: 0, transform: "translateY(-30px)" };
|
|
2378
|
+
case "fade-left":
|
|
2379
|
+
return { ...baseStyles, opacity: 0, transform: "translateX(30px)" };
|
|
2380
|
+
case "fade-right":
|
|
2381
|
+
return { ...baseStyles, opacity: 0, transform: "translateX(-30px)" };
|
|
2382
|
+
case "zoom":
|
|
2383
|
+
return { ...baseStyles, opacity: 0, transform: "scale(0.95)" };
|
|
2384
|
+
case "none":
|
|
2385
|
+
return {};
|
|
2386
|
+
default:
|
|
2387
|
+
return { ...baseStyles, opacity: 0, transform: "translateY(30px)" };
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
return { ...baseStyles, opacity: 1, transform: "translateY(0) translateX(0) scale(1)" };
|
|
2391
|
+
};
|
|
2392
|
+
if (animation === "none") {
|
|
2393
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Component, { className, children });
|
|
2394
|
+
}
|
|
2395
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Component, { ref, style: getAnimationStyles(), className, children });
|
|
2396
|
+
}
|
|
2397
|
+
function StaggerContainer({
|
|
2398
|
+
children,
|
|
2399
|
+
staggerDelay = 100,
|
|
2400
|
+
animation = "fade-up",
|
|
2401
|
+
duration = 600,
|
|
2402
|
+
className = ""
|
|
2403
|
+
}) {
|
|
2404
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className, children: import_react6.default.Children.map(children, (child, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2405
|
+
AnimatedSection,
|
|
2406
|
+
{
|
|
2407
|
+
animation,
|
|
2408
|
+
delay: index * staggerDelay,
|
|
2409
|
+
duration,
|
|
2410
|
+
children: child
|
|
2411
|
+
}
|
|
2412
|
+
)) });
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
// src/components/ui/FloatingClaimBanner.tsx
|
|
2416
|
+
var import_react7 = require("react");
|
|
2417
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2418
|
+
function FloatingClaimBanner({
|
|
2419
|
+
contactEmail = "andrew@whotookmy.com",
|
|
2420
|
+
siteUrl,
|
|
2421
|
+
businessName,
|
|
2422
|
+
position = "bottom-right",
|
|
2423
|
+
showDelay = 3e3,
|
|
2424
|
+
dismissible = true,
|
|
2425
|
+
message = "Is this your business?",
|
|
2426
|
+
buttonText = "Claim This Site",
|
|
2427
|
+
className = ""
|
|
2428
|
+
}) {
|
|
2429
|
+
const [isVisible, setIsVisible] = (0, import_react7.useState)(false);
|
|
2430
|
+
const [isDismissed, setIsDismissed] = (0, import_react7.useState)(false);
|
|
2431
|
+
(0, import_react7.useEffect)(() => {
|
|
2432
|
+
const dismissed = sessionStorage.getItem("claimBannerDismissed");
|
|
2433
|
+
if (dismissed) {
|
|
2434
|
+
setIsDismissed(true);
|
|
2435
|
+
return;
|
|
2436
|
+
}
|
|
2437
|
+
const timer = setTimeout(() => {
|
|
2438
|
+
setIsVisible(true);
|
|
2439
|
+
}, showDelay);
|
|
2440
|
+
return () => clearTimeout(timer);
|
|
2441
|
+
}, [showDelay]);
|
|
2442
|
+
const handleDismiss = () => {
|
|
2443
|
+
setIsVisible(false);
|
|
2444
|
+
setIsDismissed(true);
|
|
2445
|
+
sessionStorage.setItem("claimBannerDismissed", "true");
|
|
2446
|
+
};
|
|
2447
|
+
const handleClaim = () => {
|
|
2448
|
+
const url = siteUrl || (typeof window !== "undefined" ? window.location.hostname : "unknown");
|
|
2449
|
+
const subject = encodeURIComponent(`Claim my site - ${url}`);
|
|
2450
|
+
const body = encodeURIComponent(
|
|
2451
|
+
`Hi,
|
|
2452
|
+
|
|
2453
|
+
I am the owner of ${businessName || "this business"} and I would like to claim my website at ${url}.
|
|
2454
|
+
|
|
2455
|
+
Please contact me to discuss.
|
|
2456
|
+
|
|
2457
|
+
Thank you!`
|
|
2458
|
+
);
|
|
2459
|
+
window.location.href = `mailto:${contactEmail}?subject=${subject}&body=${body}`;
|
|
2460
|
+
};
|
|
2461
|
+
if (isDismissed || !isVisible) {
|
|
2462
|
+
return null;
|
|
2463
|
+
}
|
|
2464
|
+
const positionClasses = {
|
|
2465
|
+
"bottom-right": "bottom-4 right-4",
|
|
2466
|
+
"bottom-left": "bottom-4 left-4",
|
|
2467
|
+
"bottom-center": "bottom-4 left-1/2 -translate-x-1/2"
|
|
2468
|
+
};
|
|
2469
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
2470
|
+
"div",
|
|
2471
|
+
{
|
|
2472
|
+
className: `
|
|
2473
|
+
fixed z-50 ${positionClasses[position]}
|
|
2474
|
+
animate-slide-up
|
|
2475
|
+
${className}
|
|
2476
|
+
`,
|
|
2477
|
+
style: {
|
|
2478
|
+
animation: "slideUp 0.5s ease-out"
|
|
2479
|
+
},
|
|
2480
|
+
children: [
|
|
2481
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "bg-white rounded-lg shadow-2xl border border-gray-200 p-4 max-w-sm", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
2482
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex-shrink-0 w-10 h-10 bg-primary-100 rounded-full flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { className: "w-5 h-5 text-primary-600", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }) }),
|
|
2483
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
2484
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-sm font-medium text-gray-900", children: message }),
|
|
2485
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-xs text-gray-500 mt-1", children: "We built this site for you. Claim it today!" }),
|
|
2486
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
2487
|
+
"button",
|
|
2488
|
+
{
|
|
2489
|
+
onClick: handleClaim,
|
|
2490
|
+
className: "mt-3 w-full inline-flex items-center justify-center px-4 py-2 bg-primary-600 text-white text-sm font-medium rounded-lg hover:bg-primary-700 transition-colors",
|
|
2491
|
+
children: [
|
|
2492
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { className: "w-4 h-4 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" }) }),
|
|
2493
|
+
buttonText
|
|
2494
|
+
]
|
|
2495
|
+
}
|
|
2496
|
+
)
|
|
2497
|
+
] }),
|
|
2498
|
+
dismissible && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2499
|
+
"button",
|
|
2500
|
+
{
|
|
2501
|
+
onClick: handleDismiss,
|
|
2502
|
+
className: "flex-shrink-0 text-gray-400 hover:text-gray-600 transition-colors",
|
|
2503
|
+
"aria-label": "Dismiss",
|
|
2504
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
2505
|
+
}
|
|
2506
|
+
)
|
|
2507
|
+
] }) }),
|
|
2508
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("style", { jsx: true, children: `
|
|
2509
|
+
@keyframes slideUp {
|
|
2510
|
+
from {
|
|
2511
|
+
opacity: 0;
|
|
2512
|
+
transform: translateY(20px);
|
|
2513
|
+
}
|
|
2514
|
+
to {
|
|
2515
|
+
opacity: 1;
|
|
2516
|
+
transform: translateY(0);
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
` })
|
|
2520
|
+
]
|
|
2521
|
+
}
|
|
2522
|
+
);
|
|
2523
|
+
}
|
|
1658
2524
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1659
2525
|
0 && (module.exports = {
|
|
2526
|
+
AnimatedSection,
|
|
2527
|
+
BeforeAfter,
|
|
1660
2528
|
BriefcaseIcon,
|
|
1661
2529
|
Button,
|
|
1662
2530
|
ButtonLink,
|
|
@@ -1672,6 +2540,7 @@ function CardImage({
|
|
|
1672
2540
|
ClockIcon,
|
|
1673
2541
|
FAQ,
|
|
1674
2542
|
FacebookIcon,
|
|
2543
|
+
FloatingClaimBanner,
|
|
1675
2544
|
Footer,
|
|
1676
2545
|
Gallery,
|
|
1677
2546
|
Header,
|
|
@@ -1682,13 +2551,16 @@ function CardImage({
|
|
|
1682
2551
|
InstagramIcon,
|
|
1683
2552
|
MailIcon,
|
|
1684
2553
|
MapPinIcon,
|
|
2554
|
+
Menu,
|
|
1685
2555
|
MenuIcon,
|
|
1686
2556
|
PhoneIcon,
|
|
1687
2557
|
ScissorsIcon,
|
|
1688
2558
|
Services,
|
|
1689
2559
|
SparklesIcon,
|
|
2560
|
+
StaggerContainer,
|
|
1690
2561
|
StarIcon,
|
|
1691
2562
|
Testimonials,
|
|
2563
|
+
TrustBadges,
|
|
1692
2564
|
UtensilsIcon,
|
|
1693
2565
|
WrenchIcon,
|
|
1694
2566
|
XIcon,
|