@retinalabsllc/zairusjs 9.0.2 → 9.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/dist/index.d.mts +231 -1
- package/dist/index.d.ts +231 -1
- package/dist/index.js +1624 -268
- package/dist/index.mjs +1652 -264
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -293,8 +293,258 @@ var Header = ({
|
|
|
293
293
|
);
|
|
294
294
|
};
|
|
295
295
|
|
|
296
|
+
// src/components/PipleAuth.tsx
|
|
297
|
+
import React5, { useState as useState3, useRef as useRef2, useEffect as useEffect3, Suspense } from "react";
|
|
298
|
+
import { useSearchParams } from "next/navigation";
|
|
299
|
+
import toast from "react-hot-toast";
|
|
300
|
+
import { useGoogleReCaptcha, GoogleReCaptchaProvider } from "react-google-recaptcha-v3";
|
|
301
|
+
var InputSpinner = () => /* @__PURE__ */ React5.createElement("svg", { className: "animate-spin h-4 w-4 text-neutral-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ React5.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React5.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
|
|
302
|
+
function AuthFormInner({
|
|
303
|
+
companyName,
|
|
304
|
+
workspaceLabel = "Workspace",
|
|
305
|
+
termsUrl = "https://aeona.finance/terms-of-service",
|
|
306
|
+
privacyUrl = "https://aeona.finance/privacy-policy",
|
|
307
|
+
requireNames = true,
|
|
308
|
+
requireOrganization = true,
|
|
309
|
+
useRecaptcha = false,
|
|
310
|
+
defaultRedirectPath = "/app",
|
|
311
|
+
onAuthRequest,
|
|
312
|
+
onVerifyOtp
|
|
313
|
+
}) {
|
|
314
|
+
const searchParams = useSearchParams();
|
|
315
|
+
const redirectUrl = searchParams.get("redirect") || defaultRedirectPath;
|
|
316
|
+
const captchaContext = useRecaptcha ? useGoogleReCaptcha() : null;
|
|
317
|
+
const [mode, setMode] = useState3("LOGIN");
|
|
318
|
+
const [step, setStep] = useState3("INPUT");
|
|
319
|
+
const getInitialSignupStep = () => {
|
|
320
|
+
if (requireNames) return "NAME";
|
|
321
|
+
if (requireOrganization) return "ORGANIZATION";
|
|
322
|
+
return "EMAIL_ID";
|
|
323
|
+
};
|
|
324
|
+
const [signupStep, setSignupStep] = useState3(getInitialSignupStep());
|
|
325
|
+
const [isSubmitting, setIsSubmitting] = useState3(false);
|
|
326
|
+
const [countdown, setCountdown] = useState3(0);
|
|
327
|
+
const [emailId, setEmailId] = useState3("");
|
|
328
|
+
const [firstName, setFirstName] = useState3("");
|
|
329
|
+
const [lastName, setLastName] = useState3("");
|
|
330
|
+
const [orgName, setOrgName] = useState3("");
|
|
331
|
+
const [agreedToTerms, setAgreedToTerms] = useState3(false);
|
|
332
|
+
const [otp, setOtp] = useState3(["", "", "", "", "", ""]);
|
|
333
|
+
const inputRefs = useRef2([]);
|
|
334
|
+
const cleanAlpha = (val) => val.replace(/[^a-zA-Z\s-]/g, "");
|
|
335
|
+
const cleanOrgName = (val) => val.replace(/[^a-zA-Z0-9\s]/g, "").substring(0, 50);
|
|
336
|
+
const cleanEmailId = (val) => val.toLowerCase().replace(/[^a-z0-9@._-]/g, "");
|
|
337
|
+
useEffect3(() => {
|
|
338
|
+
if (countdown > 0) {
|
|
339
|
+
const timer = setTimeout(() => setCountdown(countdown - 1), 1e3);
|
|
340
|
+
return () => clearTimeout(timer);
|
|
341
|
+
}
|
|
342
|
+
}, [countdown]);
|
|
343
|
+
const handleOtpChange = (index, value) => {
|
|
344
|
+
const cleanValue = value.replace(/[^0-9]/g, "");
|
|
345
|
+
if (!cleanValue && value !== "") return;
|
|
346
|
+
const newOtp = [...otp];
|
|
347
|
+
newOtp[index] = cleanValue.slice(-1);
|
|
348
|
+
setOtp(newOtp);
|
|
349
|
+
if (cleanValue && index < 5) {
|
|
350
|
+
inputRefs.current[index + 1]?.focus();
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
const handlePaste = (e) => {
|
|
354
|
+
e.preventDefault();
|
|
355
|
+
const pastedData = e.clipboardData.getData("text/plain");
|
|
356
|
+
const numbersOnly = pastedData.replace(/[^0-9]/g, "");
|
|
357
|
+
if (!numbersOnly) return;
|
|
358
|
+
const newOtp = [...otp];
|
|
359
|
+
const length = Math.min(numbersOnly.length, 6);
|
|
360
|
+
for (let i = 0; i < length; i++) {
|
|
361
|
+
newOtp[i] = numbersOnly[i];
|
|
362
|
+
}
|
|
363
|
+
setOtp(newOtp);
|
|
364
|
+
if (length < 6) {
|
|
365
|
+
inputRefs.current[length]?.focus();
|
|
366
|
+
} else {
|
|
367
|
+
inputRefs.current[5]?.focus();
|
|
368
|
+
verifyOtpCode(newOtp.join(""));
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
const handleAuthRequestSubmit = async (e) => {
|
|
372
|
+
if (e) e.preventDefault();
|
|
373
|
+
if (mode === "SIGNUP" && !agreedToTerms) {
|
|
374
|
+
toast.error("You must agree to the Terms and Privacy Policy.");
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
if (isSubmitting || countdown > 0) return;
|
|
378
|
+
setIsSubmitting(true);
|
|
379
|
+
try {
|
|
380
|
+
let recaptchaToken = void 0;
|
|
381
|
+
if (useRecaptcha && captchaContext?.executeRecaptcha) {
|
|
382
|
+
recaptchaToken = await captchaContext.executeRecaptcha("auth_request");
|
|
383
|
+
}
|
|
384
|
+
const res = await onAuthRequest({
|
|
385
|
+
email: emailId,
|
|
386
|
+
firstName: mode === "SIGNUP" && requireNames ? firstName : void 0,
|
|
387
|
+
lastName: mode === "SIGNUP" && requireNames ? lastName : void 0,
|
|
388
|
+
organizationName: mode === "SIGNUP" && requireOrganization ? orgName : void 0,
|
|
389
|
+
mode,
|
|
390
|
+
recaptchaToken
|
|
391
|
+
});
|
|
392
|
+
if (res.success) {
|
|
393
|
+
toast.success("Verification code sent");
|
|
394
|
+
setStep("OTP");
|
|
395
|
+
setCountdown(60);
|
|
396
|
+
} else {
|
|
397
|
+
toast.error(res.error || "Authentication failed.");
|
|
398
|
+
}
|
|
399
|
+
} catch {
|
|
400
|
+
toast.error("Service unavailable. Try again later.");
|
|
401
|
+
} finally {
|
|
402
|
+
setIsSubmitting(false);
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
const verifyOtpCode = async (codeToVerify) => {
|
|
406
|
+
if (codeToVerify.length !== 6 || isSubmitting) return;
|
|
407
|
+
setIsSubmitting(true);
|
|
408
|
+
try {
|
|
409
|
+
const res = await onVerifyOtp({ email: emailId, code: codeToVerify });
|
|
410
|
+
if (res.success) {
|
|
411
|
+
window.location.href = res.redirect || redirectUrl;
|
|
412
|
+
} else {
|
|
413
|
+
toast.error(res.error || "Invalid code.");
|
|
414
|
+
setOtp(["", "", "", "", "", ""]);
|
|
415
|
+
inputRefs.current[0]?.focus();
|
|
416
|
+
}
|
|
417
|
+
} catch {
|
|
418
|
+
toast.error("Verification failed.");
|
|
419
|
+
} finally {
|
|
420
|
+
setIsSubmitting(false);
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
const handleNextSignupStep = () => {
|
|
424
|
+
if (signupStep === "NAME") {
|
|
425
|
+
if (requireOrganization) setSignupStep("ORGANIZATION");
|
|
426
|
+
else setSignupStep("EMAIL_ID");
|
|
427
|
+
} else if (signupStep === "ORGANIZATION") {
|
|
428
|
+
setSignupStep("EMAIL_ID");
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
const isContinueDisabled = () => {
|
|
432
|
+
if (isSubmitting) return true;
|
|
433
|
+
if (mode === "LOGIN") return emailId.length < 3;
|
|
434
|
+
if (mode === "SIGNUP") {
|
|
435
|
+
if (signupStep === "NAME") return firstName.trim() === "" || lastName.trim() === "";
|
|
436
|
+
if (signupStep === "ORGANIZATION") return orgName.trim().length < 3;
|
|
437
|
+
if (signupStep === "EMAIL_ID") return emailId.length < 3 || !agreedToTerms;
|
|
438
|
+
}
|
|
439
|
+
return false;
|
|
440
|
+
};
|
|
441
|
+
return /* @__PURE__ */ React5.createElement("div", { className: "w-full max-w-md mx-auto flex flex-col items-center gap-4 relative z-10 animate-in fade-in duration-300" }, /* @__PURE__ */ React5.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ React5.createElement("div", { className: "p-8 md:p-12" }, step === "INPUT" && /* @__PURE__ */ React5.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ React5.createElement("div", { className: "mb-12 text-center mt-2" }, /* @__PURE__ */ React5.createElement("h2", { className: " text-xl text-black mb-2 tracking-tight " }, mode === "LOGIN" ? `${companyName} ${workspaceLabel}` : "Create Account"), /* @__PURE__ */ React5.createElement("div", { className: "text-[13px] text-neutral-500" }, mode === "LOGIN" ? /* @__PURE__ */ React5.createElement(React5.Fragment, null, "Don't have an account? ", /* @__PURE__ */ React5.createElement("button", { type: "button", onClick: () => {
|
|
442
|
+
setMode("SIGNUP");
|
|
443
|
+
setSignupStep(getInitialSignupStep());
|
|
444
|
+
}, className: "text-black transition-colors ml-1" }, "Sign up")) : /* @__PURE__ */ React5.createElement(React5.Fragment, null, "Already have an account? ", /* @__PURE__ */ React5.createElement("button", { type: "button", onClick: () => setMode("LOGIN"), className: "text-black transition-colors ml-1" }, "Log in")))), /* @__PURE__ */ React5.createElement("form", { className: "space-y-6", autoComplete: "off", onSubmit: (e) => {
|
|
445
|
+
e.preventDefault();
|
|
446
|
+
if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
|
|
447
|
+
else if (mode === "SIGNUP" && signupStep === "ORGANIZATION") handleNextSignupStep();
|
|
448
|
+
else handleAuthRequestSubmit();
|
|
449
|
+
} }, mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ React5.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ React5.createElement(
|
|
450
|
+
"input",
|
|
451
|
+
{
|
|
452
|
+
type: "text",
|
|
453
|
+
value: firstName,
|
|
454
|
+
onChange: (e) => setFirstName(cleanAlpha(e.target.value)),
|
|
455
|
+
required: true,
|
|
456
|
+
autoFocus: true,
|
|
457
|
+
className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
|
|
458
|
+
placeholder: "First name"
|
|
459
|
+
}
|
|
460
|
+
)), /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ React5.createElement(
|
|
461
|
+
"input",
|
|
462
|
+
{
|
|
463
|
+
type: "text",
|
|
464
|
+
value: lastName,
|
|
465
|
+
onChange: (e) => setLastName(cleanAlpha(e.target.value)),
|
|
466
|
+
required: true,
|
|
467
|
+
className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
|
|
468
|
+
placeholder: "Last name"
|
|
469
|
+
}
|
|
470
|
+
))), mode === "SIGNUP" && signupStep === "ORGANIZATION" && requireOrganization && /* @__PURE__ */ React5.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Organization Name"), /* @__PURE__ */ React5.createElement(
|
|
471
|
+
"input",
|
|
472
|
+
{
|
|
473
|
+
type: "text",
|
|
474
|
+
value: orgName,
|
|
475
|
+
onChange: (e) => setOrgName(cleanOrgName(e.target.value)),
|
|
476
|
+
required: true,
|
|
477
|
+
autoFocus: true,
|
|
478
|
+
className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
|
|
479
|
+
placeholder: "Acme Corporation"
|
|
480
|
+
}
|
|
481
|
+
))), (mode === "LOGIN" || mode === "SIGNUP" && signupStep === "EMAIL_ID") && /* @__PURE__ */ React5.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Email ID"), /* @__PURE__ */ React5.createElement(
|
|
482
|
+
"input",
|
|
483
|
+
{
|
|
484
|
+
type: "email",
|
|
485
|
+
value: emailId,
|
|
486
|
+
onChange: (e) => setEmailId(cleanEmailId(e.target.value)),
|
|
487
|
+
required: true,
|
|
488
|
+
autoFocus: true,
|
|
489
|
+
className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-100 text-black outline-none focus:border-black transition-all duration-300",
|
|
490
|
+
placeholder: "name@company.com"
|
|
491
|
+
}
|
|
492
|
+
)), mode === "SIGNUP" && /* @__PURE__ */ React5.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ React5.createElement(
|
|
493
|
+
"input",
|
|
494
|
+
{
|
|
495
|
+
type: "checkbox",
|
|
496
|
+
id: "zairus-terms",
|
|
497
|
+
checked: agreedToTerms,
|
|
498
|
+
onChange: (e) => setAgreedToTerms(e.target.checked),
|
|
499
|
+
className: "mt-0.5 w-4 h-4 bg-white border-neutral-300 rounded text-black focus:ring-black cursor-pointer",
|
|
500
|
+
required: true
|
|
501
|
+
}
|
|
502
|
+
), /* @__PURE__ */ React5.createElement("label", { htmlFor: "zairus-terms", className: "text-[11px] text-neutral-500 cursor-pointer leading-snug" }, "I agree to ", companyName, "'s ", /* @__PURE__ */ React5.createElement("a", { href: termsUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Terms of Service"), " and ", /* @__PURE__ */ React5.createElement("a", { href: privacyUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Privacy Policy"), "."))), /* @__PURE__ */ React5.createElement(
|
|
503
|
+
ThreeDActionButton,
|
|
504
|
+
{
|
|
505
|
+
type: "submit",
|
|
506
|
+
disabled: isContinueDisabled(),
|
|
507
|
+
isLoading: isSubmitting,
|
|
508
|
+
className: "w-full mt-10"
|
|
509
|
+
},
|
|
510
|
+
"Continue"
|
|
511
|
+
))), step === "OTP" && /* @__PURE__ */ React5.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ React5.createElement("div", { className: "text-center mb-10 mt-2" }, /* @__PURE__ */ React5.createElement("h2", { className: " text-xl text-black mb-2 tracking-tight " }, "Security Check"), /* @__PURE__ */ React5.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the code sent to ", /* @__PURE__ */ React5.createElement("br", null), /* @__PURE__ */ React5.createElement("span", { className: "text-black " }, emailId))), /* @__PURE__ */ React5.createElement("form", { className: "space-y-10", autoComplete: "off", onSubmit: (e) => {
|
|
512
|
+
e.preventDefault();
|
|
513
|
+
verifyOtpCode(otp.join(""));
|
|
514
|
+
} }, /* @__PURE__ */ React5.createElement("div", { className: "flex justify-between gap-2", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ React5.createElement(
|
|
515
|
+
"input",
|
|
516
|
+
{
|
|
517
|
+
key: index,
|
|
518
|
+
ref: (el) => {
|
|
519
|
+
inputRefs.current[index] = el;
|
|
520
|
+
},
|
|
521
|
+
type: "text",
|
|
522
|
+
inputMode: "numeric",
|
|
523
|
+
maxLength: 1,
|
|
524
|
+
value: digit,
|
|
525
|
+
onChange: (e) => handleOtpChange(index, e.target.value),
|
|
526
|
+
className: "w-8 h-8 text-center text-lg bg-transparent border-b-2 border-neutral-100 text-black outline-none focus:border-black transition-all duration-300"
|
|
527
|
+
}
|
|
528
|
+
))), /* @__PURE__ */ React5.createElement(
|
|
529
|
+
ThreeDActionButton,
|
|
530
|
+
{
|
|
531
|
+
type: "submit",
|
|
532
|
+
disabled: otp.join("").length < 6,
|
|
533
|
+
isLoading: isSubmitting,
|
|
534
|
+
className: "w-full"
|
|
535
|
+
},
|
|
536
|
+
"Verify Code"
|
|
537
|
+
))))));
|
|
538
|
+
}
|
|
539
|
+
var PipleAuth = (props) => {
|
|
540
|
+
if (props.useRecaptcha && props.recaptchaSiteKey) {
|
|
541
|
+
return /* @__PURE__ */ React5.createElement(GoogleReCaptchaProvider, { reCaptchaKey: props.recaptchaSiteKey }, /* @__PURE__ */ React5.createElement(Suspense, { fallback: /* @__PURE__ */ React5.createElement("div", { className: "h-64 flex items-center justify-center" }, /* @__PURE__ */ React5.createElement(InputSpinner, null)) }, /* @__PURE__ */ React5.createElement(AuthFormInner, { ...props })));
|
|
542
|
+
}
|
|
543
|
+
return /* @__PURE__ */ React5.createElement(Suspense, { fallback: /* @__PURE__ */ React5.createElement("div", { className: "h-64 flex items-center justify-center" }, /* @__PURE__ */ React5.createElement(InputSpinner, null)) }, /* @__PURE__ */ React5.createElement(AuthFormInner, { ...props }));
|
|
544
|
+
};
|
|
545
|
+
|
|
296
546
|
// src/components/Footer.tsx
|
|
297
|
-
import
|
|
547
|
+
import React6, { useState as useState4 } from "react";
|
|
298
548
|
import Link3 from "next/link";
|
|
299
549
|
import { HugeiconsIcon as HugeiconsIcon2 } from "@hugeicons/react";
|
|
300
550
|
var Footer = ({
|
|
@@ -304,20 +554,20 @@ var Footer = ({
|
|
|
304
554
|
copyrightText,
|
|
305
555
|
topSection
|
|
306
556
|
}) => {
|
|
307
|
-
const [openCol, setOpenCol] =
|
|
557
|
+
const [openCol, setOpenCol] = useState4(null);
|
|
308
558
|
const toggleColumn = (idx) => {
|
|
309
559
|
setOpenCol(openCol === idx ? null : idx);
|
|
310
560
|
};
|
|
311
|
-
return /* @__PURE__ */
|
|
561
|
+
return /* @__PURE__ */ React6.createElement("div", { className: "" }, topSection && topSection, /* @__PURE__ */ React6.createElement("footer", { className: "relative px-6 overflow-hidden flex flex-col" }, /* @__PURE__ */ React6.createElement("div", { className: "relative w-full max-w-7xl mx-auto z-20 flex flex-col" }, /* @__PURE__ */ React6.createElement("div", { className: "relative py-12 md:py-16" }, /* @__PURE__ */ React6.createElement("div", { className: "flex flex-col lg:flex-row justify-between items-start gap-12 lg:gap-16 mb-12 text-left" }, /* @__PURE__ */ React6.createElement("div", { className: "w-full lg:max-w-sm flex flex-col items-start justify-between shrink-0" }, /* @__PURE__ */ React6.createElement("div", { className: "flex items-center gap-4 mb-4" }, /* @__PURE__ */ React6.createElement("img", { src: "https://retinalabs.company/assets/images/ndpr.avif", alt: "NDPR", className: "w-28 h-auto object-contain filter grayscale opacity-80" }), /* @__PURE__ */ React6.createElement("img", { src: "https://retinalabs.company/assets/images/gdpr.avif", alt: "GDPR", className: "w-12 h-12 object-contain filter grayscale opacity-80" })), /* @__PURE__ */ React6.createElement("div", null, /* @__PURE__ */ React6.createElement("p", { className: "text-[11px] text-neutral-600 leading-relaxed pr-4" }, description))), /* @__PURE__ */ React6.createElement("div", { className: "w-full lg:flex-1 lg:max-w-2xl" }, /* @__PURE__ */ React6.createElement("div", { className: "hidden md:grid grid-cols-2 gap-x-16 lg:gap-x-24 gap-y-12" }, columns.map((col, idx) => /* @__PURE__ */ React6.createElement("div", { key: idx, className: "flex flex-col" }, /* @__PURE__ */ React6.createElement("h4", { className: "text-[11px] tracking-[0.2em] text-black mb-6 " }, col.title), /* @__PURE__ */ React6.createElement("ul", { className: "space-y-4 text-[13px] text-neutral-500" }, col.links.map((link, lIdx) => /* @__PURE__ */ React6.createElement("li", { key: lIdx }, link.isExternal ? /* @__PURE__ */ React6.createElement("a", { href: link.href, target: "_blank", rel: "noopener noreferrer", className: "hover:text-black transition-colors block truncate" }, link.label) : /* @__PURE__ */ React6.createElement(Link3, { href: link.href, className: "hover:text-black transition-colors block truncate" }, link.label))))))), /* @__PURE__ */ React6.createElement("div", { className: "flex flex-col md:hidden w-full border-t border-neutral-100 mt-4" }, columns.map((col, idx) => {
|
|
312
562
|
const isOpen = openCol === idx;
|
|
313
|
-
return /* @__PURE__ */
|
|
563
|
+
return /* @__PURE__ */ React6.createElement("div", { key: idx, className: "border-b border-neutral-100" }, /* @__PURE__ */ React6.createElement(
|
|
314
564
|
"button",
|
|
315
565
|
{
|
|
316
566
|
onClick: () => toggleColumn(idx),
|
|
317
567
|
className: "w-full flex items-center justify-between py-5 text-left outline-none"
|
|
318
568
|
},
|
|
319
|
-
/* @__PURE__ */
|
|
320
|
-
/* @__PURE__ */
|
|
569
|
+
/* @__PURE__ */ React6.createElement("span", { className: "text-[11px] tracking-[0.2em] text-black " }, col.title),
|
|
570
|
+
/* @__PURE__ */ React6.createElement(
|
|
321
571
|
"svg",
|
|
322
572
|
{
|
|
323
573
|
className: `w-4 h-4 text-neutral-400 transition-transform duration-300 ${isOpen ? "rotate-180" : ""}`,
|
|
@@ -325,10 +575,10 @@ var Footer = ({
|
|
|
325
575
|
viewBox: "0 0 24 24",
|
|
326
576
|
stroke: "currentColor"
|
|
327
577
|
},
|
|
328
|
-
/* @__PURE__ */
|
|
578
|
+
/* @__PURE__ */ React6.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M19 9l-7 7-7-7" })
|
|
329
579
|
)
|
|
330
|
-
), /* @__PURE__ */
|
|
331
|
-
})))), /* @__PURE__ */
|
|
580
|
+
), /* @__PURE__ */ React6.createElement("div", { className: `grid transition-all duration-300 ease-in-out ${isOpen ? "grid-rows-[1fr] pb-6 opacity-100" : "grid-rows-[0fr] opacity-0"}` }, /* @__PURE__ */ React6.createElement("div", { className: "overflow-hidden" }, /* @__PURE__ */ React6.createElement("ul", { className: "space-y-4 text-[13px] text-neutral-500 pt-2" }, col.links.map((link, lIdx) => /* @__PURE__ */ React6.createElement("li", { key: lIdx }, link.isExternal ? /* @__PURE__ */ React6.createElement("a", { href: link.href, target: "_blank", rel: "noopener noreferrer", className: "hover:text-black transition-colors" }, link.label) : /* @__PURE__ */ React6.createElement(Link3, { href: link.href, className: "hover:text-black transition-colors" }, link.label)))))));
|
|
581
|
+
})))), /* @__PURE__ */ React6.createElement("div", { className: "pt-8 mt-4 flex flex-col-reverse md:flex-row justify-between items-start md:items-center gap-6 relative z-20" }, /* @__PURE__ */ React6.createElement("p", { className: "text-[11px] text-neutral-400 tracking-widest text-left" }, copyrightText), socialLinks && socialLinks.length > 0 && /* @__PURE__ */ React6.createElement("div", { className: "flex items-center gap-6" }, socialLinks.map((social, idx) => /* @__PURE__ */ React6.createElement(
|
|
332
582
|
"a",
|
|
333
583
|
{
|
|
334
584
|
key: idx,
|
|
@@ -338,21 +588,89 @@ var Footer = ({
|
|
|
338
588
|
className: "text-neutral-400 hover:text-black transition-colors",
|
|
339
589
|
"aria-label": social.name
|
|
340
590
|
},
|
|
341
|
-
/* @__PURE__ */
|
|
591
|
+
/* @__PURE__ */ React6.createElement(HugeiconsIcon2, { icon: social.icon, size: 20 })
|
|
342
592
|
))))))));
|
|
343
593
|
};
|
|
344
594
|
|
|
345
|
-
// src/components/
|
|
346
|
-
import
|
|
595
|
+
// src/components/MobileNav.tsx
|
|
596
|
+
import React7 from "react";
|
|
347
597
|
import Link4 from "next/link";
|
|
348
|
-
import
|
|
598
|
+
import { usePathname as usePathname2 } from "next/navigation";
|
|
599
|
+
import { HugeiconsIcon as HugeiconsIcon3 } from "@hugeicons/react";
|
|
600
|
+
var MobileNav = ({ items }) => {
|
|
601
|
+
const pathname = usePathname2();
|
|
602
|
+
if (!items || items.length === 0) return null;
|
|
603
|
+
return (
|
|
604
|
+
// Wrapper: Fixed at the bottom, centered, hidden on desktop (sm:hidden)
|
|
605
|
+
/* @__PURE__ */ React7.createElement("div", { className: "fixed bottom-6 inset-x-0 z-100 flex justify-center pointer-events-none px-4 sm:hidden animate-in slide-in-from-bottom-8 fade-in duration-500" }, /* @__PURE__ */ React7.createElement("nav", { className: "pointer-events-auto w-full max-w-sm bg-white/80 backdrop-blur-xl border border-neutral-200/60 shadow-[0_8px_30px_rgb(0,0,0,0.08)] rounded-full px-6 py-2.5 flex items-center justify-between" }, items.map((item) => {
|
|
606
|
+
const isActive = item.href === "/" ? pathname === "/" : pathname?.startsWith(item.href);
|
|
607
|
+
return /* @__PURE__ */ React7.createElement(
|
|
608
|
+
Link4,
|
|
609
|
+
{
|
|
610
|
+
key: item.label,
|
|
611
|
+
href: item.href,
|
|
612
|
+
className: "flex flex-col items-center justify-center gap-1 min-w-14 transition-transform active:scale-95 outline-none"
|
|
613
|
+
},
|
|
614
|
+
/* @__PURE__ */ React7.createElement("div", { className: `transition-colors duration-300 ${isActive ? "text-black" : "text-neutral-400 hover:text-neutral-600"}` }, /* @__PURE__ */ React7.createElement(
|
|
615
|
+
HugeiconsIcon3,
|
|
616
|
+
{
|
|
617
|
+
icon: item.icon,
|
|
618
|
+
size: 24
|
|
619
|
+
}
|
|
620
|
+
)),
|
|
621
|
+
/* @__PURE__ */ React7.createElement(
|
|
622
|
+
"span",
|
|
623
|
+
{
|
|
624
|
+
className: `text-[10px] tracking-wide transition-colors duration-300 font-medium ${isActive ? "text-black" : "text-neutral-400"}`
|
|
625
|
+
},
|
|
626
|
+
item.label
|
|
627
|
+
)
|
|
628
|
+
);
|
|
629
|
+
})))
|
|
630
|
+
);
|
|
631
|
+
};
|
|
349
632
|
|
|
350
|
-
// src/components/
|
|
351
|
-
import
|
|
352
|
-
import
|
|
633
|
+
// src/components/UniversalOrganizationPage.tsx
|
|
634
|
+
import React11, { useState as useState6, useEffect as useEffect4 } from "react";
|
|
635
|
+
import toast2 from "react-hot-toast";
|
|
636
|
+
|
|
637
|
+
// src/components/ManagedToaster.tsx
|
|
638
|
+
import React8 from "react";
|
|
639
|
+
import { Toaster } from "react-hot-toast";
|
|
640
|
+
var ManagedToaster = () => {
|
|
641
|
+
return /* @__PURE__ */ React8.createElement(
|
|
642
|
+
Toaster,
|
|
643
|
+
{
|
|
644
|
+
position: "top-right",
|
|
645
|
+
toastOptions: {
|
|
646
|
+
style: {
|
|
647
|
+
background: "#171717",
|
|
648
|
+
color: "#fafafa",
|
|
649
|
+
fontSize: "11px",
|
|
650
|
+
padding: "8px 12px",
|
|
651
|
+
borderRadius: "8px",
|
|
652
|
+
minWidth: "fit-content",
|
|
653
|
+
boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.5)"
|
|
654
|
+
},
|
|
655
|
+
success: {
|
|
656
|
+
iconTheme: {
|
|
657
|
+
primary: "#fafafa",
|
|
658
|
+
secondary: "#171717"
|
|
659
|
+
}
|
|
660
|
+
},
|
|
661
|
+
error: {
|
|
662
|
+
iconTheme: {
|
|
663
|
+
primary: "#fafafa",
|
|
664
|
+
secondary: "#171717"
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
);
|
|
670
|
+
};
|
|
353
671
|
|
|
354
672
|
// src/components/ReusableInputs.tsx
|
|
355
|
-
import
|
|
673
|
+
import React9 from "react";
|
|
356
674
|
var TextInput = ({
|
|
357
675
|
label,
|
|
358
676
|
value,
|
|
@@ -363,7 +681,7 @@ var TextInput = ({
|
|
|
363
681
|
readOnly,
|
|
364
682
|
type = "text",
|
|
365
683
|
onClick
|
|
366
|
-
}) => /* @__PURE__ */
|
|
684
|
+
}) => /* @__PURE__ */ React9.createElement("div", { className: "space-y-2 flex-1 w-full", onClick }, label && /* @__PURE__ */ React9.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, label), /* @__PURE__ */ React9.createElement(
|
|
367
685
|
"input",
|
|
368
686
|
{
|
|
369
687
|
type,
|
|
@@ -384,7 +702,7 @@ var NumberInput = ({
|
|
|
384
702
|
placeholder,
|
|
385
703
|
maxLength,
|
|
386
704
|
disabled
|
|
387
|
-
}) => /* @__PURE__ */
|
|
705
|
+
}) => /* @__PURE__ */ React9.createElement("div", { className: "space-y-2 flex-1 w-full" }, label && /* @__PURE__ */ React9.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, label), /* @__PURE__ */ React9.createElement(
|
|
388
706
|
"input",
|
|
389
707
|
{
|
|
390
708
|
type: "text",
|
|
@@ -401,15 +719,1132 @@ var NumberInput = ({
|
|
|
401
719
|
}
|
|
402
720
|
));
|
|
403
721
|
|
|
722
|
+
// src/components/Banner.tsx
|
|
723
|
+
import React10, { useState as useState5 } from "react";
|
|
724
|
+
import { HugeiconsIcon as HugeiconsIcon4 } from "@hugeicons/react";
|
|
725
|
+
import {
|
|
726
|
+
Alert02Icon,
|
|
727
|
+
CheckmarkBadge01Icon,
|
|
728
|
+
InformationCircleIcon,
|
|
729
|
+
Cancel01Icon
|
|
730
|
+
} from "@hugeicons/core-free-icons";
|
|
731
|
+
var Banner = ({
|
|
732
|
+
title,
|
|
733
|
+
message,
|
|
734
|
+
type,
|
|
735
|
+
icon,
|
|
736
|
+
isDismissible = true,
|
|
737
|
+
onDismiss,
|
|
738
|
+
action
|
|
739
|
+
}) => {
|
|
740
|
+
const [isVisible, setIsVisible] = useState5(true);
|
|
741
|
+
if (!isVisible) return null;
|
|
742
|
+
const handleDismiss = () => {
|
|
743
|
+
setIsVisible(false);
|
|
744
|
+
if (onDismiss) onDismiss();
|
|
745
|
+
};
|
|
746
|
+
const config = {
|
|
747
|
+
success: {
|
|
748
|
+
bg: "bg-emerald-50",
|
|
749
|
+
iconColor: "text-emerald-600",
|
|
750
|
+
titleColor: "text-emerald-900",
|
|
751
|
+
msgColor: "text-emerald-700",
|
|
752
|
+
defaultIcon: CheckmarkBadge01Icon,
|
|
753
|
+
closeHover: "hover:bg-emerald-100 text-emerald-500"
|
|
754
|
+
},
|
|
755
|
+
warning: {
|
|
756
|
+
bg: "bg-amber-50",
|
|
757
|
+
iconColor: "text-amber-600",
|
|
758
|
+
titleColor: "text-amber-900",
|
|
759
|
+
msgColor: "text-amber-700",
|
|
760
|
+
defaultIcon: InformationCircleIcon,
|
|
761
|
+
closeHover: "hover:bg-amber-100 text-amber-500"
|
|
762
|
+
},
|
|
763
|
+
alert: {
|
|
764
|
+
bg: "bg-red-50",
|
|
765
|
+
iconColor: "text-red-600",
|
|
766
|
+
titleColor: "text-red-900",
|
|
767
|
+
msgColor: "text-red-700",
|
|
768
|
+
defaultIcon: Alert02Icon,
|
|
769
|
+
closeHover: "hover:bg-red-100 text-red-500"
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
const currentConfig = config[type];
|
|
773
|
+
const IconToUse = icon || currentConfig.defaultIcon;
|
|
774
|
+
return /* @__PURE__ */ React10.createElement("div", { className: `relative w-full rounded-2xl p-4 flex items-start gap-4 transition-all duration-300 animate-in fade-in slide-in-from-top-2 ${currentConfig.bg}` }, /* @__PURE__ */ React10.createElement("div", { className: "flex-1 flex flex-col min-w-0" }, /* @__PURE__ */ React10.createElement("h4", { className: `text-sm tracking-tight mb-1 ${currentConfig.titleColor}` }, title), /* @__PURE__ */ React10.createElement("p", { className: `text-xs leading-relaxed ${currentConfig.msgColor}` }, message), action && /* @__PURE__ */ React10.createElement("div", { className: "mt-3" }, action)), isDismissible && /* @__PURE__ */ React10.createElement(
|
|
775
|
+
"button",
|
|
776
|
+
{
|
|
777
|
+
onClick: handleDismiss,
|
|
778
|
+
className: `absolute top-3 right-3 p-1.5 rounded-full transition-colors outline-none shrink-0 ${currentConfig.closeHover}`,
|
|
779
|
+
"aria-label": "Dismiss banner"
|
|
780
|
+
},
|
|
781
|
+
/* @__PURE__ */ React10.createElement(HugeiconsIcon4, { icon: Cancel01Icon, size: 16 })
|
|
782
|
+
));
|
|
783
|
+
};
|
|
784
|
+
|
|
785
|
+
// src/components/UniversalOrganizationPage.tsx
|
|
786
|
+
import { HugeiconsIcon as HugeiconsIcon5 } from "@hugeicons/react";
|
|
787
|
+
import {
|
|
788
|
+
CircleLock02Icon
|
|
789
|
+
} from "@hugeicons/core-free-icons";
|
|
790
|
+
var InputSpinner2 = () => /* @__PURE__ */ React11.createElement("svg", { className: "animate-spin h-4 w-4 text-neutral-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ React11.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React11.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
|
|
791
|
+
var UniversalOrganizationPage = ({
|
|
792
|
+
initialOrgName,
|
|
793
|
+
initialSlug,
|
|
794
|
+
initialUsername,
|
|
795
|
+
orgId,
|
|
796
|
+
isReadOnly = false,
|
|
797
|
+
slugPrefixUrl = ".aeona.eth",
|
|
798
|
+
bannerProps,
|
|
799
|
+
onSaveConfiguration,
|
|
800
|
+
onCheckSlugAvailability
|
|
801
|
+
}) => {
|
|
802
|
+
const resolvedInitialUsername = initialUsername || initialSlug;
|
|
803
|
+
const [web3Name, setWeb3Name] = useState6(initialOrgName);
|
|
804
|
+
const [username, setUsername] = useState6(resolvedInitialUsername);
|
|
805
|
+
const [slug, setSlug] = useState6(initialSlug);
|
|
806
|
+
const [isCheckingSlug, setIsCheckingSlug] = useState6(false);
|
|
807
|
+
const [slugAvailable, setSlugAvailable] = useState6(null);
|
|
808
|
+
const [isSubmitting, setIsSubmitting] = useState6(false);
|
|
809
|
+
useEffect4(() => {
|
|
810
|
+
setWeb3Name(initialOrgName || "");
|
|
811
|
+
setSlug(initialSlug || "");
|
|
812
|
+
setUsername(initialUsername || initialSlug || "");
|
|
813
|
+
}, [initialOrgName, initialSlug, initialUsername]);
|
|
814
|
+
const handleWeb3NameChange = (val) => {
|
|
815
|
+
setWeb3Name(val.replace(/[^a-zA-Z0-9\s-]/g, "").substring(0, 50));
|
|
816
|
+
};
|
|
817
|
+
const handleUsernameChange = (val) => {
|
|
818
|
+
setUsername(val.toLowerCase().replace(/[^a-z0-9-]/g, "").substring(0, 30));
|
|
819
|
+
};
|
|
820
|
+
const handleSlugChange = (val) => {
|
|
821
|
+
setSlug(val.toLowerCase().replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").substring(0, 50));
|
|
822
|
+
};
|
|
823
|
+
useEffect4(() => {
|
|
824
|
+
if (!slug || slug === initialSlug) {
|
|
825
|
+
setSlugAvailable(null);
|
|
826
|
+
setIsCheckingSlug(false);
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
if (slug.length < 3) {
|
|
830
|
+
setSlugAvailable(false);
|
|
831
|
+
setIsCheckingSlug(false);
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
setIsCheckingSlug(true);
|
|
835
|
+
setSlugAvailable(null);
|
|
836
|
+
const checkTimer = setTimeout(async () => {
|
|
837
|
+
try {
|
|
838
|
+
const res = await onCheckSlugAvailability(slug);
|
|
839
|
+
setSlugAvailable(res.available);
|
|
840
|
+
} catch (error) {
|
|
841
|
+
setSlugAvailable(null);
|
|
842
|
+
} finally {
|
|
843
|
+
setIsCheckingSlug(false);
|
|
844
|
+
}
|
|
845
|
+
}, 1500);
|
|
846
|
+
return () => clearTimeout(checkTimer);
|
|
847
|
+
}, [slug, initialSlug, onCheckSlugAvailability]);
|
|
848
|
+
const handleSave = async (e) => {
|
|
849
|
+
e.preventDefault();
|
|
850
|
+
if (isSubmitting || isCheckingSlug || isReadOnly) return;
|
|
851
|
+
if (slug !== initialSlug && slugAvailable === false) {
|
|
852
|
+
toast2.error("Please select an available profile address handles.");
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
setIsSubmitting(true);
|
|
856
|
+
try {
|
|
857
|
+
const payload = {
|
|
858
|
+
organizationId: orgId,
|
|
859
|
+
organizationName: web3Name !== initialOrgName ? web3Name : void 0,
|
|
860
|
+
slug: slug !== initialSlug ? slug : void 0,
|
|
861
|
+
username: username !== resolvedInitialUsername ? username : void 0
|
|
862
|
+
};
|
|
863
|
+
const responseData = await onSaveConfiguration(payload);
|
|
864
|
+
if (responseData.success) {
|
|
865
|
+
toast2.success("Web3 profile identity updated successfully.");
|
|
866
|
+
setTimeout(() => window.location.reload(), 1e3);
|
|
867
|
+
} else {
|
|
868
|
+
toast2.error(responseData.error || "Failed to update your identity profile.");
|
|
869
|
+
setIsSubmitting(false);
|
|
870
|
+
}
|
|
871
|
+
} catch (error) {
|
|
872
|
+
toast2.error("Service unavailable. Try again later.");
|
|
873
|
+
setIsSubmitting(false);
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
const hasChanges = web3Name !== initialOrgName || slug !== initialSlug || username !== resolvedInitialUsername;
|
|
877
|
+
const isSaveDisabled = isSubmitting || isReadOnly || isCheckingSlug || !hasChanges || web3Name.length < 3 || slug.length < 3 || username.length < 3 || slug !== initialSlug && slugAvailable === false;
|
|
878
|
+
return /* @__PURE__ */ React11.createElement("div", { className: "flex flex-col gap-8 animate-in max-w-5xl rounded-2xl p-6 bg-white fade-in duration-300" }, /* @__PURE__ */ React11.createElement(ManagedToaster, null), /* @__PURE__ */ React11.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ React11.createElement("div", null, /* @__PURE__ */ React11.createElement("h1", { className: "text-black text-xl mb-1 tracking-tight" }, "Public Profile"), /* @__PURE__ */ React11.createElement("p", { className: "text-xs text-neutral-500" }, "Manage your financial payment handle identifiers and global public cryptographic signature identity details.")), isReadOnly && /* @__PURE__ */ React11.createElement("span", { className: "p-2 w-9 h-9 bg-neutral-100 text-neutral-400 rounded-full shrink-0" }, /* @__PURE__ */ React11.createElement(HugeiconsIcon5, { icon: CircleLock02Icon, size: 18, className: "text-current" }))), bannerProps && /* @__PURE__ */ React11.createElement(Banner, { ...bannerProps }), /* @__PURE__ */ React11.createElement("div", { className: "w-full max-w-5xl" }, /* @__PURE__ */ React11.createElement("form", { className: "flex flex-col gap-8", onSubmit: handleSave, autoComplete: "off" }, /* @__PURE__ */ React11.createElement(
|
|
879
|
+
TextInput,
|
|
880
|
+
{
|
|
881
|
+
label: "Display Name",
|
|
882
|
+
value: web3Name,
|
|
883
|
+
onChange: handleWeb3NameChange,
|
|
884
|
+
disabled: isReadOnly || isSubmitting,
|
|
885
|
+
placeholder: "Sovereign User",
|
|
886
|
+
maxLength: 50
|
|
887
|
+
}
|
|
888
|
+
), /* @__PURE__ */ React11.createElement(
|
|
889
|
+
TextInput,
|
|
890
|
+
{
|
|
891
|
+
label: "Digital Identity",
|
|
892
|
+
value: username,
|
|
893
|
+
onChange: handleUsernameChange,
|
|
894
|
+
disabled: isReadOnly || isSubmitting,
|
|
895
|
+
placeholder: "sovereignuser",
|
|
896
|
+
maxLength: 30
|
|
897
|
+
}
|
|
898
|
+
), /* @__PURE__ */ React11.createElement("div", { className: "space-y-1.5 relative w-full" }, /* @__PURE__ */ React11.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block" }, "Wallet Username"), /* @__PURE__ */ React11.createElement("div", { className: "flex items-center relative w-full border-b border-neutral-100 focus-within:border-black transition-all duration-300" }, /* @__PURE__ */ React11.createElement(
|
|
899
|
+
"input",
|
|
900
|
+
{
|
|
901
|
+
type: "text",
|
|
902
|
+
value: slug,
|
|
903
|
+
disabled: isReadOnly || isSubmitting,
|
|
904
|
+
onChange: (e) => handleSlugChange(e.target.value),
|
|
905
|
+
spellCheck: "false",
|
|
906
|
+
autoComplete: "off",
|
|
907
|
+
className: "w-full px-2 py-3 text-sm bg-transparent text-black outline-none disabled:opacity-50 disabled:cursor-not-allowed",
|
|
908
|
+
placeholder: "sovereign-user-handle"
|
|
909
|
+
}
|
|
910
|
+
), /* @__PURE__ */ React11.createElement("span", { className: "text-neutral-400 text-sm py-3 pr-8 shrink-0 whitespace-nowrap" }, slugPrefixUrl), /* @__PURE__ */ React11.createElement("div", { className: "absolute right-2 top-1/2 -translate-y-1/2" }, isCheckingSlug && /* @__PURE__ */ React11.createElement(InputSpinner2, null), !isCheckingSlug && !isReadOnly && slug !== initialSlug && slug.length >= 3 && slugAvailable === false && /* @__PURE__ */ React11.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-red-100" }, /* @__PURE__ */ React11.createElement("svg", { className: "w-2 h-2 text-red-600", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React11.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" }))), !isCheckingSlug && !isReadOnly && slug !== initialSlug && slug.length >= 3 && slugAvailable === true && /* @__PURE__ */ React11.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-green-100" }, /* @__PURE__ */ React11.createElement("svg", { className: "w-2 h-2 text-green-600", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React11.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M16.707 5.293a1 1 0 00-1.414 0L8 12.586 4.707 9.293a1 1 0 10-1.414 1.414l4 4a1 1 0 001.414 0l8-8a1 1 0 000-1.414z" })))))), /* @__PURE__ */ React11.createElement("div", { className: "pt-8 mt-2 flex items-center gap-4" }, /* @__PURE__ */ React11.createElement(
|
|
911
|
+
ThreeDActionButton,
|
|
912
|
+
{
|
|
913
|
+
type: "submit",
|
|
914
|
+
disabled: isSaveDisabled,
|
|
915
|
+
isLoading: isSubmitting,
|
|
916
|
+
className: "min-w-32"
|
|
917
|
+
},
|
|
918
|
+
"Save Changes"
|
|
919
|
+
), hasChanges && !isSubmitting && !isReadOnly && /* @__PURE__ */ React11.createElement(
|
|
920
|
+
"button",
|
|
921
|
+
{
|
|
922
|
+
type: "button",
|
|
923
|
+
onClick: () => {
|
|
924
|
+
setWeb3Name(initialOrgName);
|
|
925
|
+
setSlug(initialSlug);
|
|
926
|
+
setUsername(resolvedInitialUsername);
|
|
927
|
+
},
|
|
928
|
+
className: "text-[11px] tracking-widest text-neutral-400 hover:text-black transition-colors outline-none"
|
|
929
|
+
},
|
|
930
|
+
"Cancel"
|
|
931
|
+
)))));
|
|
932
|
+
};
|
|
933
|
+
|
|
934
|
+
// src/components/UniversalProfileSettings.tsx
|
|
935
|
+
import React12, { useState as useState7, useEffect as useEffect5 } from "react";
|
|
936
|
+
import toast3 from "react-hot-toast";
|
|
937
|
+
import { HugeiconsIcon as HugeiconsIcon6 } from "@hugeicons/react";
|
|
938
|
+
import {
|
|
939
|
+
CircleLock02Icon as CircleLock02Icon2,
|
|
940
|
+
CancelCircleIcon,
|
|
941
|
+
Loading03Icon as Loading03Icon2,
|
|
942
|
+
LockKeyIcon
|
|
943
|
+
} from "@hugeicons/core-free-icons";
|
|
944
|
+
var UniversalProfileSettings = ({
|
|
945
|
+
initialFirstName,
|
|
946
|
+
initialLastName,
|
|
947
|
+
email,
|
|
948
|
+
accountStatus = "GOOD",
|
|
949
|
+
memberSince,
|
|
950
|
+
isReadOnly = false,
|
|
951
|
+
bannerProps,
|
|
952
|
+
hasPin = false,
|
|
953
|
+
isPinLoading = false,
|
|
954
|
+
onSavePin,
|
|
955
|
+
onSaveProfile
|
|
956
|
+
}) => {
|
|
957
|
+
const [firstName, setFirstName] = useState7(initialFirstName);
|
|
958
|
+
const [lastName, setLastName] = useState7(initialLastName);
|
|
959
|
+
const [isSubmitting, setIsSubmitting] = useState7(false);
|
|
960
|
+
const [isPinModalOpen, setIsPinModalOpen] = useState7(false);
|
|
961
|
+
const [oldPin, setOldPin] = useState7("");
|
|
962
|
+
const [newPin, setNewPin] = useState7("");
|
|
963
|
+
const [confirmPin, setConfirmPin] = useState7("");
|
|
964
|
+
const [isPinSubmitting, setIsPinSubmitting] = useState7(false);
|
|
965
|
+
useEffect5(() => {
|
|
966
|
+
setFirstName(initialFirstName || "");
|
|
967
|
+
setLastName(initialLastName || "");
|
|
968
|
+
}, [initialFirstName, initialLastName]);
|
|
969
|
+
const handleFirstNameChange = (val) => {
|
|
970
|
+
setFirstName(val.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50));
|
|
971
|
+
};
|
|
972
|
+
const handleLastNameChange = (val) => {
|
|
973
|
+
setLastName(val.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50));
|
|
974
|
+
};
|
|
975
|
+
const handleSave = async (e) => {
|
|
976
|
+
e.preventDefault();
|
|
977
|
+
if (isSubmitting || isReadOnly) return;
|
|
978
|
+
setIsSubmitting(true);
|
|
979
|
+
try {
|
|
980
|
+
const res = await onSaveProfile({ firstName, lastName });
|
|
981
|
+
if (res.success) {
|
|
982
|
+
toast3.success("Profile updated successfully.");
|
|
983
|
+
setTimeout(() => window.location.reload(), 1e3);
|
|
984
|
+
} else {
|
|
985
|
+
toast3.error(res.error || "Uh oh! Something went wrong.");
|
|
986
|
+
setIsSubmitting(false);
|
|
987
|
+
}
|
|
988
|
+
} catch (error) {
|
|
989
|
+
toast3.error("Uh oh! Something went wrong.");
|
|
990
|
+
setIsSubmitting(false);
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
const closePinModal = () => {
|
|
994
|
+
if (isPinSubmitting) return;
|
|
995
|
+
setIsPinModalOpen(false);
|
|
996
|
+
setOldPin("");
|
|
997
|
+
setNewPin("");
|
|
998
|
+
setConfirmPin("");
|
|
999
|
+
};
|
|
1000
|
+
const handlePinInput = (val, setter) => {
|
|
1001
|
+
setter(val.replace(/\D/g, "").substring(0, 4));
|
|
1002
|
+
};
|
|
1003
|
+
const handlePinSubmit = async (e) => {
|
|
1004
|
+
e.preventDefault();
|
|
1005
|
+
if (!onSavePin) return;
|
|
1006
|
+
if (hasPin && oldPin.length !== 4) return toast3.error("Old PIN must be exactly 4 digits.");
|
|
1007
|
+
if (newPin.length !== 4) return toast3.error("New PIN must be exactly 4 digits.");
|
|
1008
|
+
if (newPin !== confirmPin) return toast3.error("New PINs do not match.");
|
|
1009
|
+
setIsPinSubmitting(true);
|
|
1010
|
+
try {
|
|
1011
|
+
const action = hasPin ? "change_pin" : "create_pin";
|
|
1012
|
+
const res = await onSavePin({
|
|
1013
|
+
action,
|
|
1014
|
+
oldPin: hasPin ? oldPin : void 0,
|
|
1015
|
+
newPin
|
|
1016
|
+
});
|
|
1017
|
+
if (res.success) {
|
|
1018
|
+
toast3.success(res.message || "PIN updated successfully.");
|
|
1019
|
+
closePinModal();
|
|
1020
|
+
} else {
|
|
1021
|
+
toast3.error(res.error || "Failed to update PIN.");
|
|
1022
|
+
}
|
|
1023
|
+
} catch (error) {
|
|
1024
|
+
toast3.error("Uh oh! Something went wrong.");
|
|
1025
|
+
} finally {
|
|
1026
|
+
setIsPinSubmitting(false);
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
1029
|
+
const hasChanges = firstName !== initialFirstName || lastName !== initialLastName;
|
|
1030
|
+
const isSaveDisabled = isSubmitting || isReadOnly || !hasChanges || firstName.trim().length === 0 || lastName.trim().length === 0;
|
|
1031
|
+
return /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col max-w-5xl rounded-2xl p-6 bg-white gap-8 animate-in fade-in duration-300" }, /* @__PURE__ */ React12.createElement(ManagedToaster, null), /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-3 sm:gap-4" }, /* @__PURE__ */ React12.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React12.createElement("h1", { className: "text-black text-xl mb-1 truncate tracking-tight" }, "Personal Settings"), /* @__PURE__ */ React12.createElement("p", { className: "text-xs text-neutral-500 truncate" }, "Manage your personal account profile.")), isReadOnly && /* @__PURE__ */ React12.createElement("span", { className: "p-2 w-9 h-9 bg-neutral-100 text-neutral-400 rounded-full shrink-0" }, /* @__PURE__ */ React12.createElement(HugeiconsIcon6, { icon: CircleLock02Icon2, size: 18, className: "text-current" }))), bannerProps && /* @__PURE__ */ React12.createElement(Banner, { ...bannerProps }), /* @__PURE__ */ React12.createElement("div", { className: "w-full max-w-5xl" }, /* @__PURE__ */ React12.createElement("form", { className: "flex flex-col gap-8", onSubmit: handleSave, autoComplete: "off" }, /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col sm:flex-row gap-6" }, /* @__PURE__ */ React12.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React12.createElement(
|
|
1032
|
+
TextInput,
|
|
1033
|
+
{
|
|
1034
|
+
label: "First Name",
|
|
1035
|
+
value: firstName,
|
|
1036
|
+
onChange: handleFirstNameChange,
|
|
1037
|
+
disabled: isReadOnly || isSubmitting,
|
|
1038
|
+
placeholder: "System"
|
|
1039
|
+
}
|
|
1040
|
+
)), /* @__PURE__ */ React12.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React12.createElement(
|
|
1041
|
+
TextInput,
|
|
1042
|
+
{
|
|
1043
|
+
label: "Last Name",
|
|
1044
|
+
value: lastName,
|
|
1045
|
+
onChange: handleLastNameChange,
|
|
1046
|
+
disabled: isReadOnly || isSubmitting,
|
|
1047
|
+
placeholder: "Admin"
|
|
1048
|
+
}
|
|
1049
|
+
))), /* @__PURE__ */ React12.createElement("div", { className: "space-y-2 min-w-0" }, /* @__PURE__ */ React12.createElement(
|
|
1050
|
+
TextInput,
|
|
1051
|
+
{
|
|
1052
|
+
label: "Email ID",
|
|
1053
|
+
value: email,
|
|
1054
|
+
onChange: () => {
|
|
1055
|
+
},
|
|
1056
|
+
disabled: true
|
|
1057
|
+
}
|
|
1058
|
+
), /* @__PURE__ */ React12.createElement("p", { className: "text-[11px] text-neutral-500 mt-1 truncate" }, "To change your email address, please contact support.")), /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between pt-8 mt-2 gap-6 sm:gap-4" }, /* @__PURE__ */ React12.createElement("div", { className: "flex items-center gap-6 min-w-0" }, /* @__PURE__ */ React12.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React12.createElement("span", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block truncate" }, "Account Status"), /* @__PURE__ */ React12.createElement("span", { className: "text-xs text-black block truncate" }, accountStatus)), /* @__PURE__ */ React12.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React12.createElement("span", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block truncate" }, "Member Since"), /* @__PURE__ */ React12.createElement("span", { className: "text-xs text-black block truncate" }, memberSince ? new Date(memberSince).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" }) : "N/A")), /* @__PURE__ */ React12.createElement("div", { className: "min-w-0 pl-4" }, /* @__PURE__ */ React12.createElement(
|
|
1059
|
+
"button",
|
|
1060
|
+
{
|
|
1061
|
+
type: "button",
|
|
1062
|
+
onClick: () => setIsPinModalOpen(true),
|
|
1063
|
+
"aria-label": "PIN Settings",
|
|
1064
|
+
className: "w-9 h-9 flex items-center justify-center border border-neutral-200 rounded-full text-black hover:bg-neutral-50 transition-colors outline-none"
|
|
1065
|
+
},
|
|
1066
|
+
/* @__PURE__ */ React12.createElement(HugeiconsIcon6, { icon: LockKeyIcon, size: 17, className: "text-black" })
|
|
1067
|
+
))), /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col-reverse sm:flex-row items-center gap-3 sm:gap-4 w-full sm:w-auto shrink-0" }, hasChanges && !isSubmitting && !isReadOnly && /* @__PURE__ */ React12.createElement(
|
|
1068
|
+
"button",
|
|
1069
|
+
{
|
|
1070
|
+
type: "button",
|
|
1071
|
+
onClick: () => {
|
|
1072
|
+
setFirstName(initialFirstName);
|
|
1073
|
+
setLastName(initialLastName);
|
|
1074
|
+
},
|
|
1075
|
+
className: "text-[11px] tracking-widest text-neutral-400 hover:text-black transition-colors w-full sm:w-auto py-2 sm:py-0 outline-none"
|
|
1076
|
+
},
|
|
1077
|
+
"Cancel"
|
|
1078
|
+
), /* @__PURE__ */ React12.createElement(
|
|
1079
|
+
ThreeDActionButton,
|
|
1080
|
+
{
|
|
1081
|
+
type: "submit",
|
|
1082
|
+
disabled: isSaveDisabled,
|
|
1083
|
+
isLoading: isSubmitting,
|
|
1084
|
+
className: "min-w-32 w-full sm:w-auto"
|
|
1085
|
+
},
|
|
1086
|
+
"Save Changes"
|
|
1087
|
+
))))), isPinModalOpen && /* @__PURE__ */ React12.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React12.createElement("div", { className: "absolute inset-0 bg-black/40", onClick: closePinModal }), /* @__PURE__ */ React12.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React12.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ React12.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, hasPin ? "Change PIN" : "Create PIN"), /* @__PURE__ */ React12.createElement("button", { onClick: closePinModal, disabled: isPinSubmitting, className: "text-neutral-400 hover:text-black transition-colors outline-none disabled:opacity-50" }, /* @__PURE__ */ React12.createElement(HugeiconsIcon6, { icon: CancelCircleIcon, size: 18 }))), /* @__PURE__ */ React12.createElement("div", { className: "p-6" }, isPinLoading ? /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col items-center justify-center py-10" }, /* @__PURE__ */ React12.createElement(HugeiconsIcon6, { icon: Loading03Icon2, size: 28, className: "animate-spin text-neutral-400 mb-4" })) : /* @__PURE__ */ React12.createElement("form", { onSubmit: handlePinSubmit, className: "flex flex-col gap-6" }, hasPin && /* @__PURE__ */ React12.createElement(
|
|
1088
|
+
TextInput,
|
|
1089
|
+
{
|
|
1090
|
+
type: "password",
|
|
1091
|
+
label: "Old PIN",
|
|
1092
|
+
maxLength: 4,
|
|
1093
|
+
disabled: isPinSubmitting,
|
|
1094
|
+
value: oldPin,
|
|
1095
|
+
onChange: (val) => handlePinInput(val, setOldPin),
|
|
1096
|
+
placeholder: "\u2022\u2022\u2022\u2022"
|
|
1097
|
+
}
|
|
1098
|
+
), /* @__PURE__ */ React12.createElement(
|
|
1099
|
+
TextInput,
|
|
1100
|
+
{
|
|
1101
|
+
type: "password",
|
|
1102
|
+
label: hasPin ? "New PIN" : "Enter 4-Digit PIN",
|
|
1103
|
+
maxLength: 4,
|
|
1104
|
+
disabled: isPinSubmitting,
|
|
1105
|
+
value: newPin,
|
|
1106
|
+
onChange: (val) => handlePinInput(val, setNewPin),
|
|
1107
|
+
placeholder: "\u2022\u2022\u2022\u2022"
|
|
1108
|
+
}
|
|
1109
|
+
), /* @__PURE__ */ React12.createElement(
|
|
1110
|
+
TextInput,
|
|
1111
|
+
{
|
|
1112
|
+
type: "password",
|
|
1113
|
+
label: "Retype New PIN",
|
|
1114
|
+
maxLength: 4,
|
|
1115
|
+
disabled: isPinSubmitting,
|
|
1116
|
+
value: confirmPin,
|
|
1117
|
+
onChange: (val) => handlePinInput(val, setConfirmPin),
|
|
1118
|
+
placeholder: "\u2022\u2022\u2022\u2022"
|
|
1119
|
+
}
|
|
1120
|
+
), /* @__PURE__ */ React12.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React12.createElement(
|
|
1121
|
+
ThreeDActionButton,
|
|
1122
|
+
{
|
|
1123
|
+
type: "submit",
|
|
1124
|
+
disabled: isPinSubmitting || newPin.length !== 4 || confirmPin.length !== 4 || hasPin && oldPin.length !== 4,
|
|
1125
|
+
isLoading: isPinSubmitting,
|
|
1126
|
+
className: "w-full py-3"
|
|
1127
|
+
},
|
|
1128
|
+
hasPin ? "Update PIN" : "Set PIN"
|
|
1129
|
+
)))))));
|
|
1130
|
+
};
|
|
1131
|
+
|
|
1132
|
+
// src/components/UniversalErrorView.tsx
|
|
1133
|
+
import React14 from "react";
|
|
1134
|
+
import { HugeiconsIcon as HugeiconsIcon8 } from "@hugeicons/react";
|
|
1135
|
+
import { ConfusedIcon } from "@hugeicons/core-free-icons";
|
|
1136
|
+
|
|
1137
|
+
// src/components/PageSpinner.tsx
|
|
1138
|
+
import React13 from "react";
|
|
1139
|
+
import { HugeiconsIcon as HugeiconsIcon7 } from "@hugeicons/react";
|
|
1140
|
+
import { Loading03Icon as Loading03Icon3 } from "@hugeicons/core-free-icons";
|
|
1141
|
+
var PageSpinner = ({
|
|
1142
|
+
className = "",
|
|
1143
|
+
iconClassName = "text-black",
|
|
1144
|
+
size = 32
|
|
1145
|
+
}) => {
|
|
1146
|
+
return (
|
|
1147
|
+
// z-[100] ensures it sits above absolute headers and modals
|
|
1148
|
+
/* @__PURE__ */ React13.createElement("div", { className: `fixed inset-0 z-100 flex flex-col items-center justify-center w-full h-full pointer-events-none ${className}` }, /* @__PURE__ */ React13.createElement(
|
|
1149
|
+
HugeiconsIcon7,
|
|
1150
|
+
{
|
|
1151
|
+
icon: Loading03Icon3,
|
|
1152
|
+
size,
|
|
1153
|
+
className: `animate-spin mb-4 ${iconClassName}`
|
|
1154
|
+
}
|
|
1155
|
+
))
|
|
1156
|
+
);
|
|
1157
|
+
};
|
|
1158
|
+
|
|
1159
|
+
// src/components/UniversalErrorView.tsx
|
|
1160
|
+
var UniversalErrorView = ({
|
|
1161
|
+
isBooting,
|
|
1162
|
+
isLoading,
|
|
1163
|
+
activeData,
|
|
1164
|
+
activeError,
|
|
1165
|
+
envName,
|
|
1166
|
+
onRetry,
|
|
1167
|
+
returnUrl = "/app",
|
|
1168
|
+
returnLabel = "Return to Workspace"
|
|
1169
|
+
}) => {
|
|
1170
|
+
if (isBooting || isLoading && !activeData) {
|
|
1171
|
+
return /* @__PURE__ */ React14.createElement("div", { className: "flex items-center justify-center h-screen w-full bg-white" }, /* @__PURE__ */ React14.createElement(PageSpinner, null));
|
|
1172
|
+
}
|
|
1173
|
+
if (!isLoading && (!activeData || activeError)) {
|
|
1174
|
+
const errorString = typeof activeError === "string" ? activeError : JSON.stringify(activeError || "");
|
|
1175
|
+
const errorMsg = errorString.toLowerCase();
|
|
1176
|
+
const isPermissionError = errorMsg.includes("forbidden") || errorMsg.includes("unauthorized") || errorMsg.includes("permission");
|
|
1177
|
+
const isNetworkError = errorMsg.includes("network") || errorMsg.includes("connection") || errorMsg.includes("fetch");
|
|
1178
|
+
const isNotFoundError = errorMsg.includes("not found") || errorMsg.includes("404") || errorMsg.includes("does not exist") || !activeData && !isPermissionError && !isNetworkError;
|
|
1179
|
+
const apiMessage = typeof activeError === "string" && activeError.trim() !== "" ? activeError : null;
|
|
1180
|
+
let title = "Oops Connection Error";
|
|
1181
|
+
let description = apiMessage || `We could not load your request. Please check your connection and try again.`;
|
|
1182
|
+
let IconComponent = ConfusedIcon;
|
|
1183
|
+
if (isNotFoundError) {
|
|
1184
|
+
title = "Oops its not your fault";
|
|
1185
|
+
description = apiMessage || `We could not reach the ${envName} you just loaded. Our team has been notified.`;
|
|
1186
|
+
} else if (isPermissionError) {
|
|
1187
|
+
title = "Access Restricted";
|
|
1188
|
+
description = apiMessage || `You have insufficient permissions to view this ${envName}. Please contact your administrator.`;
|
|
1189
|
+
}
|
|
1190
|
+
return /* @__PURE__ */ React14.createElement("div", { className: "flex flex-col items-center justify-center h-screen w-full px-4 animate-in fade-in duration-500" }, /* @__PURE__ */ React14.createElement("div", { className: "mb-4 flex justify-center" }, /* @__PURE__ */ React14.createElement(HugeiconsIcon8, { icon: IconComponent, size: 48, className: "text-neutral-300" })), /* @__PURE__ */ React14.createElement("h2", { className: "text-lg text-black tracking-tight font-medium" }, title), /* @__PURE__ */ React14.createElement("p", { className: "text-xs mt-2 mb-8 text-neutral-500 max-w-sm text-center leading-relaxed" }, description), /* @__PURE__ */ React14.createElement("div", { className: "flex flex-col sm:flex-row items-center gap-3 w-full justify-center sm:w-auto" }, isNotFoundError || isPermissionError ? /* @__PURE__ */ React14.createElement(
|
|
1191
|
+
"button",
|
|
1192
|
+
{
|
|
1193
|
+
onClick: () => window.location.href = returnUrl,
|
|
1194
|
+
className: "px-6 py-2 text-black border border-neutral-200 hover:bg-neutral-50 rounded-full text-[11px] tracking-widest transition-colors w-full sm:w-auto outline-none font-medium"
|
|
1195
|
+
},
|
|
1196
|
+
returnLabel
|
|
1197
|
+
) : (
|
|
1198
|
+
// Soft errors (Network timeouts) allow them to retry or optionally retreat
|
|
1199
|
+
/* @__PURE__ */ React14.createElement(React14.Fragment, null, envName.toLowerCase().includes("application") && /* @__PURE__ */ React14.createElement(
|
|
1200
|
+
"button",
|
|
1201
|
+
{
|
|
1202
|
+
onClick: () => window.location.href = returnUrl,
|
|
1203
|
+
className: "px-6 py-2 bg-transparent border border-neutral-200 text-neutral-500 hover:text-black hover:bg-neutral-50 rounded-full text-[11px] tracking-widest transition-colors w-full sm:w-auto outline-none font-medium"
|
|
1204
|
+
},
|
|
1205
|
+
"Back Home"
|
|
1206
|
+
), /* @__PURE__ */ React14.createElement(
|
|
1207
|
+
"button",
|
|
1208
|
+
{
|
|
1209
|
+
onClick: onRetry,
|
|
1210
|
+
className: "px-6 py-2 bg-black text-white hover:bg-neutral-800 rounded-full text-[11px] tracking-widest transition-colors w-full sm:w-auto outline-none capitalize font-medium"
|
|
1211
|
+
},
|
|
1212
|
+
"Refresh ",
|
|
1213
|
+
envName
|
|
1214
|
+
))
|
|
1215
|
+
)));
|
|
1216
|
+
}
|
|
1217
|
+
return null;
|
|
1218
|
+
};
|
|
1219
|
+
|
|
1220
|
+
// src/components/UniversalTransactionPage.tsx
|
|
1221
|
+
import React15, { useState as useState8, useEffect as useEffect6, useRef as useRef3 } from "react";
|
|
1222
|
+
import { HugeiconsIcon as HugeiconsIcon9 } from "@hugeicons/react";
|
|
1223
|
+
import toast4 from "react-hot-toast";
|
|
1224
|
+
import {
|
|
1225
|
+
ArrowLeft01Icon,
|
|
1226
|
+
ArrowRight01Icon,
|
|
1227
|
+
Loading03Icon as Loading03Icon4,
|
|
1228
|
+
ArrowDownRight01Icon,
|
|
1229
|
+
ArrowUpRight01Icon,
|
|
1230
|
+
Search01Icon,
|
|
1231
|
+
SearchList02Icon,
|
|
1232
|
+
ListSettingIcon,
|
|
1233
|
+
CancelCircleIcon as CancelCircleIcon2
|
|
1234
|
+
} from "@hugeicons/core-free-icons";
|
|
1235
|
+
var PageSpinner2 = () => /* @__PURE__ */ React15.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: Loading03Icon4, size: 32, className: "animate-spin mb-4 text-black" }));
|
|
1236
|
+
var formatDate = (dateInput) => {
|
|
1237
|
+
const d = new Date(dateInput);
|
|
1238
|
+
const day = d.getDate();
|
|
1239
|
+
const month = d.toLocaleString("en-US", { month: "short" });
|
|
1240
|
+
const year = d.getFullYear();
|
|
1241
|
+
return `${day} ${month} ${year}`;
|
|
1242
|
+
};
|
|
1243
|
+
var formatTime = (dateInput) => {
|
|
1244
|
+
return new Date(dateInput).toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" });
|
|
1245
|
+
};
|
|
1246
|
+
var truncateAddress = (address) => {
|
|
1247
|
+
if (!address || address.length < 12) return address;
|
|
1248
|
+
return `${address.substring(0, 6)}...${address.substring(address.length - 4)}`;
|
|
1249
|
+
};
|
|
1250
|
+
var UniversalTransactionPage = ({
|
|
1251
|
+
headerTitle,
|
|
1252
|
+
headerDescription,
|
|
1253
|
+
hideControls = false,
|
|
1254
|
+
hideBalanceAmounts = false,
|
|
1255
|
+
hidePagination = false,
|
|
1256
|
+
transactions,
|
|
1257
|
+
isLoading,
|
|
1258
|
+
currentPage,
|
|
1259
|
+
totalPages,
|
|
1260
|
+
onPageChange,
|
|
1261
|
+
searchQuery,
|
|
1262
|
+
onSearchChange,
|
|
1263
|
+
activeDirectionFilter,
|
|
1264
|
+
onDirectionFilterChange,
|
|
1265
|
+
activeTypeFilter,
|
|
1266
|
+
onTypeFilterChange,
|
|
1267
|
+
onReportTransaction,
|
|
1268
|
+
onGenerateReceipt
|
|
1269
|
+
}) => {
|
|
1270
|
+
const [selectedTransaction, setSelectedTransaction] = useState8(null);
|
|
1271
|
+
const [isGeneratingReceipt, setIsGeneratingReceipt] = useState8(false);
|
|
1272
|
+
const [localSearchQuery, setLocalSearchQuery] = useState8(searchQuery);
|
|
1273
|
+
const [isTyping, setIsTyping] = useState8(false);
|
|
1274
|
+
const [isDirectionModalOpen, setIsDirectionModalOpen] = useState8(false);
|
|
1275
|
+
const [isTypeModalOpen, setIsTypeModalOpen] = useState8(false);
|
|
1276
|
+
const directionDropdownRef = useRef3(null);
|
|
1277
|
+
const typeDropdownRef = useRef3(null);
|
|
1278
|
+
useEffect6(() => {
|
|
1279
|
+
function handleClickOutside(event) {
|
|
1280
|
+
if (directionDropdownRef.current && !directionDropdownRef.current.contains(event.target)) {
|
|
1281
|
+
setIsDirectionModalOpen(false);
|
|
1282
|
+
}
|
|
1283
|
+
if (typeDropdownRef.current && !typeDropdownRef.current.contains(event.target)) {
|
|
1284
|
+
setIsTypeModalOpen(false);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1288
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1289
|
+
}, []);
|
|
1290
|
+
useEffect6(() => {
|
|
1291
|
+
setIsTyping(true);
|
|
1292
|
+
const handler = setTimeout(() => {
|
|
1293
|
+
onSearchChange(localSearchQuery);
|
|
1294
|
+
setIsTyping(false);
|
|
1295
|
+
}, 600);
|
|
1296
|
+
return () => clearTimeout(handler);
|
|
1297
|
+
}, [localSearchQuery, onSearchChange]);
|
|
1298
|
+
useEffect6(() => {
|
|
1299
|
+
if (searchQuery === "" && localSearchQuery !== "") {
|
|
1300
|
+
setLocalSearchQuery("");
|
|
1301
|
+
}
|
|
1302
|
+
}, [searchQuery]);
|
|
1303
|
+
const getDisplayName = (tx) => {
|
|
1304
|
+
if (tx.metadata?.merchantName) return tx.metadata.merchantName;
|
|
1305
|
+
if (tx.metadata?.description) return tx.metadata.description;
|
|
1306
|
+
return tx.type === "CARD_TRANSACTION" ? "Card Transaction" : "Wallet Transaction";
|
|
1307
|
+
};
|
|
1308
|
+
const handleGenerateReceipt = async () => {
|
|
1309
|
+
if (!onGenerateReceipt || !selectedTransaction) return;
|
|
1310
|
+
setIsGeneratingReceipt(true);
|
|
1311
|
+
try {
|
|
1312
|
+
await onGenerateReceipt(selectedTransaction);
|
|
1313
|
+
toast4.success("Receipt generated successfully.");
|
|
1314
|
+
} catch (error) {
|
|
1315
|
+
toast4.error("Failed to generate receipt.");
|
|
1316
|
+
} finally {
|
|
1317
|
+
setIsGeneratingReceipt(false);
|
|
1318
|
+
}
|
|
1319
|
+
};
|
|
1320
|
+
const isListLoading = isLoading || isTyping;
|
|
1321
|
+
return /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col gap-6 animate-in max-w-5xl fade-in duration-300" }, /* @__PURE__ */ React15.createElement(ManagedToaster, null), !hideControls && /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-4 w-full" }, /* @__PURE__ */ React15.createElement("div", { className: "relative w-full sm:w-96" }, /* @__PURE__ */ React15.createElement("div", { className: "absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none" }, /* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: Search01Icon, size: 16, className: "text-neutral-400" })), /* @__PURE__ */ React15.createElement(
|
|
1322
|
+
"input",
|
|
1323
|
+
{
|
|
1324
|
+
type: "text",
|
|
1325
|
+
placeholder: "Search reference or amount...",
|
|
1326
|
+
value: localSearchQuery,
|
|
1327
|
+
onChange: (e) => setLocalSearchQuery(e.target.value),
|
|
1328
|
+
className: "w-full pl-10 pr-4 py-2 bg-white rounded-full text-[13px] text-black placeholder-neutral-400 outline-none transition-colors focus:border-black"
|
|
1329
|
+
}
|
|
1330
|
+
)), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-3 w-full sm:w-auto overflow-x-auto pb-1 sm:pb-0" }, /* @__PURE__ */ React15.createElement(
|
|
1331
|
+
"button",
|
|
1332
|
+
{
|
|
1333
|
+
onClick: () => setIsDirectionModalOpen(true),
|
|
1334
|
+
className: "flex items-center gap-2 whitespace-nowrap bg-white px-5 py-2 rounded-full text-[12px] text-neutral-500 hover:text-black transition-colors outline-none"
|
|
1335
|
+
},
|
|
1336
|
+
/* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: SearchList02Icon, size: 12 }),
|
|
1337
|
+
activeDirectionFilter === "ALL" ? "Payment Type" : activeDirectionFilter
|
|
1338
|
+
), /* @__PURE__ */ React15.createElement(
|
|
1339
|
+
"button",
|
|
1340
|
+
{
|
|
1341
|
+
onClick: () => setIsTypeModalOpen(true),
|
|
1342
|
+
className: "flex items-center gap-2 whitespace-nowrap bg-white px-5 py-2 rounded-full text-[12px] text-neutral-500 hover:text-black transition-colors outline-none"
|
|
1343
|
+
},
|
|
1344
|
+
/* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: ListSettingIcon, size: 14 }),
|
|
1345
|
+
activeTypeFilter === "ALL" ? "All Transactions" : activeTypeFilter.replace("_", " ")
|
|
1346
|
+
))), /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col gap-8 p-6 rounded-2xl bg-white w-full" }, /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-4" }, /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("h1", { className: "text-black text-xl mb-1 tracking-tight" }, headerTitle), headerDescription && /* @__PURE__ */ React15.createElement("p", { className: "text-xs text-neutral-500" }, headerDescription))), /* @__PURE__ */ React15.createElement("div", { className: "w-full overflow-hidden" }, isListLoading ? /* @__PURE__ */ React15.createElement(PageSpinner2, null) : /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ React15.createElement("div", null, transactions.length === 0 ? /* @__PURE__ */ React15.createElement("p", { className: "text-xs text-neutral-400 py-6 text-center" }, "No transactions found") : transactions.map((tx) => /* @__PURE__ */ React15.createElement(
|
|
1347
|
+
"div",
|
|
1348
|
+
{
|
|
1349
|
+
key: tx.id,
|
|
1350
|
+
onClick: () => setSelectedTransaction(tx),
|
|
1351
|
+
className: "flex items-center justify-between py-4 hover:bg-neutral-50 transition-colors cursor-pointer group min-w-0 px-3 -mx-3 rounded-xl"
|
|
1352
|
+
},
|
|
1353
|
+
/* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-4 min-w-0 flex-1" }, /* @__PURE__ */ React15.createElement("div", { className: `w-10 h-10 shrink-0 rounded-full flex items-center justify-center bg-neutral-100 text-black` }, /* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: tx.direction === "CREDIT" ? ArrowDownRight01Icon : ArrowUpRight01Icon, size: 18 })), /* @__PURE__ */ React15.createElement("div", { className: "min-w-0 flex-1 flex flex-col gap-1" }, /* @__PURE__ */ React15.createElement("p", { className: "text-[13px] text-black truncate" }, getDisplayName(tx)), /* @__PURE__ */ React15.createElement("p", { className: `text-[13px] text-neutral-500 truncate transition-all duration-300 ${hideBalanceAmounts ? "blur-sm opacity-40 select-none" : ""}` }, tx.direction === "CREDIT" ? "+" : "-", tx.amount, " ", tx.currency))),
|
|
1354
|
+
/* @__PURE__ */ React15.createElement("div", { className: "shrink-0 flex flex-col items-end gap-1 text-right" }, /* @__PURE__ */ React15.createElement("span", { className: "text-[11px] text-neutral-400" }, formatDate(tx.createdAt)), /* @__PURE__ */ React15.createElement("span", { className: "text-[11px] text-neutral-400 capitalize" }, tx.direction.toLowerCase()))
|
|
1355
|
+
))), !hidePagination && /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between pt-6 mt-2 " }, /* @__PURE__ */ React15.createElement("span", { className: "text-[11px] text-neutral-400 tracking-[0.2em]" }, "Page ", currentPage, " of ", totalPages === 0 ? 1 : totalPages), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15.createElement(
|
|
1356
|
+
"button",
|
|
1357
|
+
{
|
|
1358
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
1359
|
+
disabled: currentPage <= 1 || isListLoading,
|
|
1360
|
+
className: "p-2 bg-white border border-neutral-200 rounded-full text-black hover:bg-neutral-50 disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none"
|
|
1361
|
+
},
|
|
1362
|
+
/* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: ArrowLeft01Icon, size: 14 })
|
|
1363
|
+
), /* @__PURE__ */ React15.createElement(
|
|
1364
|
+
"button",
|
|
1365
|
+
{
|
|
1366
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
1367
|
+
disabled: currentPage >= totalPages || isListLoading || totalPages === 0,
|
|
1368
|
+
className: "p-2 bg-white border border-neutral-200 rounded-full text-black hover:bg-neutral-50 disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none"
|
|
1369
|
+
},
|
|
1370
|
+
/* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: ArrowRight01Icon, size: 14 })
|
|
1371
|
+
)))))), selectedTransaction && /* @__PURE__ */ React15.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React15.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => setSelectedTransaction(null) }), /* @__PURE__ */ React15.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200 max-h-[90vh]" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ React15.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Details"), /* @__PURE__ */ React15.createElement("button", { onClick: () => setSelectedTransaction(null), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: CancelCircleIcon2, size: 18 }))), /* @__PURE__ */ React15.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6" }, /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col items-center justify-center mb-4" }, /* @__PURE__ */ React15.createElement("div", { className: `w-12 h-12 rounded-full flex items-center justify-center mb-4 bg-neutral-100 text-black` }, /* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: selectedTransaction.direction === "CREDIT" ? ArrowDownRight01Icon : ArrowUpRight01Icon, size: 20 })), /* @__PURE__ */ React15.createElement("h2", { className: `text-2xl text-black mb-2 transition-all duration-300 font-medium ${hideBalanceAmounts ? "blur-[6px] opacity-40 select-none" : ""}` }, selectedTransaction.direction === "CREDIT" ? "+" : "-", selectedTransaction.amount, " ", selectedTransaction.currency), /* @__PURE__ */ React15.createElement("span", { className: "text-[9px] tracking-widest text-neutral-500 px-4 py-1.5 rounded-full bg-neutral-50" }, selectedTransaction.status)), /* @__PURE__ */ React15.createElement("div", { className: "grid grid-cols-1 gap-y-8 gap-x-4 mb-10 mt-6" }, /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-400 block mb-2" }, "Reference ID"), /* @__PURE__ */ React15.createElement("span", { className: "text-[13px] text-black break-all" }, selectedTransaction.reference)), /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-400 block mb-2" }, "Date & Time"), /* @__PURE__ */ React15.createElement("span", { className: "text-[13px] text-black" }, formatDate(selectedTransaction.createdAt), " at ", formatTime(selectedTransaction.createdAt))), /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-400 block mb-2" }, "Transaction Type"), /* @__PURE__ */ React15.createElement("span", { className: "text-[13px] text-black capitalize" }, selectedTransaction.type.replace("_", " ").toLowerCase())), /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-400 block mb-2" }, "Flow Direction"), /* @__PURE__ */ React15.createElement("span", { className: "text-[13px] text-black capitalize" }, selectedTransaction.direction.toLowerCase())), selectedTransaction.metadata?.fromAddress && selectedTransaction.metadata?.toAddress && /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-400 block mb-2" }, "Transfer Route"), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 text-[13px] text-black" }, /* @__PURE__ */ React15.createElement("span", { className: "truncate font-medium" }, truncateAddress(String(selectedTransaction.metadata.fromAddress))), /* @__PURE__ */ React15.createElement("span", { className: "text-neutral-400" }, "\u2192"), /* @__PURE__ */ React15.createElement("span", { className: "truncate font-medium" }, truncateAddress(String(selectedTransaction.metadata.toAddress))))), selectedTransaction.metadata && Object.entries(selectedTransaction.metadata).map(([key, value]) => {
|
|
1372
|
+
if (key === "fromAddress" || key === "toAddress") return null;
|
|
1373
|
+
if (value === null || value === void 0 || typeof value === "object") return null;
|
|
1374
|
+
const formattedKey = key.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase());
|
|
1375
|
+
return /* @__PURE__ */ React15.createElement("div", { key }, /* @__PURE__ */ React15.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-400 block mb-2" }, formattedKey), /* @__PURE__ */ React15.createElement("span", { className: "text-[13px] text-black break-all" }, String(value)));
|
|
1376
|
+
})), /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React15.createElement(
|
|
1377
|
+
ThreeDActionButton,
|
|
1378
|
+
{
|
|
1379
|
+
onClick: handleGenerateReceipt,
|
|
1380
|
+
isLoading: isGeneratingReceipt,
|
|
1381
|
+
className: "w-full py-3 text-[14px]"
|
|
1382
|
+
},
|
|
1383
|
+
"Generate Receipt"
|
|
1384
|
+
), /* @__PURE__ */ React15.createElement(
|
|
1385
|
+
"button",
|
|
1386
|
+
{
|
|
1387
|
+
onClick: () => onReportTransaction && onReportTransaction(selectedTransaction),
|
|
1388
|
+
className: "w-full flex items-center font-medium justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none text-[13px] tracking-wide mt-2"
|
|
1389
|
+
},
|
|
1390
|
+
"Report Transaction"
|
|
1391
|
+
), selectedTransaction.type === "WALLET_TRANSACTION" && /* @__PURE__ */ React15.createElement(
|
|
1392
|
+
"a",
|
|
1393
|
+
{
|
|
1394
|
+
href: `https://basescan.org/tx/${selectedTransaction.reference}`,
|
|
1395
|
+
target: "_blank",
|
|
1396
|
+
rel: "noopener noreferrer",
|
|
1397
|
+
className: "w-full flex items-center font-medium justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none text-[13px] tracking-wide mt-2"
|
|
1398
|
+
},
|
|
1399
|
+
"View in block explorer"
|
|
1400
|
+
))))), isDirectionModalOpen && /* @__PURE__ */ React15.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ React15.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => setIsDirectionModalOpen(false) }), /* @__PURE__ */ React15.createElement("div", { ref: directionDropdownRef, className: "relative w-72 bg-white shadow-2xl rounded-2xl flex flex-col items-center overflow-hidden animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React15.createElement("div", { className: "p-6 text-center w-full mb-2" }, /* @__PURE__ */ React15.createElement("h3", { className: "text-[14px] text-black tracking-tight" }, "Payment Type")), /* @__PURE__ */ React15.createElement("div", { className: "w-full flex flex-col pl-2 pr-2 gap-1" }, ["ALL", "CREDIT", "DEBIT"].map((option) => /* @__PURE__ */ React15.createElement(
|
|
1401
|
+
"button",
|
|
1402
|
+
{
|
|
1403
|
+
key: option,
|
|
1404
|
+
onClick: () => {
|
|
1405
|
+
onDirectionFilterChange(option);
|
|
1406
|
+
setIsDirectionModalOpen(false);
|
|
1407
|
+
},
|
|
1408
|
+
className: `text-left px-4 py-3 text-[11px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${activeDirectionFilter === option ? "bg-neutral-100 text-black font-medium" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
|
|
1409
|
+
},
|
|
1410
|
+
/* @__PURE__ */ React15.createElement("span", { className: "truncate pr-2" }, option.charAt(0).toUpperCase() + option.slice(1).toLowerCase())
|
|
1411
|
+
))), /* @__PURE__ */ React15.createElement("div", { className: "w-full flex mt-2 " }, /* @__PURE__ */ React15.createElement(
|
|
1412
|
+
"button",
|
|
1413
|
+
{
|
|
1414
|
+
onClick: () => setIsDirectionModalOpen(false),
|
|
1415
|
+
className: "w-full py-4 text-[13px] text-neutral-500 hover:text-black transition-colors outline-none font-medium"
|
|
1416
|
+
},
|
|
1417
|
+
"Cancel"
|
|
1418
|
+
)))), isTypeModalOpen && /* @__PURE__ */ React15.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ React15.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => setIsTypeModalOpen(false) }), /* @__PURE__ */ React15.createElement("div", { ref: typeDropdownRef, className: "relative w-72 bg-white shadow-2xl rounded-2xl flex flex-col items-center overflow-hidden animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React15.createElement("div", { className: "p-6 text-center w-full mb-2" }, /* @__PURE__ */ React15.createElement("h3", { className: "text-[14px] text-black tracking-tight" }, "Transactions Type")), /* @__PURE__ */ React15.createElement("div", { className: "w-full flex flex-col pl-2 pr-2 gap-1" }, [
|
|
1419
|
+
{ label: "All Transactions", value: "ALL" },
|
|
1420
|
+
{ label: "Wallet Transactions", value: "WALLET_TRANSACTION" },
|
|
1421
|
+
{ label: "Card Transactions", value: "CARD_TRANSACTION" }
|
|
1422
|
+
].map((option) => /* @__PURE__ */ React15.createElement(
|
|
1423
|
+
"button",
|
|
1424
|
+
{
|
|
1425
|
+
key: option.value,
|
|
1426
|
+
onClick: () => {
|
|
1427
|
+
onTypeFilterChange(option.value);
|
|
1428
|
+
setIsTypeModalOpen(false);
|
|
1429
|
+
},
|
|
1430
|
+
className: `text-left px-4 py-3 text-[11px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${activeTypeFilter === option.value ? "bg-neutral-100 text-black font-medium" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
|
|
1431
|
+
},
|
|
1432
|
+
/* @__PURE__ */ React15.createElement("span", { className: "truncate pr-2" }, option.label.charAt(0).toUpperCase() + option.label.slice(1).toLowerCase())
|
|
1433
|
+
))), /* @__PURE__ */ React15.createElement("div", { className: "w-full flex mt-2 " }, /* @__PURE__ */ React15.createElement(
|
|
1434
|
+
"button",
|
|
1435
|
+
{
|
|
1436
|
+
onClick: () => setIsTypeModalOpen(false),
|
|
1437
|
+
className: "w-full py-4 text-[13px] text-neutral-500 hover:text-black transition-colors outline-none font-medium"
|
|
1438
|
+
},
|
|
1439
|
+
"Cancel"
|
|
1440
|
+
)))));
|
|
1441
|
+
};
|
|
1442
|
+
|
|
1443
|
+
// src/components/UniversalHomeView.tsx
|
|
1444
|
+
import React16, { useState as useState9, useEffect as useEffect7 } from "react";
|
|
1445
|
+
import { HugeiconsIcon as HugeiconsIcon10 } from "@hugeicons/react";
|
|
1446
|
+
import { ViewOffSlashIcon, ViewIcon } from "@hugeicons/core-free-icons";
|
|
1447
|
+
var UniversalHomeView = ({
|
|
1448
|
+
balanceLabel = "Your Balance",
|
|
1449
|
+
balanceAmount,
|
|
1450
|
+
balanceCurrency = "$",
|
|
1451
|
+
primaryAction,
|
|
1452
|
+
secondaryAction,
|
|
1453
|
+
transactionsProps
|
|
1454
|
+
}) => {
|
|
1455
|
+
const [displayAmount, setDisplayAmount] = useState9("0.00");
|
|
1456
|
+
const [isBalanceHidden, setIsBalanceHidden] = useState9(false);
|
|
1457
|
+
useEffect7(() => {
|
|
1458
|
+
const target = parseFloat(balanceAmount.replace(/,/g, ""));
|
|
1459
|
+
if (isNaN(target)) {
|
|
1460
|
+
setDisplayAmount(balanceAmount);
|
|
1461
|
+
return;
|
|
1462
|
+
}
|
|
1463
|
+
let startTimestamp = null;
|
|
1464
|
+
const duration = 1e3;
|
|
1465
|
+
const step = (timestamp) => {
|
|
1466
|
+
if (!startTimestamp) startTimestamp = timestamp;
|
|
1467
|
+
const progress = Math.min((timestamp - startTimestamp) / duration, 1);
|
|
1468
|
+
const easeProgress = progress === 1 ? 1 : 1 - Math.pow(2, -10 * progress);
|
|
1469
|
+
const currentCount = easeProgress * target;
|
|
1470
|
+
setDisplayAmount(currentCount.toLocaleString("en-US", {
|
|
1471
|
+
minimumFractionDigits: 2,
|
|
1472
|
+
maximumFractionDigits: 2
|
|
1473
|
+
}));
|
|
1474
|
+
if (progress < 1) {
|
|
1475
|
+
requestAnimationFrame(step);
|
|
1476
|
+
} else {
|
|
1477
|
+
setDisplayAmount(target.toLocaleString("en-US", {
|
|
1478
|
+
minimumFractionDigits: 2,
|
|
1479
|
+
maximumFractionDigits: 2
|
|
1480
|
+
}));
|
|
1481
|
+
}
|
|
1482
|
+
};
|
|
1483
|
+
requestAnimationFrame(step);
|
|
1484
|
+
}, [balanceAmount]);
|
|
1485
|
+
const [intPart, decPart] = displayAmount.includes(".") ? displayAmount.split(".") : [displayAmount, "00"];
|
|
1486
|
+
return /* @__PURE__ */ React16.createElement("div", { className: "w-full max-w-5xl mx-auto flex flex-col animate-in fade-in duration-300" }, /* @__PURE__ */ React16.createElement("div", { className: "relative flex items-start justify-between w-full pt-4 pb-8" }, /* @__PURE__ */ React16.createElement("div", { className: "flex flex-col items-start text-left z-10 w-full" }, /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-2 mb-1.5" }, /* @__PURE__ */ React16.createElement("span", { className: "text-[12px] sm:text-[13px] text-neutral-500" }, balanceLabel), /* @__PURE__ */ React16.createElement(
|
|
1487
|
+
"button",
|
|
1488
|
+
{
|
|
1489
|
+
onClick: () => setIsBalanceHidden(!isBalanceHidden),
|
|
1490
|
+
className: "text-neutral-400 hover:text-black transition-colors outline-none"
|
|
1491
|
+
},
|
|
1492
|
+
/* @__PURE__ */ React16.createElement(HugeiconsIcon10, { icon: isBalanceHidden ? ViewIcon : ViewOffSlashIcon, size: 14 })
|
|
1493
|
+
)), /* @__PURE__ */ React16.createElement("h1", { className: `text-3xl sm:text-4xl md:text-5xl text-black tracking-tight mb-5 tabular-nums flex items-baseline transition-all duration-300 ${isBalanceHidden ? "blur-sm opacity-40 select-none" : ""}` }, /* @__PURE__ */ React16.createElement("span", { className: "text-xl sm:text-2xl text-neutral-400 mr-1" }, balanceCurrency), intPart, /* @__PURE__ */ React16.createElement("span", { className: "text-xl sm:text-2xl text-neutral-400" }, ".", decPart)), /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-3" }, primaryAction && /* @__PURE__ */ React16.createElement(
|
|
1494
|
+
ThreeDActionButton,
|
|
1495
|
+
{
|
|
1496
|
+
onClick: primaryAction.onClick,
|
|
1497
|
+
className: "px-6 py-2.5 sm:px-8 sm:py-2.5"
|
|
1498
|
+
},
|
|
1499
|
+
/* @__PURE__ */ React16.createElement("span", { className: "flex items-center gap-1.5 text-[13px] tracking-wide font-medium" }, primaryAction.label, primaryAction.icon && /* @__PURE__ */ React16.createElement(HugeiconsIcon10, { icon: primaryAction.icon, size: 16 }))
|
|
1500
|
+
), secondaryAction && /* @__PURE__ */ React16.createElement(
|
|
1501
|
+
"button",
|
|
1502
|
+
{
|
|
1503
|
+
onClick: secondaryAction.onClick,
|
|
1504
|
+
className: "flex items-center gap-1.5 px-6 py-2.5 sm:px-8 sm:py-2.5 rounded-full bg-white border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none"
|
|
1505
|
+
},
|
|
1506
|
+
/* @__PURE__ */ React16.createElement("span", { className: "text-[13px] tracking-wide font-medium" }, secondaryAction.label),
|
|
1507
|
+
secondaryAction.icon && /* @__PURE__ */ React16.createElement(HugeiconsIcon10, { icon: secondaryAction.icon, size: 16 })
|
|
1508
|
+
)))), /* @__PURE__ */ React16.createElement("div", { className: "w-full mt-2" }, /* @__PURE__ */ React16.createElement(
|
|
1509
|
+
UniversalTransactionPage,
|
|
1510
|
+
{
|
|
1511
|
+
...transactionsProps,
|
|
1512
|
+
hideControls: true,
|
|
1513
|
+
hideBalanceAmounts: isBalanceHidden,
|
|
1514
|
+
hidePagination: true
|
|
1515
|
+
}
|
|
1516
|
+
)));
|
|
1517
|
+
};
|
|
1518
|
+
|
|
1519
|
+
// src/components/UniversalWalletPage.tsx
|
|
1520
|
+
import React17, { useState as useState10 } from "react";
|
|
1521
|
+
import toast5 from "react-hot-toast";
|
|
1522
|
+
import { HugeiconsIcon as HugeiconsIcon11 } from "@hugeicons/react";
|
|
1523
|
+
import {
|
|
1524
|
+
Search01Icon as Search01Icon2,
|
|
1525
|
+
CancelCircleIcon as CancelCircleIcon3,
|
|
1526
|
+
Loading03Icon as Loading03Icon5
|
|
1527
|
+
} from "@hugeicons/core-free-icons";
|
|
1528
|
+
var PageSpinner3 = () => /* @__PURE__ */ React17.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ React17.createElement(HugeiconsIcon11, { icon: Loading03Icon5, size: 32, className: "animate-spin mb-4 text-black" }));
|
|
1529
|
+
var WalletLogo = ({ src, alt, sizeClass = "w-10 h-10" }) => {
|
|
1530
|
+
const [isLoaded, setIsLoaded] = useState10(false);
|
|
1531
|
+
return /* @__PURE__ */ React17.createElement("div", { className: `relative shrink-0 rounded-full bg-neutral-100 flex items-center justify-center overflow-hidden ${sizeClass}` }, !isLoaded && /* @__PURE__ */ React17.createElement(HugeiconsIcon11, { icon: Loading03Icon5, size: 16, className: "animate-spin text-neutral-400 absolute" }), /* @__PURE__ */ React17.createElement(
|
|
1532
|
+
"img",
|
|
1533
|
+
{
|
|
1534
|
+
src,
|
|
1535
|
+
alt,
|
|
1536
|
+
onLoad: () => setIsLoaded(true),
|
|
1537
|
+
className: `w-full h-full object-cover transition-opacity duration-300 ${isLoaded ? "opacity-100" : "opacity-0"}`
|
|
1538
|
+
}
|
|
1539
|
+
));
|
|
1540
|
+
};
|
|
1541
|
+
var UniversalWalletPage = ({
|
|
1542
|
+
headerTitle,
|
|
1543
|
+
headerDescription,
|
|
1544
|
+
hideControls = false,
|
|
1545
|
+
hideBalanceAmounts = false,
|
|
1546
|
+
isGeneratingStatement = false,
|
|
1547
|
+
wallets,
|
|
1548
|
+
isLoading = false,
|
|
1549
|
+
renderQrCode,
|
|
1550
|
+
onDownloadPayId,
|
|
1551
|
+
onCopyAddress
|
|
1552
|
+
}) => {
|
|
1553
|
+
const [selectedWallet, setSelectedWallet] = useState10(null);
|
|
1554
|
+
const [localSearchQuery, setLocalSearchQuery] = useState10("");
|
|
1555
|
+
const filteredWallets = wallets.filter((wallet) => {
|
|
1556
|
+
const q = localSearchQuery.toLowerCase();
|
|
1557
|
+
return wallet.name.toLowerCase().includes(q) || wallet.currency.toLowerCase().includes(q) || wallet.network.toLowerCase().includes(q);
|
|
1558
|
+
});
|
|
1559
|
+
const handleCopy = (wallet) => {
|
|
1560
|
+
if (onCopyAddress) onCopyAddress(wallet);
|
|
1561
|
+
if (typeof navigator !== "undefined" && navigator.clipboard) {
|
|
1562
|
+
navigator.clipboard.writeText(wallet.address).catch(() => {
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
toast5.success("Address copied to clipboard");
|
|
1566
|
+
};
|
|
1567
|
+
return /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-6 animate-in max-w-5xl fade-in duration-300" }, /* @__PURE__ */ React17.createElement(ManagedToaster, null), !hideControls && /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-4 w-full" }, /* @__PURE__ */ React17.createElement("div", { className: "relative w-full sm:w-96" }, /* @__PURE__ */ React17.createElement("div", { className: "absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none" }, /* @__PURE__ */ React17.createElement(HugeiconsIcon11, { icon: Search01Icon2, size: 16, className: "text-neutral-400" })), /* @__PURE__ */ React17.createElement(
|
|
1568
|
+
"input",
|
|
1569
|
+
{
|
|
1570
|
+
type: "text",
|
|
1571
|
+
placeholder: "Search wallets by name or network...",
|
|
1572
|
+
value: localSearchQuery,
|
|
1573
|
+
onChange: (e) => setLocalSearchQuery(e.target.value),
|
|
1574
|
+
className: "w-full pl-10 pr-4 py-2 bg-white border border-neutral-200 rounded-full text-[13px] text-black placeholder-neutral-400 outline-none transition-all duration-300 focus:border-black"
|
|
1575
|
+
}
|
|
1576
|
+
))), /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-8 p-6 rounded-2xl bg-white w-full" }, /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-4" }, /* @__PURE__ */ React17.createElement("div", null, /* @__PURE__ */ React17.createElement("h1", { className: "text-black text-xl mb-1 tracking-tight" }, headerTitle), headerDescription && /* @__PURE__ */ React17.createElement("p", { className: "text-xs text-neutral-500" }, headerDescription))), /* @__PURE__ */ React17.createElement("div", { className: "w-full overflow-hidden" }, isLoading ? /* @__PURE__ */ React17.createElement(PageSpinner3, null) : /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ React17.createElement("div", null, filteredWallets.length === 0 ? /* @__PURE__ */ React17.createElement("p", { className: "text-xs text-neutral-400 py-6 text-center" }, "No wallets found") : filteredWallets.map((wallet) => /* @__PURE__ */ React17.createElement(
|
|
1577
|
+
"div",
|
|
1578
|
+
{
|
|
1579
|
+
key: wallet.id,
|
|
1580
|
+
onClick: () => setSelectedWallet(wallet),
|
|
1581
|
+
className: "flex items-center justify-between py-4 hover:bg-neutral-50 transition-colors cursor-pointer group min-w-0 px-3 -mx-3 rounded-xl"
|
|
1582
|
+
},
|
|
1583
|
+
/* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-4 min-w-0 flex-1" }, /* @__PURE__ */ React17.createElement(WalletLogo, { src: wallet.logoSrc, alt: wallet.name }), /* @__PURE__ */ React17.createElement("div", { className: "min-w-0 flex-1 flex flex-col gap-1" }, /* @__PURE__ */ React17.createElement("p", { className: "text-[13px] text-black truncate font-medium" }, wallet.name), /* @__PURE__ */ React17.createElement("p", { className: `text-[13px] text-neutral-500 truncate transition-all duration-300 ${hideBalanceAmounts ? "blur-sm opacity-40 select-none" : ""}` }, wallet.balance, " ", wallet.currency))),
|
|
1584
|
+
/* @__PURE__ */ React17.createElement("div", { className: "shrink-0 flex flex-col items-end gap-1 text-right" }, /* @__PURE__ */ React17.createElement("span", { className: "text-[10px] tracking-wide text-neutral-600 bg-neutral-100 px-2.5 py-1 rounded-full " }, wallet.network))
|
|
1585
|
+
)))))), selectedWallet && /* @__PURE__ */ React17.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React17.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => setSelectedWallet(null) }), /* @__PURE__ */ React17.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200 max-h-[90vh]" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ React17.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Wallet Details"), /* @__PURE__ */ React17.createElement("button", { onClick: () => setSelectedWallet(null), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React17.createElement(HugeiconsIcon11, { icon: CancelCircleIcon3, size: 18 }))), /* @__PURE__ */ React17.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 pt-6" }, /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col items-center justify-center mb-6" }, /* @__PURE__ */ React17.createElement(WalletLogo, { src: selectedWallet.logoSrc, alt: selectedWallet.name, sizeClass: "w-14 h-14 mb-4" }), /* @__PURE__ */ React17.createElement("h2", { className: `text-2xl text-black mb-2 transition-all duration-300 font-medium ${hideBalanceAmounts ? "blur-[6px] opacity-40 select-none" : ""}` }, selectedWallet.balance, " ", selectedWallet.currency), /* @__PURE__ */ React17.createElement("span", { className: "text-[9px] tracking-widest text-neutral-500 px-4 py-1.5 rounded-full border border-neutral-200 uppercase mt-1 " }, selectedWallet.network, " NETWORK")), renderQrCode && /* @__PURE__ */ React17.createElement("div", { className: "w-full flex justify-center mb-6 mix-blend-multiply" }, renderQrCode(selectedWallet)), /* @__PURE__ */ React17.createElement("div", { className: "grid grid-cols-1 gap-y-6 gap-x-4 mb-10" }, /* @__PURE__ */ React17.createElement("div", null, /* @__PURE__ */ React17.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-400 block mb-2" }, "Wallet Address"), /* @__PURE__ */ React17.createElement("span", { className: "text-[13px] text-black break-all font-medium" }, selectedWallet.address)), /* @__PURE__ */ React17.createElement("div", null, /* @__PURE__ */ React17.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-400 block mb-2" }, "Wallet Name"), /* @__PURE__ */ React17.createElement("span", { className: "text-[13px] text-black" }, selectedWallet.name))), /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React17.createElement(
|
|
1586
|
+
ThreeDActionButton,
|
|
1587
|
+
{
|
|
1588
|
+
onClick: () => onDownloadPayId && onDownloadPayId(selectedWallet),
|
|
1589
|
+
isLoading: isGeneratingStatement,
|
|
1590
|
+
className: "w-full py-3 text-[13px]"
|
|
1591
|
+
},
|
|
1592
|
+
"Generate Statement"
|
|
1593
|
+
), /* @__PURE__ */ React17.createElement(
|
|
1594
|
+
"button",
|
|
1595
|
+
{
|
|
1596
|
+
onClick: () => handleCopy(selectedWallet),
|
|
1597
|
+
className: "w-full flex font-medium items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 outline-none text-[13px] tracking-wide transition-colors"
|
|
1598
|
+
},
|
|
1599
|
+
"Copy Wallet Address"
|
|
1600
|
+
))))));
|
|
1601
|
+
};
|
|
1602
|
+
|
|
1603
|
+
// src/components/UniversalCardPage.tsx
|
|
1604
|
+
import React18, { useState as useState11 } from "react";
|
|
1605
|
+
import { HugeiconsIcon as HugeiconsIcon12 } from "@hugeicons/react";
|
|
1606
|
+
import {
|
|
1607
|
+
EyeIcon,
|
|
1608
|
+
SnowIcon,
|
|
1609
|
+
Settings02Icon,
|
|
1610
|
+
Delete02Icon,
|
|
1611
|
+
ArrowRight01Icon as ArrowRight01Icon2
|
|
1612
|
+
} from "@hugeicons/core-free-icons";
|
|
1613
|
+
var UniversalCardPage = ({
|
|
1614
|
+
cardHolderName,
|
|
1615
|
+
cardNumber,
|
|
1616
|
+
expiry,
|
|
1617
|
+
cvv,
|
|
1618
|
+
cardBgSrc,
|
|
1619
|
+
companyLogoSrc,
|
|
1620
|
+
networkLogoSrc,
|
|
1621
|
+
onReveal,
|
|
1622
|
+
onFreeze,
|
|
1623
|
+
onSetLimits,
|
|
1624
|
+
onDelete
|
|
1625
|
+
}) => {
|
|
1626
|
+
const [isFlipped, setIsFlipped] = useState11(false);
|
|
1627
|
+
return /* @__PURE__ */ React18.createElement("div", { className: "w-full max-w-md mx-auto flex flex-col items-center animate-in fade-in duration-300 pb-12" }, /* @__PURE__ */ React18.createElement("div", { className: "w-full px-4 pt-6 pb-2", style: { perspective: "1000px" } }, /* @__PURE__ */ React18.createElement(
|
|
1628
|
+
"div",
|
|
1629
|
+
{
|
|
1630
|
+
onClick: () => setIsFlipped(!isFlipped),
|
|
1631
|
+
className: "relative w-full h-50.5 cursor-pointer transition-transform duration-700",
|
|
1632
|
+
style: {
|
|
1633
|
+
transformStyle: "preserve-3d",
|
|
1634
|
+
transform: isFlipped ? "rotateY(180deg)" : "rotateY(0deg)"
|
|
1635
|
+
}
|
|
1636
|
+
},
|
|
1637
|
+
/* @__PURE__ */ React18.createElement(
|
|
1638
|
+
"div",
|
|
1639
|
+
{
|
|
1640
|
+
className: "absolute inset-0 w-full h-full rounded-2xl overflow-hidden shadow-xl",
|
|
1641
|
+
style: { backfaceVisibility: "hidden" }
|
|
1642
|
+
},
|
|
1643
|
+
/* @__PURE__ */ React18.createElement(
|
|
1644
|
+
"div",
|
|
1645
|
+
{
|
|
1646
|
+
className: "absolute inset-0 bg-cover bg-center",
|
|
1647
|
+
style: { backgroundImage: `url(${cardBgSrc}), linear-gradient(to bottom right, #111, #333)` }
|
|
1648
|
+
}
|
|
1649
|
+
),
|
|
1650
|
+
/* @__PURE__ */ React18.createElement("div", { className: "relative z-10 w-full h-full p-5 flex flex-col justify-between" }, /* @__PURE__ */ React18.createElement("div", { className: "flex justify-between items-start w-full" }, /* @__PURE__ */ React18.createElement("div", null, /* @__PURE__ */ React18.createElement("span", { className: "text-[13px] text-white/70 font-medium" }, "Prepaid Card")), companyLogoSrc && /* @__PURE__ */ React18.createElement("img", { src: companyLogoSrc, alt: "Company Logo", className: "h-6 object-contain opacity-90" })), /* @__PURE__ */ React18.createElement("div", { className: "flex justify-between items-end w-full" }, /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React18.createElement("span", { className: "text-[11px] text-white/60 tracking-widest" }, "Card Number"), /* @__PURE__ */ React18.createElement("span", { className: "text-[18px] text-white tracking-widest font-light" }, cardNumber)), networkLogoSrc && /* @__PURE__ */ React18.createElement("img", { src: networkLogoSrc, alt: "Network Logo", className: "h-10 object-contain opacity-90" })))
|
|
1651
|
+
),
|
|
1652
|
+
/* @__PURE__ */ React18.createElement(
|
|
1653
|
+
"div",
|
|
1654
|
+
{
|
|
1655
|
+
className: "absolute inset-0 w-full h-full rounded-2xl overflow-hidden shadow-xl",
|
|
1656
|
+
style: {
|
|
1657
|
+
backfaceVisibility: "hidden",
|
|
1658
|
+
transform: "rotateY(180deg)"
|
|
1659
|
+
}
|
|
1660
|
+
},
|
|
1661
|
+
/* @__PURE__ */ React18.createElement(
|
|
1662
|
+
"div",
|
|
1663
|
+
{
|
|
1664
|
+
className: "absolute inset-0 bg-cover bg-center",
|
|
1665
|
+
style: { backgroundImage: `url(${cardBgSrc}), linear-gradient(to bottom right, #111, #333)` }
|
|
1666
|
+
}
|
|
1667
|
+
),
|
|
1668
|
+
/* @__PURE__ */ React18.createElement("div", { className: "absolute top-6 left-0 right-0 h-10 bg-black/80 w-full" }),
|
|
1669
|
+
/* @__PURE__ */ React18.createElement("div", { className: "relative z-10 w-full h-full p-5 flex flex-col justify-end" }, /* @__PURE__ */ React18.createElement("div", { className: "w-full text-center mb-6" }, /* @__PURE__ */ React18.createElement("span", { className: "text-white text-3xl font-serif italic tracking-wide opacity-90" }, cardHolderName)), /* @__PURE__ */ React18.createElement("div", { className: "flex justify-between w-full max-w-[80%]" }, /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React18.createElement("span", { className: "text-[11px] text-white/60 tracking-widest" }, "Expiry"), /* @__PURE__ */ React18.createElement("span", { className: "text-[16px] text-white font-light" }, expiry)), /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React18.createElement("span", { className: "text-[11px] text-white/60 tracking-widest" }, "CVV"), /* @__PURE__ */ React18.createElement("span", { className: "text-[16px] text-white font-light" }, cvv))))
|
|
1670
|
+
)
|
|
1671
|
+
)), /* @__PURE__ */ React18.createElement("p", { className: "text-xs text-neutral-400 mb-6" }, "Tap to flip card"), /* @__PURE__ */ React18.createElement("div", { className: "w-full px-4 flex flex-col gap-4" }, /* @__PURE__ */ React18.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ React18.createElement(
|
|
1672
|
+
MenuRow,
|
|
1673
|
+
{
|
|
1674
|
+
icon: EyeIcon,
|
|
1675
|
+
title: "Reveal Information",
|
|
1676
|
+
subtitle: "Show card informations",
|
|
1677
|
+
onClick: onReveal
|
|
1678
|
+
}
|
|
1679
|
+
), /* @__PURE__ */ React18.createElement(
|
|
1680
|
+
MenuRow,
|
|
1681
|
+
{
|
|
1682
|
+
icon: SnowIcon,
|
|
1683
|
+
title: "Freeze",
|
|
1684
|
+
subtitle: "Freeze & Unfreeze card",
|
|
1685
|
+
onClick: onFreeze
|
|
1686
|
+
}
|
|
1687
|
+
), /* @__PURE__ */ React18.createElement(
|
|
1688
|
+
MenuRow,
|
|
1689
|
+
{
|
|
1690
|
+
icon: Settings02Icon,
|
|
1691
|
+
title: "Set Limits",
|
|
1692
|
+
subtitle: "Set card limits",
|
|
1693
|
+
onClick: onSetLimits,
|
|
1694
|
+
isLast: true
|
|
1695
|
+
}
|
|
1696
|
+
)), /* @__PURE__ */ React18.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ React18.createElement(
|
|
1697
|
+
MenuRow,
|
|
1698
|
+
{
|
|
1699
|
+
icon: Delete02Icon,
|
|
1700
|
+
title: "Delete card",
|
|
1701
|
+
subtitle: "Permanently delete card",
|
|
1702
|
+
onClick: onDelete,
|
|
1703
|
+
isLast: true
|
|
1704
|
+
}
|
|
1705
|
+
))));
|
|
1706
|
+
};
|
|
1707
|
+
var MenuRow = ({ icon, title, subtitle, onClick, iconColor = "text-black", titleColor = "text-black", isLast = false }) => /* @__PURE__ */ React18.createElement(
|
|
1708
|
+
"div",
|
|
1709
|
+
{
|
|
1710
|
+
onClick,
|
|
1711
|
+
className: `flex items-center p-4 cursor-pointer hover:bg-neutral-50 transition-colors ${!isLast ? "border-b border-neutral-100" : ""}`
|
|
1712
|
+
},
|
|
1713
|
+
/* @__PURE__ */ React18.createElement("div", { className: "w-10 h-10 rounded-full bg-neutral-100 flex items-center justify-center shrink-0 mr-4" }, /* @__PURE__ */ React18.createElement(HugeiconsIcon12, { icon, size: 20, className: iconColor })),
|
|
1714
|
+
/* @__PURE__ */ React18.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React18.createElement("p", { className: `text-[15px] font-medium truncate ${titleColor}` }, title), /* @__PURE__ */ React18.createElement("p", { className: "text-[13px] text-neutral-500 truncate" }, subtitle)),
|
|
1715
|
+
/* @__PURE__ */ React18.createElement(HugeiconsIcon12, { icon: ArrowRight01Icon2, size: 20, className: "text-neutral-400 shrink-0 ml-2" })
|
|
1716
|
+
);
|
|
1717
|
+
|
|
1718
|
+
// src/components/UniversalProfilePage.tsx
|
|
1719
|
+
import React19 from "react";
|
|
1720
|
+
import { HugeiconsIcon as HugeiconsIcon13 } from "@hugeicons/react";
|
|
1721
|
+
import {
|
|
1722
|
+
UserIcon,
|
|
1723
|
+
LockKeyIcon as LockKeyIcon2,
|
|
1724
|
+
Notification03Icon,
|
|
1725
|
+
HelpCircleIcon,
|
|
1726
|
+
Shield01Icon,
|
|
1727
|
+
Download04Icon,
|
|
1728
|
+
Logout03Icon,
|
|
1729
|
+
Delete02Icon as Delete02Icon2,
|
|
1730
|
+
ArrowRight01Icon as ArrowRight01Icon3
|
|
1731
|
+
} from "@hugeicons/core-free-icons";
|
|
1732
|
+
var UniversalProfilePage = ({
|
|
1733
|
+
avatarSrc,
|
|
1734
|
+
roleName,
|
|
1735
|
+
memberSince,
|
|
1736
|
+
onAccountTap,
|
|
1737
|
+
onSecurityTap,
|
|
1738
|
+
onNotificationsTap,
|
|
1739
|
+
onHelpTap,
|
|
1740
|
+
onVerificationsTap,
|
|
1741
|
+
onExportTap,
|
|
1742
|
+
onLogoutTap,
|
|
1743
|
+
onDeleteTap
|
|
1744
|
+
}) => {
|
|
1745
|
+
return /* @__PURE__ */ React19.createElement("div", { className: "w-full max-w-md mx-auto flex flex-col items-center animate-in fade-in duration-300 pb-12" }, /* @__PURE__ */ React19.createElement("div", { className: "pt-8 pb-4 flex flex-col items-center" }, /* @__PURE__ */ React19.createElement("div", { className: "w-24 h-24 rounded-full bg-white p-1 mb-4 shadow-sm flex items-center justify-center" }, /* @__PURE__ */ React19.createElement("div", { className: "w-full h-full rounded-full overflow-hidden bg-neutral-100 flex items-center justify-center" }, avatarSrc ? /* @__PURE__ */ React19.createElement(
|
|
1746
|
+
"img",
|
|
1747
|
+
{
|
|
1748
|
+
src: avatarSrc,
|
|
1749
|
+
alt: "User Avatar",
|
|
1750
|
+
className: "w-full h-full object-cover"
|
|
1751
|
+
}
|
|
1752
|
+
) : /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: UserIcon, size: 40, className: "text-neutral-300" }))), /* @__PURE__ */ React19.createElement("div", { className: "bg-white rounded-full px-5 py-2 flex items-center justify-center gap-2 shadow-sm mb-3" }, /* @__PURE__ */ React19.createElement("span", { className: "text-[14px] font-medium text-black" }, roleName), /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: ArrowRight01Icon3, size: 16, className: "text-neutral-400" })), /* @__PURE__ */ React19.createElement("span", { className: "text-[12px] text-neutral-500" }, memberSince)), /* @__PURE__ */ React19.createElement("div", { className: "w-full px-4 flex flex-col gap-4 mt-2" }, /* @__PURE__ */ React19.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden shadow-sm" }, /* @__PURE__ */ React19.createElement(
|
|
1753
|
+
MenuRow2,
|
|
1754
|
+
{
|
|
1755
|
+
icon: UserIcon,
|
|
1756
|
+
title: "Account",
|
|
1757
|
+
subtitle: "Your account details",
|
|
1758
|
+
onClick: onAccountTap
|
|
1759
|
+
}
|
|
1760
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1761
|
+
MenuRow2,
|
|
1762
|
+
{
|
|
1763
|
+
icon: LockKeyIcon2,
|
|
1764
|
+
title: "Security",
|
|
1765
|
+
subtitle: "2FA & authentication",
|
|
1766
|
+
onClick: onSecurityTap
|
|
1767
|
+
}
|
|
1768
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1769
|
+
MenuRow2,
|
|
1770
|
+
{
|
|
1771
|
+
icon: Notification03Icon,
|
|
1772
|
+
title: "Notifications",
|
|
1773
|
+
subtitle: "Manage notifications",
|
|
1774
|
+
onClick: onNotificationsTap
|
|
1775
|
+
}
|
|
1776
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1777
|
+
MenuRow2,
|
|
1778
|
+
{
|
|
1779
|
+
icon: HelpCircleIcon,
|
|
1780
|
+
title: "Get Help",
|
|
1781
|
+
subtitle: "24/7 Support",
|
|
1782
|
+
onClick: onHelpTap,
|
|
1783
|
+
isLast: true
|
|
1784
|
+
}
|
|
1785
|
+
)), /* @__PURE__ */ React19.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden shadow-sm" }, /* @__PURE__ */ React19.createElement(
|
|
1786
|
+
MenuRow2,
|
|
1787
|
+
{
|
|
1788
|
+
icon: Shield01Icon,
|
|
1789
|
+
title: "Verifications",
|
|
1790
|
+
subtitle: "Account Verifications",
|
|
1791
|
+
onClick: onVerificationsTap
|
|
1792
|
+
}
|
|
1793
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1794
|
+
MenuRow2,
|
|
1795
|
+
{
|
|
1796
|
+
icon: Download04Icon,
|
|
1797
|
+
title: "Export Account",
|
|
1798
|
+
subtitle: "Transfer your account",
|
|
1799
|
+
onClick: onExportTap
|
|
1800
|
+
}
|
|
1801
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1802
|
+
MenuRow2,
|
|
1803
|
+
{
|
|
1804
|
+
icon: Logout03Icon,
|
|
1805
|
+
title: "LogOut",
|
|
1806
|
+
subtitle: "End your session",
|
|
1807
|
+
onClick: onLogoutTap,
|
|
1808
|
+
isLast: true
|
|
1809
|
+
}
|
|
1810
|
+
)), /* @__PURE__ */ React19.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden shadow-sm mb-4" }, /* @__PURE__ */ React19.createElement(
|
|
1811
|
+
MenuRow2,
|
|
1812
|
+
{
|
|
1813
|
+
icon: Delete02Icon2,
|
|
1814
|
+
title: "Delete Account",
|
|
1815
|
+
subtitle: "Remove account",
|
|
1816
|
+
onClick: onDeleteTap,
|
|
1817
|
+
isLast: true
|
|
1818
|
+
}
|
|
1819
|
+
))));
|
|
1820
|
+
};
|
|
1821
|
+
var MenuRow2 = ({ icon, title, subtitle, onClick, iconColor = "text-black", titleColor = "text-black", isLast = false }) => /* @__PURE__ */ React19.createElement(
|
|
1822
|
+
"div",
|
|
1823
|
+
{
|
|
1824
|
+
onClick,
|
|
1825
|
+
className: `flex items-center p-4 cursor-pointer hover:bg-neutral-50 transition-colors ${!isLast ? "border-b border-neutral-100" : ""}`
|
|
1826
|
+
},
|
|
1827
|
+
/* @__PURE__ */ React19.createElement("div", { className: "w-10 h-10 rounded-full bg-neutral-100 flex items-center justify-center shrink-0 mr-4" }, /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon, size: 20, className: iconColor })),
|
|
1828
|
+
/* @__PURE__ */ React19.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React19.createElement("p", { className: `text-[15px] font-medium truncate ${titleColor}` }, title), /* @__PURE__ */ React19.createElement("p", { className: "text-[13px] text-neutral-500 truncate" }, subtitle)),
|
|
1829
|
+
/* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: ArrowRight01Icon3, size: 20, className: "text-neutral-400 shrink-0 ml-2" })
|
|
1830
|
+
);
|
|
1831
|
+
|
|
1832
|
+
// src/components/HeroSection.tsx
|
|
1833
|
+
import React21, { useState as useState13, useEffect as useEffect8, useRef as useRef4 } from "react";
|
|
1834
|
+
import Link5 from "next/link";
|
|
1835
|
+
import Image2 from "next/image";
|
|
1836
|
+
|
|
404
1837
|
// src/components/WaitlistDialog.tsx
|
|
1838
|
+
import React20, { useState as useState12 } from "react";
|
|
1839
|
+
import { toast as toast6 } from "react-hot-toast";
|
|
405
1840
|
var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
406
|
-
const [email, setEmail] =
|
|
407
|
-
const [isLoading, setIsLoading] =
|
|
1841
|
+
const [email, setEmail] = useState12("");
|
|
1842
|
+
const [isLoading, setIsLoading] = useState12(false);
|
|
408
1843
|
if (!isOpen) return null;
|
|
409
1844
|
const handleSubmit = async (e) => {
|
|
410
1845
|
e.preventDefault();
|
|
411
1846
|
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
412
|
-
|
|
1847
|
+
toast6.error("Please enter a valid email address.");
|
|
413
1848
|
return;
|
|
414
1849
|
}
|
|
415
1850
|
setIsLoading(true);
|
|
@@ -423,24 +1858,24 @@ var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
|
423
1858
|
});
|
|
424
1859
|
const data = await response.json();
|
|
425
1860
|
if (response.ok && data.success) {
|
|
426
|
-
|
|
1861
|
+
toast6.success(data.message || "You've been added to the waitlist!");
|
|
427
1862
|
setEmail("");
|
|
428
1863
|
onClose();
|
|
429
1864
|
} else {
|
|
430
|
-
|
|
1865
|
+
toast6.error(data.error || "Something went wrong. Please try again.");
|
|
431
1866
|
}
|
|
432
1867
|
} catch (error) {
|
|
433
|
-
|
|
1868
|
+
toast6.error("Network error. Please check your connection.");
|
|
434
1869
|
} finally {
|
|
435
1870
|
setIsLoading(false);
|
|
436
1871
|
}
|
|
437
1872
|
};
|
|
438
|
-
return /* @__PURE__ */
|
|
1873
|
+
return /* @__PURE__ */ React20.createElement("div", { className: "fixed inset-0 z-100 flex items-center justify-center p-4 bg-black/40" }, /* @__PURE__ */ React20.createElement("div", { className: "absolute inset-0", onClick: !isLoading ? onClose : void 0 }), /* @__PURE__ */ React20.createElement(
|
|
439
1874
|
"div",
|
|
440
1875
|
{
|
|
441
1876
|
className: "w-full max-w-md bg-white rounded-2xl shadow-2xl overflow-hidden relative z-10 animate-in fade-in zoom-in-95 duration-200"
|
|
442
1877
|
},
|
|
443
|
-
/* @__PURE__ */
|
|
1878
|
+
/* @__PURE__ */ React20.createElement(
|
|
444
1879
|
"button",
|
|
445
1880
|
{
|
|
446
1881
|
onClick: onClose,
|
|
@@ -448,7 +1883,7 @@ var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
|
448
1883
|
className: "absolute top-4 right-4 p-2 text-neutral-700 hover:text-neutral-400 transition-colors disabled:opacity-50 outline-none",
|
|
449
1884
|
"aria-label": "Close dialog"
|
|
450
1885
|
},
|
|
451
|
-
/* @__PURE__ */
|
|
1886
|
+
/* @__PURE__ */ React20.createElement(
|
|
452
1887
|
"svg",
|
|
453
1888
|
{
|
|
454
1889
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -461,11 +1896,11 @@ var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
|
461
1896
|
strokeLinecap: "round",
|
|
462
1897
|
strokeLinejoin: "round"
|
|
463
1898
|
},
|
|
464
|
-
/* @__PURE__ */
|
|
465
|
-
/* @__PURE__ */
|
|
1899
|
+
/* @__PURE__ */ React20.createElement("path", { d: "M18 6 6 18" }),
|
|
1900
|
+
/* @__PURE__ */ React20.createElement("path", { d: "m6 6 12 12" })
|
|
466
1901
|
)
|
|
467
1902
|
),
|
|
468
|
-
/* @__PURE__ */
|
|
1903
|
+
/* @__PURE__ */ React20.createElement("div", { className: "p-6 sm:p-8" }, /* @__PURE__ */ React20.createElement("div", { className: "mb-8 mt-2" }, /* @__PURE__ */ React20.createElement("h2", { className: "text-2xl text-black tracking-tight mb-2" }, "Join the Waitlist"), /* @__PURE__ */ React20.createElement("p", { className: "text-[13px] text-neutral-500 leading-relaxed" }, "Be the first to experience the future of natural language computing. Secure your early access spot today.")), /* @__PURE__ */ React20.createElement("form", { onSubmit: handleSubmit, className: "flex flex-col gap-8" }, /* @__PURE__ */ React20.createElement(
|
|
469
1904
|
TextInput,
|
|
470
1905
|
{
|
|
471
1906
|
label: "Email ID",
|
|
@@ -475,7 +1910,7 @@ var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
|
475
1910
|
placeholder: "name@example.com",
|
|
476
1911
|
disabled: isLoading
|
|
477
1912
|
}
|
|
478
|
-
), /* @__PURE__ */
|
|
1913
|
+
), /* @__PURE__ */ React20.createElement(
|
|
479
1914
|
ThreeDActionButton,
|
|
480
1915
|
{
|
|
481
1916
|
type: "submit",
|
|
@@ -508,10 +1943,10 @@ var HeroSection = ({
|
|
|
508
1943
|
bgImageSrc,
|
|
509
1944
|
isWaitlist = false
|
|
510
1945
|
}) => {
|
|
511
|
-
const [isAnimating, setIsAnimating] =
|
|
512
|
-
const [isWaitlistOpen, setIsWaitlistOpen] =
|
|
513
|
-
const titleRef =
|
|
514
|
-
|
|
1946
|
+
const [isAnimating, setIsAnimating] = useState13(false);
|
|
1947
|
+
const [isWaitlistOpen, setIsWaitlistOpen] = useState13(false);
|
|
1948
|
+
const titleRef = useRef4(null);
|
|
1949
|
+
useEffect8(() => {
|
|
515
1950
|
const observer = new IntersectionObserver(
|
|
516
1951
|
([entry]) => {
|
|
517
1952
|
if (entry.isIntersecting) {
|
|
@@ -533,7 +1968,7 @@ var HeroSection = ({
|
|
|
533
1968
|
setIsWaitlistOpen(true);
|
|
534
1969
|
}
|
|
535
1970
|
};
|
|
536
|
-
return /* @__PURE__ */
|
|
1971
|
+
return /* @__PURE__ */ React21.createElement("div", { className: "w-screen min-h-screen flex justify-center items-center p-4" }, /* @__PURE__ */ React21.createElement("section", { className: "relative h-[95vh] w-full overflow-hidden rounded-2xl " }, bgVideoSrc ? /* @__PURE__ */ React21.createElement(
|
|
537
1972
|
"video",
|
|
538
1973
|
{
|
|
539
1974
|
src: bgVideoSrc,
|
|
@@ -544,7 +1979,7 @@ var HeroSection = ({
|
|
|
544
1979
|
playsInline: true,
|
|
545
1980
|
className: "absolute inset-0 h-full w-full object-cover z-0"
|
|
546
1981
|
}
|
|
547
|
-
) : bgImageSrc ? /* @__PURE__ */
|
|
1982
|
+
) : bgImageSrc ? /* @__PURE__ */ React21.createElement(
|
|
548
1983
|
Image2,
|
|
549
1984
|
{
|
|
550
1985
|
src: bgImageSrc,
|
|
@@ -553,7 +1988,7 @@ var HeroSection = ({
|
|
|
553
1988
|
priority: true,
|
|
554
1989
|
className: "absolute inset-0 h-full w-full object-cover z-0"
|
|
555
1990
|
}
|
|
556
|
-
) : null, /* @__PURE__ */
|
|
1991
|
+
) : null, /* @__PURE__ */ React21.createElement(
|
|
557
1992
|
"div",
|
|
558
1993
|
{
|
|
559
1994
|
className: "pointer-events-none absolute inset-0 z-10 opacity-[0.7] mix-blend-overlay",
|
|
@@ -561,31 +1996,31 @@ var HeroSection = ({
|
|
|
561
1996
|
backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E")`
|
|
562
1997
|
}
|
|
563
1998
|
}
|
|
564
|
-
), /* @__PURE__ */
|
|
1999
|
+
), /* @__PURE__ */ React21.createElement("div", { className: "pointer-events-none absolute inset-0 bg-linear-to-b from-black/30 via-transparent to-black/80 z-10" }), /* @__PURE__ */ React21.createElement("div", { className: "absolute bottom-0 left-0 right-0 px-4 pb-4 sm:px-6 md:px-10 z-20" }, /* @__PURE__ */ React21.createElement("div", { className: "grid grid-cols-12 items-end gap-4" }, /* @__PURE__ */ React21.createElement("div", { className: "col-span-12 lg:col-span-8" }, /* @__PURE__ */ React21.createElement(
|
|
565
2000
|
"h1",
|
|
566
2001
|
{
|
|
567
2002
|
ref: titleRef,
|
|
568
2003
|
className: "leading-[0.85] tracking-[-0.07em] text-[18.2vw] sm:text-[16.8vw] md:text-[15.4vw] lg:text-[14vw] xl:text-[13.3vw] 2xl:text-[14vw] text-[#ffffff]"
|
|
569
2004
|
},
|
|
570
|
-
/* @__PURE__ */
|
|
571
|
-
)), /* @__PURE__ */
|
|
572
|
-
/* @__PURE__ */
|
|
573
|
-
|
|
2005
|
+
/* @__PURE__ */ React21.createElement("div", { className: "inline-flex flex-wrap" }, /* @__PURE__ */ React21.createElement("span", { className: `inline-block relative transition-all duration-1000 ${isAnimating ? "opacity-100 translate-y-0" : "opacity-0 translate-y-10"}` }, titlePrefix, titlePrefix && /* @__PURE__ */ React21.createElement("br", null), highlightText, /* @__PURE__ */ React21.createElement("span", { className: "absolute top-[0.65em] right-[-0.3em] text-[0.31em] text-[#ffffff]/70" }, "*")))
|
|
2006
|
+
)), /* @__PURE__ */ React21.createElement("div", { className: "col-span-12 flex flex-col gap-5 pb-6 lg:col-span-4 lg:pb-10" }, subtitle && /* @__PURE__ */ React21.createElement("p", { className: "text-xs text-[#ffffff]/70 sm:text-sm md:text-base leading-[1.2] max-w-md transition-opacity duration-1000 delay-300" }, subtitle), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col sm:flex-row items-start sm:items-center gap-4" }, ctaText && // Changed from <button> to <Link> so it actually navigates!
|
|
2007
|
+
/* @__PURE__ */ React21.createElement(
|
|
2008
|
+
Link5,
|
|
574
2009
|
{
|
|
575
2010
|
href: isWaitlist ? "#" : ctaHref || "#",
|
|
576
2011
|
onClick: handleCtaClick,
|
|
577
2012
|
className: "group inline-flex h-10 items-center gap-2 self-start rounded-full bg-[#ffffff] pl-5 pr-1 text-xs text-black transition-all hover:gap-3"
|
|
578
2013
|
},
|
|
579
2014
|
ctaText,
|
|
580
|
-
/* @__PURE__ */
|
|
581
|
-
), secondaryCtaText && secondaryCtaHref && /* @__PURE__ */
|
|
582
|
-
|
|
2015
|
+
/* @__PURE__ */ React21.createElement("span", { className: "flex h-8 w-8 items-center justify-center rounded-full bg-black transition-transform group-hover:scale-110" }, /* @__PURE__ */ React21.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "lucide lucide-arrow-right h-4 w-4 text-[#ffffff]" }, /* @__PURE__ */ React21.createElement("path", { d: "M5 12h14" }), /* @__PURE__ */ React21.createElement("path", { d: "m12 5 7 7-7 7" })))
|
|
2016
|
+
), secondaryCtaText && secondaryCtaHref && /* @__PURE__ */ React21.createElement(
|
|
2017
|
+
Link5,
|
|
583
2018
|
{
|
|
584
2019
|
href: secondaryCtaHref,
|
|
585
2020
|
className: "inline-flex h-10 items-center self-start justify-center text-xs tracking-wide rounded-full px-6 border border-[#ffffff]/30 text-[#ffffff] hover:bg-[#ffffff]/10 transition-colors"
|
|
586
2021
|
},
|
|
587
2022
|
secondaryCtaText
|
|
588
|
-
)), showApps && appLogos && appLogos.length > 0 && /* @__PURE__ */
|
|
2023
|
+
)), showApps && appLogos && appLogos.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-3 mt-4" }, appsText && /* @__PURE__ */ React21.createElement("span", { className: "text-[10px] tracking-widest uppercase text-[#ffffff]/50 " }, appsText), /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-4" }, appLogos.map((logo, idx) => /* @__PURE__ */ React21.createElement("div", { key: idx, className: "relative h-6 w-6 sm:h-7 sm:w-7 opacity-70 hover:opacity-100 transition-opacity invert" }, /* @__PURE__ */ React21.createElement(
|
|
589
2024
|
Image2,
|
|
590
2025
|
{
|
|
591
2026
|
src: logo.src,
|
|
@@ -594,7 +2029,7 @@ var HeroSection = ({
|
|
|
594
2029
|
height: 28,
|
|
595
2030
|
className: "object-contain"
|
|
596
2031
|
}
|
|
597
|
-
))))))))), /* @__PURE__ */
|
|
2032
|
+
))))))))), /* @__PURE__ */ React21.createElement(
|
|
598
2033
|
WaitlistDialog,
|
|
599
2034
|
{
|
|
600
2035
|
isOpen: isWaitlistOpen,
|
|
@@ -604,12 +2039,12 @@ var HeroSection = ({
|
|
|
604
2039
|
};
|
|
605
2040
|
|
|
606
2041
|
// src/components/AppBento2.tsx
|
|
607
|
-
import
|
|
608
|
-
import { HugeiconsIcon as
|
|
2042
|
+
import React22, { useState as useState14, useEffect as useEffect9, useRef as useRef5 } from "react";
|
|
2043
|
+
import { HugeiconsIcon as HugeiconsIcon14 } from "@hugeicons/react";
|
|
609
2044
|
var AppBento2 = ({ tagline, headline, features }) => {
|
|
610
|
-
const [isAnimating, setIsAnimating] =
|
|
611
|
-
const titleRef =
|
|
612
|
-
|
|
2045
|
+
const [isAnimating, setIsAnimating] = useState14(false);
|
|
2046
|
+
const titleRef = useRef5(null);
|
|
2047
|
+
useEffect9(() => {
|
|
613
2048
|
const observer = new IntersectionObserver(
|
|
614
2049
|
([entry]) => {
|
|
615
2050
|
if (entry.isIntersecting) {
|
|
@@ -627,7 +2062,7 @@ var AppBento2 = ({ tagline, headline, features }) => {
|
|
|
627
2062
|
}
|
|
628
2063
|
return () => observer.disconnect();
|
|
629
2064
|
}, []);
|
|
630
|
-
return /* @__PURE__ */
|
|
2065
|
+
return /* @__PURE__ */ React22.createElement("div", { className: "w-full py-16" }, /* @__PURE__ */ React22.createElement("div", { className: "w-full flex justify-center px-4" }, /* @__PURE__ */ React22.createElement("div", { className: "max-w-6xl w-full" }, /* @__PURE__ */ React22.createElement("div", { className: "relative overflow-hidden mb-12 text-left" }, /* @__PURE__ */ React22.createElement("div", { className: "relative z-10" }, /* @__PURE__ */ React22.createElement("span", { className: "text-[11px] tracking-[0.4em] text-neutral-500 block mb-4 " }, tagline), /* @__PURE__ */ React22.createElement(
|
|
631
2066
|
"h2",
|
|
632
2067
|
{
|
|
633
2068
|
ref: titleRef,
|
|
@@ -635,7 +2070,7 @@ var AppBento2 = ({ tagline, headline, features }) => {
|
|
|
635
2070
|
style: isAnimating ? { animationIterationCount: 1 } : {}
|
|
636
2071
|
},
|
|
637
2072
|
headline
|
|
638
|
-
))), /* @__PURE__ */
|
|
2073
|
+
))), /* @__PURE__ */ React22.createElement("div", { className: "grid grid-cols-1 lg:grid-cols-6 gap-6" }, features.map((f, i) => {
|
|
639
2074
|
const isWhite = i === 0;
|
|
640
2075
|
const isBlack = i === 1;
|
|
641
2076
|
const isNeutral = i === 2;
|
|
@@ -657,36 +2092,36 @@ var AppBento2 = ({ tagline, headline, features }) => {
|
|
|
657
2092
|
const textColor = isBlack ? "text-white" : "text-black";
|
|
658
2093
|
const subTextColor = isBlack ? "text-neutral-300" : "text-neutral-600";
|
|
659
2094
|
const labelColor = isBlack ? "text-neutral-400" : "text-neutral-500";
|
|
660
|
-
return /* @__PURE__ */
|
|
2095
|
+
return /* @__PURE__ */ React22.createElement(
|
|
661
2096
|
"div",
|
|
662
2097
|
{
|
|
663
2098
|
key: i,
|
|
664
2099
|
className: `relative rounded-2xl overflow-hidden p-8 flex flex-col min-h-75 transition-all duration-500 group text-left ${getBgStyle()} ${f.size}`,
|
|
665
2100
|
style: { boxShadow: getShadowStyle() }
|
|
666
2101
|
},
|
|
667
|
-
/* @__PURE__ */
|
|
2102
|
+
/* @__PURE__ */ React22.createElement(
|
|
668
2103
|
"div",
|
|
669
2104
|
{
|
|
670
2105
|
className: "absolute inset-0 pointer-events-none opacity-[0.03] z-0",
|
|
671
2106
|
style: { backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E")` }
|
|
672
2107
|
}
|
|
673
2108
|
),
|
|
674
|
-
isBlack && /* @__PURE__ */
|
|
675
|
-
/* @__PURE__ */
|
|
676
|
-
/* @__PURE__ */
|
|
2109
|
+
isBlack && /* @__PURE__ */ React22.createElement("span", { className: "absolute inset-0 rounded-2xl bg-linear-to-b from-white/10 via-white/5 to-transparent pointer-events-none z-10" }),
|
|
2110
|
+
/* @__PURE__ */ React22.createElement("div", { className: "absolute inset-0 overflow-hidden pointer-events-none z-0" }, /* @__PURE__ */ React22.createElement("div", { className: `absolute -bottom-8 -right-8 transform group-hover:scale-110 transition-transform duration-700 ease-out ${isBlack ? "text-white/5" : "text-black/5"}` }, /* @__PURE__ */ React22.createElement(HugeiconsIcon14, { icon: f.icon, size: 180 }))),
|
|
2111
|
+
/* @__PURE__ */ React22.createElement("div", { className: "relative z-10 w-full h-full flex flex-col pointer-events-auto" }, /* @__PURE__ */ React22.createElement("div", { className: "flex items-center justify-between mb-8" }, /* @__PURE__ */ React22.createElement("span", { className: `text-[9px] tracking-widest ${labelColor}` }, f.label), /* @__PURE__ */ React22.createElement("div", { className: `p-2 rounded-full transition-colors ${isBlack ? "bg-white/10" : "bg-white/50 backdrop-blur-sm"}` }, /* @__PURE__ */ React22.createElement(HugeiconsIcon14, { icon: f.icon, size: 20, className: textColor }))), /* @__PURE__ */ React22.createElement("div", { className: "mt-auto" }, /* @__PURE__ */ React22.createElement("h3", { className: `text-xl mb-2 tracking-tight ${textColor}` }, f.title), /* @__PURE__ */ React22.createElement("p", { className: `text-[13px] leading-relaxed max-w-sm ${subTextColor}` }, f.desc)))
|
|
677
2112
|
);
|
|
678
2113
|
})))));
|
|
679
2114
|
};
|
|
680
2115
|
|
|
681
2116
|
// src/components/FeatureScroll.tsx
|
|
682
|
-
import
|
|
2117
|
+
import React23, { useRef as useRef6, useState as useState15, useEffect as useEffect10 } from "react";
|
|
683
2118
|
import Image3 from "next/image";
|
|
684
|
-
import { HugeiconsIcon as
|
|
685
|
-
import { ArrowLeft01Icon, ArrowRight01Icon, Loading03Icon as
|
|
2119
|
+
import { HugeiconsIcon as HugeiconsIcon15 } from "@hugeicons/react";
|
|
2120
|
+
import { ArrowLeft01Icon as ArrowLeft01Icon2, ArrowRight01Icon as ArrowRight01Icon4, Loading03Icon as Loading03Icon6 } from "@hugeicons/core-free-icons";
|
|
686
2121
|
var FeatureCard = ({ feature, bgImage }) => {
|
|
687
|
-
const [isBgLoading, setIsBgLoading] =
|
|
688
|
-
const [isFgLoading, setIsFgLoading] =
|
|
689
|
-
return /* @__PURE__ */
|
|
2122
|
+
const [isBgLoading, setIsBgLoading] = useState15(true);
|
|
2123
|
+
const [isFgLoading, setIsFgLoading] = useState15(!!feature.image);
|
|
2124
|
+
return /* @__PURE__ */ React23.createElement("div", { className: "flex flex-col shrink-0 w-[90vw] sm:w-150 snap-center md:snap-start group cursor-grab active:cursor-grabbing" }, /* @__PURE__ */ React23.createElement("div", { className: "relative w-full aspect-16/10 bg-neutral-100 rounded-2xl overflow-hidden mb-6 flex items-center justify-center" }, /* @__PURE__ */ React23.createElement(
|
|
690
2125
|
Image3,
|
|
691
2126
|
{
|
|
692
2127
|
src: bgImage,
|
|
@@ -699,7 +2134,7 @@ var FeatureCard = ({ feature, bgImage }) => {
|
|
|
699
2134
|
${isBgLoading ? "blur-xl scale-110" : "blur-0 scale-100"}
|
|
700
2135
|
`
|
|
701
2136
|
}
|
|
702
|
-
), /* @__PURE__ */
|
|
2137
|
+
), /* @__PURE__ */ React23.createElement(
|
|
703
2138
|
"div",
|
|
704
2139
|
{
|
|
705
2140
|
className: "absolute inset-0 w-full h-full pointer-events-none z-0 opacity-[0.25] mix-blend-overlay",
|
|
@@ -707,7 +2142,7 @@ var FeatureCard = ({ feature, bgImage }) => {
|
|
|
707
2142
|
backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E")`
|
|
708
2143
|
}
|
|
709
2144
|
}
|
|
710
|
-
), isFgLoading && feature.image && /* @__PURE__ */
|
|
2145
|
+
), isFgLoading && feature.image && /* @__PURE__ */ React23.createElement("div", { className: "absolute inset-0 flex items-center justify-center z-20 bg-neutral-50/50 backdrop-blur-sm transition-opacity duration-300" }, /* @__PURE__ */ React23.createElement(HugeiconsIcon15, { icon: Loading03Icon6, size: 32, className: "animate-spin text-neutral-400" })), feature.image && /* @__PURE__ */ React23.createElement("div", { className: "absolute -bottom-6 -right-6 w-[85%] h-[85%] z-10 transition-transform duration-700 ease-out group-hover:-translate-x-2 group-hover:-translate-y-2" }, /* @__PURE__ */ React23.createElement(
|
|
711
2146
|
Image3,
|
|
712
2147
|
{
|
|
713
2148
|
src: feature.image,
|
|
@@ -720,12 +2155,12 @@ var FeatureCard = ({ feature, bgImage }) => {
|
|
|
720
2155
|
${isFgLoading ? "opacity-0 blur-xl" : "opacity-100 blur-0"}
|
|
721
2156
|
`
|
|
722
2157
|
}
|
|
723
|
-
))), /* @__PURE__ */
|
|
2158
|
+
))), /* @__PURE__ */ React23.createElement("div", { className: "flex flex-col text-left pr-4" }, /* @__PURE__ */ React23.createElement("h3", { className: " text-xl tracking-tight text-black mb-2" }, feature.title), /* @__PURE__ */ React23.createElement("p", { className: "text-[13px] leading-relaxed text-neutral-600 max-w-[90%]" }, feature.desc)));
|
|
724
2159
|
};
|
|
725
2160
|
var FeatureScroll = ({ tagline, headline, features }) => {
|
|
726
|
-
const scrollRef =
|
|
727
|
-
const [canScrollLeft, setCanScrollLeft] =
|
|
728
|
-
const [canScrollRight, setCanScrollRight] =
|
|
2161
|
+
const scrollRef = useRef6(null);
|
|
2162
|
+
const [canScrollLeft, setCanScrollLeft] = useState15(false);
|
|
2163
|
+
const [canScrollRight, setCanScrollRight] = useState15(true);
|
|
729
2164
|
const checkScroll = () => {
|
|
730
2165
|
if (scrollRef.current) {
|
|
731
2166
|
const { scrollLeft, scrollWidth, clientWidth } = scrollRef.current;
|
|
@@ -733,7 +2168,7 @@ var FeatureScroll = ({ tagline, headline, features }) => {
|
|
|
733
2168
|
setCanScrollRight(scrollLeft < scrollWidth - clientWidth - 2);
|
|
734
2169
|
}
|
|
735
2170
|
};
|
|
736
|
-
|
|
2171
|
+
useEffect10(() => {
|
|
737
2172
|
checkScroll();
|
|
738
2173
|
window.addEventListener("resize", checkScroll);
|
|
739
2174
|
return () => window.removeEventListener("resize", checkScroll);
|
|
@@ -749,7 +2184,7 @@ var FeatureScroll = ({ tagline, headline, features }) => {
|
|
|
749
2184
|
"https://retinalabs.company/assets/images/bg_6.avif",
|
|
750
2185
|
"https://retinalabs.company/assets/images/bg_1.avif"
|
|
751
2186
|
];
|
|
752
|
-
return /* @__PURE__ */
|
|
2187
|
+
return /* @__PURE__ */ React23.createElement("section", { className: "py-24 w-full flex justify-center relative z-10 overflow-hidden" }, /* @__PURE__ */ React23.createElement("div", { className: "max-w-6xl w-full flex flex-col px-4 md:px-8" }, /* @__PURE__ */ React23.createElement("div", { className: "flex flex-col md:flex-row md:items-end justify-between gap-6 mb-12" }, /* @__PURE__ */ React23.createElement("div", { className: "relative z-10 text-left" }, /* @__PURE__ */ React23.createElement("span", { className: "text-[11px] tracking-[0.4em] text-neutral-500 block mb-4" }, tagline), /* @__PURE__ */ React23.createElement("h2", { className: " text-3xl tracking-tight text-black leading-[1.05]" }, headline)), /* @__PURE__ */ React23.createElement("div", { className: "hidden md:flex items-center gap-3" }, /* @__PURE__ */ React23.createElement(
|
|
753
2188
|
"button",
|
|
754
2189
|
{
|
|
755
2190
|
onClick: () => scroll("left"),
|
|
@@ -757,8 +2192,8 @@ var FeatureScroll = ({ tagline, headline, features }) => {
|
|
|
757
2192
|
className: "p-4 border border-neutral-200 rounded-full text-neutral-500 hover:text-black hover:border-black disabled:opacity-30 disabled:hover:border-neutral-200 disabled:hover:text-neutral-500 disabled:cursor-not-allowed transition-all outline-none",
|
|
758
2193
|
"aria-label": "Previous feature"
|
|
759
2194
|
},
|
|
760
|
-
/* @__PURE__ */
|
|
761
|
-
), /* @__PURE__ */
|
|
2195
|
+
/* @__PURE__ */ React23.createElement(HugeiconsIcon15, { icon: ArrowLeft01Icon2, size: 20 })
|
|
2196
|
+
), /* @__PURE__ */ React23.createElement(
|
|
762
2197
|
"button",
|
|
763
2198
|
{
|
|
764
2199
|
onClick: () => scroll("right"),
|
|
@@ -766,57 +2201,57 @@ var FeatureScroll = ({ tagline, headline, features }) => {
|
|
|
766
2201
|
className: "p-4 border border-neutral-200 rounded-full text-neutral-500 hover:text-black hover:border-black disabled:opacity-30 disabled:hover:border-neutral-200 disabled:hover:text-neutral-500 disabled:cursor-not-allowed transition-all outline-none",
|
|
767
2202
|
"aria-label": "Next feature"
|
|
768
2203
|
},
|
|
769
|
-
/* @__PURE__ */
|
|
770
|
-
))), /* @__PURE__ */
|
|
2204
|
+
/* @__PURE__ */ React23.createElement(HugeiconsIcon15, { icon: ArrowRight01Icon4, size: 20 })
|
|
2205
|
+
))), /* @__PURE__ */ React23.createElement(
|
|
771
2206
|
"div",
|
|
772
2207
|
{
|
|
773
2208
|
ref: scrollRef,
|
|
774
2209
|
onScroll: checkScroll,
|
|
775
2210
|
className: "flex gap-6 overflow-x-auto snap-x snap-mandatory [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] scrollbar-none pb-8 -mx-4 px-4 md:mx-0 md:px-0"
|
|
776
2211
|
},
|
|
777
|
-
features.slice(0, 3).map((feature, idx) => /* @__PURE__ */
|
|
778
|
-
), /* @__PURE__ */
|
|
2212
|
+
features.slice(0, 3).map((feature, idx) => /* @__PURE__ */ React23.createElement(FeatureCard, { key: idx, feature, bgImage: bgImages[idx] }))
|
|
2213
|
+
), /* @__PURE__ */ React23.createElement("div", { className: "flex md:hidden items-center justify-center gap-4 mt-2" }, /* @__PURE__ */ React23.createElement(
|
|
779
2214
|
"button",
|
|
780
2215
|
{
|
|
781
2216
|
onClick: () => scroll("left"),
|
|
782
2217
|
disabled: !canScrollLeft,
|
|
783
2218
|
className: "p-4 border border-neutral-200 rounded-full text-neutral-500 hover:text-black hover:border-black disabled:opacity-30 transition-all outline-none"
|
|
784
2219
|
},
|
|
785
|
-
/* @__PURE__ */
|
|
786
|
-
), /* @__PURE__ */
|
|
2220
|
+
/* @__PURE__ */ React23.createElement(HugeiconsIcon15, { icon: ArrowLeft01Icon2, size: 20 })
|
|
2221
|
+
), /* @__PURE__ */ React23.createElement(
|
|
787
2222
|
"button",
|
|
788
2223
|
{
|
|
789
2224
|
onClick: () => scroll("right"),
|
|
790
2225
|
disabled: !canScrollRight,
|
|
791
2226
|
className: "p-4 border border-neutral-200 rounded-full text-neutral-500 hover:text-black hover:border-black disabled:opacity-30 transition-all outline-none"
|
|
792
2227
|
},
|
|
793
|
-
/* @__PURE__ */
|
|
2228
|
+
/* @__PURE__ */ React23.createElement(HugeiconsIcon15, { icon: ArrowRight01Icon4, size: 20 })
|
|
794
2229
|
))));
|
|
795
2230
|
};
|
|
796
2231
|
|
|
797
2232
|
// src/components/PlatformFeatures.tsx
|
|
798
|
-
import
|
|
799
|
-
import { HugeiconsIcon as
|
|
2233
|
+
import React24 from "react";
|
|
2234
|
+
import { HugeiconsIcon as HugeiconsIcon16 } from "@hugeicons/react";
|
|
800
2235
|
var PlatformFeatures = ({
|
|
801
2236
|
tagline,
|
|
802
2237
|
headline,
|
|
803
2238
|
description,
|
|
804
2239
|
features
|
|
805
2240
|
}) => {
|
|
806
|
-
return /* @__PURE__ */
|
|
2241
|
+
return /* @__PURE__ */ React24.createElement("section", { className: "w-full flex justify-center mb-15 relative z-10" }, /* @__PURE__ */ React24.createElement("div", { className: "max-w-6xl w-full flex flex-col px-4 md:px-8" }, /* @__PURE__ */ React24.createElement("div", { className: "flex flex-col items-start mb-16 relative z-10" }, /* @__PURE__ */ React24.createElement("span", { className: "text-[11px] tracking-[0.4em] text-neutral-500 block mb-4" }, tagline), /* @__PURE__ */ React24.createElement("h2", { className: "text-3xl tracking-tight text-black leading-[1.05] mb-6" }, headline), /* @__PURE__ */ React24.createElement("p", { className: "text-[15px] leading-[1.8] text-neutral-600 max-w-2xl" }, description)), /* @__PURE__ */ React24.createElement("div", { className: "w-full h-px bg-neutral-100 mb-16", "aria-hidden": "true" }), /* @__PURE__ */ React24.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-12" }, features.map((feature, idx) => /* @__PURE__ */ React24.createElement(
|
|
807
2242
|
"div",
|
|
808
2243
|
{
|
|
809
2244
|
key: idx,
|
|
810
2245
|
className: "flex flex-col group animate-in fade-in slide-in-from-bottom-4 duration-700 fill-mode-both",
|
|
811
2246
|
style: { animationDelay: feature.delay || "0ms" }
|
|
812
2247
|
},
|
|
813
|
-
/* @__PURE__ */
|
|
814
|
-
/* @__PURE__ */
|
|
2248
|
+
/* @__PURE__ */ React24.createElement("div", { className: "flex flex-row items-center gap-4 mb-4" }, /* @__PURE__ */ React24.createElement("div", { className: "w-14 h-14 shrink-0 rounded-xl border border-neutral-200 flex items-center justify-center text-neutral-600 transition-colors duration-300" }, /* @__PURE__ */ React24.createElement(HugeiconsIcon16, { icon: feature.icon, size: 24 })), /* @__PURE__ */ React24.createElement("div", { className: "flex flex-col justify-center" }, /* @__PURE__ */ React24.createElement("span", { className: "text-[11px] tracking-widest text-neutral-400 mb-0.5" }, feature.label || "CAPABILITY"), /* @__PURE__ */ React24.createElement("h3", { className: "text-xl tracking-tight text-black" }, feature.title))),
|
|
2249
|
+
/* @__PURE__ */ React24.createElement("div", null, /* @__PURE__ */ React24.createElement("p", { className: "text-[13px] leading-relaxed text-neutral-600 pr-4" }, feature.desc))
|
|
815
2250
|
)))));
|
|
816
2251
|
};
|
|
817
2252
|
|
|
818
2253
|
// src/components/ManagedDocument.tsx
|
|
819
|
-
import
|
|
2254
|
+
import React25, { useState as useState16, useEffect as useEffect11, useRef as useRef7 } from "react";
|
|
820
2255
|
var ManagedDocument = ({
|
|
821
2256
|
tagline,
|
|
822
2257
|
title,
|
|
@@ -824,9 +2259,9 @@ var ManagedDocument = ({
|
|
|
824
2259
|
contactText,
|
|
825
2260
|
contactEmail
|
|
826
2261
|
}) => {
|
|
827
|
-
const [isAnimating, setIsAnimating] =
|
|
828
|
-
const titleRef =
|
|
829
|
-
|
|
2262
|
+
const [isAnimating, setIsAnimating] = useState16(false);
|
|
2263
|
+
const titleRef = useRef7(null);
|
|
2264
|
+
useEffect11(() => {
|
|
830
2265
|
const observer = new IntersectionObserver(
|
|
831
2266
|
([entry]) => {
|
|
832
2267
|
if (entry.isIntersecting) {
|
|
@@ -846,7 +2281,7 @@ var ManagedDocument = ({
|
|
|
846
2281
|
}, []);
|
|
847
2282
|
return (
|
|
848
2283
|
// Outer layout wrapper (takes up available space, adds padding)
|
|
849
|
-
/* @__PURE__ */
|
|
2284
|
+
/* @__PURE__ */ React25.createElement("div", { className: "grow pt-4 px-3 md:px-8 w-full flex justify-center z-10 relative" }, /* @__PURE__ */ React25.createElement("div", { className: "relative bg-white rounded-2xl w-full max-w-7xl mx-auto overflow-hidden" }, /* @__PURE__ */ React25.createElement("div", { className: "relative z-10" }, /* @__PURE__ */ React25.createElement("div", { className: "relative px-5 md:px-12 py-8 md:py-10" }, tagline && /* @__PURE__ */ React25.createElement("span", { className: "text-[11px] tracking-[0.4em] text-neutral-500 text-left block " }, tagline), /* @__PURE__ */ React25.createElement(
|
|
850
2285
|
"h1",
|
|
851
2286
|
{
|
|
852
2287
|
ref: titleRef,
|
|
@@ -854,7 +2289,7 @@ var ManagedDocument = ({
|
|
|
854
2289
|
style: isAnimating ? { animationIterationCount: 1 } : {}
|
|
855
2290
|
},
|
|
856
2291
|
title
|
|
857
|
-
)), sections.map((section, index) => /* @__PURE__ */
|
|
2292
|
+
)), sections.map((section, index) => /* @__PURE__ */ React25.createElement("div", { key: index, className: "relative px-5 md:px-12 py-8 md:py-10" }, section.heading && /* @__PURE__ */ React25.createElement("p", { className: " text-[11px] tracking-[0.2em] text-black mb-4 text-left " }, section.heading), section.paragraphs && section.paragraphs.length > 0 && /* @__PURE__ */ React25.createElement("div", { className: "text-[14px] leading-[1.8] text-neutral-700 space-y-4 text-left " }, section.paragraphs.map((text, pIndex) => /* @__PURE__ */ React25.createElement("p", { key: pIndex }, text))), section.quote && /* @__PURE__ */ React25.createElement("div", { className: `border-neutral-100 border rounded-xl p-6 ${section.paragraphs && section.paragraphs.length > 0 ? "mt-6" : ""}` }, /* @__PURE__ */ React25.createElement("p", { className: "text-neutral-900 text-[14px] md:text-[14px] leading-relaxed" }, '"', section.quote, '"')))), (contactText || contactEmail) && /* @__PURE__ */ React25.createElement("div", { className: "relative px-5 md:px-12 py-8 md:py-10 pb-12 md:pb-14" }, /* @__PURE__ */ React25.createElement("p", { className: "text-[11px] text-neutral-600 text-left" }, contactText, contactEmail && /* @__PURE__ */ React25.createElement(
|
|
858
2293
|
"a",
|
|
859
2294
|
{
|
|
860
2295
|
href: `mailto:${contactEmail}`,
|
|
@@ -866,18 +2301,18 @@ var ManagedDocument = ({
|
|
|
866
2301
|
};
|
|
867
2302
|
|
|
868
2303
|
// src/components/ManagedContactBlock.tsx
|
|
869
|
-
import
|
|
870
|
-
import { HugeiconsIcon as
|
|
2304
|
+
import React26, { useState as useState17, useEffect as useEffect12 } from "react";
|
|
2305
|
+
import { HugeiconsIcon as HugeiconsIcon17 } from "@hugeicons/react";
|
|
871
2306
|
var SecureEmail = ({ user, domain, className }) => {
|
|
872
|
-
const [isMounted, setIsMounted] =
|
|
873
|
-
|
|
2307
|
+
const [isMounted, setIsMounted] = useState17(false);
|
|
2308
|
+
useEffect12(() => {
|
|
874
2309
|
setIsMounted(true);
|
|
875
2310
|
}, []);
|
|
876
2311
|
if (!isMounted) {
|
|
877
|
-
return /* @__PURE__ */
|
|
2312
|
+
return /* @__PURE__ */ React26.createElement("span", { className, style: { opacity: 0 } }, "Loading");
|
|
878
2313
|
}
|
|
879
2314
|
const email = `${user}@${domain}`;
|
|
880
|
-
return /* @__PURE__ */
|
|
2315
|
+
return /* @__PURE__ */ React26.createElement("a", { href: `mailto:${email}`, className }, email);
|
|
881
2316
|
};
|
|
882
2317
|
var ManagedContactBlock = ({
|
|
883
2318
|
tagline,
|
|
@@ -886,7 +2321,7 @@ var ManagedContactBlock = ({
|
|
|
886
2321
|
emails,
|
|
887
2322
|
socials
|
|
888
2323
|
}) => {
|
|
889
|
-
return /* @__PURE__ */
|
|
2324
|
+
return /* @__PURE__ */ React26.createElement("div", { className: "grow pt-4 pb-20 px-4 md:px-8 w-full flex justify-center z-10 relative" }, /* @__PURE__ */ React26.createElement("div", { className: "relative bg-white rounded-2xl w-full max-w-7xl mx-auto overflow-hidden" }, /* @__PURE__ */ React26.createElement(
|
|
890
2325
|
"div",
|
|
891
2326
|
{
|
|
892
2327
|
className: "absolute inset-0 pointer-events-none opacity-[0.03] z-0",
|
|
@@ -895,21 +2330,21 @@ var ManagedContactBlock = ({
|
|
|
895
2330
|
backgroundRepeat: "repeat"
|
|
896
2331
|
}
|
|
897
2332
|
}
|
|
898
|
-
), /* @__PURE__ */
|
|
2333
|
+
), /* @__PURE__ */ React26.createElement("div", { className: "relative z-10" }, /* @__PURE__ */ React26.createElement("div", { className: "relative px-8 md:px-12 py-10" }, tagline && /* @__PURE__ */ React26.createElement("span", { className: "text-[11px] tracking-[0.4em] text-neutral-500 text-left block " }, tagline), /* @__PURE__ */ React26.createElement("h1", { className: " text-3xl mt-4 text-black tracking-tight text-left" }, title)), /* @__PURE__ */ React26.createElement("div", { className: "relative px-8 md:px-12 py-8 pb-14" }, /* @__PURE__ */ React26.createElement("div", { className: "flex flex-wrap gap-12 lg:gap-16 w-full" }, company && /* @__PURE__ */ React26.createElement("div", { className: "flex-1 min-w-65 space-y-6" }, /* @__PURE__ */ React26.createElement("p", { className: "text-[11px] tracking-[0.2em] text-black mb-4 " }, "Contact Details"), /* @__PURE__ */ React26.createElement("div", { className: "space-y-3 text-[13px] text-neutral-600 leading-[1.8]" }, company.name && /* @__PURE__ */ React26.createElement("p", { className: "text-black" }, company.name), company.lines && company.lines.map((line, idx) => /* @__PURE__ */ React26.createElement("p", { key: idx }, line)), company.phone && /* @__PURE__ */ React26.createElement("p", { className: "pt-2" }, /* @__PURE__ */ React26.createElement(
|
|
899
2334
|
"a",
|
|
900
2335
|
{
|
|
901
2336
|
href: `tel:${company.phone.replace(/\s+/g, "")}`,
|
|
902
2337
|
className: "transition-colors hover:text-black"
|
|
903
2338
|
},
|
|
904
2339
|
company.phone
|
|
905
|
-
)))), emails && emails.length > 0 && /* @__PURE__ */
|
|
2340
|
+
)))), emails && emails.length > 0 && /* @__PURE__ */ React26.createElement("div", { className: "flex-1 min-w-65 space-y-6" }, /* @__PURE__ */ React26.createElement("p", { className: "text-[11px] tracking-[0.2em] text-black mb-4 " }, "Email Directory"), /* @__PURE__ */ React26.createElement("div", { className: "space-y-6 text-[13px]" }, emails.map((email, idx) => /* @__PURE__ */ React26.createElement("div", { key: idx }, /* @__PURE__ */ React26.createElement("p", { className: "text-[11px] tracking-[0.2em] mb-1.5 text-neutral-500 " }, email.label), /* @__PURE__ */ React26.createElement(
|
|
906
2341
|
SecureEmail,
|
|
907
2342
|
{
|
|
908
2343
|
user: email.user,
|
|
909
2344
|
domain: email.domain,
|
|
910
2345
|
className: "text-neutral-600 transition-colors hover:text-black"
|
|
911
2346
|
}
|
|
912
|
-
))))), socials && socials.length > 0 && /* @__PURE__ */
|
|
2347
|
+
))))), socials && socials.length > 0 && /* @__PURE__ */ React26.createElement("div", { className: "flex-1 min-w-65 space-y-6" }, /* @__PURE__ */ React26.createElement("p", { className: "text-[11px] tracking-[0.2em] text-black mb-4 " }, "Find Us Online"), /* @__PURE__ */ React26.createElement("div", { className: "flex flex-col space-y-5 pt-1" }, socials.map((social, idx) => /* @__PURE__ */ React26.createElement(
|
|
913
2348
|
"a",
|
|
914
2349
|
{
|
|
915
2350
|
key: idx,
|
|
@@ -919,27 +2354,27 @@ var ManagedContactBlock = ({
|
|
|
919
2354
|
className: "flex items-center gap-3 transition-colors group text-neutral-600 hover:text-black",
|
|
920
2355
|
"aria-label": social.label
|
|
921
2356
|
},
|
|
922
|
-
/* @__PURE__ */
|
|
923
|
-
/* @__PURE__ */
|
|
2357
|
+
/* @__PURE__ */ React26.createElement(HugeiconsIcon17, { icon: social.icon, size: 18 }),
|
|
2358
|
+
/* @__PURE__ */ React26.createElement("span", { className: "text-[13px]" }, social.label)
|
|
924
2359
|
)))))))));
|
|
925
2360
|
};
|
|
926
2361
|
|
|
927
2362
|
// src/components/ManagedPricingBlock.tsx
|
|
928
|
-
import
|
|
929
|
-
import
|
|
2363
|
+
import React27, { useState as useState18, useEffect as useEffect13, useRef as useRef8 } from "react";
|
|
2364
|
+
import Link6 from "next/link";
|
|
930
2365
|
import Image4 from "next/image";
|
|
931
|
-
var CheckIcon = ({ className = "" }) => /* @__PURE__ */
|
|
932
|
-
var CrossIcon = ({ className = "" }) => /* @__PURE__ */
|
|
2366
|
+
var CheckIcon = ({ className = "" }) => /* @__PURE__ */ React27.createElement("svg", { viewBox: "0 0 24 24", fill: "none", className: `w-4 h-4 shrink-0 ${className}`, xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React27.createElement("circle", { cx: "12", cy: "12", r: "10", fill: "black" }), /* @__PURE__ */ React27.createElement("path", { d: "M8 12L11 15L16 9", stroke: "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }));
|
|
2367
|
+
var CrossIcon = ({ className = "" }) => /* @__PURE__ */ React27.createElement("svg", { viewBox: "0 0 24 24", fill: "none", className: `w-4 h-4 shrink-0 ${className}`, xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React27.createElement("circle", { cx: "12", cy: "12", r: "10", fill: "#F5F5F5" }), /* @__PURE__ */ React27.createElement("path", { d: "M15 9L9 15M9 9l6 6", stroke: "#D4D4D4", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }));
|
|
933
2368
|
var ManagedPricingBlock = ({
|
|
934
2369
|
tagline,
|
|
935
2370
|
title,
|
|
936
2371
|
plans = [],
|
|
937
2372
|
tabs
|
|
938
2373
|
}) => {
|
|
939
|
-
const [isAnimating, setIsAnimating] =
|
|
940
|
-
const [activeTabIndex, setActiveTabIndex] =
|
|
941
|
-
const titleRef =
|
|
942
|
-
|
|
2374
|
+
const [isAnimating, setIsAnimating] = useState18(false);
|
|
2375
|
+
const [activeTabIndex, setActiveTabIndex] = useState18(0);
|
|
2376
|
+
const titleRef = useRef8(null);
|
|
2377
|
+
useEffect13(() => {
|
|
943
2378
|
const observer = new IntersectionObserver(
|
|
944
2379
|
([entry]) => {
|
|
945
2380
|
if (entry.isIntersecting) {
|
|
@@ -959,7 +2394,7 @@ var ManagedPricingBlock = ({
|
|
|
959
2394
|
}, []);
|
|
960
2395
|
const hasTabs = tabs && tabs.length > 0;
|
|
961
2396
|
const currentPlans = hasTabs ? tabs[activeTabIndex].plans : plans;
|
|
962
|
-
return /* @__PURE__ */
|
|
2397
|
+
return /* @__PURE__ */ React27.createElement("div", { className: "grow pt-10 pb-20 px-4 md:px-8 w-full flex justify-center z-10 relative" }, /* @__PURE__ */ React27.createElement("div", { className: "w-full max-w-5xl mx-auto flex flex-col items-center" }, /* @__PURE__ */ React27.createElement("div", { className: "w-full flex flex-col items-center text-center mb-10 sm:mb-12" }, tagline && /* @__PURE__ */ React27.createElement("span", { className: "text-[9px] tracking-[0.4em] text-black block " }, tagline), /* @__PURE__ */ React27.createElement(
|
|
963
2398
|
"h1",
|
|
964
2399
|
{
|
|
965
2400
|
ref: titleRef,
|
|
@@ -967,9 +2402,9 @@ var ManagedPricingBlock = ({
|
|
|
967
2402
|
style: isAnimating ? { animationIterationCount: 1 } : {}
|
|
968
2403
|
},
|
|
969
2404
|
title
|
|
970
|
-
)), hasTabs && /* @__PURE__ */
|
|
2405
|
+
)), hasTabs && /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-center mb-8 sm:mb-10 w-full animate-in fade-in duration-300 px-2" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center bg-white rounded-full p-1 sm:p-1.5 max-w-full overflow-x-auto custom-scrollbar" }, tabs.map((tab, idx) => {
|
|
971
2406
|
const isActive = activeTabIndex === idx;
|
|
972
|
-
return /* @__PURE__ */
|
|
2407
|
+
return /* @__PURE__ */ React27.createElement(
|
|
973
2408
|
"button",
|
|
974
2409
|
{
|
|
975
2410
|
key: idx,
|
|
@@ -978,19 +2413,19 @@ var ManagedPricingBlock = ({
|
|
|
978
2413
|
},
|
|
979
2414
|
tab.label
|
|
980
2415
|
);
|
|
981
|
-
}))), /* @__PURE__ */
|
|
2416
|
+
}))), /* @__PURE__ */ React27.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-5 w-full max-w-3xl animate-in slide-in-from-bottom-2 fade-in duration-500" }, currentPlans.map((plan, planIdx) => /* @__PURE__ */ React27.createElement(
|
|
982
2417
|
"div",
|
|
983
2418
|
{
|
|
984
2419
|
key: `${activeTabIndex}-${planIdx}`,
|
|
985
2420
|
className: `bg-white rounded-3xl p-6 flex flex-col relative overflow-hidden transition-all duration-300 ${plan.isPremium ? "" : ""}`
|
|
986
2421
|
},
|
|
987
|
-
/* @__PURE__ */
|
|
2422
|
+
/* @__PURE__ */ React27.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React27.createElement("span", { className: "text-black text-base block mb-1" }, plan.name), /* @__PURE__ */ React27.createElement("div", { className: "flex items-baseline gap-1" }, /* @__PURE__ */ React27.createElement("h3", { className: "text-3xl font-light text-black" }, plan.price), plan.period && /* @__PURE__ */ React27.createElement("span", { className: "text-xs text-neutral-500" }, plan.period)), /* @__PURE__ */ React27.createElement("p", { className: "text-xs text-neutral-500 mt-2 min-h-8" }, plan.description), plan.showApps && plan.appLogos && plan.appLogos.length > 0 && /* @__PURE__ */ React27.createElement("div", { className: "flex items-center gap-2 mt-4" }, plan.appLogos.map((logo, logoIdx) => /* @__PURE__ */ React27.createElement(
|
|
988
2423
|
"div",
|
|
989
2424
|
{
|
|
990
2425
|
key: logoIdx,
|
|
991
2426
|
className: "relative w-5 h-5 overflow-hidden flex items-center justify-center shrink-0"
|
|
992
2427
|
},
|
|
993
|
-
/* @__PURE__ */
|
|
2428
|
+
/* @__PURE__ */ React27.createElement(
|
|
994
2429
|
Image4,
|
|
995
2430
|
{
|
|
996
2431
|
src: logo.src,
|
|
@@ -1001,28 +2436,28 @@ var ManagedPricingBlock = ({
|
|
|
1001
2436
|
}
|
|
1002
2437
|
)
|
|
1003
2438
|
)))),
|
|
1004
|
-
plan.isPremium ? /* @__PURE__ */
|
|
1005
|
-
|
|
2439
|
+
plan.isPremium ? /* @__PURE__ */ React27.createElement(ThreeDButton, { href: plan.ctaHref, className: "mb-6 w-full" }, plan.ctaText) : /* @__PURE__ */ React27.createElement(
|
|
2440
|
+
Link6,
|
|
1006
2441
|
{
|
|
1007
2442
|
href: plan.ctaHref,
|
|
1008
2443
|
className: "w-full py-2.5 px-5 rounded-full border border-neutral-100 text-center text-black text-xs hover:bg-neutral-50 transition-colors mb-6 outline-none block"
|
|
1009
2444
|
},
|
|
1010
2445
|
plan.ctaText
|
|
1011
2446
|
),
|
|
1012
|
-
/* @__PURE__ */
|
|
2447
|
+
/* @__PURE__ */ React27.createElement("div", { className: "flex flex-col gap-3" }, plan.features.map((feature, featureIdx) => {
|
|
1013
2448
|
const isAvailable = feature.value !== false;
|
|
1014
2449
|
const valueText = typeof feature.value === "string" ? feature.value : "";
|
|
1015
|
-
return /* @__PURE__ */
|
|
2450
|
+
return /* @__PURE__ */ React27.createElement("div", { key: featureIdx, className: "flex items-center gap-2.5" }, isAvailable ? /* @__PURE__ */ React27.createElement(CheckIcon, null) : /* @__PURE__ */ React27.createElement(CrossIcon, null), /* @__PURE__ */ React27.createElement("span", { className: `text-xs truncate ${isAvailable ? "text-neutral-800" : "text-neutral-400"}` }, feature.name, valueText && /* @__PURE__ */ React27.createElement("span", { className: "text-neutral-500 ml-1" }, "(", valueText, ")")));
|
|
1016
2451
|
}))
|
|
1017
2452
|
)))));
|
|
1018
2453
|
};
|
|
1019
2454
|
|
|
1020
2455
|
// src/components/ManagedBoardBlock.tsx
|
|
1021
|
-
import
|
|
2456
|
+
import React28 from "react";
|
|
1022
2457
|
import Image5 from "next/image";
|
|
1023
|
-
import { HugeiconsIcon as
|
|
2458
|
+
import { HugeiconsIcon as HugeiconsIcon18 } from "@hugeicons/react";
|
|
1024
2459
|
import { TwitterIcon, LinkedinIcon } from "@hugeicons/core-free-icons";
|
|
1025
|
-
var MemberSocialLink = ({ href, icon, label, name }) => /* @__PURE__ */
|
|
2460
|
+
var MemberSocialLink = ({ href, icon, label, name }) => /* @__PURE__ */ React28.createElement(
|
|
1026
2461
|
"a",
|
|
1027
2462
|
{
|
|
1028
2463
|
href,
|
|
@@ -1031,7 +2466,7 @@ var MemberSocialLink = ({ href, icon, label, name }) => /* @__PURE__ */ React15.
|
|
|
1031
2466
|
className: "text-neutral-400 hover:text-black transition-colors",
|
|
1032
2467
|
"aria-label": `${name} on ${label}`
|
|
1033
2468
|
},
|
|
1034
|
-
/* @__PURE__ */
|
|
2469
|
+
/* @__PURE__ */ React28.createElement(HugeiconsIcon18, { icon, size: 16 })
|
|
1035
2470
|
);
|
|
1036
2471
|
var ManagedBoardBlock = ({
|
|
1037
2472
|
tagline,
|
|
@@ -1040,7 +2475,7 @@ var ManagedBoardBlock = ({
|
|
|
1040
2475
|
contactText,
|
|
1041
2476
|
contactEmail
|
|
1042
2477
|
}) => {
|
|
1043
|
-
return /* @__PURE__ */
|
|
2478
|
+
return /* @__PURE__ */ React28.createElement("div", { className: "grow pt-4 pb-20 px-3 md:px-8 w-full flex justify-center z-10 relative" }, /* @__PURE__ */ React28.createElement("div", { className: "relative w-full mx-auto overflow-hidden max-w-7xl" }, /* @__PURE__ */ React28.createElement(
|
|
1044
2479
|
"div",
|
|
1045
2480
|
{
|
|
1046
2481
|
className: "absolute inset-0 pointer-events-none opacity-[0.03] z-0",
|
|
@@ -1049,7 +2484,7 @@ var ManagedBoardBlock = ({
|
|
|
1049
2484
|
backgroundRepeat: "repeat"
|
|
1050
2485
|
}
|
|
1051
2486
|
}
|
|
1052
|
-
), /* @__PURE__ */
|
|
2487
|
+
), /* @__PURE__ */ React28.createElement("div", { className: "relative z-10" }, /* @__PURE__ */ React28.createElement("div", { className: "relative px-5 md:px-12 py-8 md:py-10" }, tagline && /* @__PURE__ */ React28.createElement("span", { className: "text-[11px] tracking-[0.4em] text-neutral-500 text-left block " }, tagline), /* @__PURE__ */ React28.createElement("h1", { className: " text-3xl mt-4 text-black tracking-tight text-left" }, title)), /* @__PURE__ */ React28.createElement("div", { className: "relative px-5 md:px-12 py-4 md:py-8" }, /* @__PURE__ */ React28.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 md:gap-8" }, members.map((member, idx) => /* @__PURE__ */ React28.createElement("div", { key: idx, className: "relative p-6 md:p-8 rounded-2xl bg-white flex flex-col transition-all group" }, /* @__PURE__ */ React28.createElement("div", { className: "flex items-start space-x-4 md:space-x-5 mb-5 md:mb-6" }, /* @__PURE__ */ React28.createElement("div", { className: "relative w-14 h-14 md:w-16 md:h-16 shrink-0 bg-white overflow-hidden rounded-xl" }, /* @__PURE__ */ React28.createElement(
|
|
1053
2488
|
Image5,
|
|
1054
2489
|
{
|
|
1055
2490
|
src: member.imageSrc,
|
|
@@ -1058,7 +2493,7 @@ var ManagedBoardBlock = ({
|
|
|
1058
2493
|
sizes: "(max-width: 768px) 56px, 64px",
|
|
1059
2494
|
className: "object-cover grayscale opacity-100 transition-opacity"
|
|
1060
2495
|
}
|
|
1061
|
-
)), /* @__PURE__ */
|
|
2496
|
+
)), /* @__PURE__ */ React28.createElement("div", { className: "pt-1" }, /* @__PURE__ */ React28.createElement("h3", { className: " text-[14px] md:text-[15px] text-black tracking-tight" }, member.name), /* @__PURE__ */ React28.createElement("p", { className: "text-[11px] tracking-[0.2em] text-neutral-500 mt-1.5 " }, member.title))), /* @__PURE__ */ React28.createElement("p", { className: "text-[13px] leading-[1.8] text-neutral-600 text-left grow mb-8" }, member.bio), /* @__PURE__ */ React28.createElement("div", { className: "space-y-6 mt-auto" }, /* @__PURE__ */ React28.createElement("div", { className: "w-full *:w-full" }, /* @__PURE__ */ React28.createElement(ThreeDButton, { href: member.website }, "Visit Website")), /* @__PURE__ */ React28.createElement("div", { className: "flex space-x-4 pt-5" }, member.twitterHandle && member.twitterHandle.length > 0 && /* @__PURE__ */ React28.createElement(
|
|
1062
2497
|
MemberSocialLink,
|
|
1063
2498
|
{
|
|
1064
2499
|
href: `https://x.com/${member.twitterHandle}`,
|
|
@@ -1066,7 +2501,7 @@ var ManagedBoardBlock = ({
|
|
|
1066
2501
|
label: "X",
|
|
1067
2502
|
name: member.name
|
|
1068
2503
|
}
|
|
1069
|
-
), member.linkedinHandle && member.linkedinHandle.length > 0 && /* @__PURE__ */
|
|
2504
|
+
), member.linkedinHandle && member.linkedinHandle.length > 0 && /* @__PURE__ */ React28.createElement(
|
|
1070
2505
|
MemberSocialLink,
|
|
1071
2506
|
{
|
|
1072
2507
|
href: member.linkedinHandle,
|
|
@@ -1074,85 +2509,28 @@ var ManagedBoardBlock = ({
|
|
|
1074
2509
|
label: "LinkedIn",
|
|
1075
2510
|
name: member.name
|
|
1076
2511
|
}
|
|
1077
|
-
))))))), (contactText || contactEmail) && /* @__PURE__ */
|
|
2512
|
+
))))))), (contactText || contactEmail) && /* @__PURE__ */ React28.createElement("div", { className: "relative px-5 md:px-12 py-8 md:py-10 pb-12 md:pb-14" }, /* @__PURE__ */ React28.createElement("p", { className: "text-[11px] text-neutral-600 text-left" }, contactText, contactEmail && /* @__PURE__ */ React28.createElement("a", { href: `mailto:${contactEmail}`, className: "text-black decoration-black decoration-2 underline-offset-4 ml-1 transition-colors" }, contactEmail))))));
|
|
1078
2513
|
};
|
|
1079
2514
|
|
|
1080
2515
|
// src/components/ManagedNotFoundBlock.tsx
|
|
1081
|
-
import
|
|
2516
|
+
import React29 from "react";
|
|
1082
2517
|
var ManagedNotFoundBlock = ({
|
|
1083
2518
|
title = "404 - Page Not Found",
|
|
1084
2519
|
description = "The page you are looking for does not exist or has been moved."
|
|
1085
2520
|
}) => {
|
|
1086
|
-
return /* @__PURE__ */
|
|
2521
|
+
return /* @__PURE__ */ React29.createElement("main", { className: "min-h-screen flex items-center justify-center relative z-20 bg-transparent" }, /* @__PURE__ */ React29.createElement("div", { className: "p-6 w-full max-w-md mx-auto text-center" }, /* @__PURE__ */ React29.createElement("div", { className: "mb-8 flex justify-center" }, /* @__PURE__ */ React29.createElement(
|
|
1087
2522
|
"svg",
|
|
1088
2523
|
{
|
|
1089
2524
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1090
2525
|
viewBox: "0 0 24 24",
|
|
1091
2526
|
className: "w-12 h-12 fill-neutral-100"
|
|
1092
2527
|
},
|
|
1093
|
-
/* @__PURE__ */
|
|
1094
|
-
)), /* @__PURE__ */
|
|
1095
|
-
};
|
|
1096
|
-
|
|
1097
|
-
// src/components/PageSpinner.tsx
|
|
1098
|
-
import React17 from "react";
|
|
1099
|
-
import { HugeiconsIcon as HugeiconsIcon8 } from "@hugeicons/react";
|
|
1100
|
-
import { Loading03Icon as Loading03Icon3 } from "@hugeicons/core-free-icons";
|
|
1101
|
-
var PageSpinner = ({
|
|
1102
|
-
className = "",
|
|
1103
|
-
iconClassName = "text-black",
|
|
1104
|
-
size = 32
|
|
1105
|
-
}) => {
|
|
1106
|
-
return (
|
|
1107
|
-
// z-[100] ensures it sits above absolute headers and modals
|
|
1108
|
-
/* @__PURE__ */ React17.createElement("div", { className: `fixed inset-0 z-100 flex flex-col items-center justify-center w-full h-full pointer-events-none ${className}` }, /* @__PURE__ */ React17.createElement(
|
|
1109
|
-
HugeiconsIcon8,
|
|
1110
|
-
{
|
|
1111
|
-
icon: Loading03Icon3,
|
|
1112
|
-
size,
|
|
1113
|
-
className: `animate-spin mb-4 ${iconClassName}`
|
|
1114
|
-
}
|
|
1115
|
-
))
|
|
1116
|
-
);
|
|
1117
|
-
};
|
|
1118
|
-
|
|
1119
|
-
// src/components/ManagedToaster.tsx
|
|
1120
|
-
import React18 from "react";
|
|
1121
|
-
import { Toaster } from "react-hot-toast";
|
|
1122
|
-
var ManagedToaster = () => {
|
|
1123
|
-
return /* @__PURE__ */ React18.createElement(
|
|
1124
|
-
Toaster,
|
|
1125
|
-
{
|
|
1126
|
-
position: "top-right",
|
|
1127
|
-
toastOptions: {
|
|
1128
|
-
style: {
|
|
1129
|
-
background: "#171717",
|
|
1130
|
-
color: "#fafafa",
|
|
1131
|
-
fontSize: "11px",
|
|
1132
|
-
padding: "8px 12px",
|
|
1133
|
-
borderRadius: "8px",
|
|
1134
|
-
minWidth: "fit-content",
|
|
1135
|
-
boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.5)"
|
|
1136
|
-
},
|
|
1137
|
-
success: {
|
|
1138
|
-
iconTheme: {
|
|
1139
|
-
primary: "#fafafa",
|
|
1140
|
-
secondary: "#171717"
|
|
1141
|
-
}
|
|
1142
|
-
},
|
|
1143
|
-
error: {
|
|
1144
|
-
iconTheme: {
|
|
1145
|
-
primary: "#fafafa",
|
|
1146
|
-
secondary: "#171717"
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
);
|
|
2528
|
+
/* @__PURE__ */ React29.createElement("path", { fillRule: "evenodd", d: "M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z", clipRule: "evenodd" })
|
|
2529
|
+
)), /* @__PURE__ */ React29.createElement("h1", { className: " text-xl md:text-3xl text-black tracking-tight mb-4" }, title), /* @__PURE__ */ React29.createElement("p", { className: "text-[13px] leading-[1.8] text-neutral-600 mb-12" }, description)));
|
|
1152
2530
|
};
|
|
1153
2531
|
|
|
1154
2532
|
// src/components/ManagedNewsletterSplitBlock.tsx
|
|
1155
|
-
import
|
|
2533
|
+
import React30 from "react";
|
|
1156
2534
|
import Image6 from "next/image";
|
|
1157
2535
|
var ManagedNewsletterSplitBlock = ({
|
|
1158
2536
|
tagline,
|
|
@@ -1166,7 +2544,7 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1166
2544
|
ctaHref = "/contact",
|
|
1167
2545
|
children
|
|
1168
2546
|
}) => {
|
|
1169
|
-
return /* @__PURE__ */
|
|
2547
|
+
return /* @__PURE__ */ React30.createElement("div", { className: "grow flex flex-col md:flex-row relative w-full pt-32 md:pt-0" }, /* @__PURE__ */ React30.createElement("div", { className: "hidden md:block md:w-1/2 relative min-h-screen overflow-hidden" }, /* @__PURE__ */ React30.createElement(
|
|
1170
2548
|
Image6,
|
|
1171
2549
|
{
|
|
1172
2550
|
src: imageSrc,
|
|
@@ -1176,7 +2554,7 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1176
2554
|
className: "object-cover object-top grayscale opacity-60",
|
|
1177
2555
|
quality: 100
|
|
1178
2556
|
}
|
|
1179
|
-
), /* @__PURE__ */
|
|
2557
|
+
), /* @__PURE__ */ React30.createElement(
|
|
1180
2558
|
"div",
|
|
1181
2559
|
{
|
|
1182
2560
|
className: "absolute inset-0 z-10 pointer-events-none",
|
|
@@ -1184,7 +2562,7 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1184
2562
|
background: "linear-gradient(to right, rgba(255,255,255,0) 30%, #ffffff 100%)"
|
|
1185
2563
|
}
|
|
1186
2564
|
}
|
|
1187
|
-
), /* @__PURE__ */
|
|
2565
|
+
), /* @__PURE__ */ React30.createElement(
|
|
1188
2566
|
"div",
|
|
1189
2567
|
{
|
|
1190
2568
|
className: "absolute inset-x-0 bottom-0 h-40 z-10 pointer-events-none",
|
|
@@ -1192,7 +2570,7 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1192
2570
|
background: "linear-gradient(to bottom, rgba(255,255,255,0) 0%, #ffffff 100%)"
|
|
1193
2571
|
}
|
|
1194
2572
|
}
|
|
1195
|
-
)), /* @__PURE__ */
|
|
2573
|
+
)), /* @__PURE__ */ React30.createElement("div", { className: "w-full md:w-1/2 flex mt-22 flex-col items-center justify-center p-4 md:p-12 relative z-20" }, /* @__PURE__ */ React30.createElement("div", { className: "relative w-full max-w-lg p-8 md:p-12 text-center md:text-left transition-all duration-700 ease-out" }, /* @__PURE__ */ React30.createElement(
|
|
1196
2574
|
"div",
|
|
1197
2575
|
{
|
|
1198
2576
|
className: "absolute inset-0 pointer-events-none opacity-[0.03] z-0",
|
|
@@ -1201,7 +2579,7 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1201
2579
|
backgroundRepeat: "repeat"
|
|
1202
2580
|
}
|
|
1203
2581
|
}
|
|
1204
|
-
), /* @__PURE__ */
|
|
2582
|
+
), /* @__PURE__ */ React30.createElement("div", { className: "relative z-10" }, /* @__PURE__ */ React30.createElement("div", { className: "mb-10 border-b border-neutral-100 pb-8 text-center md:text-left" }, tagline && /* @__PURE__ */ React30.createElement("span", { className: "text-[11px] tracking-[0.4em] text-neutral-500 " }, tagline), /* @__PURE__ */ React30.createElement("h1", { className: " text-3xl mt-4 text-black tracking-tight mb-4" }, title), subtitle && /* @__PURE__ */ React30.createElement("p", { className: "text-[11px] tracking-[0.2em] text-neutral-500 " }, subtitle)), /* @__PURE__ */ React30.createElement("p", { className: "text-[13px] leading-[1.8] text-neutral-600 mb-10 text-center md:text-left" }, description), children && /* @__PURE__ */ React30.createElement("div", { className: "mb-8 text-left" }, children), /* @__PURE__ */ React30.createElement("div", { className: "text-center md:text-left mt-10 space-y-6" }, dividerText && /* @__PURE__ */ React30.createElement("div", { className: "flex items-center" }, /* @__PURE__ */ React30.createElement("div", { className: "grow h-px bg-neutral-100" }), /* @__PURE__ */ React30.createElement("span", { className: "shrink mx-4 text-[11px] tracking-[0.2em] text-neutral-400 " }, dividerText), /* @__PURE__ */ React30.createElement("div", { className: "grow h-px bg-neutral-100" })), ctaText && ctaHref && /* @__PURE__ */ React30.createElement("div", { className: "w-full *:w-full" }, /* @__PURE__ */ React30.createElement(
|
|
1205
2583
|
ThreeDButton,
|
|
1206
2584
|
{
|
|
1207
2585
|
href: ctaHref,
|
|
@@ -1212,14 +2590,14 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1212
2590
|
};
|
|
1213
2591
|
|
|
1214
2592
|
// src/components/PortfolioHero.tsx
|
|
1215
|
-
import
|
|
1216
|
-
import
|
|
2593
|
+
import React31, { useEffect as useEffect14, useRef as useRef9 } from "react";
|
|
2594
|
+
import Link7 from "next/link";
|
|
1217
2595
|
import Image7 from "next/image";
|
|
1218
|
-
import { HugeiconsIcon as
|
|
1219
|
-
import { ArrowRight01Icon as
|
|
2596
|
+
import { HugeiconsIcon as HugeiconsIcon19 } from "@hugeicons/react";
|
|
2597
|
+
import { ArrowRight01Icon as ArrowRight01Icon5 } from "@hugeicons/core-free-icons";
|
|
1220
2598
|
var useScrollAnimation = () => {
|
|
1221
|
-
const elementRef =
|
|
1222
|
-
|
|
2599
|
+
const elementRef = useRef9(null);
|
|
2600
|
+
useEffect14(() => {
|
|
1223
2601
|
const el = elementRef.current;
|
|
1224
2602
|
if (!el) return;
|
|
1225
2603
|
const observer = new IntersectionObserver(
|
|
@@ -1255,13 +2633,13 @@ var PortfolioHero = ({
|
|
|
1255
2633
|
secondaryCtaHref
|
|
1256
2634
|
}) => {
|
|
1257
2635
|
const heroContentRef = useScrollAnimation();
|
|
1258
|
-
return /* @__PURE__ */
|
|
2636
|
+
return /* @__PURE__ */ React31.createElement("section", { className: "pt-44 md:pt-52 pb-16 px-6 md:px-12 flex flex-col relative overflow-hidden z-10 w-full" }, /* @__PURE__ */ React31.createElement(
|
|
1259
2637
|
"div",
|
|
1260
2638
|
{
|
|
1261
2639
|
ref: heroContentRef,
|
|
1262
2640
|
className: "w-full opacity-0 translate-y-5 transition-all duration-1000 ease-out relative z-10"
|
|
1263
2641
|
},
|
|
1264
|
-
/* @__PURE__ */
|
|
2642
|
+
/* @__PURE__ */ React31.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center gap-5 sm:gap-8 mb-10" }, /* @__PURE__ */ React31.createElement("div", { className: "relative w-20 h-20 sm:w-32 sm:h-32 rounded-full overflow-hidden border border-neutral-100 shrink-0 shadow-sm" }, /* @__PURE__ */ React31.createElement(
|
|
1265
2643
|
Image7,
|
|
1266
2644
|
{
|
|
1267
2645
|
src: imageSrc,
|
|
@@ -1272,7 +2650,7 @@ var PortfolioHero = ({
|
|
|
1272
2650
|
sizes: "(max-width: 640px) 80px, 128px",
|
|
1273
2651
|
quality: 100
|
|
1274
2652
|
}
|
|
1275
|
-
)), /* @__PURE__ */
|
|
2653
|
+
)), /* @__PURE__ */ React31.createElement("div", { className: "flex flex-col text-left" }, /* @__PURE__ */ React31.createElement("h1", { className: " text-3xl sm:text-5xl lg:text-6xl tracking-tight text-black leading-none mb-3" }, name), socialLabel && /* @__PURE__ */ React31.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-500 " }, socialLabel), socialLinkText && socialLinkHref && /* @__PURE__ */ React31.createElement(
|
|
1276
2654
|
"a",
|
|
1277
2655
|
{
|
|
1278
2656
|
href: socialLinkHref,
|
|
@@ -1282,31 +2660,31 @@ var PortfolioHero = ({
|
|
|
1282
2660
|
},
|
|
1283
2661
|
socialLinkText
|
|
1284
2662
|
))),
|
|
1285
|
-
/* @__PURE__ */
|
|
1286
|
-
/* @__PURE__ */
|
|
2663
|
+
/* @__PURE__ */ React31.createElement("p", { className: "text-[13px] leading-[1.8] max-w-4xl mb-12 text-neutral-600" }, bio),
|
|
2664
|
+
/* @__PURE__ */ React31.createElement("div", { className: "flex flex-col sm:flex-row gap-4 w-full sm:w-auto" }, primaryCtaText && primaryCtaHref && /* @__PURE__ */ React31.createElement("div", { className: "w-full sm:w-auto *:w-full" }, /* @__PURE__ */ React31.createElement(
|
|
1287
2665
|
ThreeDButton,
|
|
1288
2666
|
{
|
|
1289
2667
|
href: primaryCtaHref,
|
|
1290
2668
|
className: "py-3 tracking-widest text-[11px]"
|
|
1291
2669
|
},
|
|
1292
2670
|
primaryCtaText
|
|
1293
|
-
)), secondaryCtaText && secondaryCtaHref && /* @__PURE__ */
|
|
1294
|
-
|
|
2671
|
+
)), secondaryCtaText && secondaryCtaHref && /* @__PURE__ */ React31.createElement(
|
|
2672
|
+
Link7,
|
|
1295
2673
|
{
|
|
1296
2674
|
href: secondaryCtaHref,
|
|
1297
2675
|
className: "w-full sm:w-auto inline-flex items-center justify-center gap-3 text-[11px] tracking-[0.2em] rounded-full px-8 py-3.5 bg-neutral-200 transition-colors text-black hover:bg-neutral-200 outline-none"
|
|
1298
2676
|
},
|
|
1299
2677
|
secondaryCtaText,
|
|
1300
|
-
/* @__PURE__ */
|
|
2678
|
+
/* @__PURE__ */ React31.createElement(HugeiconsIcon19, { icon: ArrowRight01Icon5, size: 16 })
|
|
1301
2679
|
))
|
|
1302
2680
|
));
|
|
1303
2681
|
};
|
|
1304
2682
|
|
|
1305
2683
|
// src/components/GifFeatureCard.tsx
|
|
1306
|
-
import
|
|
2684
|
+
import React32, { useState as useState19 } from "react";
|
|
1307
2685
|
import Image8 from "next/image";
|
|
1308
|
-
import { HugeiconsIcon as
|
|
1309
|
-
import { Loading03Icon as
|
|
2686
|
+
import { HugeiconsIcon as HugeiconsIcon20 } from "@hugeicons/react";
|
|
2687
|
+
import { Loading03Icon as Loading03Icon7 } from "@hugeicons/core-free-icons";
|
|
1310
2688
|
var GifFeatureCard = ({
|
|
1311
2689
|
gifSrc,
|
|
1312
2690
|
title,
|
|
@@ -1314,20 +2692,20 @@ var GifFeatureCard = ({
|
|
|
1314
2692
|
alt = "Feature animation",
|
|
1315
2693
|
className = "aspect-video"
|
|
1316
2694
|
}) => {
|
|
1317
|
-
const [isLoading, setIsLoading] =
|
|
1318
|
-
return /* @__PURE__ */
|
|
1319
|
-
|
|
2695
|
+
const [isLoading, setIsLoading] = useState19(true);
|
|
2696
|
+
return /* @__PURE__ */ React32.createElement("div", { className: `relative w-full bg-black overflow-hidden shadow-2xl ${className}` }, isLoading && /* @__PURE__ */ React32.createElement("div", { className: "absolute inset-0 flex items-center justify-center z-20 bg-black" }, /* @__PURE__ */ React32.createElement(
|
|
2697
|
+
HugeiconsIcon20,
|
|
1320
2698
|
{
|
|
1321
|
-
icon:
|
|
2699
|
+
icon: Loading03Icon7,
|
|
1322
2700
|
size: 32,
|
|
1323
2701
|
className: "animate-spin text-white"
|
|
1324
2702
|
}
|
|
1325
|
-
)), /* @__PURE__ */
|
|
2703
|
+
)), /* @__PURE__ */ React32.createElement(
|
|
1326
2704
|
"div",
|
|
1327
2705
|
{
|
|
1328
2706
|
className: `absolute inset-0 z-0 transition-all duration-1000 ease-out ${isLoading ? "scale-105 blur-2xl opacity-0" : "scale-100 blur-0 opacity-100"}`
|
|
1329
2707
|
},
|
|
1330
|
-
/* @__PURE__ */
|
|
2708
|
+
/* @__PURE__ */ React32.createElement(
|
|
1331
2709
|
Image8,
|
|
1332
2710
|
{
|
|
1333
2711
|
src: gifSrc,
|
|
@@ -1338,16 +2716,16 @@ var GifFeatureCard = ({
|
|
|
1338
2716
|
className: "object-cover object-center pointer-events-none"
|
|
1339
2717
|
}
|
|
1340
2718
|
)
|
|
1341
|
-
), /* @__PURE__ */
|
|
2719
|
+
), /* @__PURE__ */ React32.createElement(
|
|
1342
2720
|
"div",
|
|
1343
2721
|
{
|
|
1344
2722
|
className: "absolute inset-x-0 bottom-0 h-1/2 sm:h-2/3 bg-linear-to-t from-black/95 via-black/40 to-transparent z-10 pointer-events-none transition-opacity duration-700"
|
|
1345
2723
|
}
|
|
1346
|
-
), /* @__PURE__ */
|
|
2724
|
+
), /* @__PURE__ */ React32.createElement("div", { className: "absolute inset-x-0 bottom-0 p-6 sm:p-8 z-30 flex flex-col justify-end text-left pointer-events-none" }, title && /* @__PURE__ */ React32.createElement("h3", { className: " text-xl sm:text-2xl md:text-3xl text-white tracking-tight mb-2 sm:mb-3 drop-shadow-md" }, title), subtitle && /* @__PURE__ */ React32.createElement("p", { className: "text-[13px] sm:text-[15px] leading-relaxed text-neutral-300 max-w-2xl drop-shadow-sm" }, subtitle)));
|
|
1347
2725
|
};
|
|
1348
2726
|
|
|
1349
2727
|
// src/components/MedicalFeatureStatsBlock.tsx
|
|
1350
|
-
import
|
|
2728
|
+
import React33, { useState as useState20, useEffect as useEffect15, useRef as useRef10 } from "react";
|
|
1351
2729
|
import Image9 from "next/image";
|
|
1352
2730
|
var MedicalFeatureStatsBlock = ({
|
|
1353
2731
|
bottomHeadline,
|
|
@@ -1356,9 +2734,9 @@ var MedicalFeatureStatsBlock = ({
|
|
|
1356
2734
|
trustText,
|
|
1357
2735
|
stats
|
|
1358
2736
|
}) => {
|
|
1359
|
-
const [isAnimating, setIsAnimating] =
|
|
1360
|
-
const titleRef =
|
|
1361
|
-
|
|
2737
|
+
const [isAnimating, setIsAnimating] = useState20(false);
|
|
2738
|
+
const titleRef = useRef10(null);
|
|
2739
|
+
useEffect15(() => {
|
|
1362
2740
|
const observer = new IntersectionObserver(
|
|
1363
2741
|
([entry]) => {
|
|
1364
2742
|
if (entry.isIntersecting) {
|
|
@@ -1376,7 +2754,7 @@ var MedicalFeatureStatsBlock = ({
|
|
|
1376
2754
|
}
|
|
1377
2755
|
return () => observer.disconnect();
|
|
1378
2756
|
}, []);
|
|
1379
|
-
return /* @__PURE__ */
|
|
2757
|
+
return /* @__PURE__ */ React33.createElement("section", { className: "py-24 w-full flex justify-center relative z-10" }, /* @__PURE__ */ React33.createElement("div", { className: "max-w-6xl w-full flex flex-col px-4 md:px-8" }, /* @__PURE__ */ React33.createElement("div", { className: "flex flex-col lg:flex-row justify-between items-start lg:items-end gap-10 mb-12" }, /* @__PURE__ */ React33.createElement("div", { className: "max-w-xl" }, /* @__PURE__ */ React33.createElement(
|
|
1380
2758
|
"h2",
|
|
1381
2759
|
{
|
|
1382
2760
|
ref: titleRef,
|
|
@@ -1384,7 +2762,7 @@ var MedicalFeatureStatsBlock = ({
|
|
|
1384
2762
|
style: isAnimating ? { animationIterationCount: 1 } : {}
|
|
1385
2763
|
},
|
|
1386
2764
|
bottomHeadline
|
|
1387
|
-
), /* @__PURE__ */
|
|
2765
|
+
), /* @__PURE__ */ React33.createElement("p", { className: "text-[14px] leading-relaxed text-neutral-500" }, bottomDescription)), /* @__PURE__ */ React33.createElement("div", { className: "flex items-center gap-4 shrink-0" }, /* @__PURE__ */ React33.createElement("div", { className: "flex -space-x-3" }, avatars.map((src, i) => /* @__PURE__ */ React33.createElement("div", { key: i, className: "relative w-12 h-12 rounded-full border-[3px] border-white overflow-hidden bg-neutral-100 z-1 hover:z-10 transition-all" }, /* @__PURE__ */ React33.createElement(
|
|
1388
2766
|
Image9,
|
|
1389
2767
|
{
|
|
1390
2768
|
src,
|
|
@@ -1393,17 +2771,17 @@ var MedicalFeatureStatsBlock = ({
|
|
|
1393
2771
|
sizes: "48px",
|
|
1394
2772
|
className: "object-cover"
|
|
1395
2773
|
}
|
|
1396
|
-
)))), /* @__PURE__ */
|
|
2774
|
+
)))), /* @__PURE__ */ React33.createElement("p", { className: "text-[11px] text-neutral-800 leading-[1.4] max-w-55" }, trustText))), /* @__PURE__ */ React33.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6" }, stats.map((stat, idx) => /* @__PURE__ */ React33.createElement("div", { key: idx, className: "bg-white rounded-4xl p-8 md:p-10 flex flex-col h-70" }, /* @__PURE__ */ React33.createElement("div", { className: "flex items-center p-0.5 mb-6" }, /* @__PURE__ */ React33.createElement("span", { className: "text-[14px] text-neutral-500 tracking-wide" }, stat.label)), /* @__PURE__ */ React33.createElement("h1", { className: "text-6xl gradient-text md:text-[80px] tracking-tighter text-black mt-auto leading-none" }, stat.value))))));
|
|
1397
2775
|
};
|
|
1398
2776
|
|
|
1399
2777
|
// src/components/ConsultantShowcase.tsx
|
|
1400
|
-
import
|
|
2778
|
+
import React34, { useState as useState21 } from "react";
|
|
1401
2779
|
import Image10 from "next/image";
|
|
1402
|
-
import { HugeiconsIcon as
|
|
1403
|
-
import { Loading03Icon as
|
|
2780
|
+
import { HugeiconsIcon as HugeiconsIcon21 } from "@hugeicons/react";
|
|
2781
|
+
import { Loading03Icon as Loading03Icon8 } from "@hugeicons/core-free-icons";
|
|
1404
2782
|
var ImageWithLoader = ({ src, alt, className, sizes, priority = false }) => {
|
|
1405
|
-
const [isLoading, setIsLoading] =
|
|
1406
|
-
return /* @__PURE__ */
|
|
2783
|
+
const [isLoading, setIsLoading] = useState21(true);
|
|
2784
|
+
return /* @__PURE__ */ React34.createElement("div", { className: `absolute inset-0 bg-neutral-800 ${className}` }, isLoading && /* @__PURE__ */ React34.createElement("div", { className: "absolute inset-0 flex items-center justify-center z-20 bg-neutral-800/50 backdrop-blur-md transition-opacity duration-300" }, /* @__PURE__ */ React34.createElement(HugeiconsIcon21, { icon: Loading03Icon8, size: 24, className: "animate-spin text-white/50" })), /* @__PURE__ */ React34.createElement(
|
|
1407
2785
|
Image10,
|
|
1408
2786
|
{
|
|
1409
2787
|
src,
|
|
@@ -1422,9 +2800,9 @@ var ImageWithLoader = ({ src, alt, className, sizes, priority = false }) => {
|
|
|
1422
2800
|
var ConsultantShowcase = ({
|
|
1423
2801
|
profiles
|
|
1424
2802
|
}) => {
|
|
1425
|
-
const [currentIndex, setCurrentIndex] =
|
|
1426
|
-
const [touchStart, setTouchStart] =
|
|
1427
|
-
const [touchEnd, setTouchEnd] =
|
|
2803
|
+
const [currentIndex, setCurrentIndex] = useState21(0);
|
|
2804
|
+
const [touchStart, setTouchStart] = useState21(null);
|
|
2805
|
+
const [touchEnd, setTouchEnd] = useState21(null);
|
|
1428
2806
|
const nextSlide = () => {
|
|
1429
2807
|
setCurrentIndex((prev) => prev === profiles.length - 1 ? 0 : prev + 1);
|
|
1430
2808
|
};
|
|
@@ -1449,7 +2827,7 @@ var ConsultantShowcase = ({
|
|
|
1449
2827
|
}
|
|
1450
2828
|
};
|
|
1451
2829
|
if (!profiles || profiles.length === 0) return null;
|
|
1452
|
-
return /* @__PURE__ */
|
|
2830
|
+
return /* @__PURE__ */ React34.createElement("section", { className: "py-24 w-full flex justify-center px-4 md:px-8 z-10 relative" }, /* @__PURE__ */ React34.createElement("div", { className: "max-w-6xl w-full" }, /* @__PURE__ */ React34.createElement(
|
|
1453
2831
|
"div",
|
|
1454
2832
|
{
|
|
1455
2833
|
className: "relative w-full h-100 md:h-112.5 rounded-4xl overflow-hidden bg-neutral-900 group select-none",
|
|
@@ -1459,13 +2837,13 @@ var ConsultantShowcase = ({
|
|
|
1459
2837
|
},
|
|
1460
2838
|
profiles.map((profile, idx) => {
|
|
1461
2839
|
const isActive = idx === currentIndex;
|
|
1462
|
-
return /* @__PURE__ */
|
|
2840
|
+
return /* @__PURE__ */ React34.createElement(
|
|
1463
2841
|
"div",
|
|
1464
2842
|
{
|
|
1465
2843
|
key: profile.id,
|
|
1466
2844
|
className: `absolute inset-0 transition-opacity duration-700 ease-in-out ${isActive ? "opacity-100 z-10" : "opacity-0 z-0 pointer-events-none"}`
|
|
1467
2845
|
},
|
|
1468
|
-
/* @__PURE__ */
|
|
2846
|
+
/* @__PURE__ */ React34.createElement(
|
|
1469
2847
|
ImageWithLoader,
|
|
1470
2848
|
{
|
|
1471
2849
|
src: profile.imageSrc,
|
|
@@ -1473,14 +2851,14 @@ var ConsultantShowcase = ({
|
|
|
1473
2851
|
priority: idx === 0
|
|
1474
2852
|
}
|
|
1475
2853
|
),
|
|
1476
|
-
/* @__PURE__ */
|
|
1477
|
-
/* @__PURE__ */
|
|
1478
|
-
/* @__PURE__ */
|
|
2854
|
+
/* @__PURE__ */ React34.createElement("div", { className: "absolute inset-0 bg-black/20 z-10 pointer-events-none" }),
|
|
2855
|
+
/* @__PURE__ */ React34.createElement("div", { className: "absolute top-0 left-0 w-full h-[60%] bg-linear-to-b from-black/80 via-black/30 to-transparent z-20 pointer-events-none" }),
|
|
2856
|
+
/* @__PURE__ */ React34.createElement("div", { className: `absolute top-8 left-8 md:top-12 md:left-12 z-30 text-white max-w-lg transition-transform duration-700 ease-out ${isActive ? "translate-y-0" : "-translate-y-4"}` }, /* @__PURE__ */ React34.createElement("h2", { className: "text-[29px] tracking-tight mb-2 leading-none" }, profile.name), /* @__PURE__ */ React34.createElement("div", { className: "flex flex-col gap-0.5" }, /* @__PURE__ */ React34.createElement("p", { className: "text-[15px] text-white/80 tracking-wide" }, profile.role), profile.description && /* @__PURE__ */ React34.createElement("p", { className: "text-[15px] text-white/80 tracking-wide mt-1" }, profile.description)))
|
|
1479
2857
|
);
|
|
1480
2858
|
}),
|
|
1481
|
-
/* @__PURE__ */
|
|
1482
|
-
/* @__PURE__ */
|
|
1483
|
-
/* @__PURE__ */
|
|
2859
|
+
/* @__PURE__ */ React34.createElement("div", { className: "absolute top-0 left-0 w-[20%] h-full z-40 cursor-w-resize hidden md:block", onClick: prevSlide, "aria-label": "Previous image" }),
|
|
2860
|
+
/* @__PURE__ */ React34.createElement("div", { className: "absolute top-0 right-0 w-[20%] h-full z-40 cursor-e-resize hidden md:block", onClick: nextSlide, "aria-label": "Next image" }),
|
|
2861
|
+
/* @__PURE__ */ React34.createElement("div", { className: "absolute bottom-6 md:bottom-8 left-0 w-full px-4 z-30 flex justify-center items-center gap-2" }, profiles.map((_, idx) => /* @__PURE__ */ React34.createElement(
|
|
1484
2862
|
"button",
|
|
1485
2863
|
{
|
|
1486
2864
|
key: idx,
|
|
@@ -1493,13 +2871,13 @@ var ConsultantShowcase = ({
|
|
|
1493
2871
|
};
|
|
1494
2872
|
|
|
1495
2873
|
// src/components/ContentGridBlock.tsx
|
|
1496
|
-
import
|
|
2874
|
+
import React35, { useState as useState22 } from "react";
|
|
1497
2875
|
import Image11 from "next/image";
|
|
1498
|
-
import { HugeiconsIcon as
|
|
1499
|
-
import { Loading03Icon as
|
|
2876
|
+
import { HugeiconsIcon as HugeiconsIcon22 } from "@hugeicons/react";
|
|
2877
|
+
import { Loading03Icon as Loading03Icon9 } from "@hugeicons/core-free-icons";
|
|
1500
2878
|
var ImageWithLoader2 = ({ src, alt, className, sizes }) => {
|
|
1501
|
-
const [isLoading, setIsLoading] =
|
|
1502
|
-
return /* @__PURE__ */
|
|
2879
|
+
const [isLoading, setIsLoading] = useState22(true);
|
|
2880
|
+
return /* @__PURE__ */ React35.createElement("div", { className: `relative overflow-hidden bg-neutral-100 ${className}` }, isLoading && /* @__PURE__ */ React35.createElement("div", { className: "absolute inset-0 flex items-center justify-center z-20 bg-neutral-100/50 backdrop-blur-sm transition-opacity duration-300" }, /* @__PURE__ */ React35.createElement(HugeiconsIcon22, { icon: Loading03Icon9, size: 24, className: "animate-spin text-neutral-400" })), /* @__PURE__ */ React35.createElement(
|
|
1503
2881
|
Image11,
|
|
1504
2882
|
{
|
|
1505
2883
|
src,
|
|
@@ -1521,30 +2899,30 @@ var ContentGridBlock = ({
|
|
|
1521
2899
|
middleBottomCard,
|
|
1522
2900
|
rightCards
|
|
1523
2901
|
}) => {
|
|
1524
|
-
return /* @__PURE__ */
|
|
2902
|
+
return /* @__PURE__ */ React35.createElement("section", { className: " w-full flex justify-center z-10 relative" }, /* @__PURE__ */ React35.createElement("div", { className: "max-w-300 w-full px-4 md:px-8 flex flex-col gap-12" }, /* @__PURE__ */ React35.createElement("div", { className: "flex flex-col lg:flex-row justify-between items-start lg:items-end gap-6 w-full" }, /* @__PURE__ */ React35.createElement("h2", { className: "text-3xl tracking-tight text-black leading-[1.15] max-w-lg" }, header.titlePrefix, " ", /* @__PURE__ */ React35.createElement("span", { className: "gradient-text" }, header.highlightText))), /* @__PURE__ */ React35.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" }, /* @__PURE__ */ React35.createElement("div", { className: "flex flex-col justify-end" }, /* @__PURE__ */ React35.createElement("div", { className: "bg-black rounded-3xl p-8 flex flex-col h-80" }, /* @__PURE__ */ React35.createElement("p", { className: "text-[17px] text-white leading-snug mb-4" }, leftCard.mainText), leftCard.tag && /* @__PURE__ */ React35.createElement("span", { className: "mb-auto text-[11px] text-neutral-200 tracking-widest" }, leftCard.tag), /* @__PURE__ */ React35.createElement("div", { className: "flex items-center justify-between mt-8" }, /* @__PURE__ */ React35.createElement("div", null, /* @__PURE__ */ React35.createElement("h4", { className: "text-[15px] text-white" }, leftCard.title), /* @__PURE__ */ React35.createElement("p", { className: "text-[13px] text-neutral-300" }, leftCard.subtitle)), /* @__PURE__ */ React35.createElement("div", { className: "w-10 h-10 rounded-full overflow-hidden relative" }, /* @__PURE__ */ React35.createElement(Image11, { src: leftCard.thumbnailSrc, alt: leftCard.title, fill: true, className: "object-cover" }))))), /* @__PURE__ */ React35.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React35.createElement("div", { className: "bg-white rounded-3xl p-8 flex flex-col relative h-75" }, /* @__PURE__ */ React35.createElement("div", { className: "absolute top-6 right-6 flex flex-col items-end gap-1" }, /* @__PURE__ */ React35.createElement("span", { className: "text-[11px] text-neutral-400 tracking-wide" }, middleTopCard.topRightLabel), /* @__PURE__ */ React35.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React35.createElement("div", { className: "flex -space-x-2" }, middleTopCard.topRightAvatars.map((src, i) => /* @__PURE__ */ React35.createElement("div", { key: i, className: "w-7 h-7 rounded-full border-2 border-white overflow-hidden relative z-10" }, /* @__PURE__ */ React35.createElement(Image11, { src, alt: "Avatar", fill: true, className: "object-cover", sizes: "28px" })))), /* @__PURE__ */ React35.createElement("span", { className: "text-sm text-neutral-500" }, middleTopCard.topRightCount))), /* @__PURE__ */ React35.createElement("div", { className: "grow flex flex-col justify-center items-center py-6" }, /* @__PURE__ */ React35.createElement("div", { className: "px-5 py-2 rounded-full bg-neutral-50/50 border border-neutral-100 text-[13px] text-neutral-600" }, middleTopCard.badgePrefix, " ", /* @__PURE__ */ React35.createElement("span", { className: " text-black" }, middleTopCard.badgeHighlight), middleTopCard.badgeSuffix)), /* @__PURE__ */ React35.createElement("div", { className: "mt-auto" }, /* @__PURE__ */ React35.createElement("p", { className: "text-[11px] text-neutral-400 tracking-wide mb-1" }, middleTopCard.title), /* @__PURE__ */ React35.createElement("p", { className: "text-[14px] text-black leading-snug pr-4" }, middleTopCard.description))), /* @__PURE__ */ React35.createElement("div", { className: "bg-white rounded-3xl p-8 flex flex-col h-80" }, /* @__PURE__ */ React35.createElement("div", { className: "flex justify-between items-start mb-6" }, /* @__PURE__ */ React35.createElement("div", null, /* @__PURE__ */ React35.createElement("h4", { className: "text-[15px] text-black leading-tight" }, middleBottomCard.title), /* @__PURE__ */ React35.createElement("p", { className: "text-[13px] text-neutral-400" }, middleBottomCard.subtitle)), /* @__PURE__ */ React35.createElement("div", { className: "w-10 h-10 rounded-full overflow-hidden relative" }, /* @__PURE__ */ React35.createElement(Image11, { src: middleBottomCard.thumbnailSrc, alt: middleBottomCard.title, fill: true, className: "object-cover" }))), /* @__PURE__ */ React35.createElement("div", { className: "mt-auto" }, /* @__PURE__ */ React35.createElement("p", { className: "text-[16px] text-black leading-snug mb-4" }, middleBottomCard.mainText), middleBottomCard.tag && /* @__PURE__ */ React35.createElement("span", { className: "text-[11px] text-neutral-400 tracking-widest" }, middleBottomCard.tag)))), /* @__PURE__ */ React35.createElement("div", { className: "flex flex-col gap-6" }, rightCards.slice(0, 2).map((card, idx) => /* @__PURE__ */ React35.createElement("div", { key: idx, className: "relative w-full h-80 text-white rounded-3xl overflow-hidden group" }, /* @__PURE__ */ React35.createElement(
|
|
1525
2903
|
ImageWithLoader2,
|
|
1526
2904
|
{
|
|
1527
2905
|
src: card.bgImageSrc,
|
|
1528
2906
|
alt: card.title,
|
|
1529
2907
|
className: "absolute inset-0 w-full h-full"
|
|
1530
2908
|
}
|
|
1531
|
-
), /* @__PURE__ */
|
|
2909
|
+
), /* @__PURE__ */ React35.createElement("div", { className: "absolute inset-0 z-20 pointer-events-none" }), /* @__PURE__ */ React35.createElement("div", { className: "absolute inset-0 z-30 p-6 flex flex-col justify-end text-white" }, /* @__PURE__ */ React35.createElement("p", { className: "text-[14px] leading-snug mb-3 pr-2 text-white/90" }, card.mainText), card.tag && /* @__PURE__ */ React35.createElement("span", { className: "mb-4 text-[11px] text-white/50 tracking-widest" }, card.tag), /* @__PURE__ */ React35.createElement("div", { className: "pt-3" }, /* @__PURE__ */ React35.createElement("h4", { className: "text-[15px] text-white tracking-wide" }, card.title), /* @__PURE__ */ React35.createElement("p", { className: "text-[13px] text-white/60" }, card.subtitle)))))))));
|
|
1532
2910
|
};
|
|
1533
2911
|
|
|
1534
2912
|
// src/components/ManagedProjectsBlock.tsx
|
|
1535
|
-
import
|
|
1536
|
-
import
|
|
2913
|
+
import React36 from "react";
|
|
2914
|
+
import Link8 from "next/link";
|
|
1537
2915
|
var GridSection = ({
|
|
1538
2916
|
children,
|
|
1539
2917
|
isLast = false,
|
|
1540
2918
|
className = "py-8 md:py-10"
|
|
1541
|
-
}) => /* @__PURE__ */
|
|
2919
|
+
}) => /* @__PURE__ */ React36.createElement("div", { className: `relative px-5 md:px-12 ${className} ${!isLast ? "" : ""}` }, children);
|
|
1542
2920
|
var ManagedProjectsBlock = ({
|
|
1543
2921
|
tagline,
|
|
1544
2922
|
title,
|
|
1545
2923
|
projects
|
|
1546
2924
|
}) => {
|
|
1547
|
-
return /* @__PURE__ */
|
|
2925
|
+
return /* @__PURE__ */ React36.createElement("div", { className: "grow pt-4 pb-20 px-3 md:px-8 w-full flex justify-center z-10 relative" }, /* @__PURE__ */ React36.createElement("div", { className: "relative bg-white rounded-2xl w-full max-w-5xl mx-auto overflow-hidden" }, /* @__PURE__ */ React36.createElement(
|
|
1548
2926
|
"div",
|
|
1549
2927
|
{
|
|
1550
2928
|
className: "absolute inset-0 pointer-events-none opacity-[0.03] z-0",
|
|
@@ -1553,10 +2931,10 @@ var ManagedProjectsBlock = ({
|
|
|
1553
2931
|
backgroundRepeat: "repeat"
|
|
1554
2932
|
}
|
|
1555
2933
|
}
|
|
1556
|
-
), /* @__PURE__ */
|
|
2934
|
+
), /* @__PURE__ */ React36.createElement("div", { className: "relative z-10" }, /* @__PURE__ */ React36.createElement(GridSection, null, tagline && /* @__PURE__ */ React36.createElement("span", { className: "text-[11px] tracking-[0.4em] text-neutral-500 text-left block " }, tagline), /* @__PURE__ */ React36.createElement("h1", { className: " text-3xl mt-4 text-black tracking-tight text-left" }, title)), projects.map((project, index) => {
|
|
1557
2935
|
const isLast = index === projects.length - 1;
|
|
1558
|
-
const projectContent = /* @__PURE__ */
|
|
1559
|
-
return /* @__PURE__ */
|
|
2936
|
+
const projectContent = /* @__PURE__ */ React36.createElement("div", { className: "group block w-full" }, /* @__PURE__ */ React36.createElement("div", { className: "flex flex-col md:flex-row md:items-center justify-between gap-3 md:gap-4 mb-4 md:mb-5" }, /* @__PURE__ */ React36.createElement("div", { className: "flex items-center gap-3 md:gap-4" }, /* @__PURE__ */ React36.createElement("h2", { className: " text-[16px] text-black transition-all flex items-center gap-2" }, project.title, /* @__PURE__ */ React36.createElement("span", { className: "text-[11px] opacity-0 -translate-x-2 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-300" }, project.isExternal ? "\u2197" : "\u2192")), /* @__PURE__ */ React36.createElement("span", { className: `text-[9px] px-2.5 py-1 rounded-full tracking-[0.15em] transition-colors ${project.status.toLowerCase() === "production" ? "bg-black text-white" : "bg-neutral-100 text-neutral-500 group-hover:bg-neutral-100 group-hover:text-black"}` }, project.status)), /* @__PURE__ */ React36.createElement("span", { className: "text-[11px] tracking-[0.2em] text-neutral-500 shrink-0 " }, project.date)), /* @__PURE__ */ React36.createElement("p", { className: "text-[13px] leading-[1.8] text-neutral-600 max-w-4xl text-left transition-colors group-hover:text-black" }, project.description));
|
|
2937
|
+
return /* @__PURE__ */ React36.createElement(GridSection, { key: project.id || index, isLast, className: isLast ? "py-8 md:py-10 pb-12 md:pb-14" : "py-8 md:py-10" }, project.isExternal ? /* @__PURE__ */ React36.createElement("a", { href: project.link, target: "_blank", rel: "noopener noreferrer", className: "block outline-none" }, projectContent) : /* @__PURE__ */ React36.createElement(Link8, { href: project.link, className: "block outline-none" }, projectContent));
|
|
1560
2938
|
}))));
|
|
1561
2939
|
};
|
|
1562
2940
|
export {
|
|
@@ -1578,12 +2956,22 @@ export {
|
|
|
1578
2956
|
ManagedProjectsBlock,
|
|
1579
2957
|
ManagedToaster,
|
|
1580
2958
|
MedicalFeatureStatsBlock,
|
|
2959
|
+
MobileNav,
|
|
1581
2960
|
NumberInput,
|
|
1582
2961
|
PageSpinner,
|
|
2962
|
+
PipleAuth,
|
|
1583
2963
|
PlatformFeatures,
|
|
1584
2964
|
PortfolioHero,
|
|
1585
2965
|
TextInput,
|
|
1586
2966
|
ThreeDActionButton,
|
|
1587
2967
|
ThreeDButton,
|
|
2968
|
+
UniversalCardPage,
|
|
2969
|
+
UniversalErrorView,
|
|
2970
|
+
UniversalHomeView,
|
|
2971
|
+
UniversalOrganizationPage,
|
|
2972
|
+
UniversalProfilePage,
|
|
2973
|
+
UniversalProfileSettings,
|
|
2974
|
+
UniversalTransactionPage,
|
|
2975
|
+
UniversalWalletPage,
|
|
1588
2976
|
WaitlistDialog
|
|
1589
2977
|
};
|