@retinalabsllc/zairusjs 9.0.3 → 9.0.5
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 +1621 -268
- package/dist/index.mjs +1649 -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,86 @@ 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 /* @__PURE__ */ React7.createElement("div", { className: "fixed bottom-6 inset-x-0 z-100 flex justify-center pointer-events-none px-3 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 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) => {
|
|
604
|
+
const isActive = item.href === "/" ? pathname === "/" : pathname?.startsWith(item.href);
|
|
605
|
+
return /* @__PURE__ */ React7.createElement(
|
|
606
|
+
Link4,
|
|
607
|
+
{
|
|
608
|
+
key: item.label,
|
|
609
|
+
href: item.href,
|
|
610
|
+
className: "flex flex-col items-center justify-center gap-1 min-w-14 transition-transform active:scale-95 outline-none"
|
|
611
|
+
},
|
|
612
|
+
/* @__PURE__ */ React7.createElement("div", { className: `transition-colors duration-300 ${isActive ? "text-black" : "text-neutral-400 hover:text-neutral-600"}` }, /* @__PURE__ */ React7.createElement(
|
|
613
|
+
HugeiconsIcon3,
|
|
614
|
+
{
|
|
615
|
+
icon: item.icon,
|
|
616
|
+
size: 20
|
|
617
|
+
}
|
|
618
|
+
)),
|
|
619
|
+
/* @__PURE__ */ React7.createElement(
|
|
620
|
+
"span",
|
|
621
|
+
{
|
|
622
|
+
className: `text-[9px] tracking-wide transition-colors duration-300 font-medium ${isActive ? "text-black" : "text-neutral-400"}`
|
|
623
|
+
},
|
|
624
|
+
item.label
|
|
625
|
+
)
|
|
626
|
+
);
|
|
627
|
+
})));
|
|
628
|
+
};
|
|
349
629
|
|
|
350
|
-
// src/components/
|
|
351
|
-
import
|
|
352
|
-
import
|
|
630
|
+
// src/components/UniversalOrganizationPage.tsx
|
|
631
|
+
import React11, { useState as useState6, useEffect as useEffect4 } from "react";
|
|
632
|
+
import toast2 from "react-hot-toast";
|
|
633
|
+
|
|
634
|
+
// src/components/ManagedToaster.tsx
|
|
635
|
+
import React8 from "react";
|
|
636
|
+
import { Toaster } from "react-hot-toast";
|
|
637
|
+
var ManagedToaster = () => {
|
|
638
|
+
return /* @__PURE__ */ React8.createElement(
|
|
639
|
+
Toaster,
|
|
640
|
+
{
|
|
641
|
+
position: "top-right",
|
|
642
|
+
toastOptions: {
|
|
643
|
+
style: {
|
|
644
|
+
background: "#171717",
|
|
645
|
+
color: "#fafafa",
|
|
646
|
+
fontSize: "11px",
|
|
647
|
+
padding: "8px 12px",
|
|
648
|
+
borderRadius: "8px",
|
|
649
|
+
minWidth: "fit-content",
|
|
650
|
+
boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.5)"
|
|
651
|
+
},
|
|
652
|
+
success: {
|
|
653
|
+
iconTheme: {
|
|
654
|
+
primary: "#fafafa",
|
|
655
|
+
secondary: "#171717"
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
error: {
|
|
659
|
+
iconTheme: {
|
|
660
|
+
primary: "#fafafa",
|
|
661
|
+
secondary: "#171717"
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
);
|
|
667
|
+
};
|
|
353
668
|
|
|
354
669
|
// src/components/ReusableInputs.tsx
|
|
355
|
-
import
|
|
670
|
+
import React9 from "react";
|
|
356
671
|
var TextInput = ({
|
|
357
672
|
label,
|
|
358
673
|
value,
|
|
@@ -363,7 +678,7 @@ var TextInput = ({
|
|
|
363
678
|
readOnly,
|
|
364
679
|
type = "text",
|
|
365
680
|
onClick
|
|
366
|
-
}) => /* @__PURE__ */
|
|
681
|
+
}) => /* @__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
682
|
"input",
|
|
368
683
|
{
|
|
369
684
|
type,
|
|
@@ -384,7 +699,7 @@ var NumberInput = ({
|
|
|
384
699
|
placeholder,
|
|
385
700
|
maxLength,
|
|
386
701
|
disabled
|
|
387
|
-
}) => /* @__PURE__ */
|
|
702
|
+
}) => /* @__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
703
|
"input",
|
|
389
704
|
{
|
|
390
705
|
type: "text",
|
|
@@ -401,15 +716,1132 @@ var NumberInput = ({
|
|
|
401
716
|
}
|
|
402
717
|
));
|
|
403
718
|
|
|
719
|
+
// src/components/Banner.tsx
|
|
720
|
+
import React10, { useState as useState5 } from "react";
|
|
721
|
+
import { HugeiconsIcon as HugeiconsIcon4 } from "@hugeicons/react";
|
|
722
|
+
import {
|
|
723
|
+
Alert02Icon,
|
|
724
|
+
CheckmarkBadge01Icon,
|
|
725
|
+
InformationCircleIcon,
|
|
726
|
+
Cancel01Icon
|
|
727
|
+
} from "@hugeicons/core-free-icons";
|
|
728
|
+
var Banner = ({
|
|
729
|
+
title,
|
|
730
|
+
message,
|
|
731
|
+
type,
|
|
732
|
+
icon,
|
|
733
|
+
isDismissible = true,
|
|
734
|
+
onDismiss,
|
|
735
|
+
action
|
|
736
|
+
}) => {
|
|
737
|
+
const [isVisible, setIsVisible] = useState5(true);
|
|
738
|
+
if (!isVisible) return null;
|
|
739
|
+
const handleDismiss = () => {
|
|
740
|
+
setIsVisible(false);
|
|
741
|
+
if (onDismiss) onDismiss();
|
|
742
|
+
};
|
|
743
|
+
const config = {
|
|
744
|
+
success: {
|
|
745
|
+
bg: "bg-emerald-50",
|
|
746
|
+
iconColor: "text-emerald-600",
|
|
747
|
+
titleColor: "text-emerald-900",
|
|
748
|
+
msgColor: "text-emerald-700",
|
|
749
|
+
defaultIcon: CheckmarkBadge01Icon,
|
|
750
|
+
closeHover: "hover:bg-emerald-100 text-emerald-500"
|
|
751
|
+
},
|
|
752
|
+
warning: {
|
|
753
|
+
bg: "bg-amber-50",
|
|
754
|
+
iconColor: "text-amber-600",
|
|
755
|
+
titleColor: "text-amber-900",
|
|
756
|
+
msgColor: "text-amber-700",
|
|
757
|
+
defaultIcon: InformationCircleIcon,
|
|
758
|
+
closeHover: "hover:bg-amber-100 text-amber-500"
|
|
759
|
+
},
|
|
760
|
+
alert: {
|
|
761
|
+
bg: "bg-red-50",
|
|
762
|
+
iconColor: "text-red-600",
|
|
763
|
+
titleColor: "text-red-900",
|
|
764
|
+
msgColor: "text-red-700",
|
|
765
|
+
defaultIcon: Alert02Icon,
|
|
766
|
+
closeHover: "hover:bg-red-100 text-red-500"
|
|
767
|
+
}
|
|
768
|
+
};
|
|
769
|
+
const currentConfig = config[type];
|
|
770
|
+
const IconToUse = icon || currentConfig.defaultIcon;
|
|
771
|
+
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(
|
|
772
|
+
"button",
|
|
773
|
+
{
|
|
774
|
+
onClick: handleDismiss,
|
|
775
|
+
className: `absolute top-3 right-3 p-1.5 rounded-full transition-colors outline-none shrink-0 ${currentConfig.closeHover}`,
|
|
776
|
+
"aria-label": "Dismiss banner"
|
|
777
|
+
},
|
|
778
|
+
/* @__PURE__ */ React10.createElement(HugeiconsIcon4, { icon: Cancel01Icon, size: 16 })
|
|
779
|
+
));
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
// src/components/UniversalOrganizationPage.tsx
|
|
783
|
+
import { HugeiconsIcon as HugeiconsIcon5 } from "@hugeicons/react";
|
|
784
|
+
import {
|
|
785
|
+
CircleLock02Icon
|
|
786
|
+
} from "@hugeicons/core-free-icons";
|
|
787
|
+
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" }));
|
|
788
|
+
var UniversalOrganizationPage = ({
|
|
789
|
+
initialOrgName,
|
|
790
|
+
initialSlug,
|
|
791
|
+
initialUsername,
|
|
792
|
+
orgId,
|
|
793
|
+
isReadOnly = false,
|
|
794
|
+
slugPrefixUrl = ".aeona.eth",
|
|
795
|
+
bannerProps,
|
|
796
|
+
onSaveConfiguration,
|
|
797
|
+
onCheckSlugAvailability
|
|
798
|
+
}) => {
|
|
799
|
+
const resolvedInitialUsername = initialUsername || initialSlug;
|
|
800
|
+
const [web3Name, setWeb3Name] = useState6(initialOrgName);
|
|
801
|
+
const [username, setUsername] = useState6(resolvedInitialUsername);
|
|
802
|
+
const [slug, setSlug] = useState6(initialSlug);
|
|
803
|
+
const [isCheckingSlug, setIsCheckingSlug] = useState6(false);
|
|
804
|
+
const [slugAvailable, setSlugAvailable] = useState6(null);
|
|
805
|
+
const [isSubmitting, setIsSubmitting] = useState6(false);
|
|
806
|
+
useEffect4(() => {
|
|
807
|
+
setWeb3Name(initialOrgName || "");
|
|
808
|
+
setSlug(initialSlug || "");
|
|
809
|
+
setUsername(initialUsername || initialSlug || "");
|
|
810
|
+
}, [initialOrgName, initialSlug, initialUsername]);
|
|
811
|
+
const handleWeb3NameChange = (val) => {
|
|
812
|
+
setWeb3Name(val.replace(/[^a-zA-Z0-9\s-]/g, "").substring(0, 50));
|
|
813
|
+
};
|
|
814
|
+
const handleUsernameChange = (val) => {
|
|
815
|
+
setUsername(val.toLowerCase().replace(/[^a-z0-9-]/g, "").substring(0, 30));
|
|
816
|
+
};
|
|
817
|
+
const handleSlugChange = (val) => {
|
|
818
|
+
setSlug(val.toLowerCase().replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").substring(0, 50));
|
|
819
|
+
};
|
|
820
|
+
useEffect4(() => {
|
|
821
|
+
if (!slug || slug === initialSlug) {
|
|
822
|
+
setSlugAvailable(null);
|
|
823
|
+
setIsCheckingSlug(false);
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
if (slug.length < 3) {
|
|
827
|
+
setSlugAvailable(false);
|
|
828
|
+
setIsCheckingSlug(false);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
setIsCheckingSlug(true);
|
|
832
|
+
setSlugAvailable(null);
|
|
833
|
+
const checkTimer = setTimeout(async () => {
|
|
834
|
+
try {
|
|
835
|
+
const res = await onCheckSlugAvailability(slug);
|
|
836
|
+
setSlugAvailable(res.available);
|
|
837
|
+
} catch (error) {
|
|
838
|
+
setSlugAvailable(null);
|
|
839
|
+
} finally {
|
|
840
|
+
setIsCheckingSlug(false);
|
|
841
|
+
}
|
|
842
|
+
}, 1500);
|
|
843
|
+
return () => clearTimeout(checkTimer);
|
|
844
|
+
}, [slug, initialSlug, onCheckSlugAvailability]);
|
|
845
|
+
const handleSave = async (e) => {
|
|
846
|
+
e.preventDefault();
|
|
847
|
+
if (isSubmitting || isCheckingSlug || isReadOnly) return;
|
|
848
|
+
if (slug !== initialSlug && slugAvailable === false) {
|
|
849
|
+
toast2.error("Please select an available profile address handles.");
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
setIsSubmitting(true);
|
|
853
|
+
try {
|
|
854
|
+
const payload = {
|
|
855
|
+
organizationId: orgId,
|
|
856
|
+
organizationName: web3Name !== initialOrgName ? web3Name : void 0,
|
|
857
|
+
slug: slug !== initialSlug ? slug : void 0,
|
|
858
|
+
username: username !== resolvedInitialUsername ? username : void 0
|
|
859
|
+
};
|
|
860
|
+
const responseData = await onSaveConfiguration(payload);
|
|
861
|
+
if (responseData.success) {
|
|
862
|
+
toast2.success("Web3 profile identity updated successfully.");
|
|
863
|
+
setTimeout(() => window.location.reload(), 1e3);
|
|
864
|
+
} else {
|
|
865
|
+
toast2.error(responseData.error || "Failed to update your identity profile.");
|
|
866
|
+
setIsSubmitting(false);
|
|
867
|
+
}
|
|
868
|
+
} catch (error) {
|
|
869
|
+
toast2.error("Service unavailable. Try again later.");
|
|
870
|
+
setIsSubmitting(false);
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
const hasChanges = web3Name !== initialOrgName || slug !== initialSlug || username !== resolvedInitialUsername;
|
|
874
|
+
const isSaveDisabled = isSubmitting || isReadOnly || isCheckingSlug || !hasChanges || web3Name.length < 3 || slug.length < 3 || username.length < 3 || slug !== initialSlug && slugAvailable === false;
|
|
875
|
+
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(
|
|
876
|
+
TextInput,
|
|
877
|
+
{
|
|
878
|
+
label: "Display Name",
|
|
879
|
+
value: web3Name,
|
|
880
|
+
onChange: handleWeb3NameChange,
|
|
881
|
+
disabled: isReadOnly || isSubmitting,
|
|
882
|
+
placeholder: "Sovereign User",
|
|
883
|
+
maxLength: 50
|
|
884
|
+
}
|
|
885
|
+
), /* @__PURE__ */ React11.createElement(
|
|
886
|
+
TextInput,
|
|
887
|
+
{
|
|
888
|
+
label: "Digital Identity",
|
|
889
|
+
value: username,
|
|
890
|
+
onChange: handleUsernameChange,
|
|
891
|
+
disabled: isReadOnly || isSubmitting,
|
|
892
|
+
placeholder: "sovereignuser",
|
|
893
|
+
maxLength: 30
|
|
894
|
+
}
|
|
895
|
+
), /* @__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(
|
|
896
|
+
"input",
|
|
897
|
+
{
|
|
898
|
+
type: "text",
|
|
899
|
+
value: slug,
|
|
900
|
+
disabled: isReadOnly || isSubmitting,
|
|
901
|
+
onChange: (e) => handleSlugChange(e.target.value),
|
|
902
|
+
spellCheck: "false",
|
|
903
|
+
autoComplete: "off",
|
|
904
|
+
className: "w-full px-2 py-3 text-sm bg-transparent text-black outline-none disabled:opacity-50 disabled:cursor-not-allowed",
|
|
905
|
+
placeholder: "sovereign-user-handle"
|
|
906
|
+
}
|
|
907
|
+
), /* @__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(
|
|
908
|
+
ThreeDActionButton,
|
|
909
|
+
{
|
|
910
|
+
type: "submit",
|
|
911
|
+
disabled: isSaveDisabled,
|
|
912
|
+
isLoading: isSubmitting,
|
|
913
|
+
className: "min-w-32"
|
|
914
|
+
},
|
|
915
|
+
"Save Changes"
|
|
916
|
+
), hasChanges && !isSubmitting && !isReadOnly && /* @__PURE__ */ React11.createElement(
|
|
917
|
+
"button",
|
|
918
|
+
{
|
|
919
|
+
type: "button",
|
|
920
|
+
onClick: () => {
|
|
921
|
+
setWeb3Name(initialOrgName);
|
|
922
|
+
setSlug(initialSlug);
|
|
923
|
+
setUsername(resolvedInitialUsername);
|
|
924
|
+
},
|
|
925
|
+
className: "text-[11px] tracking-widest text-neutral-400 hover:text-black transition-colors outline-none"
|
|
926
|
+
},
|
|
927
|
+
"Cancel"
|
|
928
|
+
)))));
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
// src/components/UniversalProfileSettings.tsx
|
|
932
|
+
import React12, { useState as useState7, useEffect as useEffect5 } from "react";
|
|
933
|
+
import toast3 from "react-hot-toast";
|
|
934
|
+
import { HugeiconsIcon as HugeiconsIcon6 } from "@hugeicons/react";
|
|
935
|
+
import {
|
|
936
|
+
CircleLock02Icon as CircleLock02Icon2,
|
|
937
|
+
CancelCircleIcon,
|
|
938
|
+
Loading03Icon as Loading03Icon2,
|
|
939
|
+
LockKeyIcon
|
|
940
|
+
} from "@hugeicons/core-free-icons";
|
|
941
|
+
var UniversalProfileSettings = ({
|
|
942
|
+
initialFirstName,
|
|
943
|
+
initialLastName,
|
|
944
|
+
email,
|
|
945
|
+
accountStatus = "GOOD",
|
|
946
|
+
memberSince,
|
|
947
|
+
isReadOnly = false,
|
|
948
|
+
bannerProps,
|
|
949
|
+
hasPin = false,
|
|
950
|
+
isPinLoading = false,
|
|
951
|
+
onSavePin,
|
|
952
|
+
onSaveProfile
|
|
953
|
+
}) => {
|
|
954
|
+
const [firstName, setFirstName] = useState7(initialFirstName);
|
|
955
|
+
const [lastName, setLastName] = useState7(initialLastName);
|
|
956
|
+
const [isSubmitting, setIsSubmitting] = useState7(false);
|
|
957
|
+
const [isPinModalOpen, setIsPinModalOpen] = useState7(false);
|
|
958
|
+
const [oldPin, setOldPin] = useState7("");
|
|
959
|
+
const [newPin, setNewPin] = useState7("");
|
|
960
|
+
const [confirmPin, setConfirmPin] = useState7("");
|
|
961
|
+
const [isPinSubmitting, setIsPinSubmitting] = useState7(false);
|
|
962
|
+
useEffect5(() => {
|
|
963
|
+
setFirstName(initialFirstName || "");
|
|
964
|
+
setLastName(initialLastName || "");
|
|
965
|
+
}, [initialFirstName, initialLastName]);
|
|
966
|
+
const handleFirstNameChange = (val) => {
|
|
967
|
+
setFirstName(val.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50));
|
|
968
|
+
};
|
|
969
|
+
const handleLastNameChange = (val) => {
|
|
970
|
+
setLastName(val.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50));
|
|
971
|
+
};
|
|
972
|
+
const handleSave = async (e) => {
|
|
973
|
+
e.preventDefault();
|
|
974
|
+
if (isSubmitting || isReadOnly) return;
|
|
975
|
+
setIsSubmitting(true);
|
|
976
|
+
try {
|
|
977
|
+
const res = await onSaveProfile({ firstName, lastName });
|
|
978
|
+
if (res.success) {
|
|
979
|
+
toast3.success("Profile updated successfully.");
|
|
980
|
+
setTimeout(() => window.location.reload(), 1e3);
|
|
981
|
+
} else {
|
|
982
|
+
toast3.error(res.error || "Uh oh! Something went wrong.");
|
|
983
|
+
setIsSubmitting(false);
|
|
984
|
+
}
|
|
985
|
+
} catch (error) {
|
|
986
|
+
toast3.error("Uh oh! Something went wrong.");
|
|
987
|
+
setIsSubmitting(false);
|
|
988
|
+
}
|
|
989
|
+
};
|
|
990
|
+
const closePinModal = () => {
|
|
991
|
+
if (isPinSubmitting) return;
|
|
992
|
+
setIsPinModalOpen(false);
|
|
993
|
+
setOldPin("");
|
|
994
|
+
setNewPin("");
|
|
995
|
+
setConfirmPin("");
|
|
996
|
+
};
|
|
997
|
+
const handlePinInput = (val, setter) => {
|
|
998
|
+
setter(val.replace(/\D/g, "").substring(0, 4));
|
|
999
|
+
};
|
|
1000
|
+
const handlePinSubmit = async (e) => {
|
|
1001
|
+
e.preventDefault();
|
|
1002
|
+
if (!onSavePin) return;
|
|
1003
|
+
if (hasPin && oldPin.length !== 4) return toast3.error("Old PIN must be exactly 4 digits.");
|
|
1004
|
+
if (newPin.length !== 4) return toast3.error("New PIN must be exactly 4 digits.");
|
|
1005
|
+
if (newPin !== confirmPin) return toast3.error("New PINs do not match.");
|
|
1006
|
+
setIsPinSubmitting(true);
|
|
1007
|
+
try {
|
|
1008
|
+
const action = hasPin ? "change_pin" : "create_pin";
|
|
1009
|
+
const res = await onSavePin({
|
|
1010
|
+
action,
|
|
1011
|
+
oldPin: hasPin ? oldPin : void 0,
|
|
1012
|
+
newPin
|
|
1013
|
+
});
|
|
1014
|
+
if (res.success) {
|
|
1015
|
+
toast3.success(res.message || "PIN updated successfully.");
|
|
1016
|
+
closePinModal();
|
|
1017
|
+
} else {
|
|
1018
|
+
toast3.error(res.error || "Failed to update PIN.");
|
|
1019
|
+
}
|
|
1020
|
+
} catch (error) {
|
|
1021
|
+
toast3.error("Uh oh! Something went wrong.");
|
|
1022
|
+
} finally {
|
|
1023
|
+
setIsPinSubmitting(false);
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
const hasChanges = firstName !== initialFirstName || lastName !== initialLastName;
|
|
1027
|
+
const isSaveDisabled = isSubmitting || isReadOnly || !hasChanges || firstName.trim().length === 0 || lastName.trim().length === 0;
|
|
1028
|
+
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(
|
|
1029
|
+
TextInput,
|
|
1030
|
+
{
|
|
1031
|
+
label: "First Name",
|
|
1032
|
+
value: firstName,
|
|
1033
|
+
onChange: handleFirstNameChange,
|
|
1034
|
+
disabled: isReadOnly || isSubmitting,
|
|
1035
|
+
placeholder: "System"
|
|
1036
|
+
}
|
|
1037
|
+
)), /* @__PURE__ */ React12.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React12.createElement(
|
|
1038
|
+
TextInput,
|
|
1039
|
+
{
|
|
1040
|
+
label: "Last Name",
|
|
1041
|
+
value: lastName,
|
|
1042
|
+
onChange: handleLastNameChange,
|
|
1043
|
+
disabled: isReadOnly || isSubmitting,
|
|
1044
|
+
placeholder: "Admin"
|
|
1045
|
+
}
|
|
1046
|
+
))), /* @__PURE__ */ React12.createElement("div", { className: "space-y-2 min-w-0" }, /* @__PURE__ */ React12.createElement(
|
|
1047
|
+
TextInput,
|
|
1048
|
+
{
|
|
1049
|
+
label: "Email ID",
|
|
1050
|
+
value: email,
|
|
1051
|
+
onChange: () => {
|
|
1052
|
+
},
|
|
1053
|
+
disabled: true
|
|
1054
|
+
}
|
|
1055
|
+
), /* @__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(
|
|
1056
|
+
"button",
|
|
1057
|
+
{
|
|
1058
|
+
type: "button",
|
|
1059
|
+
onClick: () => setIsPinModalOpen(true),
|
|
1060
|
+
"aria-label": "PIN Settings",
|
|
1061
|
+
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"
|
|
1062
|
+
},
|
|
1063
|
+
/* @__PURE__ */ React12.createElement(HugeiconsIcon6, { icon: LockKeyIcon, size: 17, className: "text-black" })
|
|
1064
|
+
))), /* @__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(
|
|
1065
|
+
"button",
|
|
1066
|
+
{
|
|
1067
|
+
type: "button",
|
|
1068
|
+
onClick: () => {
|
|
1069
|
+
setFirstName(initialFirstName);
|
|
1070
|
+
setLastName(initialLastName);
|
|
1071
|
+
},
|
|
1072
|
+
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"
|
|
1073
|
+
},
|
|
1074
|
+
"Cancel"
|
|
1075
|
+
), /* @__PURE__ */ React12.createElement(
|
|
1076
|
+
ThreeDActionButton,
|
|
1077
|
+
{
|
|
1078
|
+
type: "submit",
|
|
1079
|
+
disabled: isSaveDisabled,
|
|
1080
|
+
isLoading: isSubmitting,
|
|
1081
|
+
className: "min-w-32 w-full sm:w-auto"
|
|
1082
|
+
},
|
|
1083
|
+
"Save Changes"
|
|
1084
|
+
))))), 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(
|
|
1085
|
+
TextInput,
|
|
1086
|
+
{
|
|
1087
|
+
type: "password",
|
|
1088
|
+
label: "Old PIN",
|
|
1089
|
+
maxLength: 4,
|
|
1090
|
+
disabled: isPinSubmitting,
|
|
1091
|
+
value: oldPin,
|
|
1092
|
+
onChange: (val) => handlePinInput(val, setOldPin),
|
|
1093
|
+
placeholder: "\u2022\u2022\u2022\u2022"
|
|
1094
|
+
}
|
|
1095
|
+
), /* @__PURE__ */ React12.createElement(
|
|
1096
|
+
TextInput,
|
|
1097
|
+
{
|
|
1098
|
+
type: "password",
|
|
1099
|
+
label: hasPin ? "New PIN" : "Enter 4-Digit PIN",
|
|
1100
|
+
maxLength: 4,
|
|
1101
|
+
disabled: isPinSubmitting,
|
|
1102
|
+
value: newPin,
|
|
1103
|
+
onChange: (val) => handlePinInput(val, setNewPin),
|
|
1104
|
+
placeholder: "\u2022\u2022\u2022\u2022"
|
|
1105
|
+
}
|
|
1106
|
+
), /* @__PURE__ */ React12.createElement(
|
|
1107
|
+
TextInput,
|
|
1108
|
+
{
|
|
1109
|
+
type: "password",
|
|
1110
|
+
label: "Retype New PIN",
|
|
1111
|
+
maxLength: 4,
|
|
1112
|
+
disabled: isPinSubmitting,
|
|
1113
|
+
value: confirmPin,
|
|
1114
|
+
onChange: (val) => handlePinInput(val, setConfirmPin),
|
|
1115
|
+
placeholder: "\u2022\u2022\u2022\u2022"
|
|
1116
|
+
}
|
|
1117
|
+
), /* @__PURE__ */ React12.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React12.createElement(
|
|
1118
|
+
ThreeDActionButton,
|
|
1119
|
+
{
|
|
1120
|
+
type: "submit",
|
|
1121
|
+
disabled: isPinSubmitting || newPin.length !== 4 || confirmPin.length !== 4 || hasPin && oldPin.length !== 4,
|
|
1122
|
+
isLoading: isPinSubmitting,
|
|
1123
|
+
className: "w-full py-3"
|
|
1124
|
+
},
|
|
1125
|
+
hasPin ? "Update PIN" : "Set PIN"
|
|
1126
|
+
)))))));
|
|
1127
|
+
};
|
|
1128
|
+
|
|
1129
|
+
// src/components/UniversalErrorView.tsx
|
|
1130
|
+
import React14 from "react";
|
|
1131
|
+
import { HugeiconsIcon as HugeiconsIcon8 } from "@hugeicons/react";
|
|
1132
|
+
import { ConfusedIcon } from "@hugeicons/core-free-icons";
|
|
1133
|
+
|
|
1134
|
+
// src/components/PageSpinner.tsx
|
|
1135
|
+
import React13 from "react";
|
|
1136
|
+
import { HugeiconsIcon as HugeiconsIcon7 } from "@hugeicons/react";
|
|
1137
|
+
import { Loading03Icon as Loading03Icon3 } from "@hugeicons/core-free-icons";
|
|
1138
|
+
var PageSpinner = ({
|
|
1139
|
+
className = "",
|
|
1140
|
+
iconClassName = "text-black",
|
|
1141
|
+
size = 32
|
|
1142
|
+
}) => {
|
|
1143
|
+
return (
|
|
1144
|
+
// z-[100] ensures it sits above absolute headers and modals
|
|
1145
|
+
/* @__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(
|
|
1146
|
+
HugeiconsIcon7,
|
|
1147
|
+
{
|
|
1148
|
+
icon: Loading03Icon3,
|
|
1149
|
+
size,
|
|
1150
|
+
className: `animate-spin mb-4 ${iconClassName}`
|
|
1151
|
+
}
|
|
1152
|
+
))
|
|
1153
|
+
);
|
|
1154
|
+
};
|
|
1155
|
+
|
|
1156
|
+
// src/components/UniversalErrorView.tsx
|
|
1157
|
+
var UniversalErrorView = ({
|
|
1158
|
+
isBooting,
|
|
1159
|
+
isLoading,
|
|
1160
|
+
activeData,
|
|
1161
|
+
activeError,
|
|
1162
|
+
envName,
|
|
1163
|
+
onRetry,
|
|
1164
|
+
returnUrl = "/app",
|
|
1165
|
+
returnLabel = "Return to Workspace"
|
|
1166
|
+
}) => {
|
|
1167
|
+
if (isBooting || isLoading && !activeData) {
|
|
1168
|
+
return /* @__PURE__ */ React14.createElement("div", { className: "flex items-center justify-center h-screen w-full bg-white" }, /* @__PURE__ */ React14.createElement(PageSpinner, null));
|
|
1169
|
+
}
|
|
1170
|
+
if (!isLoading && (!activeData || activeError)) {
|
|
1171
|
+
const errorString = typeof activeError === "string" ? activeError : JSON.stringify(activeError || "");
|
|
1172
|
+
const errorMsg = errorString.toLowerCase();
|
|
1173
|
+
const isPermissionError = errorMsg.includes("forbidden") || errorMsg.includes("unauthorized") || errorMsg.includes("permission");
|
|
1174
|
+
const isNetworkError = errorMsg.includes("network") || errorMsg.includes("connection") || errorMsg.includes("fetch");
|
|
1175
|
+
const isNotFoundError = errorMsg.includes("not found") || errorMsg.includes("404") || errorMsg.includes("does not exist") || !activeData && !isPermissionError && !isNetworkError;
|
|
1176
|
+
const apiMessage = typeof activeError === "string" && activeError.trim() !== "" ? activeError : null;
|
|
1177
|
+
let title = "Oops Connection Error";
|
|
1178
|
+
let description = apiMessage || `We could not load your request. Please check your connection and try again.`;
|
|
1179
|
+
let IconComponent = ConfusedIcon;
|
|
1180
|
+
if (isNotFoundError) {
|
|
1181
|
+
title = "Oops its not your fault";
|
|
1182
|
+
description = apiMessage || `We could not reach the ${envName} you just loaded. Our team has been notified.`;
|
|
1183
|
+
} else if (isPermissionError) {
|
|
1184
|
+
title = "Access Restricted";
|
|
1185
|
+
description = apiMessage || `You have insufficient permissions to view this ${envName}. Please contact your administrator.`;
|
|
1186
|
+
}
|
|
1187
|
+
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(
|
|
1188
|
+
"button",
|
|
1189
|
+
{
|
|
1190
|
+
onClick: () => window.location.href = returnUrl,
|
|
1191
|
+
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"
|
|
1192
|
+
},
|
|
1193
|
+
returnLabel
|
|
1194
|
+
) : (
|
|
1195
|
+
// Soft errors (Network timeouts) allow them to retry or optionally retreat
|
|
1196
|
+
/* @__PURE__ */ React14.createElement(React14.Fragment, null, envName.toLowerCase().includes("application") && /* @__PURE__ */ React14.createElement(
|
|
1197
|
+
"button",
|
|
1198
|
+
{
|
|
1199
|
+
onClick: () => window.location.href = returnUrl,
|
|
1200
|
+
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"
|
|
1201
|
+
},
|
|
1202
|
+
"Back Home"
|
|
1203
|
+
), /* @__PURE__ */ React14.createElement(
|
|
1204
|
+
"button",
|
|
1205
|
+
{
|
|
1206
|
+
onClick: onRetry,
|
|
1207
|
+
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"
|
|
1208
|
+
},
|
|
1209
|
+
"Refresh ",
|
|
1210
|
+
envName
|
|
1211
|
+
))
|
|
1212
|
+
)));
|
|
1213
|
+
}
|
|
1214
|
+
return null;
|
|
1215
|
+
};
|
|
1216
|
+
|
|
1217
|
+
// src/components/UniversalTransactionPage.tsx
|
|
1218
|
+
import React15, { useState as useState8, useEffect as useEffect6, useRef as useRef3 } from "react";
|
|
1219
|
+
import { HugeiconsIcon as HugeiconsIcon9 } from "@hugeicons/react";
|
|
1220
|
+
import toast4 from "react-hot-toast";
|
|
1221
|
+
import {
|
|
1222
|
+
ArrowLeft01Icon,
|
|
1223
|
+
ArrowRight01Icon,
|
|
1224
|
+
Loading03Icon as Loading03Icon4,
|
|
1225
|
+
ArrowDownRight01Icon,
|
|
1226
|
+
ArrowUpRight01Icon,
|
|
1227
|
+
Search01Icon,
|
|
1228
|
+
SearchList02Icon,
|
|
1229
|
+
ListSettingIcon,
|
|
1230
|
+
CancelCircleIcon as CancelCircleIcon2
|
|
1231
|
+
} from "@hugeicons/core-free-icons";
|
|
1232
|
+
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" }));
|
|
1233
|
+
var formatDate = (dateInput) => {
|
|
1234
|
+
const d = new Date(dateInput);
|
|
1235
|
+
const day = d.getDate();
|
|
1236
|
+
const month = d.toLocaleString("en-US", { month: "short" });
|
|
1237
|
+
const year = d.getFullYear();
|
|
1238
|
+
return `${day} ${month} ${year}`;
|
|
1239
|
+
};
|
|
1240
|
+
var formatTime = (dateInput) => {
|
|
1241
|
+
return new Date(dateInput).toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" });
|
|
1242
|
+
};
|
|
1243
|
+
var truncateAddress = (address) => {
|
|
1244
|
+
if (!address || address.length < 12) return address;
|
|
1245
|
+
return `${address.substring(0, 6)}...${address.substring(address.length - 4)}`;
|
|
1246
|
+
};
|
|
1247
|
+
var UniversalTransactionPage = ({
|
|
1248
|
+
headerTitle,
|
|
1249
|
+
headerDescription,
|
|
1250
|
+
hideControls = false,
|
|
1251
|
+
hideBalanceAmounts = false,
|
|
1252
|
+
hidePagination = false,
|
|
1253
|
+
transactions,
|
|
1254
|
+
isLoading,
|
|
1255
|
+
currentPage,
|
|
1256
|
+
totalPages,
|
|
1257
|
+
onPageChange,
|
|
1258
|
+
searchQuery,
|
|
1259
|
+
onSearchChange,
|
|
1260
|
+
activeDirectionFilter,
|
|
1261
|
+
onDirectionFilterChange,
|
|
1262
|
+
activeTypeFilter,
|
|
1263
|
+
onTypeFilterChange,
|
|
1264
|
+
onReportTransaction,
|
|
1265
|
+
onGenerateReceipt
|
|
1266
|
+
}) => {
|
|
1267
|
+
const [selectedTransaction, setSelectedTransaction] = useState8(null);
|
|
1268
|
+
const [isGeneratingReceipt, setIsGeneratingReceipt] = useState8(false);
|
|
1269
|
+
const [localSearchQuery, setLocalSearchQuery] = useState8(searchQuery);
|
|
1270
|
+
const [isTyping, setIsTyping] = useState8(false);
|
|
1271
|
+
const [isDirectionModalOpen, setIsDirectionModalOpen] = useState8(false);
|
|
1272
|
+
const [isTypeModalOpen, setIsTypeModalOpen] = useState8(false);
|
|
1273
|
+
const directionDropdownRef = useRef3(null);
|
|
1274
|
+
const typeDropdownRef = useRef3(null);
|
|
1275
|
+
useEffect6(() => {
|
|
1276
|
+
function handleClickOutside(event) {
|
|
1277
|
+
if (directionDropdownRef.current && !directionDropdownRef.current.contains(event.target)) {
|
|
1278
|
+
setIsDirectionModalOpen(false);
|
|
1279
|
+
}
|
|
1280
|
+
if (typeDropdownRef.current && !typeDropdownRef.current.contains(event.target)) {
|
|
1281
|
+
setIsTypeModalOpen(false);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1285
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1286
|
+
}, []);
|
|
1287
|
+
useEffect6(() => {
|
|
1288
|
+
setIsTyping(true);
|
|
1289
|
+
const handler = setTimeout(() => {
|
|
1290
|
+
onSearchChange(localSearchQuery);
|
|
1291
|
+
setIsTyping(false);
|
|
1292
|
+
}, 600);
|
|
1293
|
+
return () => clearTimeout(handler);
|
|
1294
|
+
}, [localSearchQuery, onSearchChange]);
|
|
1295
|
+
useEffect6(() => {
|
|
1296
|
+
if (searchQuery === "" && localSearchQuery !== "") {
|
|
1297
|
+
setLocalSearchQuery("");
|
|
1298
|
+
}
|
|
1299
|
+
}, [searchQuery]);
|
|
1300
|
+
const getDisplayName = (tx) => {
|
|
1301
|
+
if (tx.metadata?.merchantName) return tx.metadata.merchantName;
|
|
1302
|
+
if (tx.metadata?.description) return tx.metadata.description;
|
|
1303
|
+
return tx.type === "CARD_TRANSACTION" ? "Card Transaction" : "Wallet Transaction";
|
|
1304
|
+
};
|
|
1305
|
+
const handleGenerateReceipt = async () => {
|
|
1306
|
+
if (!onGenerateReceipt || !selectedTransaction) return;
|
|
1307
|
+
setIsGeneratingReceipt(true);
|
|
1308
|
+
try {
|
|
1309
|
+
await onGenerateReceipt(selectedTransaction);
|
|
1310
|
+
toast4.success("Receipt generated successfully.");
|
|
1311
|
+
} catch (error) {
|
|
1312
|
+
toast4.error("Failed to generate receipt.");
|
|
1313
|
+
} finally {
|
|
1314
|
+
setIsGeneratingReceipt(false);
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
const isListLoading = isLoading || isTyping;
|
|
1318
|
+
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(
|
|
1319
|
+
"input",
|
|
1320
|
+
{
|
|
1321
|
+
type: "text",
|
|
1322
|
+
placeholder: "Search reference or amount...",
|
|
1323
|
+
value: localSearchQuery,
|
|
1324
|
+
onChange: (e) => setLocalSearchQuery(e.target.value),
|
|
1325
|
+
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"
|
|
1326
|
+
}
|
|
1327
|
+
)), /* @__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(
|
|
1328
|
+
"button",
|
|
1329
|
+
{
|
|
1330
|
+
onClick: () => setIsDirectionModalOpen(true),
|
|
1331
|
+
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"
|
|
1332
|
+
},
|
|
1333
|
+
/* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: SearchList02Icon, size: 12 }),
|
|
1334
|
+
activeDirectionFilter === "ALL" ? "Payment Type" : activeDirectionFilter
|
|
1335
|
+
), /* @__PURE__ */ React15.createElement(
|
|
1336
|
+
"button",
|
|
1337
|
+
{
|
|
1338
|
+
onClick: () => setIsTypeModalOpen(true),
|
|
1339
|
+
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"
|
|
1340
|
+
},
|
|
1341
|
+
/* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: ListSettingIcon, size: 14 }),
|
|
1342
|
+
activeTypeFilter === "ALL" ? "All Transactions" : activeTypeFilter.replace("_", " ")
|
|
1343
|
+
))), /* @__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(
|
|
1344
|
+
"div",
|
|
1345
|
+
{
|
|
1346
|
+
key: tx.id,
|
|
1347
|
+
onClick: () => setSelectedTransaction(tx),
|
|
1348
|
+
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"
|
|
1349
|
+
},
|
|
1350
|
+
/* @__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))),
|
|
1351
|
+
/* @__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()))
|
|
1352
|
+
))), !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(
|
|
1353
|
+
"button",
|
|
1354
|
+
{
|
|
1355
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
1356
|
+
disabled: currentPage <= 1 || isListLoading,
|
|
1357
|
+
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"
|
|
1358
|
+
},
|
|
1359
|
+
/* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: ArrowLeft01Icon, size: 14 })
|
|
1360
|
+
), /* @__PURE__ */ React15.createElement(
|
|
1361
|
+
"button",
|
|
1362
|
+
{
|
|
1363
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
1364
|
+
disabled: currentPage >= totalPages || isListLoading || totalPages === 0,
|
|
1365
|
+
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"
|
|
1366
|
+
},
|
|
1367
|
+
/* @__PURE__ */ React15.createElement(HugeiconsIcon9, { icon: ArrowRight01Icon, size: 14 })
|
|
1368
|
+
)))))), 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]) => {
|
|
1369
|
+
if (key === "fromAddress" || key === "toAddress") return null;
|
|
1370
|
+
if (value === null || value === void 0 || typeof value === "object") return null;
|
|
1371
|
+
const formattedKey = key.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase());
|
|
1372
|
+
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)));
|
|
1373
|
+
})), /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React15.createElement(
|
|
1374
|
+
ThreeDActionButton,
|
|
1375
|
+
{
|
|
1376
|
+
onClick: handleGenerateReceipt,
|
|
1377
|
+
isLoading: isGeneratingReceipt,
|
|
1378
|
+
className: "w-full py-3 text-[14px]"
|
|
1379
|
+
},
|
|
1380
|
+
"Generate Receipt"
|
|
1381
|
+
), /* @__PURE__ */ React15.createElement(
|
|
1382
|
+
"button",
|
|
1383
|
+
{
|
|
1384
|
+
onClick: () => onReportTransaction && onReportTransaction(selectedTransaction),
|
|
1385
|
+
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"
|
|
1386
|
+
},
|
|
1387
|
+
"Report Transaction"
|
|
1388
|
+
), selectedTransaction.type === "WALLET_TRANSACTION" && /* @__PURE__ */ React15.createElement(
|
|
1389
|
+
"a",
|
|
1390
|
+
{
|
|
1391
|
+
href: `https://basescan.org/tx/${selectedTransaction.reference}`,
|
|
1392
|
+
target: "_blank",
|
|
1393
|
+
rel: "noopener noreferrer",
|
|
1394
|
+
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"
|
|
1395
|
+
},
|
|
1396
|
+
"View in block explorer"
|
|
1397
|
+
))))), 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(
|
|
1398
|
+
"button",
|
|
1399
|
+
{
|
|
1400
|
+
key: option,
|
|
1401
|
+
onClick: () => {
|
|
1402
|
+
onDirectionFilterChange(option);
|
|
1403
|
+
setIsDirectionModalOpen(false);
|
|
1404
|
+
},
|
|
1405
|
+
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"}`
|
|
1406
|
+
},
|
|
1407
|
+
/* @__PURE__ */ React15.createElement("span", { className: "truncate pr-2" }, option.charAt(0).toUpperCase() + option.slice(1).toLowerCase())
|
|
1408
|
+
))), /* @__PURE__ */ React15.createElement("div", { className: "w-full flex mt-2 " }, /* @__PURE__ */ React15.createElement(
|
|
1409
|
+
"button",
|
|
1410
|
+
{
|
|
1411
|
+
onClick: () => setIsDirectionModalOpen(false),
|
|
1412
|
+
className: "w-full py-4 text-[13px] text-neutral-500 hover:text-black transition-colors outline-none font-medium"
|
|
1413
|
+
},
|
|
1414
|
+
"Cancel"
|
|
1415
|
+
)))), 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" }, [
|
|
1416
|
+
{ label: "All Transactions", value: "ALL" },
|
|
1417
|
+
{ label: "Wallet Transactions", value: "WALLET_TRANSACTION" },
|
|
1418
|
+
{ label: "Card Transactions", value: "CARD_TRANSACTION" }
|
|
1419
|
+
].map((option) => /* @__PURE__ */ React15.createElement(
|
|
1420
|
+
"button",
|
|
1421
|
+
{
|
|
1422
|
+
key: option.value,
|
|
1423
|
+
onClick: () => {
|
|
1424
|
+
onTypeFilterChange(option.value);
|
|
1425
|
+
setIsTypeModalOpen(false);
|
|
1426
|
+
},
|
|
1427
|
+
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"}`
|
|
1428
|
+
},
|
|
1429
|
+
/* @__PURE__ */ React15.createElement("span", { className: "truncate pr-2" }, option.label.charAt(0).toUpperCase() + option.label.slice(1).toLowerCase())
|
|
1430
|
+
))), /* @__PURE__ */ React15.createElement("div", { className: "w-full flex mt-2 " }, /* @__PURE__ */ React15.createElement(
|
|
1431
|
+
"button",
|
|
1432
|
+
{
|
|
1433
|
+
onClick: () => setIsTypeModalOpen(false),
|
|
1434
|
+
className: "w-full py-4 text-[13px] text-neutral-500 hover:text-black transition-colors outline-none font-medium"
|
|
1435
|
+
},
|
|
1436
|
+
"Cancel"
|
|
1437
|
+
)))));
|
|
1438
|
+
};
|
|
1439
|
+
|
|
1440
|
+
// src/components/UniversalHomeView.tsx
|
|
1441
|
+
import React16, { useState as useState9, useEffect as useEffect7 } from "react";
|
|
1442
|
+
import { HugeiconsIcon as HugeiconsIcon10 } from "@hugeicons/react";
|
|
1443
|
+
import { ViewOffSlashIcon, ViewIcon } from "@hugeicons/core-free-icons";
|
|
1444
|
+
var UniversalHomeView = ({
|
|
1445
|
+
balanceLabel = "Your Balance",
|
|
1446
|
+
balanceAmount,
|
|
1447
|
+
balanceCurrency = "$",
|
|
1448
|
+
primaryAction,
|
|
1449
|
+
secondaryAction,
|
|
1450
|
+
transactionsProps
|
|
1451
|
+
}) => {
|
|
1452
|
+
const [displayAmount, setDisplayAmount] = useState9("0.00");
|
|
1453
|
+
const [isBalanceHidden, setIsBalanceHidden] = useState9(false);
|
|
1454
|
+
useEffect7(() => {
|
|
1455
|
+
const target = parseFloat(balanceAmount.replace(/,/g, ""));
|
|
1456
|
+
if (isNaN(target)) {
|
|
1457
|
+
setDisplayAmount(balanceAmount);
|
|
1458
|
+
return;
|
|
1459
|
+
}
|
|
1460
|
+
let startTimestamp = null;
|
|
1461
|
+
const duration = 1e3;
|
|
1462
|
+
const step = (timestamp) => {
|
|
1463
|
+
if (!startTimestamp) startTimestamp = timestamp;
|
|
1464
|
+
const progress = Math.min((timestamp - startTimestamp) / duration, 1);
|
|
1465
|
+
const easeProgress = progress === 1 ? 1 : 1 - Math.pow(2, -10 * progress);
|
|
1466
|
+
const currentCount = easeProgress * target;
|
|
1467
|
+
setDisplayAmount(currentCount.toLocaleString("en-US", {
|
|
1468
|
+
minimumFractionDigits: 2,
|
|
1469
|
+
maximumFractionDigits: 2
|
|
1470
|
+
}));
|
|
1471
|
+
if (progress < 1) {
|
|
1472
|
+
requestAnimationFrame(step);
|
|
1473
|
+
} else {
|
|
1474
|
+
setDisplayAmount(target.toLocaleString("en-US", {
|
|
1475
|
+
minimumFractionDigits: 2,
|
|
1476
|
+
maximumFractionDigits: 2
|
|
1477
|
+
}));
|
|
1478
|
+
}
|
|
1479
|
+
};
|
|
1480
|
+
requestAnimationFrame(step);
|
|
1481
|
+
}, [balanceAmount]);
|
|
1482
|
+
const [intPart, decPart] = displayAmount.includes(".") ? displayAmount.split(".") : [displayAmount, "00"];
|
|
1483
|
+
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(
|
|
1484
|
+
"button",
|
|
1485
|
+
{
|
|
1486
|
+
onClick: () => setIsBalanceHidden(!isBalanceHidden),
|
|
1487
|
+
className: "text-neutral-400 hover:text-black transition-colors outline-none"
|
|
1488
|
+
},
|
|
1489
|
+
/* @__PURE__ */ React16.createElement(HugeiconsIcon10, { icon: isBalanceHidden ? ViewIcon : ViewOffSlashIcon, size: 14 })
|
|
1490
|
+
)), /* @__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(
|
|
1491
|
+
ThreeDActionButton,
|
|
1492
|
+
{
|
|
1493
|
+
onClick: primaryAction.onClick,
|
|
1494
|
+
className: "px-6 py-2.5 sm:px-8 sm:py-2.5"
|
|
1495
|
+
},
|
|
1496
|
+
/* @__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 }))
|
|
1497
|
+
), secondaryAction && /* @__PURE__ */ React16.createElement(
|
|
1498
|
+
"button",
|
|
1499
|
+
{
|
|
1500
|
+
onClick: secondaryAction.onClick,
|
|
1501
|
+
className: "flex items-center gap-1.5 px-6 py-2.5 sm:px-8 sm:py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 transition-colors outline-none"
|
|
1502
|
+
},
|
|
1503
|
+
/* @__PURE__ */ React16.createElement("span", { className: "text-[13px] tracking-wide font-medium" }, secondaryAction.label),
|
|
1504
|
+
secondaryAction.icon && /* @__PURE__ */ React16.createElement(HugeiconsIcon10, { icon: secondaryAction.icon, size: 16 })
|
|
1505
|
+
)))), /* @__PURE__ */ React16.createElement("div", { className: "w-full mt-2" }, /* @__PURE__ */ React16.createElement(
|
|
1506
|
+
UniversalTransactionPage,
|
|
1507
|
+
{
|
|
1508
|
+
...transactionsProps,
|
|
1509
|
+
hideControls: true,
|
|
1510
|
+
hideBalanceAmounts: isBalanceHidden,
|
|
1511
|
+
hidePagination: true
|
|
1512
|
+
}
|
|
1513
|
+
)));
|
|
1514
|
+
};
|
|
1515
|
+
|
|
1516
|
+
// src/components/UniversalWalletPage.tsx
|
|
1517
|
+
import React17, { useState as useState10 } from "react";
|
|
1518
|
+
import toast5 from "react-hot-toast";
|
|
1519
|
+
import { HugeiconsIcon as HugeiconsIcon11 } from "@hugeicons/react";
|
|
1520
|
+
import {
|
|
1521
|
+
Search01Icon as Search01Icon2,
|
|
1522
|
+
CancelCircleIcon as CancelCircleIcon3,
|
|
1523
|
+
Loading03Icon as Loading03Icon5
|
|
1524
|
+
} from "@hugeicons/core-free-icons";
|
|
1525
|
+
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" }));
|
|
1526
|
+
var WalletLogo = ({ src, alt, sizeClass = "w-10 h-10" }) => {
|
|
1527
|
+
const [isLoaded, setIsLoaded] = useState10(false);
|
|
1528
|
+
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(
|
|
1529
|
+
"img",
|
|
1530
|
+
{
|
|
1531
|
+
src,
|
|
1532
|
+
alt,
|
|
1533
|
+
onLoad: () => setIsLoaded(true),
|
|
1534
|
+
className: `w-full h-full object-cover transition-opacity duration-300 ${isLoaded ? "opacity-100" : "opacity-0"}`
|
|
1535
|
+
}
|
|
1536
|
+
));
|
|
1537
|
+
};
|
|
1538
|
+
var UniversalWalletPage = ({
|
|
1539
|
+
headerTitle,
|
|
1540
|
+
headerDescription,
|
|
1541
|
+
hideControls = false,
|
|
1542
|
+
hideBalanceAmounts = false,
|
|
1543
|
+
isGeneratingStatement = false,
|
|
1544
|
+
wallets,
|
|
1545
|
+
isLoading = false,
|
|
1546
|
+
renderQrCode,
|
|
1547
|
+
onDownloadPayId,
|
|
1548
|
+
onCopyAddress
|
|
1549
|
+
}) => {
|
|
1550
|
+
const [selectedWallet, setSelectedWallet] = useState10(null);
|
|
1551
|
+
const [localSearchQuery, setLocalSearchQuery] = useState10("");
|
|
1552
|
+
const filteredWallets = wallets.filter((wallet) => {
|
|
1553
|
+
const q = localSearchQuery.toLowerCase();
|
|
1554
|
+
return wallet.name.toLowerCase().includes(q) || wallet.currency.toLowerCase().includes(q) || wallet.network.toLowerCase().includes(q);
|
|
1555
|
+
});
|
|
1556
|
+
const handleCopy = (wallet) => {
|
|
1557
|
+
if (onCopyAddress) onCopyAddress(wallet);
|
|
1558
|
+
if (typeof navigator !== "undefined" && navigator.clipboard) {
|
|
1559
|
+
navigator.clipboard.writeText(wallet.address).catch(() => {
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
toast5.success("Address copied to clipboard");
|
|
1563
|
+
};
|
|
1564
|
+
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(
|
|
1565
|
+
"input",
|
|
1566
|
+
{
|
|
1567
|
+
type: "text",
|
|
1568
|
+
placeholder: "Search wallets by name or network...",
|
|
1569
|
+
value: localSearchQuery,
|
|
1570
|
+
onChange: (e) => setLocalSearchQuery(e.target.value),
|
|
1571
|
+
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"
|
|
1572
|
+
}
|
|
1573
|
+
))), /* @__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(
|
|
1574
|
+
"div",
|
|
1575
|
+
{
|
|
1576
|
+
key: wallet.id,
|
|
1577
|
+
onClick: () => setSelectedWallet(wallet),
|
|
1578
|
+
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"
|
|
1579
|
+
},
|
|
1580
|
+
/* @__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))),
|
|
1581
|
+
/* @__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))
|
|
1582
|
+
)))))), 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(
|
|
1583
|
+
ThreeDActionButton,
|
|
1584
|
+
{
|
|
1585
|
+
onClick: () => onDownloadPayId && onDownloadPayId(selectedWallet),
|
|
1586
|
+
isLoading: isGeneratingStatement,
|
|
1587
|
+
className: "w-full py-3 text-[13px]"
|
|
1588
|
+
},
|
|
1589
|
+
"Generate Statement"
|
|
1590
|
+
), /* @__PURE__ */ React17.createElement(
|
|
1591
|
+
"button",
|
|
1592
|
+
{
|
|
1593
|
+
onClick: () => handleCopy(selectedWallet),
|
|
1594
|
+
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"
|
|
1595
|
+
},
|
|
1596
|
+
"Copy Wallet Address"
|
|
1597
|
+
))))));
|
|
1598
|
+
};
|
|
1599
|
+
|
|
1600
|
+
// src/components/UniversalCardPage.tsx
|
|
1601
|
+
import React18, { useState as useState11 } from "react";
|
|
1602
|
+
import { HugeiconsIcon as HugeiconsIcon12 } from "@hugeicons/react";
|
|
1603
|
+
import {
|
|
1604
|
+
EyeIcon,
|
|
1605
|
+
SnowIcon,
|
|
1606
|
+
Settings02Icon,
|
|
1607
|
+
Delete02Icon,
|
|
1608
|
+
ArrowRight01Icon as ArrowRight01Icon2
|
|
1609
|
+
} from "@hugeicons/core-free-icons";
|
|
1610
|
+
var UniversalCardPage = ({
|
|
1611
|
+
cardHolderName,
|
|
1612
|
+
cardNumber,
|
|
1613
|
+
expiry,
|
|
1614
|
+
cvv,
|
|
1615
|
+
cardBgSrc,
|
|
1616
|
+
companyLogoSrc,
|
|
1617
|
+
networkLogoSrc,
|
|
1618
|
+
onReveal,
|
|
1619
|
+
onFreeze,
|
|
1620
|
+
onSetLimits,
|
|
1621
|
+
onDelete
|
|
1622
|
+
}) => {
|
|
1623
|
+
const [isFlipped, setIsFlipped] = useState11(false);
|
|
1624
|
+
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(
|
|
1625
|
+
"div",
|
|
1626
|
+
{
|
|
1627
|
+
onClick: () => setIsFlipped(!isFlipped),
|
|
1628
|
+
className: "relative w-full h-50.5 cursor-pointer transition-transform duration-700",
|
|
1629
|
+
style: {
|
|
1630
|
+
transformStyle: "preserve-3d",
|
|
1631
|
+
transform: isFlipped ? "rotateY(180deg)" : "rotateY(0deg)"
|
|
1632
|
+
}
|
|
1633
|
+
},
|
|
1634
|
+
/* @__PURE__ */ React18.createElement(
|
|
1635
|
+
"div",
|
|
1636
|
+
{
|
|
1637
|
+
className: "absolute inset-0 w-full h-full rounded-2xl overflow-hidden shadow-xl",
|
|
1638
|
+
style: { backfaceVisibility: "hidden" }
|
|
1639
|
+
},
|
|
1640
|
+
/* @__PURE__ */ React18.createElement(
|
|
1641
|
+
"div",
|
|
1642
|
+
{
|
|
1643
|
+
className: "absolute inset-0 bg-cover bg-center",
|
|
1644
|
+
style: { backgroundImage: `url(${cardBgSrc}), linear-gradient(to bottom right, #111, #333)` }
|
|
1645
|
+
}
|
|
1646
|
+
),
|
|
1647
|
+
/* @__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" })))
|
|
1648
|
+
),
|
|
1649
|
+
/* @__PURE__ */ React18.createElement(
|
|
1650
|
+
"div",
|
|
1651
|
+
{
|
|
1652
|
+
className: "absolute inset-0 w-full h-full rounded-2xl overflow-hidden shadow-xl",
|
|
1653
|
+
style: {
|
|
1654
|
+
backfaceVisibility: "hidden",
|
|
1655
|
+
transform: "rotateY(180deg)"
|
|
1656
|
+
}
|
|
1657
|
+
},
|
|
1658
|
+
/* @__PURE__ */ React18.createElement(
|
|
1659
|
+
"div",
|
|
1660
|
+
{
|
|
1661
|
+
className: "absolute inset-0 bg-cover bg-center",
|
|
1662
|
+
style: { backgroundImage: `url(${cardBgSrc}), linear-gradient(to bottom right, #111, #333)` }
|
|
1663
|
+
}
|
|
1664
|
+
),
|
|
1665
|
+
/* @__PURE__ */ React18.createElement("div", { className: "absolute top-6 left-0 right-0 h-10 bg-black/80 w-full" }),
|
|
1666
|
+
/* @__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))))
|
|
1667
|
+
)
|
|
1668
|
+
)), /* @__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(
|
|
1669
|
+
MenuRow,
|
|
1670
|
+
{
|
|
1671
|
+
icon: EyeIcon,
|
|
1672
|
+
title: "Reveal Information",
|
|
1673
|
+
subtitle: "Show card informations",
|
|
1674
|
+
onClick: onReveal
|
|
1675
|
+
}
|
|
1676
|
+
), /* @__PURE__ */ React18.createElement(
|
|
1677
|
+
MenuRow,
|
|
1678
|
+
{
|
|
1679
|
+
icon: SnowIcon,
|
|
1680
|
+
title: "Freeze",
|
|
1681
|
+
subtitle: "Freeze & Unfreeze card",
|
|
1682
|
+
onClick: onFreeze
|
|
1683
|
+
}
|
|
1684
|
+
), /* @__PURE__ */ React18.createElement(
|
|
1685
|
+
MenuRow,
|
|
1686
|
+
{
|
|
1687
|
+
icon: Settings02Icon,
|
|
1688
|
+
title: "Set Limits",
|
|
1689
|
+
subtitle: "Set card limits",
|
|
1690
|
+
onClick: onSetLimits,
|
|
1691
|
+
isLast: true
|
|
1692
|
+
}
|
|
1693
|
+
)), /* @__PURE__ */ React18.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ React18.createElement(
|
|
1694
|
+
MenuRow,
|
|
1695
|
+
{
|
|
1696
|
+
icon: Delete02Icon,
|
|
1697
|
+
title: "Delete card",
|
|
1698
|
+
subtitle: "Permanently delete card",
|
|
1699
|
+
onClick: onDelete,
|
|
1700
|
+
isLast: true
|
|
1701
|
+
}
|
|
1702
|
+
))));
|
|
1703
|
+
};
|
|
1704
|
+
var MenuRow = ({ icon, title, subtitle, onClick, iconColor = "text-black", titleColor = "text-black", isLast = false }) => /* @__PURE__ */ React18.createElement(
|
|
1705
|
+
"div",
|
|
1706
|
+
{
|
|
1707
|
+
onClick,
|
|
1708
|
+
className: `flex items-center p-4 cursor-pointer hover:bg-neutral-50 transition-colors ${!isLast ? "border-b border-neutral-100" : ""}`
|
|
1709
|
+
},
|
|
1710
|
+
/* @__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 })),
|
|
1711
|
+
/* @__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)),
|
|
1712
|
+
/* @__PURE__ */ React18.createElement(HugeiconsIcon12, { icon: ArrowRight01Icon2, size: 20, className: "text-neutral-400 shrink-0 ml-2" })
|
|
1713
|
+
);
|
|
1714
|
+
|
|
1715
|
+
// src/components/UniversalProfilePage.tsx
|
|
1716
|
+
import React19 from "react";
|
|
1717
|
+
import { HugeiconsIcon as HugeiconsIcon13 } from "@hugeicons/react";
|
|
1718
|
+
import {
|
|
1719
|
+
UserIcon,
|
|
1720
|
+
LockKeyIcon as LockKeyIcon2,
|
|
1721
|
+
Notification03Icon,
|
|
1722
|
+
HelpCircleIcon,
|
|
1723
|
+
Shield01Icon,
|
|
1724
|
+
Download04Icon,
|
|
1725
|
+
Logout03Icon,
|
|
1726
|
+
Delete02Icon as Delete02Icon2,
|
|
1727
|
+
ArrowRight01Icon as ArrowRight01Icon3
|
|
1728
|
+
} from "@hugeicons/core-free-icons";
|
|
1729
|
+
var UniversalProfilePage = ({
|
|
1730
|
+
avatarSrc,
|
|
1731
|
+
roleName,
|
|
1732
|
+
memberSince,
|
|
1733
|
+
onAccountTap,
|
|
1734
|
+
onSecurityTap,
|
|
1735
|
+
onNotificationsTap,
|
|
1736
|
+
onHelpTap,
|
|
1737
|
+
onVerificationsTap,
|
|
1738
|
+
onExportTap,
|
|
1739
|
+
onLogoutTap,
|
|
1740
|
+
onDeleteTap
|
|
1741
|
+
}) => {
|
|
1742
|
+
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(
|
|
1743
|
+
"img",
|
|
1744
|
+
{
|
|
1745
|
+
src: avatarSrc,
|
|
1746
|
+
alt: "User Avatar",
|
|
1747
|
+
className: "w-full h-full object-cover"
|
|
1748
|
+
}
|
|
1749
|
+
) : /* @__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(
|
|
1750
|
+
MenuRow2,
|
|
1751
|
+
{
|
|
1752
|
+
icon: UserIcon,
|
|
1753
|
+
title: "Account",
|
|
1754
|
+
subtitle: "Your account details",
|
|
1755
|
+
onClick: onAccountTap
|
|
1756
|
+
}
|
|
1757
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1758
|
+
MenuRow2,
|
|
1759
|
+
{
|
|
1760
|
+
icon: LockKeyIcon2,
|
|
1761
|
+
title: "Security",
|
|
1762
|
+
subtitle: "2FA & authentication",
|
|
1763
|
+
onClick: onSecurityTap
|
|
1764
|
+
}
|
|
1765
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1766
|
+
MenuRow2,
|
|
1767
|
+
{
|
|
1768
|
+
icon: Notification03Icon,
|
|
1769
|
+
title: "Notifications",
|
|
1770
|
+
subtitle: "Manage notifications",
|
|
1771
|
+
onClick: onNotificationsTap
|
|
1772
|
+
}
|
|
1773
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1774
|
+
MenuRow2,
|
|
1775
|
+
{
|
|
1776
|
+
icon: HelpCircleIcon,
|
|
1777
|
+
title: "Get Help",
|
|
1778
|
+
subtitle: "24/7 Support",
|
|
1779
|
+
onClick: onHelpTap,
|
|
1780
|
+
isLast: true
|
|
1781
|
+
}
|
|
1782
|
+
)), /* @__PURE__ */ React19.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden shadow-sm" }, /* @__PURE__ */ React19.createElement(
|
|
1783
|
+
MenuRow2,
|
|
1784
|
+
{
|
|
1785
|
+
icon: Shield01Icon,
|
|
1786
|
+
title: "Verifications",
|
|
1787
|
+
subtitle: "Account Verifications",
|
|
1788
|
+
onClick: onVerificationsTap
|
|
1789
|
+
}
|
|
1790
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1791
|
+
MenuRow2,
|
|
1792
|
+
{
|
|
1793
|
+
icon: Download04Icon,
|
|
1794
|
+
title: "Export Account",
|
|
1795
|
+
subtitle: "Transfer your account",
|
|
1796
|
+
onClick: onExportTap
|
|
1797
|
+
}
|
|
1798
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1799
|
+
MenuRow2,
|
|
1800
|
+
{
|
|
1801
|
+
icon: Logout03Icon,
|
|
1802
|
+
title: "LogOut",
|
|
1803
|
+
subtitle: "End your session",
|
|
1804
|
+
onClick: onLogoutTap,
|
|
1805
|
+
isLast: true
|
|
1806
|
+
}
|
|
1807
|
+
)), /* @__PURE__ */ React19.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden shadow-sm mb-4" }, /* @__PURE__ */ React19.createElement(
|
|
1808
|
+
MenuRow2,
|
|
1809
|
+
{
|
|
1810
|
+
icon: Delete02Icon2,
|
|
1811
|
+
title: "Delete Account",
|
|
1812
|
+
subtitle: "Remove account",
|
|
1813
|
+
onClick: onDeleteTap,
|
|
1814
|
+
isLast: true
|
|
1815
|
+
}
|
|
1816
|
+
))));
|
|
1817
|
+
};
|
|
1818
|
+
var MenuRow2 = ({ icon, title, subtitle, onClick, iconColor = "text-black", titleColor = "text-black", isLast = false }) => /* @__PURE__ */ React19.createElement(
|
|
1819
|
+
"div",
|
|
1820
|
+
{
|
|
1821
|
+
onClick,
|
|
1822
|
+
className: `flex items-center p-4 cursor-pointer hover:bg-neutral-50 transition-colors ${!isLast ? "border-b border-neutral-100" : ""}`
|
|
1823
|
+
},
|
|
1824
|
+
/* @__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 })),
|
|
1825
|
+
/* @__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)),
|
|
1826
|
+
/* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: ArrowRight01Icon3, size: 20, className: "text-neutral-400 shrink-0 ml-2" })
|
|
1827
|
+
);
|
|
1828
|
+
|
|
1829
|
+
// src/components/HeroSection.tsx
|
|
1830
|
+
import React21, { useState as useState13, useEffect as useEffect8, useRef as useRef4 } from "react";
|
|
1831
|
+
import Link5 from "next/link";
|
|
1832
|
+
import Image2 from "next/image";
|
|
1833
|
+
|
|
404
1834
|
// src/components/WaitlistDialog.tsx
|
|
1835
|
+
import React20, { useState as useState12 } from "react";
|
|
1836
|
+
import { toast as toast6 } from "react-hot-toast";
|
|
405
1837
|
var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
406
|
-
const [email, setEmail] =
|
|
407
|
-
const [isLoading, setIsLoading] =
|
|
1838
|
+
const [email, setEmail] = useState12("");
|
|
1839
|
+
const [isLoading, setIsLoading] = useState12(false);
|
|
408
1840
|
if (!isOpen) return null;
|
|
409
1841
|
const handleSubmit = async (e) => {
|
|
410
1842
|
e.preventDefault();
|
|
411
1843
|
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
412
|
-
|
|
1844
|
+
toast6.error("Please enter a valid email address.");
|
|
413
1845
|
return;
|
|
414
1846
|
}
|
|
415
1847
|
setIsLoading(true);
|
|
@@ -423,24 +1855,24 @@ var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
|
423
1855
|
});
|
|
424
1856
|
const data = await response.json();
|
|
425
1857
|
if (response.ok && data.success) {
|
|
426
|
-
|
|
1858
|
+
toast6.success(data.message || "You've been added to the waitlist!");
|
|
427
1859
|
setEmail("");
|
|
428
1860
|
onClose();
|
|
429
1861
|
} else {
|
|
430
|
-
|
|
1862
|
+
toast6.error(data.error || "Something went wrong. Please try again.");
|
|
431
1863
|
}
|
|
432
1864
|
} catch (error) {
|
|
433
|
-
|
|
1865
|
+
toast6.error("Network error. Please check your connection.");
|
|
434
1866
|
} finally {
|
|
435
1867
|
setIsLoading(false);
|
|
436
1868
|
}
|
|
437
1869
|
};
|
|
438
|
-
return /* @__PURE__ */
|
|
1870
|
+
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
1871
|
"div",
|
|
440
1872
|
{
|
|
441
1873
|
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
1874
|
},
|
|
443
|
-
/* @__PURE__ */
|
|
1875
|
+
/* @__PURE__ */ React20.createElement(
|
|
444
1876
|
"button",
|
|
445
1877
|
{
|
|
446
1878
|
onClick: onClose,
|
|
@@ -448,7 +1880,7 @@ var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
|
448
1880
|
className: "absolute top-4 right-4 p-2 text-neutral-700 hover:text-neutral-400 transition-colors disabled:opacity-50 outline-none",
|
|
449
1881
|
"aria-label": "Close dialog"
|
|
450
1882
|
},
|
|
451
|
-
/* @__PURE__ */
|
|
1883
|
+
/* @__PURE__ */ React20.createElement(
|
|
452
1884
|
"svg",
|
|
453
1885
|
{
|
|
454
1886
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -461,11 +1893,11 @@ var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
|
461
1893
|
strokeLinecap: "round",
|
|
462
1894
|
strokeLinejoin: "round"
|
|
463
1895
|
},
|
|
464
|
-
/* @__PURE__ */
|
|
465
|
-
/* @__PURE__ */
|
|
1896
|
+
/* @__PURE__ */ React20.createElement("path", { d: "M18 6 6 18" }),
|
|
1897
|
+
/* @__PURE__ */ React20.createElement("path", { d: "m6 6 12 12" })
|
|
466
1898
|
)
|
|
467
1899
|
),
|
|
468
|
-
/* @__PURE__ */
|
|
1900
|
+
/* @__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
1901
|
TextInput,
|
|
470
1902
|
{
|
|
471
1903
|
label: "Email ID",
|
|
@@ -475,7 +1907,7 @@ var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
|
475
1907
|
placeholder: "name@example.com",
|
|
476
1908
|
disabled: isLoading
|
|
477
1909
|
}
|
|
478
|
-
), /* @__PURE__ */
|
|
1910
|
+
), /* @__PURE__ */ React20.createElement(
|
|
479
1911
|
ThreeDActionButton,
|
|
480
1912
|
{
|
|
481
1913
|
type: "submit",
|
|
@@ -508,10 +1940,10 @@ var HeroSection = ({
|
|
|
508
1940
|
bgImageSrc,
|
|
509
1941
|
isWaitlist = false
|
|
510
1942
|
}) => {
|
|
511
|
-
const [isAnimating, setIsAnimating] =
|
|
512
|
-
const [isWaitlistOpen, setIsWaitlistOpen] =
|
|
513
|
-
const titleRef =
|
|
514
|
-
|
|
1943
|
+
const [isAnimating, setIsAnimating] = useState13(false);
|
|
1944
|
+
const [isWaitlistOpen, setIsWaitlistOpen] = useState13(false);
|
|
1945
|
+
const titleRef = useRef4(null);
|
|
1946
|
+
useEffect8(() => {
|
|
515
1947
|
const observer = new IntersectionObserver(
|
|
516
1948
|
([entry]) => {
|
|
517
1949
|
if (entry.isIntersecting) {
|
|
@@ -533,7 +1965,7 @@ var HeroSection = ({
|
|
|
533
1965
|
setIsWaitlistOpen(true);
|
|
534
1966
|
}
|
|
535
1967
|
};
|
|
536
|
-
return /* @__PURE__ */
|
|
1968
|
+
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
1969
|
"video",
|
|
538
1970
|
{
|
|
539
1971
|
src: bgVideoSrc,
|
|
@@ -544,7 +1976,7 @@ var HeroSection = ({
|
|
|
544
1976
|
playsInline: true,
|
|
545
1977
|
className: "absolute inset-0 h-full w-full object-cover z-0"
|
|
546
1978
|
}
|
|
547
|
-
) : bgImageSrc ? /* @__PURE__ */
|
|
1979
|
+
) : bgImageSrc ? /* @__PURE__ */ React21.createElement(
|
|
548
1980
|
Image2,
|
|
549
1981
|
{
|
|
550
1982
|
src: bgImageSrc,
|
|
@@ -553,7 +1985,7 @@ var HeroSection = ({
|
|
|
553
1985
|
priority: true,
|
|
554
1986
|
className: "absolute inset-0 h-full w-full object-cover z-0"
|
|
555
1987
|
}
|
|
556
|
-
) : null, /* @__PURE__ */
|
|
1988
|
+
) : null, /* @__PURE__ */ React21.createElement(
|
|
557
1989
|
"div",
|
|
558
1990
|
{
|
|
559
1991
|
className: "pointer-events-none absolute inset-0 z-10 opacity-[0.7] mix-blend-overlay",
|
|
@@ -561,31 +1993,31 @@ var HeroSection = ({
|
|
|
561
1993
|
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
1994
|
}
|
|
563
1995
|
}
|
|
564
|
-
), /* @__PURE__ */
|
|
1996
|
+
), /* @__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
1997
|
"h1",
|
|
566
1998
|
{
|
|
567
1999
|
ref: titleRef,
|
|
568
2000
|
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
2001
|
},
|
|
570
|
-
/* @__PURE__ */
|
|
571
|
-
)), /* @__PURE__ */
|
|
572
|
-
/* @__PURE__ */
|
|
573
|
-
|
|
2002
|
+
/* @__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" }, "*")))
|
|
2003
|
+
)), /* @__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!
|
|
2004
|
+
/* @__PURE__ */ React21.createElement(
|
|
2005
|
+
Link5,
|
|
574
2006
|
{
|
|
575
2007
|
href: isWaitlist ? "#" : ctaHref || "#",
|
|
576
2008
|
onClick: handleCtaClick,
|
|
577
2009
|
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
2010
|
},
|
|
579
2011
|
ctaText,
|
|
580
|
-
/* @__PURE__ */
|
|
581
|
-
), secondaryCtaText && secondaryCtaHref && /* @__PURE__ */
|
|
582
|
-
|
|
2012
|
+
/* @__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" })))
|
|
2013
|
+
), secondaryCtaText && secondaryCtaHref && /* @__PURE__ */ React21.createElement(
|
|
2014
|
+
Link5,
|
|
583
2015
|
{
|
|
584
2016
|
href: secondaryCtaHref,
|
|
585
2017
|
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
2018
|
},
|
|
587
2019
|
secondaryCtaText
|
|
588
|
-
)), showApps && appLogos && appLogos.length > 0 && /* @__PURE__ */
|
|
2020
|
+
)), 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
2021
|
Image2,
|
|
590
2022
|
{
|
|
591
2023
|
src: logo.src,
|
|
@@ -594,7 +2026,7 @@ var HeroSection = ({
|
|
|
594
2026
|
height: 28,
|
|
595
2027
|
className: "object-contain"
|
|
596
2028
|
}
|
|
597
|
-
))))))))), /* @__PURE__ */
|
|
2029
|
+
))))))))), /* @__PURE__ */ React21.createElement(
|
|
598
2030
|
WaitlistDialog,
|
|
599
2031
|
{
|
|
600
2032
|
isOpen: isWaitlistOpen,
|
|
@@ -604,12 +2036,12 @@ var HeroSection = ({
|
|
|
604
2036
|
};
|
|
605
2037
|
|
|
606
2038
|
// src/components/AppBento2.tsx
|
|
607
|
-
import
|
|
608
|
-
import { HugeiconsIcon as
|
|
2039
|
+
import React22, { useState as useState14, useEffect as useEffect9, useRef as useRef5 } from "react";
|
|
2040
|
+
import { HugeiconsIcon as HugeiconsIcon14 } from "@hugeicons/react";
|
|
609
2041
|
var AppBento2 = ({ tagline, headline, features }) => {
|
|
610
|
-
const [isAnimating, setIsAnimating] =
|
|
611
|
-
const titleRef =
|
|
612
|
-
|
|
2042
|
+
const [isAnimating, setIsAnimating] = useState14(false);
|
|
2043
|
+
const titleRef = useRef5(null);
|
|
2044
|
+
useEffect9(() => {
|
|
613
2045
|
const observer = new IntersectionObserver(
|
|
614
2046
|
([entry]) => {
|
|
615
2047
|
if (entry.isIntersecting) {
|
|
@@ -627,7 +2059,7 @@ var AppBento2 = ({ tagline, headline, features }) => {
|
|
|
627
2059
|
}
|
|
628
2060
|
return () => observer.disconnect();
|
|
629
2061
|
}, []);
|
|
630
|
-
return /* @__PURE__ */
|
|
2062
|
+
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
2063
|
"h2",
|
|
632
2064
|
{
|
|
633
2065
|
ref: titleRef,
|
|
@@ -635,7 +2067,7 @@ var AppBento2 = ({ tagline, headline, features }) => {
|
|
|
635
2067
|
style: isAnimating ? { animationIterationCount: 1 } : {}
|
|
636
2068
|
},
|
|
637
2069
|
headline
|
|
638
|
-
))), /* @__PURE__ */
|
|
2070
|
+
))), /* @__PURE__ */ React22.createElement("div", { className: "grid grid-cols-1 lg:grid-cols-6 gap-6" }, features.map((f, i) => {
|
|
639
2071
|
const isWhite = i === 0;
|
|
640
2072
|
const isBlack = i === 1;
|
|
641
2073
|
const isNeutral = i === 2;
|
|
@@ -657,36 +2089,36 @@ var AppBento2 = ({ tagline, headline, features }) => {
|
|
|
657
2089
|
const textColor = isBlack ? "text-white" : "text-black";
|
|
658
2090
|
const subTextColor = isBlack ? "text-neutral-300" : "text-neutral-600";
|
|
659
2091
|
const labelColor = isBlack ? "text-neutral-400" : "text-neutral-500";
|
|
660
|
-
return /* @__PURE__ */
|
|
2092
|
+
return /* @__PURE__ */ React22.createElement(
|
|
661
2093
|
"div",
|
|
662
2094
|
{
|
|
663
2095
|
key: i,
|
|
664
2096
|
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
2097
|
style: { boxShadow: getShadowStyle() }
|
|
666
2098
|
},
|
|
667
|
-
/* @__PURE__ */
|
|
2099
|
+
/* @__PURE__ */ React22.createElement(
|
|
668
2100
|
"div",
|
|
669
2101
|
{
|
|
670
2102
|
className: "absolute inset-0 pointer-events-none opacity-[0.03] z-0",
|
|
671
2103
|
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
2104
|
}
|
|
673
2105
|
),
|
|
674
|
-
isBlack && /* @__PURE__ */
|
|
675
|
-
/* @__PURE__ */
|
|
676
|
-
/* @__PURE__ */
|
|
2106
|
+
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" }),
|
|
2107
|
+
/* @__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 }))),
|
|
2108
|
+
/* @__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
2109
|
);
|
|
678
2110
|
})))));
|
|
679
2111
|
};
|
|
680
2112
|
|
|
681
2113
|
// src/components/FeatureScroll.tsx
|
|
682
|
-
import
|
|
2114
|
+
import React23, { useRef as useRef6, useState as useState15, useEffect as useEffect10 } from "react";
|
|
683
2115
|
import Image3 from "next/image";
|
|
684
|
-
import { HugeiconsIcon as
|
|
685
|
-
import { ArrowLeft01Icon, ArrowRight01Icon, Loading03Icon as
|
|
2116
|
+
import { HugeiconsIcon as HugeiconsIcon15 } from "@hugeicons/react";
|
|
2117
|
+
import { ArrowLeft01Icon as ArrowLeft01Icon2, ArrowRight01Icon as ArrowRight01Icon4, Loading03Icon as Loading03Icon6 } from "@hugeicons/core-free-icons";
|
|
686
2118
|
var FeatureCard = ({ feature, bgImage }) => {
|
|
687
|
-
const [isBgLoading, setIsBgLoading] =
|
|
688
|
-
const [isFgLoading, setIsFgLoading] =
|
|
689
|
-
return /* @__PURE__ */
|
|
2119
|
+
const [isBgLoading, setIsBgLoading] = useState15(true);
|
|
2120
|
+
const [isFgLoading, setIsFgLoading] = useState15(!!feature.image);
|
|
2121
|
+
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
2122
|
Image3,
|
|
691
2123
|
{
|
|
692
2124
|
src: bgImage,
|
|
@@ -699,7 +2131,7 @@ var FeatureCard = ({ feature, bgImage }) => {
|
|
|
699
2131
|
${isBgLoading ? "blur-xl scale-110" : "blur-0 scale-100"}
|
|
700
2132
|
`
|
|
701
2133
|
}
|
|
702
|
-
), /* @__PURE__ */
|
|
2134
|
+
), /* @__PURE__ */ React23.createElement(
|
|
703
2135
|
"div",
|
|
704
2136
|
{
|
|
705
2137
|
className: "absolute inset-0 w-full h-full pointer-events-none z-0 opacity-[0.25] mix-blend-overlay",
|
|
@@ -707,7 +2139,7 @@ var FeatureCard = ({ feature, bgImage }) => {
|
|
|
707
2139
|
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
2140
|
}
|
|
709
2141
|
}
|
|
710
|
-
), isFgLoading && feature.image && /* @__PURE__ */
|
|
2142
|
+
), 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
2143
|
Image3,
|
|
712
2144
|
{
|
|
713
2145
|
src: feature.image,
|
|
@@ -720,12 +2152,12 @@ var FeatureCard = ({ feature, bgImage }) => {
|
|
|
720
2152
|
${isFgLoading ? "opacity-0 blur-xl" : "opacity-100 blur-0"}
|
|
721
2153
|
`
|
|
722
2154
|
}
|
|
723
|
-
))), /* @__PURE__ */
|
|
2155
|
+
))), /* @__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
2156
|
};
|
|
725
2157
|
var FeatureScroll = ({ tagline, headline, features }) => {
|
|
726
|
-
const scrollRef =
|
|
727
|
-
const [canScrollLeft, setCanScrollLeft] =
|
|
728
|
-
const [canScrollRight, setCanScrollRight] =
|
|
2158
|
+
const scrollRef = useRef6(null);
|
|
2159
|
+
const [canScrollLeft, setCanScrollLeft] = useState15(false);
|
|
2160
|
+
const [canScrollRight, setCanScrollRight] = useState15(true);
|
|
729
2161
|
const checkScroll = () => {
|
|
730
2162
|
if (scrollRef.current) {
|
|
731
2163
|
const { scrollLeft, scrollWidth, clientWidth } = scrollRef.current;
|
|
@@ -733,7 +2165,7 @@ var FeatureScroll = ({ tagline, headline, features }) => {
|
|
|
733
2165
|
setCanScrollRight(scrollLeft < scrollWidth - clientWidth - 2);
|
|
734
2166
|
}
|
|
735
2167
|
};
|
|
736
|
-
|
|
2168
|
+
useEffect10(() => {
|
|
737
2169
|
checkScroll();
|
|
738
2170
|
window.addEventListener("resize", checkScroll);
|
|
739
2171
|
return () => window.removeEventListener("resize", checkScroll);
|
|
@@ -749,7 +2181,7 @@ var FeatureScroll = ({ tagline, headline, features }) => {
|
|
|
749
2181
|
"https://retinalabs.company/assets/images/bg_6.avif",
|
|
750
2182
|
"https://retinalabs.company/assets/images/bg_1.avif"
|
|
751
2183
|
];
|
|
752
|
-
return /* @__PURE__ */
|
|
2184
|
+
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
2185
|
"button",
|
|
754
2186
|
{
|
|
755
2187
|
onClick: () => scroll("left"),
|
|
@@ -757,8 +2189,8 @@ var FeatureScroll = ({ tagline, headline, features }) => {
|
|
|
757
2189
|
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
2190
|
"aria-label": "Previous feature"
|
|
759
2191
|
},
|
|
760
|
-
/* @__PURE__ */
|
|
761
|
-
), /* @__PURE__ */
|
|
2192
|
+
/* @__PURE__ */ React23.createElement(HugeiconsIcon15, { icon: ArrowLeft01Icon2, size: 20 })
|
|
2193
|
+
), /* @__PURE__ */ React23.createElement(
|
|
762
2194
|
"button",
|
|
763
2195
|
{
|
|
764
2196
|
onClick: () => scroll("right"),
|
|
@@ -766,57 +2198,57 @@ var FeatureScroll = ({ tagline, headline, features }) => {
|
|
|
766
2198
|
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
2199
|
"aria-label": "Next feature"
|
|
768
2200
|
},
|
|
769
|
-
/* @__PURE__ */
|
|
770
|
-
))), /* @__PURE__ */
|
|
2201
|
+
/* @__PURE__ */ React23.createElement(HugeiconsIcon15, { icon: ArrowRight01Icon4, size: 20 })
|
|
2202
|
+
))), /* @__PURE__ */ React23.createElement(
|
|
771
2203
|
"div",
|
|
772
2204
|
{
|
|
773
2205
|
ref: scrollRef,
|
|
774
2206
|
onScroll: checkScroll,
|
|
775
2207
|
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
2208
|
},
|
|
777
|
-
features.slice(0, 3).map((feature, idx) => /* @__PURE__ */
|
|
778
|
-
), /* @__PURE__ */
|
|
2209
|
+
features.slice(0, 3).map((feature, idx) => /* @__PURE__ */ React23.createElement(FeatureCard, { key: idx, feature, bgImage: bgImages[idx] }))
|
|
2210
|
+
), /* @__PURE__ */ React23.createElement("div", { className: "flex md:hidden items-center justify-center gap-4 mt-2" }, /* @__PURE__ */ React23.createElement(
|
|
779
2211
|
"button",
|
|
780
2212
|
{
|
|
781
2213
|
onClick: () => scroll("left"),
|
|
782
2214
|
disabled: !canScrollLeft,
|
|
783
2215
|
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
2216
|
},
|
|
785
|
-
/* @__PURE__ */
|
|
786
|
-
), /* @__PURE__ */
|
|
2217
|
+
/* @__PURE__ */ React23.createElement(HugeiconsIcon15, { icon: ArrowLeft01Icon2, size: 20 })
|
|
2218
|
+
), /* @__PURE__ */ React23.createElement(
|
|
787
2219
|
"button",
|
|
788
2220
|
{
|
|
789
2221
|
onClick: () => scroll("right"),
|
|
790
2222
|
disabled: !canScrollRight,
|
|
791
2223
|
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
2224
|
},
|
|
793
|
-
/* @__PURE__ */
|
|
2225
|
+
/* @__PURE__ */ React23.createElement(HugeiconsIcon15, { icon: ArrowRight01Icon4, size: 20 })
|
|
794
2226
|
))));
|
|
795
2227
|
};
|
|
796
2228
|
|
|
797
2229
|
// src/components/PlatformFeatures.tsx
|
|
798
|
-
import
|
|
799
|
-
import { HugeiconsIcon as
|
|
2230
|
+
import React24 from "react";
|
|
2231
|
+
import { HugeiconsIcon as HugeiconsIcon16 } from "@hugeicons/react";
|
|
800
2232
|
var PlatformFeatures = ({
|
|
801
2233
|
tagline,
|
|
802
2234
|
headline,
|
|
803
2235
|
description,
|
|
804
2236
|
features
|
|
805
2237
|
}) => {
|
|
806
|
-
return /* @__PURE__ */
|
|
2238
|
+
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
2239
|
"div",
|
|
808
2240
|
{
|
|
809
2241
|
key: idx,
|
|
810
2242
|
className: "flex flex-col group animate-in fade-in slide-in-from-bottom-4 duration-700 fill-mode-both",
|
|
811
2243
|
style: { animationDelay: feature.delay || "0ms" }
|
|
812
2244
|
},
|
|
813
|
-
/* @__PURE__ */
|
|
814
|
-
/* @__PURE__ */
|
|
2245
|
+
/* @__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))),
|
|
2246
|
+
/* @__PURE__ */ React24.createElement("div", null, /* @__PURE__ */ React24.createElement("p", { className: "text-[13px] leading-relaxed text-neutral-600 pr-4" }, feature.desc))
|
|
815
2247
|
)))));
|
|
816
2248
|
};
|
|
817
2249
|
|
|
818
2250
|
// src/components/ManagedDocument.tsx
|
|
819
|
-
import
|
|
2251
|
+
import React25, { useState as useState16, useEffect as useEffect11, useRef as useRef7 } from "react";
|
|
820
2252
|
var ManagedDocument = ({
|
|
821
2253
|
tagline,
|
|
822
2254
|
title,
|
|
@@ -824,9 +2256,9 @@ var ManagedDocument = ({
|
|
|
824
2256
|
contactText,
|
|
825
2257
|
contactEmail
|
|
826
2258
|
}) => {
|
|
827
|
-
const [isAnimating, setIsAnimating] =
|
|
828
|
-
const titleRef =
|
|
829
|
-
|
|
2259
|
+
const [isAnimating, setIsAnimating] = useState16(false);
|
|
2260
|
+
const titleRef = useRef7(null);
|
|
2261
|
+
useEffect11(() => {
|
|
830
2262
|
const observer = new IntersectionObserver(
|
|
831
2263
|
([entry]) => {
|
|
832
2264
|
if (entry.isIntersecting) {
|
|
@@ -846,7 +2278,7 @@ var ManagedDocument = ({
|
|
|
846
2278
|
}, []);
|
|
847
2279
|
return (
|
|
848
2280
|
// Outer layout wrapper (takes up available space, adds padding)
|
|
849
|
-
/* @__PURE__ */
|
|
2281
|
+
/* @__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
2282
|
"h1",
|
|
851
2283
|
{
|
|
852
2284
|
ref: titleRef,
|
|
@@ -854,7 +2286,7 @@ var ManagedDocument = ({
|
|
|
854
2286
|
style: isAnimating ? { animationIterationCount: 1 } : {}
|
|
855
2287
|
},
|
|
856
2288
|
title
|
|
857
|
-
)), sections.map((section, index) => /* @__PURE__ */
|
|
2289
|
+
)), 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
2290
|
"a",
|
|
859
2291
|
{
|
|
860
2292
|
href: `mailto:${contactEmail}`,
|
|
@@ -866,18 +2298,18 @@ var ManagedDocument = ({
|
|
|
866
2298
|
};
|
|
867
2299
|
|
|
868
2300
|
// src/components/ManagedContactBlock.tsx
|
|
869
|
-
import
|
|
870
|
-
import { HugeiconsIcon as
|
|
2301
|
+
import React26, { useState as useState17, useEffect as useEffect12 } from "react";
|
|
2302
|
+
import { HugeiconsIcon as HugeiconsIcon17 } from "@hugeicons/react";
|
|
871
2303
|
var SecureEmail = ({ user, domain, className }) => {
|
|
872
|
-
const [isMounted, setIsMounted] =
|
|
873
|
-
|
|
2304
|
+
const [isMounted, setIsMounted] = useState17(false);
|
|
2305
|
+
useEffect12(() => {
|
|
874
2306
|
setIsMounted(true);
|
|
875
2307
|
}, []);
|
|
876
2308
|
if (!isMounted) {
|
|
877
|
-
return /* @__PURE__ */
|
|
2309
|
+
return /* @__PURE__ */ React26.createElement("span", { className, style: { opacity: 0 } }, "Loading");
|
|
878
2310
|
}
|
|
879
2311
|
const email = `${user}@${domain}`;
|
|
880
|
-
return /* @__PURE__ */
|
|
2312
|
+
return /* @__PURE__ */ React26.createElement("a", { href: `mailto:${email}`, className }, email);
|
|
881
2313
|
};
|
|
882
2314
|
var ManagedContactBlock = ({
|
|
883
2315
|
tagline,
|
|
@@ -886,7 +2318,7 @@ var ManagedContactBlock = ({
|
|
|
886
2318
|
emails,
|
|
887
2319
|
socials
|
|
888
2320
|
}) => {
|
|
889
|
-
return /* @__PURE__ */
|
|
2321
|
+
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
2322
|
"div",
|
|
891
2323
|
{
|
|
892
2324
|
className: "absolute inset-0 pointer-events-none opacity-[0.03] z-0",
|
|
@@ -895,21 +2327,21 @@ var ManagedContactBlock = ({
|
|
|
895
2327
|
backgroundRepeat: "repeat"
|
|
896
2328
|
}
|
|
897
2329
|
}
|
|
898
|
-
), /* @__PURE__ */
|
|
2330
|
+
), /* @__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
2331
|
"a",
|
|
900
2332
|
{
|
|
901
2333
|
href: `tel:${company.phone.replace(/\s+/g, "")}`,
|
|
902
2334
|
className: "transition-colors hover:text-black"
|
|
903
2335
|
},
|
|
904
2336
|
company.phone
|
|
905
|
-
)))), emails && emails.length > 0 && /* @__PURE__ */
|
|
2337
|
+
)))), 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
2338
|
SecureEmail,
|
|
907
2339
|
{
|
|
908
2340
|
user: email.user,
|
|
909
2341
|
domain: email.domain,
|
|
910
2342
|
className: "text-neutral-600 transition-colors hover:text-black"
|
|
911
2343
|
}
|
|
912
|
-
))))), socials && socials.length > 0 && /* @__PURE__ */
|
|
2344
|
+
))))), 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
2345
|
"a",
|
|
914
2346
|
{
|
|
915
2347
|
key: idx,
|
|
@@ -919,27 +2351,27 @@ var ManagedContactBlock = ({
|
|
|
919
2351
|
className: "flex items-center gap-3 transition-colors group text-neutral-600 hover:text-black",
|
|
920
2352
|
"aria-label": social.label
|
|
921
2353
|
},
|
|
922
|
-
/* @__PURE__ */
|
|
923
|
-
/* @__PURE__ */
|
|
2354
|
+
/* @__PURE__ */ React26.createElement(HugeiconsIcon17, { icon: social.icon, size: 18 }),
|
|
2355
|
+
/* @__PURE__ */ React26.createElement("span", { className: "text-[13px]" }, social.label)
|
|
924
2356
|
)))))))));
|
|
925
2357
|
};
|
|
926
2358
|
|
|
927
2359
|
// src/components/ManagedPricingBlock.tsx
|
|
928
|
-
import
|
|
929
|
-
import
|
|
2360
|
+
import React27, { useState as useState18, useEffect as useEffect13, useRef as useRef8 } from "react";
|
|
2361
|
+
import Link6 from "next/link";
|
|
930
2362
|
import Image4 from "next/image";
|
|
931
|
-
var CheckIcon = ({ className = "" }) => /* @__PURE__ */
|
|
932
|
-
var CrossIcon = ({ className = "" }) => /* @__PURE__ */
|
|
2363
|
+
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" }));
|
|
2364
|
+
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
2365
|
var ManagedPricingBlock = ({
|
|
934
2366
|
tagline,
|
|
935
2367
|
title,
|
|
936
2368
|
plans = [],
|
|
937
2369
|
tabs
|
|
938
2370
|
}) => {
|
|
939
|
-
const [isAnimating, setIsAnimating] =
|
|
940
|
-
const [activeTabIndex, setActiveTabIndex] =
|
|
941
|
-
const titleRef =
|
|
942
|
-
|
|
2371
|
+
const [isAnimating, setIsAnimating] = useState18(false);
|
|
2372
|
+
const [activeTabIndex, setActiveTabIndex] = useState18(0);
|
|
2373
|
+
const titleRef = useRef8(null);
|
|
2374
|
+
useEffect13(() => {
|
|
943
2375
|
const observer = new IntersectionObserver(
|
|
944
2376
|
([entry]) => {
|
|
945
2377
|
if (entry.isIntersecting) {
|
|
@@ -959,7 +2391,7 @@ var ManagedPricingBlock = ({
|
|
|
959
2391
|
}, []);
|
|
960
2392
|
const hasTabs = tabs && tabs.length > 0;
|
|
961
2393
|
const currentPlans = hasTabs ? tabs[activeTabIndex].plans : plans;
|
|
962
|
-
return /* @__PURE__ */
|
|
2394
|
+
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
2395
|
"h1",
|
|
964
2396
|
{
|
|
965
2397
|
ref: titleRef,
|
|
@@ -967,9 +2399,9 @@ var ManagedPricingBlock = ({
|
|
|
967
2399
|
style: isAnimating ? { animationIterationCount: 1 } : {}
|
|
968
2400
|
},
|
|
969
2401
|
title
|
|
970
|
-
)), hasTabs && /* @__PURE__ */
|
|
2402
|
+
)), 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
2403
|
const isActive = activeTabIndex === idx;
|
|
972
|
-
return /* @__PURE__ */
|
|
2404
|
+
return /* @__PURE__ */ React27.createElement(
|
|
973
2405
|
"button",
|
|
974
2406
|
{
|
|
975
2407
|
key: idx,
|
|
@@ -978,19 +2410,19 @@ var ManagedPricingBlock = ({
|
|
|
978
2410
|
},
|
|
979
2411
|
tab.label
|
|
980
2412
|
);
|
|
981
|
-
}))), /* @__PURE__ */
|
|
2413
|
+
}))), /* @__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
2414
|
"div",
|
|
983
2415
|
{
|
|
984
2416
|
key: `${activeTabIndex}-${planIdx}`,
|
|
985
2417
|
className: `bg-white rounded-3xl p-6 flex flex-col relative overflow-hidden transition-all duration-300 ${plan.isPremium ? "" : ""}`
|
|
986
2418
|
},
|
|
987
|
-
/* @__PURE__ */
|
|
2419
|
+
/* @__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
2420
|
"div",
|
|
989
2421
|
{
|
|
990
2422
|
key: logoIdx,
|
|
991
2423
|
className: "relative w-5 h-5 overflow-hidden flex items-center justify-center shrink-0"
|
|
992
2424
|
},
|
|
993
|
-
/* @__PURE__ */
|
|
2425
|
+
/* @__PURE__ */ React27.createElement(
|
|
994
2426
|
Image4,
|
|
995
2427
|
{
|
|
996
2428
|
src: logo.src,
|
|
@@ -1001,28 +2433,28 @@ var ManagedPricingBlock = ({
|
|
|
1001
2433
|
}
|
|
1002
2434
|
)
|
|
1003
2435
|
)))),
|
|
1004
|
-
plan.isPremium ? /* @__PURE__ */
|
|
1005
|
-
|
|
2436
|
+
plan.isPremium ? /* @__PURE__ */ React27.createElement(ThreeDButton, { href: plan.ctaHref, className: "mb-6 w-full" }, plan.ctaText) : /* @__PURE__ */ React27.createElement(
|
|
2437
|
+
Link6,
|
|
1006
2438
|
{
|
|
1007
2439
|
href: plan.ctaHref,
|
|
1008
2440
|
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
2441
|
},
|
|
1010
2442
|
plan.ctaText
|
|
1011
2443
|
),
|
|
1012
|
-
/* @__PURE__ */
|
|
2444
|
+
/* @__PURE__ */ React27.createElement("div", { className: "flex flex-col gap-3" }, plan.features.map((feature, featureIdx) => {
|
|
1013
2445
|
const isAvailable = feature.value !== false;
|
|
1014
2446
|
const valueText = typeof feature.value === "string" ? feature.value : "";
|
|
1015
|
-
return /* @__PURE__ */
|
|
2447
|
+
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
2448
|
}))
|
|
1017
2449
|
)))));
|
|
1018
2450
|
};
|
|
1019
2451
|
|
|
1020
2452
|
// src/components/ManagedBoardBlock.tsx
|
|
1021
|
-
import
|
|
2453
|
+
import React28 from "react";
|
|
1022
2454
|
import Image5 from "next/image";
|
|
1023
|
-
import { HugeiconsIcon as
|
|
2455
|
+
import { HugeiconsIcon as HugeiconsIcon18 } from "@hugeicons/react";
|
|
1024
2456
|
import { TwitterIcon, LinkedinIcon } from "@hugeicons/core-free-icons";
|
|
1025
|
-
var MemberSocialLink = ({ href, icon, label, name }) => /* @__PURE__ */
|
|
2457
|
+
var MemberSocialLink = ({ href, icon, label, name }) => /* @__PURE__ */ React28.createElement(
|
|
1026
2458
|
"a",
|
|
1027
2459
|
{
|
|
1028
2460
|
href,
|
|
@@ -1031,7 +2463,7 @@ var MemberSocialLink = ({ href, icon, label, name }) => /* @__PURE__ */ React15.
|
|
|
1031
2463
|
className: "text-neutral-400 hover:text-black transition-colors",
|
|
1032
2464
|
"aria-label": `${name} on ${label}`
|
|
1033
2465
|
},
|
|
1034
|
-
/* @__PURE__ */
|
|
2466
|
+
/* @__PURE__ */ React28.createElement(HugeiconsIcon18, { icon, size: 16 })
|
|
1035
2467
|
);
|
|
1036
2468
|
var ManagedBoardBlock = ({
|
|
1037
2469
|
tagline,
|
|
@@ -1040,7 +2472,7 @@ var ManagedBoardBlock = ({
|
|
|
1040
2472
|
contactText,
|
|
1041
2473
|
contactEmail
|
|
1042
2474
|
}) => {
|
|
1043
|
-
return /* @__PURE__ */
|
|
2475
|
+
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
2476
|
"div",
|
|
1045
2477
|
{
|
|
1046
2478
|
className: "absolute inset-0 pointer-events-none opacity-[0.03] z-0",
|
|
@@ -1049,7 +2481,7 @@ var ManagedBoardBlock = ({
|
|
|
1049
2481
|
backgroundRepeat: "repeat"
|
|
1050
2482
|
}
|
|
1051
2483
|
}
|
|
1052
|
-
), /* @__PURE__ */
|
|
2484
|
+
), /* @__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
2485
|
Image5,
|
|
1054
2486
|
{
|
|
1055
2487
|
src: member.imageSrc,
|
|
@@ -1058,7 +2490,7 @@ var ManagedBoardBlock = ({
|
|
|
1058
2490
|
sizes: "(max-width: 768px) 56px, 64px",
|
|
1059
2491
|
className: "object-cover grayscale opacity-100 transition-opacity"
|
|
1060
2492
|
}
|
|
1061
|
-
)), /* @__PURE__ */
|
|
2493
|
+
)), /* @__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
2494
|
MemberSocialLink,
|
|
1063
2495
|
{
|
|
1064
2496
|
href: `https://x.com/${member.twitterHandle}`,
|
|
@@ -1066,7 +2498,7 @@ var ManagedBoardBlock = ({
|
|
|
1066
2498
|
label: "X",
|
|
1067
2499
|
name: member.name
|
|
1068
2500
|
}
|
|
1069
|
-
), member.linkedinHandle && member.linkedinHandle.length > 0 && /* @__PURE__ */
|
|
2501
|
+
), member.linkedinHandle && member.linkedinHandle.length > 0 && /* @__PURE__ */ React28.createElement(
|
|
1070
2502
|
MemberSocialLink,
|
|
1071
2503
|
{
|
|
1072
2504
|
href: member.linkedinHandle,
|
|
@@ -1074,85 +2506,28 @@ var ManagedBoardBlock = ({
|
|
|
1074
2506
|
label: "LinkedIn",
|
|
1075
2507
|
name: member.name
|
|
1076
2508
|
}
|
|
1077
|
-
))))))), (contactText || contactEmail) && /* @__PURE__ */
|
|
2509
|
+
))))))), (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
2510
|
};
|
|
1079
2511
|
|
|
1080
2512
|
// src/components/ManagedNotFoundBlock.tsx
|
|
1081
|
-
import
|
|
2513
|
+
import React29 from "react";
|
|
1082
2514
|
var ManagedNotFoundBlock = ({
|
|
1083
2515
|
title = "404 - Page Not Found",
|
|
1084
2516
|
description = "The page you are looking for does not exist or has been moved."
|
|
1085
2517
|
}) => {
|
|
1086
|
-
return /* @__PURE__ */
|
|
2518
|
+
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
2519
|
"svg",
|
|
1088
2520
|
{
|
|
1089
2521
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1090
2522
|
viewBox: "0 0 24 24",
|
|
1091
2523
|
className: "w-12 h-12 fill-neutral-100"
|
|
1092
2524
|
},
|
|
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
|
-
);
|
|
2525
|
+
/* @__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" })
|
|
2526
|
+
)), /* @__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
2527
|
};
|
|
1153
2528
|
|
|
1154
2529
|
// src/components/ManagedNewsletterSplitBlock.tsx
|
|
1155
|
-
import
|
|
2530
|
+
import React30 from "react";
|
|
1156
2531
|
import Image6 from "next/image";
|
|
1157
2532
|
var ManagedNewsletterSplitBlock = ({
|
|
1158
2533
|
tagline,
|
|
@@ -1166,7 +2541,7 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1166
2541
|
ctaHref = "/contact",
|
|
1167
2542
|
children
|
|
1168
2543
|
}) => {
|
|
1169
|
-
return /* @__PURE__ */
|
|
2544
|
+
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
2545
|
Image6,
|
|
1171
2546
|
{
|
|
1172
2547
|
src: imageSrc,
|
|
@@ -1176,7 +2551,7 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1176
2551
|
className: "object-cover object-top grayscale opacity-60",
|
|
1177
2552
|
quality: 100
|
|
1178
2553
|
}
|
|
1179
|
-
), /* @__PURE__ */
|
|
2554
|
+
), /* @__PURE__ */ React30.createElement(
|
|
1180
2555
|
"div",
|
|
1181
2556
|
{
|
|
1182
2557
|
className: "absolute inset-0 z-10 pointer-events-none",
|
|
@@ -1184,7 +2559,7 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1184
2559
|
background: "linear-gradient(to right, rgba(255,255,255,0) 30%, #ffffff 100%)"
|
|
1185
2560
|
}
|
|
1186
2561
|
}
|
|
1187
|
-
), /* @__PURE__ */
|
|
2562
|
+
), /* @__PURE__ */ React30.createElement(
|
|
1188
2563
|
"div",
|
|
1189
2564
|
{
|
|
1190
2565
|
className: "absolute inset-x-0 bottom-0 h-40 z-10 pointer-events-none",
|
|
@@ -1192,7 +2567,7 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1192
2567
|
background: "linear-gradient(to bottom, rgba(255,255,255,0) 0%, #ffffff 100%)"
|
|
1193
2568
|
}
|
|
1194
2569
|
}
|
|
1195
|
-
)), /* @__PURE__ */
|
|
2570
|
+
)), /* @__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
2571
|
"div",
|
|
1197
2572
|
{
|
|
1198
2573
|
className: "absolute inset-0 pointer-events-none opacity-[0.03] z-0",
|
|
@@ -1201,7 +2576,7 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1201
2576
|
backgroundRepeat: "repeat"
|
|
1202
2577
|
}
|
|
1203
2578
|
}
|
|
1204
|
-
), /* @__PURE__ */
|
|
2579
|
+
), /* @__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
2580
|
ThreeDButton,
|
|
1206
2581
|
{
|
|
1207
2582
|
href: ctaHref,
|
|
@@ -1212,14 +2587,14 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
1212
2587
|
};
|
|
1213
2588
|
|
|
1214
2589
|
// src/components/PortfolioHero.tsx
|
|
1215
|
-
import
|
|
1216
|
-
import
|
|
2590
|
+
import React31, { useEffect as useEffect14, useRef as useRef9 } from "react";
|
|
2591
|
+
import Link7 from "next/link";
|
|
1217
2592
|
import Image7 from "next/image";
|
|
1218
|
-
import { HugeiconsIcon as
|
|
1219
|
-
import { ArrowRight01Icon as
|
|
2593
|
+
import { HugeiconsIcon as HugeiconsIcon19 } from "@hugeicons/react";
|
|
2594
|
+
import { ArrowRight01Icon as ArrowRight01Icon5 } from "@hugeicons/core-free-icons";
|
|
1220
2595
|
var useScrollAnimation = () => {
|
|
1221
|
-
const elementRef =
|
|
1222
|
-
|
|
2596
|
+
const elementRef = useRef9(null);
|
|
2597
|
+
useEffect14(() => {
|
|
1223
2598
|
const el = elementRef.current;
|
|
1224
2599
|
if (!el) return;
|
|
1225
2600
|
const observer = new IntersectionObserver(
|
|
@@ -1255,13 +2630,13 @@ var PortfolioHero = ({
|
|
|
1255
2630
|
secondaryCtaHref
|
|
1256
2631
|
}) => {
|
|
1257
2632
|
const heroContentRef = useScrollAnimation();
|
|
1258
|
-
return /* @__PURE__ */
|
|
2633
|
+
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
2634
|
"div",
|
|
1260
2635
|
{
|
|
1261
2636
|
ref: heroContentRef,
|
|
1262
2637
|
className: "w-full opacity-0 translate-y-5 transition-all duration-1000 ease-out relative z-10"
|
|
1263
2638
|
},
|
|
1264
|
-
/* @__PURE__ */
|
|
2639
|
+
/* @__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
2640
|
Image7,
|
|
1266
2641
|
{
|
|
1267
2642
|
src: imageSrc,
|
|
@@ -1272,7 +2647,7 @@ var PortfolioHero = ({
|
|
|
1272
2647
|
sizes: "(max-width: 640px) 80px, 128px",
|
|
1273
2648
|
quality: 100
|
|
1274
2649
|
}
|
|
1275
|
-
)), /* @__PURE__ */
|
|
2650
|
+
)), /* @__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
2651
|
"a",
|
|
1277
2652
|
{
|
|
1278
2653
|
href: socialLinkHref,
|
|
@@ -1282,31 +2657,31 @@ var PortfolioHero = ({
|
|
|
1282
2657
|
},
|
|
1283
2658
|
socialLinkText
|
|
1284
2659
|
))),
|
|
1285
|
-
/* @__PURE__ */
|
|
1286
|
-
/* @__PURE__ */
|
|
2660
|
+
/* @__PURE__ */ React31.createElement("p", { className: "text-[13px] leading-[1.8] max-w-4xl mb-12 text-neutral-600" }, bio),
|
|
2661
|
+
/* @__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
2662
|
ThreeDButton,
|
|
1288
2663
|
{
|
|
1289
2664
|
href: primaryCtaHref,
|
|
1290
2665
|
className: "py-3 tracking-widest text-[11px]"
|
|
1291
2666
|
},
|
|
1292
2667
|
primaryCtaText
|
|
1293
|
-
)), secondaryCtaText && secondaryCtaHref && /* @__PURE__ */
|
|
1294
|
-
|
|
2668
|
+
)), secondaryCtaText && secondaryCtaHref && /* @__PURE__ */ React31.createElement(
|
|
2669
|
+
Link7,
|
|
1295
2670
|
{
|
|
1296
2671
|
href: secondaryCtaHref,
|
|
1297
2672
|
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
2673
|
},
|
|
1299
2674
|
secondaryCtaText,
|
|
1300
|
-
/* @__PURE__ */
|
|
2675
|
+
/* @__PURE__ */ React31.createElement(HugeiconsIcon19, { icon: ArrowRight01Icon5, size: 16 })
|
|
1301
2676
|
))
|
|
1302
2677
|
));
|
|
1303
2678
|
};
|
|
1304
2679
|
|
|
1305
2680
|
// src/components/GifFeatureCard.tsx
|
|
1306
|
-
import
|
|
2681
|
+
import React32, { useState as useState19 } from "react";
|
|
1307
2682
|
import Image8 from "next/image";
|
|
1308
|
-
import { HugeiconsIcon as
|
|
1309
|
-
import { Loading03Icon as
|
|
2683
|
+
import { HugeiconsIcon as HugeiconsIcon20 } from "@hugeicons/react";
|
|
2684
|
+
import { Loading03Icon as Loading03Icon7 } from "@hugeicons/core-free-icons";
|
|
1310
2685
|
var GifFeatureCard = ({
|
|
1311
2686
|
gifSrc,
|
|
1312
2687
|
title,
|
|
@@ -1314,20 +2689,20 @@ var GifFeatureCard = ({
|
|
|
1314
2689
|
alt = "Feature animation",
|
|
1315
2690
|
className = "aspect-video"
|
|
1316
2691
|
}) => {
|
|
1317
|
-
const [isLoading, setIsLoading] =
|
|
1318
|
-
return /* @__PURE__ */
|
|
1319
|
-
|
|
2692
|
+
const [isLoading, setIsLoading] = useState19(true);
|
|
2693
|
+
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(
|
|
2694
|
+
HugeiconsIcon20,
|
|
1320
2695
|
{
|
|
1321
|
-
icon:
|
|
2696
|
+
icon: Loading03Icon7,
|
|
1322
2697
|
size: 32,
|
|
1323
2698
|
className: "animate-spin text-white"
|
|
1324
2699
|
}
|
|
1325
|
-
)), /* @__PURE__ */
|
|
2700
|
+
)), /* @__PURE__ */ React32.createElement(
|
|
1326
2701
|
"div",
|
|
1327
2702
|
{
|
|
1328
2703
|
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
2704
|
},
|
|
1330
|
-
/* @__PURE__ */
|
|
2705
|
+
/* @__PURE__ */ React32.createElement(
|
|
1331
2706
|
Image8,
|
|
1332
2707
|
{
|
|
1333
2708
|
src: gifSrc,
|
|
@@ -1338,16 +2713,16 @@ var GifFeatureCard = ({
|
|
|
1338
2713
|
className: "object-cover object-center pointer-events-none"
|
|
1339
2714
|
}
|
|
1340
2715
|
)
|
|
1341
|
-
), /* @__PURE__ */
|
|
2716
|
+
), /* @__PURE__ */ React32.createElement(
|
|
1342
2717
|
"div",
|
|
1343
2718
|
{
|
|
1344
2719
|
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
2720
|
}
|
|
1346
|
-
), /* @__PURE__ */
|
|
2721
|
+
), /* @__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
2722
|
};
|
|
1348
2723
|
|
|
1349
2724
|
// src/components/MedicalFeatureStatsBlock.tsx
|
|
1350
|
-
import
|
|
2725
|
+
import React33, { useState as useState20, useEffect as useEffect15, useRef as useRef10 } from "react";
|
|
1351
2726
|
import Image9 from "next/image";
|
|
1352
2727
|
var MedicalFeatureStatsBlock = ({
|
|
1353
2728
|
bottomHeadline,
|
|
@@ -1356,9 +2731,9 @@ var MedicalFeatureStatsBlock = ({
|
|
|
1356
2731
|
trustText,
|
|
1357
2732
|
stats
|
|
1358
2733
|
}) => {
|
|
1359
|
-
const [isAnimating, setIsAnimating] =
|
|
1360
|
-
const titleRef =
|
|
1361
|
-
|
|
2734
|
+
const [isAnimating, setIsAnimating] = useState20(false);
|
|
2735
|
+
const titleRef = useRef10(null);
|
|
2736
|
+
useEffect15(() => {
|
|
1362
2737
|
const observer = new IntersectionObserver(
|
|
1363
2738
|
([entry]) => {
|
|
1364
2739
|
if (entry.isIntersecting) {
|
|
@@ -1376,7 +2751,7 @@ var MedicalFeatureStatsBlock = ({
|
|
|
1376
2751
|
}
|
|
1377
2752
|
return () => observer.disconnect();
|
|
1378
2753
|
}, []);
|
|
1379
|
-
return /* @__PURE__ */
|
|
2754
|
+
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
2755
|
"h2",
|
|
1381
2756
|
{
|
|
1382
2757
|
ref: titleRef,
|
|
@@ -1384,7 +2759,7 @@ var MedicalFeatureStatsBlock = ({
|
|
|
1384
2759
|
style: isAnimating ? { animationIterationCount: 1 } : {}
|
|
1385
2760
|
},
|
|
1386
2761
|
bottomHeadline
|
|
1387
|
-
), /* @__PURE__ */
|
|
2762
|
+
), /* @__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
2763
|
Image9,
|
|
1389
2764
|
{
|
|
1390
2765
|
src,
|
|
@@ -1393,17 +2768,17 @@ var MedicalFeatureStatsBlock = ({
|
|
|
1393
2768
|
sizes: "48px",
|
|
1394
2769
|
className: "object-cover"
|
|
1395
2770
|
}
|
|
1396
|
-
)))), /* @__PURE__ */
|
|
2771
|
+
)))), /* @__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
2772
|
};
|
|
1398
2773
|
|
|
1399
2774
|
// src/components/ConsultantShowcase.tsx
|
|
1400
|
-
import
|
|
2775
|
+
import React34, { useState as useState21 } from "react";
|
|
1401
2776
|
import Image10 from "next/image";
|
|
1402
|
-
import { HugeiconsIcon as
|
|
1403
|
-
import { Loading03Icon as
|
|
2777
|
+
import { HugeiconsIcon as HugeiconsIcon21 } from "@hugeicons/react";
|
|
2778
|
+
import { Loading03Icon as Loading03Icon8 } from "@hugeicons/core-free-icons";
|
|
1404
2779
|
var ImageWithLoader = ({ src, alt, className, sizes, priority = false }) => {
|
|
1405
|
-
const [isLoading, setIsLoading] =
|
|
1406
|
-
return /* @__PURE__ */
|
|
2780
|
+
const [isLoading, setIsLoading] = useState21(true);
|
|
2781
|
+
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
2782
|
Image10,
|
|
1408
2783
|
{
|
|
1409
2784
|
src,
|
|
@@ -1422,9 +2797,9 @@ var ImageWithLoader = ({ src, alt, className, sizes, priority = false }) => {
|
|
|
1422
2797
|
var ConsultantShowcase = ({
|
|
1423
2798
|
profiles
|
|
1424
2799
|
}) => {
|
|
1425
|
-
const [currentIndex, setCurrentIndex] =
|
|
1426
|
-
const [touchStart, setTouchStart] =
|
|
1427
|
-
const [touchEnd, setTouchEnd] =
|
|
2800
|
+
const [currentIndex, setCurrentIndex] = useState21(0);
|
|
2801
|
+
const [touchStart, setTouchStart] = useState21(null);
|
|
2802
|
+
const [touchEnd, setTouchEnd] = useState21(null);
|
|
1428
2803
|
const nextSlide = () => {
|
|
1429
2804
|
setCurrentIndex((prev) => prev === profiles.length - 1 ? 0 : prev + 1);
|
|
1430
2805
|
};
|
|
@@ -1449,7 +2824,7 @@ var ConsultantShowcase = ({
|
|
|
1449
2824
|
}
|
|
1450
2825
|
};
|
|
1451
2826
|
if (!profiles || profiles.length === 0) return null;
|
|
1452
|
-
return /* @__PURE__ */
|
|
2827
|
+
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
2828
|
"div",
|
|
1454
2829
|
{
|
|
1455
2830
|
className: "relative w-full h-100 md:h-112.5 rounded-4xl overflow-hidden bg-neutral-900 group select-none",
|
|
@@ -1459,13 +2834,13 @@ var ConsultantShowcase = ({
|
|
|
1459
2834
|
},
|
|
1460
2835
|
profiles.map((profile, idx) => {
|
|
1461
2836
|
const isActive = idx === currentIndex;
|
|
1462
|
-
return /* @__PURE__ */
|
|
2837
|
+
return /* @__PURE__ */ React34.createElement(
|
|
1463
2838
|
"div",
|
|
1464
2839
|
{
|
|
1465
2840
|
key: profile.id,
|
|
1466
2841
|
className: `absolute inset-0 transition-opacity duration-700 ease-in-out ${isActive ? "opacity-100 z-10" : "opacity-0 z-0 pointer-events-none"}`
|
|
1467
2842
|
},
|
|
1468
|
-
/* @__PURE__ */
|
|
2843
|
+
/* @__PURE__ */ React34.createElement(
|
|
1469
2844
|
ImageWithLoader,
|
|
1470
2845
|
{
|
|
1471
2846
|
src: profile.imageSrc,
|
|
@@ -1473,14 +2848,14 @@ var ConsultantShowcase = ({
|
|
|
1473
2848
|
priority: idx === 0
|
|
1474
2849
|
}
|
|
1475
2850
|
),
|
|
1476
|
-
/* @__PURE__ */
|
|
1477
|
-
/* @__PURE__ */
|
|
1478
|
-
/* @__PURE__ */
|
|
2851
|
+
/* @__PURE__ */ React34.createElement("div", { className: "absolute inset-0 bg-black/20 z-10 pointer-events-none" }),
|
|
2852
|
+
/* @__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" }),
|
|
2853
|
+
/* @__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
2854
|
);
|
|
1480
2855
|
}),
|
|
1481
|
-
/* @__PURE__ */
|
|
1482
|
-
/* @__PURE__ */
|
|
1483
|
-
/* @__PURE__ */
|
|
2856
|
+
/* @__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" }),
|
|
2857
|
+
/* @__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" }),
|
|
2858
|
+
/* @__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
2859
|
"button",
|
|
1485
2860
|
{
|
|
1486
2861
|
key: idx,
|
|
@@ -1493,13 +2868,13 @@ var ConsultantShowcase = ({
|
|
|
1493
2868
|
};
|
|
1494
2869
|
|
|
1495
2870
|
// src/components/ContentGridBlock.tsx
|
|
1496
|
-
import
|
|
2871
|
+
import React35, { useState as useState22 } from "react";
|
|
1497
2872
|
import Image11 from "next/image";
|
|
1498
|
-
import { HugeiconsIcon as
|
|
1499
|
-
import { Loading03Icon as
|
|
2873
|
+
import { HugeiconsIcon as HugeiconsIcon22 } from "@hugeicons/react";
|
|
2874
|
+
import { Loading03Icon as Loading03Icon9 } from "@hugeicons/core-free-icons";
|
|
1500
2875
|
var ImageWithLoader2 = ({ src, alt, className, sizes }) => {
|
|
1501
|
-
const [isLoading, setIsLoading] =
|
|
1502
|
-
return /* @__PURE__ */
|
|
2876
|
+
const [isLoading, setIsLoading] = useState22(true);
|
|
2877
|
+
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
2878
|
Image11,
|
|
1504
2879
|
{
|
|
1505
2880
|
src,
|
|
@@ -1521,30 +2896,30 @@ var ContentGridBlock = ({
|
|
|
1521
2896
|
middleBottomCard,
|
|
1522
2897
|
rightCards
|
|
1523
2898
|
}) => {
|
|
1524
|
-
return /* @__PURE__ */
|
|
2899
|
+
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
2900
|
ImageWithLoader2,
|
|
1526
2901
|
{
|
|
1527
2902
|
src: card.bgImageSrc,
|
|
1528
2903
|
alt: card.title,
|
|
1529
2904
|
className: "absolute inset-0 w-full h-full"
|
|
1530
2905
|
}
|
|
1531
|
-
), /* @__PURE__ */
|
|
2906
|
+
), /* @__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
2907
|
};
|
|
1533
2908
|
|
|
1534
2909
|
// src/components/ManagedProjectsBlock.tsx
|
|
1535
|
-
import
|
|
1536
|
-
import
|
|
2910
|
+
import React36 from "react";
|
|
2911
|
+
import Link8 from "next/link";
|
|
1537
2912
|
var GridSection = ({
|
|
1538
2913
|
children,
|
|
1539
2914
|
isLast = false,
|
|
1540
2915
|
className = "py-8 md:py-10"
|
|
1541
|
-
}) => /* @__PURE__ */
|
|
2916
|
+
}) => /* @__PURE__ */ React36.createElement("div", { className: `relative px-5 md:px-12 ${className} ${!isLast ? "" : ""}` }, children);
|
|
1542
2917
|
var ManagedProjectsBlock = ({
|
|
1543
2918
|
tagline,
|
|
1544
2919
|
title,
|
|
1545
2920
|
projects
|
|
1546
2921
|
}) => {
|
|
1547
|
-
return /* @__PURE__ */
|
|
2922
|
+
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
2923
|
"div",
|
|
1549
2924
|
{
|
|
1550
2925
|
className: "absolute inset-0 pointer-events-none opacity-[0.03] z-0",
|
|
@@ -1553,10 +2928,10 @@ var ManagedProjectsBlock = ({
|
|
|
1553
2928
|
backgroundRepeat: "repeat"
|
|
1554
2929
|
}
|
|
1555
2930
|
}
|
|
1556
|
-
), /* @__PURE__ */
|
|
2931
|
+
), /* @__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
2932
|
const isLast = index === projects.length - 1;
|
|
1558
|
-
const projectContent = /* @__PURE__ */
|
|
1559
|
-
return /* @__PURE__ */
|
|
2933
|
+
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));
|
|
2934
|
+
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
2935
|
}))));
|
|
1561
2936
|
};
|
|
1562
2937
|
export {
|
|
@@ -1578,12 +2953,22 @@ export {
|
|
|
1578
2953
|
ManagedProjectsBlock,
|
|
1579
2954
|
ManagedToaster,
|
|
1580
2955
|
MedicalFeatureStatsBlock,
|
|
2956
|
+
MobileNav,
|
|
1581
2957
|
NumberInput,
|
|
1582
2958
|
PageSpinner,
|
|
2959
|
+
PipleAuth,
|
|
1583
2960
|
PlatformFeatures,
|
|
1584
2961
|
PortfolioHero,
|
|
1585
2962
|
TextInput,
|
|
1586
2963
|
ThreeDActionButton,
|
|
1587
2964
|
ThreeDButton,
|
|
2965
|
+
UniversalCardPage,
|
|
2966
|
+
UniversalErrorView,
|
|
2967
|
+
UniversalHomeView,
|
|
2968
|
+
UniversalOrganizationPage,
|
|
2969
|
+
UniversalProfilePage,
|
|
2970
|
+
UniversalProfileSettings,
|
|
2971
|
+
UniversalTransactionPage,
|
|
2972
|
+
UniversalWalletPage,
|
|
1588
2973
|
WaitlistDialog
|
|
1589
2974
|
};
|