@retinalabsllc/zairusjs 16.0.70 → 16.0.80
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 +78 -2
- package/dist/index.d.ts +78 -2
- package/dist/index.js +385 -25
- package/dist/index.mjs +396 -25
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -67,7 +67,7 @@ interface PipleAuthProps {
|
|
|
67
67
|
firstName?: string;
|
|
68
68
|
lastName?: string;
|
|
69
69
|
organizationName?: string;
|
|
70
|
-
|
|
70
|
+
accountType?: "INDIVIDUAL" | "ORGANIZATION";
|
|
71
71
|
mode: AuthMode;
|
|
72
72
|
recaptchaToken?: string;
|
|
73
73
|
}) => Promise<{
|
|
@@ -972,4 +972,80 @@ interface UniversalBuyCryptoPageProps {
|
|
|
972
972
|
}
|
|
973
973
|
declare const UniversalBuyCryptoPage: React.FC<UniversalBuyCryptoPageProps>;
|
|
974
974
|
|
|
975
|
-
|
|
975
|
+
interface UniversalDepartment {
|
|
976
|
+
id: string;
|
|
977
|
+
name: string;
|
|
978
|
+
totalMembers: number;
|
|
979
|
+
avatars: string[];
|
|
980
|
+
}
|
|
981
|
+
interface UniversalDepartmentsPageProps {
|
|
982
|
+
headerTitle: string;
|
|
983
|
+
headerDescription: string;
|
|
984
|
+
departments: UniversalDepartment[];
|
|
985
|
+
isLoading: boolean;
|
|
986
|
+
currentPage: number;
|
|
987
|
+
totalPages: number;
|
|
988
|
+
onPageChange: (page: number) => void;
|
|
989
|
+
onDepartmentClick: (departmentId: string) => void;
|
|
990
|
+
}
|
|
991
|
+
declare const UniversalDepartmentsPage: React.FC<UniversalDepartmentsPageProps>;
|
|
992
|
+
|
|
993
|
+
interface UniversalMember {
|
|
994
|
+
id: string;
|
|
995
|
+
userId: string;
|
|
996
|
+
name: string;
|
|
997
|
+
avatarUrl?: string | null;
|
|
998
|
+
status: 'ACTIVE' | 'BUSY' | 'AWAY' | 'OFFLINE' | string;
|
|
999
|
+
role: string;
|
|
1000
|
+
departmentName?: string;
|
|
1001
|
+
}
|
|
1002
|
+
interface UniversalMembersPageProps {
|
|
1003
|
+
headerTitle: string;
|
|
1004
|
+
headerDescription: string;
|
|
1005
|
+
members: UniversalMember[];
|
|
1006
|
+
isLoading: boolean;
|
|
1007
|
+
currentPage: number;
|
|
1008
|
+
totalPages: number;
|
|
1009
|
+
onPageChange: (page: number) => void;
|
|
1010
|
+
searchQuery: string;
|
|
1011
|
+
onSearchChange: (query: string) => void;
|
|
1012
|
+
activeStatusFilter: string;
|
|
1013
|
+
onStatusFilterChange: (status: string) => void;
|
|
1014
|
+
activeRoleFilter: string;
|
|
1015
|
+
onRoleFilterChange: (role: string) => void;
|
|
1016
|
+
actionButtonText: string;
|
|
1017
|
+
hideAction?: boolean;
|
|
1018
|
+
onRemoveMember: (memberId: string) => Promise<void>;
|
|
1019
|
+
}
|
|
1020
|
+
declare const UniversalMembersPage: React.FC<UniversalMembersPageProps>;
|
|
1021
|
+
|
|
1022
|
+
interface HomeActionBtn2 {
|
|
1023
|
+
label: string;
|
|
1024
|
+
icon?: any;
|
|
1025
|
+
onClick: () => void;
|
|
1026
|
+
}
|
|
1027
|
+
interface NotificationItem2 {
|
|
1028
|
+
id: string;
|
|
1029
|
+
title: string;
|
|
1030
|
+
message: string;
|
|
1031
|
+
isRead: boolean;
|
|
1032
|
+
createdAt: string | Date;
|
|
1033
|
+
}
|
|
1034
|
+
interface UniversalHome2Props {
|
|
1035
|
+
fullName?: string;
|
|
1036
|
+
avatarSrc?: string | null;
|
|
1037
|
+
createHuddleAction?: HomeActionBtn2;
|
|
1038
|
+
joinHuddleAction?: HomeActionBtn2;
|
|
1039
|
+
notifications?: NotificationItem2[];
|
|
1040
|
+
notificationPage?: number;
|
|
1041
|
+
notificationTotalPages?: number;
|
|
1042
|
+
isNotifsLoading?: boolean;
|
|
1043
|
+
onNotificationPageChange?: (page: number) => void;
|
|
1044
|
+
onNotificationClick?: (notif: NotificationItem2) => void;
|
|
1045
|
+
formatNotifDate: (date: string | Date) => string;
|
|
1046
|
+
customContent?: React.ReactNode;
|
|
1047
|
+
departmentsProps: UniversalDepartmentsPageProps;
|
|
1048
|
+
}
|
|
1049
|
+
declare const UniversalHome2: React.FC<UniversalHome2Props>;
|
|
1050
|
+
|
|
1051
|
+
export { AppBento2, type AppBento2Props, type BannerProps, type BentoFeature, type BoardMember, type CardData, CardInfoDialog, type CardInfoDialogProps, type CompanyDetails, type ConsultantProfile, ConsultantShowcase, type ConsultantShowcaseProps, ContentGridBlock, type ContentGridBlockProps, type CryptoOption, type DocumentSectionData, type EmailContact, Faq, type FaqItem, type FaqProps, FeatureScroll, type FeatureScrollProps, type FiatCurrencyOption, Footer, type FooterColumn, type FooterLink, type FooterProps, FundCardDialog, type FundCardDialogProps, GifFeatureCard, type GifFeatureCardProps, Header, type HeaderLink, type HeaderProps, type AppLogo$1 as HeroAppLogo, HeroSection, type HeroSectionProps, type HomeActionBtn, type HomeActionBtn2, type LeaderboardItem, ManagedBoardBlock, type ManagedBoardBlockProps, ManagedContactBlock, type ManagedContactBlockProps, ManagedDocument, type ManagedDocumentProps, ManagedNewsletterSplitBlock, type ManagedNewsletterSplitBlockProps, ManagedNotFoundBlock, type ManagedNotFoundBlockProps, ManagedPricingBlock, type ManagedPricingBlockProps, ManagedProjectsBlock, type ManagedProjectsBlockProps, ManagedToaster, MedicalFeatureStatsBlock, MobileNav, type MobileNavItem, type MobileNavProps, type NavItem, type NetworkOption, type NotificationItem, type NotificationItem2, NumberInput, type NumberInputProps, PageSpinner, type PageSpinnerProps, PinDialerBottomSheet, type PinDialerBottomSheetProps, PipleAuth, type PipleAuthProps, type PlatformFeatureItem, PlatformFeatures, type PlatformFeaturesProps, PortfolioHero, type PortfolioHeroProps, type AppLogo as PricingAppLogo, type PricingFeature, type PricingFeature2, type PricingPlan, type PricingTab, type ProjectItem, type RateCalculationPayload, type ReferralProfile, type RewardItem, type RewardProfile, type ScrollFeature, type SocialContact, type SocialLink, type StatItem, TextInput, type TextInputProps, ThreeDActionButton, type ThreeDActionButtonProps, ThreeDButton, type ThreeDButtonProps, type TierOption, UniversalBuyCryptoPage, type UniversalBuyCryptoPageProps, UniversalCardActionPage, type UniversalCardActionPageProps, UniversalCardPage, type UniversalCardPageProps, type UniversalDepartment, UniversalDepartmentsPage, type UniversalDepartmentsPageProps, UniversalErrorView, type UniversalErrorViewProps, UniversalHome2, type UniversalHome2Props, UniversalHomeView, type UniversalHomeViewProps, type UniversalMember, UniversalMembersPage, type UniversalMembersPageProps, UniversalOrganizationPage, type UniversalOrganizationPageProps, UniversalProfilePage, type UniversalProfilePageProps, UniversalProfileSettings, type UniversalProfileSettingsProps, type UniversalReferralItem, UniversalReferralPage, type UniversalReferralPageProps, UniversalRewardPage, type UniversalRewardPageProps, UniversalSecurityPage, type UniversalSecurityPageProps, UniversalSidebar, type UniversalSidebarProps, type UniversalTransaction, UniversalTransactionPage, type UniversalTransactionPageProps, UniversalVerificationPage, type UniversalVerificationPageProps, type UniversalWallet, UniversalWalletPage, type UniversalWalletPageProps, type VerificationStatus, WaitlistDialog, type WaitlistDialogProps };
|
package/dist/index.d.ts
CHANGED
|
@@ -67,7 +67,7 @@ interface PipleAuthProps {
|
|
|
67
67
|
firstName?: string;
|
|
68
68
|
lastName?: string;
|
|
69
69
|
organizationName?: string;
|
|
70
|
-
|
|
70
|
+
accountType?: "INDIVIDUAL" | "ORGANIZATION";
|
|
71
71
|
mode: AuthMode;
|
|
72
72
|
recaptchaToken?: string;
|
|
73
73
|
}) => Promise<{
|
|
@@ -972,4 +972,80 @@ interface UniversalBuyCryptoPageProps {
|
|
|
972
972
|
}
|
|
973
973
|
declare const UniversalBuyCryptoPage: React.FC<UniversalBuyCryptoPageProps>;
|
|
974
974
|
|
|
975
|
-
|
|
975
|
+
interface UniversalDepartment {
|
|
976
|
+
id: string;
|
|
977
|
+
name: string;
|
|
978
|
+
totalMembers: number;
|
|
979
|
+
avatars: string[];
|
|
980
|
+
}
|
|
981
|
+
interface UniversalDepartmentsPageProps {
|
|
982
|
+
headerTitle: string;
|
|
983
|
+
headerDescription: string;
|
|
984
|
+
departments: UniversalDepartment[];
|
|
985
|
+
isLoading: boolean;
|
|
986
|
+
currentPage: number;
|
|
987
|
+
totalPages: number;
|
|
988
|
+
onPageChange: (page: number) => void;
|
|
989
|
+
onDepartmentClick: (departmentId: string) => void;
|
|
990
|
+
}
|
|
991
|
+
declare const UniversalDepartmentsPage: React.FC<UniversalDepartmentsPageProps>;
|
|
992
|
+
|
|
993
|
+
interface UniversalMember {
|
|
994
|
+
id: string;
|
|
995
|
+
userId: string;
|
|
996
|
+
name: string;
|
|
997
|
+
avatarUrl?: string | null;
|
|
998
|
+
status: 'ACTIVE' | 'BUSY' | 'AWAY' | 'OFFLINE' | string;
|
|
999
|
+
role: string;
|
|
1000
|
+
departmentName?: string;
|
|
1001
|
+
}
|
|
1002
|
+
interface UniversalMembersPageProps {
|
|
1003
|
+
headerTitle: string;
|
|
1004
|
+
headerDescription: string;
|
|
1005
|
+
members: UniversalMember[];
|
|
1006
|
+
isLoading: boolean;
|
|
1007
|
+
currentPage: number;
|
|
1008
|
+
totalPages: number;
|
|
1009
|
+
onPageChange: (page: number) => void;
|
|
1010
|
+
searchQuery: string;
|
|
1011
|
+
onSearchChange: (query: string) => void;
|
|
1012
|
+
activeStatusFilter: string;
|
|
1013
|
+
onStatusFilterChange: (status: string) => void;
|
|
1014
|
+
activeRoleFilter: string;
|
|
1015
|
+
onRoleFilterChange: (role: string) => void;
|
|
1016
|
+
actionButtonText: string;
|
|
1017
|
+
hideAction?: boolean;
|
|
1018
|
+
onRemoveMember: (memberId: string) => Promise<void>;
|
|
1019
|
+
}
|
|
1020
|
+
declare const UniversalMembersPage: React.FC<UniversalMembersPageProps>;
|
|
1021
|
+
|
|
1022
|
+
interface HomeActionBtn2 {
|
|
1023
|
+
label: string;
|
|
1024
|
+
icon?: any;
|
|
1025
|
+
onClick: () => void;
|
|
1026
|
+
}
|
|
1027
|
+
interface NotificationItem2 {
|
|
1028
|
+
id: string;
|
|
1029
|
+
title: string;
|
|
1030
|
+
message: string;
|
|
1031
|
+
isRead: boolean;
|
|
1032
|
+
createdAt: string | Date;
|
|
1033
|
+
}
|
|
1034
|
+
interface UniversalHome2Props {
|
|
1035
|
+
fullName?: string;
|
|
1036
|
+
avatarSrc?: string | null;
|
|
1037
|
+
createHuddleAction?: HomeActionBtn2;
|
|
1038
|
+
joinHuddleAction?: HomeActionBtn2;
|
|
1039
|
+
notifications?: NotificationItem2[];
|
|
1040
|
+
notificationPage?: number;
|
|
1041
|
+
notificationTotalPages?: number;
|
|
1042
|
+
isNotifsLoading?: boolean;
|
|
1043
|
+
onNotificationPageChange?: (page: number) => void;
|
|
1044
|
+
onNotificationClick?: (notif: NotificationItem2) => void;
|
|
1045
|
+
formatNotifDate: (date: string | Date) => string;
|
|
1046
|
+
customContent?: React.ReactNode;
|
|
1047
|
+
departmentsProps: UniversalDepartmentsPageProps;
|
|
1048
|
+
}
|
|
1049
|
+
declare const UniversalHome2: React.FC<UniversalHome2Props>;
|
|
1050
|
+
|
|
1051
|
+
export { AppBento2, type AppBento2Props, type BannerProps, type BentoFeature, type BoardMember, type CardData, CardInfoDialog, type CardInfoDialogProps, type CompanyDetails, type ConsultantProfile, ConsultantShowcase, type ConsultantShowcaseProps, ContentGridBlock, type ContentGridBlockProps, type CryptoOption, type DocumentSectionData, type EmailContact, Faq, type FaqItem, type FaqProps, FeatureScroll, type FeatureScrollProps, type FiatCurrencyOption, Footer, type FooterColumn, type FooterLink, type FooterProps, FundCardDialog, type FundCardDialogProps, GifFeatureCard, type GifFeatureCardProps, Header, type HeaderLink, type HeaderProps, type AppLogo$1 as HeroAppLogo, HeroSection, type HeroSectionProps, type HomeActionBtn, type HomeActionBtn2, type LeaderboardItem, ManagedBoardBlock, type ManagedBoardBlockProps, ManagedContactBlock, type ManagedContactBlockProps, ManagedDocument, type ManagedDocumentProps, ManagedNewsletterSplitBlock, type ManagedNewsletterSplitBlockProps, ManagedNotFoundBlock, type ManagedNotFoundBlockProps, ManagedPricingBlock, type ManagedPricingBlockProps, ManagedProjectsBlock, type ManagedProjectsBlockProps, ManagedToaster, MedicalFeatureStatsBlock, MobileNav, type MobileNavItem, type MobileNavProps, type NavItem, type NetworkOption, type NotificationItem, type NotificationItem2, NumberInput, type NumberInputProps, PageSpinner, type PageSpinnerProps, PinDialerBottomSheet, type PinDialerBottomSheetProps, PipleAuth, type PipleAuthProps, type PlatformFeatureItem, PlatformFeatures, type PlatformFeaturesProps, PortfolioHero, type PortfolioHeroProps, type AppLogo as PricingAppLogo, type PricingFeature, type PricingFeature2, type PricingPlan, type PricingTab, type ProjectItem, type RateCalculationPayload, type ReferralProfile, type RewardItem, type RewardProfile, type ScrollFeature, type SocialContact, type SocialLink, type StatItem, TextInput, type TextInputProps, ThreeDActionButton, type ThreeDActionButtonProps, ThreeDButton, type ThreeDButtonProps, type TierOption, UniversalBuyCryptoPage, type UniversalBuyCryptoPageProps, UniversalCardActionPage, type UniversalCardActionPageProps, UniversalCardPage, type UniversalCardPageProps, type UniversalDepartment, UniversalDepartmentsPage, type UniversalDepartmentsPageProps, UniversalErrorView, type UniversalErrorViewProps, UniversalHome2, type UniversalHome2Props, UniversalHomeView, type UniversalHomeViewProps, type UniversalMember, UniversalMembersPage, type UniversalMembersPageProps, UniversalOrganizationPage, type UniversalOrganizationPageProps, UniversalProfilePage, type UniversalProfilePageProps, UniversalProfileSettings, type UniversalProfileSettingsProps, type UniversalReferralItem, UniversalReferralPage, type UniversalReferralPageProps, UniversalRewardPage, type UniversalRewardPageProps, UniversalSecurityPage, type UniversalSecurityPageProps, UniversalSidebar, type UniversalSidebarProps, type UniversalTransaction, UniversalTransactionPage, type UniversalTransactionPageProps, UniversalVerificationPage, type UniversalVerificationPageProps, type UniversalWallet, UniversalWalletPage, type UniversalWalletPageProps, type VerificationStatus, WaitlistDialog, type WaitlistDialogProps };
|
package/dist/index.js
CHANGED
|
@@ -64,8 +64,11 @@ __export(index_exports, {
|
|
|
64
64
|
UniversalBuyCryptoPage: () => UniversalBuyCryptoPage,
|
|
65
65
|
UniversalCardActionPage: () => UniversalCardActionPage,
|
|
66
66
|
UniversalCardPage: () => UniversalCardPage,
|
|
67
|
+
UniversalDepartmentsPage: () => UniversalDepartmentsPage,
|
|
67
68
|
UniversalErrorView: () => UniversalErrorView,
|
|
69
|
+
UniversalHome2: () => UniversalHome2,
|
|
68
70
|
UniversalHomeView: () => UniversalHomeView,
|
|
71
|
+
UniversalMembersPage: () => UniversalMembersPage,
|
|
69
72
|
UniversalOrganizationPage: () => UniversalOrganizationPage,
|
|
70
73
|
UniversalProfilePage: () => UniversalProfilePage,
|
|
71
74
|
UniversalProfileSettings: () => UniversalProfileSettings,
|
|
@@ -382,8 +385,8 @@ var InputSpinner = () => /* @__PURE__ */ import_react6.default.createElement("sv
|
|
|
382
385
|
function AuthFormInner({
|
|
383
386
|
companyName,
|
|
384
387
|
workspaceLabel = "Workspace",
|
|
385
|
-
termsUrl = "
|
|
386
|
-
privacyUrl = "
|
|
388
|
+
termsUrl = "",
|
|
389
|
+
privacyUrl = "",
|
|
387
390
|
requireNames = true,
|
|
388
391
|
requireOrganization = true,
|
|
389
392
|
useRecaptcha = false,
|
|
@@ -397,12 +400,13 @@ function AuthFormInner({
|
|
|
397
400
|
const [mode, setMode] = (0, import_react6.useState)("LOGIN");
|
|
398
401
|
const [step, setStep] = (0, import_react6.useState)("INPUT");
|
|
399
402
|
const getInitialSignupStep = () => {
|
|
400
|
-
return "
|
|
403
|
+
if (requireNames) return "NAME";
|
|
404
|
+
if (requireOrganization) return "ORGANIZATION";
|
|
405
|
+
return "EMAIL_ID";
|
|
401
406
|
};
|
|
402
407
|
const [signupStep, setSignupStep] = (0, import_react6.useState)(getInitialSignupStep());
|
|
403
408
|
const [isSubmitting, setIsSubmitting] = (0, import_react6.useState)(false);
|
|
404
409
|
const [countdown, setCountdown] = (0, import_react6.useState)(0);
|
|
405
|
-
const [invitationCode, setInvitationCode] = (0, import_react6.useState)("");
|
|
406
410
|
const [emailId, setEmailId] = (0, import_react6.useState)("");
|
|
407
411
|
const [firstName, setFirstName] = (0, import_react6.useState)("");
|
|
408
412
|
const [lastName, setLastName] = (0, import_react6.useState)("");
|
|
@@ -458,12 +462,13 @@ function AuthFormInner({
|
|
|
458
462
|
if (useRecaptcha && captchaContext?.executeRecaptcha) {
|
|
459
463
|
recaptchaToken = await captchaContext.executeRecaptcha("auth_request");
|
|
460
464
|
}
|
|
465
|
+
const hasOrg = mode === "SIGNUP" && requireOrganization && orgName.trim().length > 0;
|
|
461
466
|
const res = await onAuthRequest({
|
|
462
467
|
email: emailId,
|
|
463
468
|
firstName: mode === "SIGNUP" && requireNames ? firstName : void 0,
|
|
464
469
|
lastName: mode === "SIGNUP" && requireNames ? lastName : void 0,
|
|
465
|
-
organizationName:
|
|
466
|
-
|
|
470
|
+
organizationName: hasOrg ? orgName.trim() : void 0,
|
|
471
|
+
accountType: hasOrg ? "ORGANIZATION" : "INDIVIDUAL",
|
|
467
472
|
mode,
|
|
468
473
|
recaptchaToken
|
|
469
474
|
});
|
|
@@ -519,11 +524,7 @@ function AuthFormInner({
|
|
|
519
524
|
}
|
|
520
525
|
};
|
|
521
526
|
const handleNextSignupStep = () => {
|
|
522
|
-
if (signupStep === "
|
|
523
|
-
if (requireNames) setSignupStep("NAME");
|
|
524
|
-
else if (requireOrganization) setSignupStep("ORGANIZATION");
|
|
525
|
-
else setSignupStep("EMAIL_ID");
|
|
526
|
-
} else if (signupStep === "NAME") {
|
|
527
|
+
if (signupStep === "NAME") {
|
|
527
528
|
if (requireOrganization) setSignupStep("ORGANIZATION");
|
|
528
529
|
else setSignupStep("EMAIL_ID");
|
|
529
530
|
} else if (signupStep === "ORGANIZATION") {
|
|
@@ -534,7 +535,6 @@ function AuthFormInner({
|
|
|
534
535
|
if (isSubmitting) return true;
|
|
535
536
|
if (mode === "LOGIN") return emailId.length < 3;
|
|
536
537
|
if (mode === "SIGNUP") {
|
|
537
|
-
if (signupStep === "INVITATION") return invitationCode.trim().length > 0 && invitationCode.trim().length < 3;
|
|
538
538
|
if (signupStep === "NAME") return firstName.trim() === "" || lastName.trim() === "";
|
|
539
539
|
if (signupStep === "ORGANIZATION") return orgName.trim().length < 3;
|
|
540
540
|
if (signupStep === "EMAIL_ID") return emailId.length < 3 || !agreedToTerms;
|
|
@@ -546,21 +546,10 @@ function AuthFormInner({
|
|
|
546
546
|
setSignupStep(getInitialSignupStep());
|
|
547
547
|
}, className: "text-black transition-colors ml-1" }, "Sign up")) : /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, "Already have an account? ", /* @__PURE__ */ import_react6.default.createElement("button", { type: "button", onClick: () => setMode("LOGIN"), className: "text-black transition-colors ml-1" }, "Log in")))), /* @__PURE__ */ import_react6.default.createElement("form", { className: "space-y-6", autoComplete: "off", onSubmit: (e) => {
|
|
548
548
|
e.preventDefault();
|
|
549
|
-
if (mode === "SIGNUP" && signupStep === "
|
|
550
|
-
else if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
|
|
549
|
+
if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
|
|
551
550
|
else if (mode === "SIGNUP" && signupStep === "ORGANIZATION") handleNextSignupStep();
|
|
552
551
|
else handleAuthRequestSubmit();
|
|
553
|
-
} }, mode === "SIGNUP" && signupStep === "
|
|
554
|
-
"input",
|
|
555
|
-
{
|
|
556
|
-
type: "text",
|
|
557
|
-
value: invitationCode,
|
|
558
|
-
onChange: (e) => setInvitationCode(e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, "")),
|
|
559
|
-
autoFocus: true,
|
|
560
|
-
className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300 tracking-widest",
|
|
561
|
-
placeholder: "Referral Code (Optional)"
|
|
562
|
-
}
|
|
563
|
-
))), mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "text", value: firstName, onChange: (e) => setFirstName(cleanAlpha(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "First name" })), /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "text", value: lastName, onChange: (e) => setLastName(cleanAlpha(e.target.value)), required: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Last name" }))), mode === "SIGNUP" && signupStep === "ORGANIZATION" && requireOrganization && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Organization Name"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "text", value: orgName, onChange: (e) => setOrgName(cleanOrgName(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Acme Corporation" }))), (mode === "LOGIN" || mode === "SIGNUP" && signupStep === "EMAIL_ID") && /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Email ID"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "email", value: emailId, onChange: (e) => setEmailId(cleanEmailId(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "name@company.com" })), mode === "SIGNUP" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ import_react6.default.createElement("input", { type: "checkbox", id: "zairus-terms", checked: agreedToTerms, onChange: (e) => setAgreedToTerms(e.target.checked), className: "mt-0.5 w-4 h-4 bg-white border-neutral-300 rounded text-black focus:ring-black cursor-pointer", required: true }), /* @__PURE__ */ import_react6.default.createElement("label", { htmlFor: "zairus-terms", className: "text-[11px] text-neutral-500 cursor-pointer leading-snug" }, "I agree to ", companyName, "'s ", /* @__PURE__ */ import_react6.default.createElement("a", { href: termsUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Terms of Service"), " and ", /* @__PURE__ */ import_react6.default.createElement("a", { href: privacyUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Privacy Policy"), "."))), /* @__PURE__ */ import_react6.default.createElement(ThreeDActionButton, { type: "submit", disabled: isContinueDisabled(), isLoading: isSubmitting, className: "w-full mt-10" }, "Continue"))), step === "OTP" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "text-center mb-10 mt-2" }, /* @__PURE__ */ import_react6.default.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-[13px] text-neutral-500" }, userHas2FA ? "Enter the code from your authenticator app." : `Enter the code sent to ${emailId}`)), /* @__PURE__ */ import_react6.default.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
|
|
552
|
+
} }, mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "text", value: firstName, onChange: (e) => setFirstName(cleanAlpha(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "First name" })), /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "text", value: lastName, onChange: (e) => setLastName(cleanAlpha(e.target.value)), required: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Last name" }))), mode === "SIGNUP" && signupStep === "ORGANIZATION" && requireOrganization && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Organization Name"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "text", value: orgName, onChange: (e) => setOrgName(cleanOrgName(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Acme Corporation" }))), (mode === "LOGIN" || mode === "SIGNUP" && signupStep === "EMAIL_ID") && /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Email ID"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "email", value: emailId, onChange: (e) => setEmailId(cleanEmailId(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "name@company.com" })), mode === "SIGNUP" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ import_react6.default.createElement("input", { type: "checkbox", id: "zairus-terms", checked: agreedToTerms, onChange: (e) => setAgreedToTerms(e.target.checked), className: "mt-0.5 w-4 h-4 bg-white border-neutral-300 rounded text-black focus:ring-black cursor-pointer", required: true }), /* @__PURE__ */ import_react6.default.createElement("label", { htmlFor: "zairus-terms", className: "text-[11px] text-neutral-500 cursor-pointer leading-snug" }, "I agree to ", companyName, "'s ", /* @__PURE__ */ import_react6.default.createElement("a", { href: termsUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Terms of Service"), " and ", /* @__PURE__ */ import_react6.default.createElement("a", { href: privacyUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Privacy Policy"), "."))), /* @__PURE__ */ import_react6.default.createElement(ThreeDActionButton, { type: "submit", disabled: isContinueDisabled(), isLoading: isSubmitting, className: "w-full mt-10" }, "Continue"))), step === "OTP" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "text-center mb-10 mt-2" }, /* @__PURE__ */ import_react6.default.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-[13px] text-neutral-500" }, userHas2FA ? "Enter the code from your authenticator app." : `Enter the code sent to ${emailId}`)), /* @__PURE__ */ import_react6.default.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
|
|
564
553
|
e.preventDefault();
|
|
565
554
|
verifyOtpCode(otp.join(""));
|
|
566
555
|
} }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex justify-between gap-2", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ import_react6.default.createElement(
|
|
@@ -4452,6 +4441,374 @@ var UniversalBuyCryptoPage = ({
|
|
|
4452
4441
|
);
|
|
4453
4442
|
}))))));
|
|
4454
4443
|
};
|
|
4444
|
+
|
|
4445
|
+
// src/components/UniversalDepartmentsPage.tsx
|
|
4446
|
+
var import_react77 = __toESM(require("react"));
|
|
4447
|
+
var import_react78 = require("@hugeicons/react");
|
|
4448
|
+
var import_core_free_icons27 = require("@hugeicons/core-free-icons");
|
|
4449
|
+
var formatMembersCount = (num) => {
|
|
4450
|
+
if (num >= 1e6) return (num / 1e6).toFixed(1) + "m";
|
|
4451
|
+
if (num >= 1e3) return (num / 1e3).toFixed(1) + "k";
|
|
4452
|
+
return num.toString();
|
|
4453
|
+
};
|
|
4454
|
+
var PageSpinner6 = () => /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ import_react77.default.createElement(import_react78.HugeiconsIcon, { icon: import_core_free_icons27.Loading03Icon, size: 32, className: "animate-spin mb-4 text-black" }));
|
|
4455
|
+
var UniversalDepartmentsPage = ({
|
|
4456
|
+
headerTitle,
|
|
4457
|
+
headerDescription,
|
|
4458
|
+
departments,
|
|
4459
|
+
isLoading,
|
|
4460
|
+
currentPage,
|
|
4461
|
+
totalPages,
|
|
4462
|
+
onPageChange,
|
|
4463
|
+
onDepartmentClick
|
|
4464
|
+
}) => {
|
|
4465
|
+
return /* @__PURE__ */ import_react77.default.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300" }, /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex flex-col gap-8 p-6 rounded-2xl bg-white w-full" }, /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-4" }, /* @__PURE__ */ import_react77.default.createElement("div", null, /* @__PURE__ */ import_react77.default.createElement("h1", { className: "text-black text-xl mb-1 tracking-tight" }, headerTitle), headerDescription && /* @__PURE__ */ import_react77.default.createElement("p", { className: "text-[12px] text-neutral-500" }, headerDescription))), /* @__PURE__ */ import_react77.default.createElement("div", { className: "w-full overflow-hidden" }, isLoading ? /* @__PURE__ */ import_react77.default.createElement(PageSpinner6, null) : /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react77.default.createElement("div", null, departments.length === 0 ? /* @__PURE__ */ import_react77.default.createElement("p", { className: "text-[12px] text-neutral-400 py-6 text-center" }, "No departments available") : departments.map((dept) => /* @__PURE__ */ import_react77.default.createElement(
|
|
4466
|
+
"div",
|
|
4467
|
+
{
|
|
4468
|
+
key: dept.id,
|
|
4469
|
+
onClick: () => onDepartmentClick(dept.id),
|
|
4470
|
+
className: "flex flex-col py-4 hover:bg-neutral-50 transition-colors cursor-pointer group min-w-0 px-3 -mx-3 rounded-xl gap-2"
|
|
4471
|
+
},
|
|
4472
|
+
/* @__PURE__ */ import_react77.default.createElement("p", { className: "text-[14px] text-black tracking-tight truncate" }, dept.name),
|
|
4473
|
+
/* @__PURE__ */ import_react77.default.createElement("div", { className: "flex items-center gap-3 min-w-0" }, dept.avatars && dept.avatars.length > 0 && /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex items-center -space-x-2 shrink-0" }, dept.avatars.slice(0, 4).map((src, idx) => /* @__PURE__ */ import_react77.default.createElement("div", { key: idx, className: "w-7 h-7 rounded-lg border-2 border-white bg-neutral-100 overflow-hidden shrink-0" }, /* @__PURE__ */ import_react77.default.createElement(
|
|
4474
|
+
"img",
|
|
4475
|
+
{
|
|
4476
|
+
src: src || "https://storage.googleapis.com/retina-cloud-v2/assets/images/avatar.avif",
|
|
4477
|
+
alt: "Member",
|
|
4478
|
+
className: "w-full h-full object-cover"
|
|
4479
|
+
}
|
|
4480
|
+
)))), dept.totalMembers > 0 ? /* @__PURE__ */ import_react77.default.createElement("span", { className: "text-[11px] text-neutral-500 truncate block" }, formatMembersCount(dept.totalMembers), " ", dept.totalMembers > 4 ? "+" : "") : /* @__PURE__ */ import_react77.default.createElement("span", { className: "text-[11px] text-neutral-400 truncate block" }, "Empty"))
|
|
4481
|
+
))), /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex items-center justify-between pt-6 mt-2" }, /* @__PURE__ */ import_react77.default.createElement("span", { className: "text-[11px] text-neutral-400 tracking-[0.2em]" }, "Page ", currentPage, " of ", totalPages === 0 ? 1 : totalPages), /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react77.default.createElement(
|
|
4482
|
+
"button",
|
|
4483
|
+
{
|
|
4484
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
4485
|
+
disabled: currentPage <= 1 || isLoading,
|
|
4486
|
+
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"
|
|
4487
|
+
},
|
|
4488
|
+
/* @__PURE__ */ import_react77.default.createElement(import_react78.HugeiconsIcon, { icon: import_core_free_icons27.ArrowLeft01Icon, size: 14 })
|
|
4489
|
+
), /* @__PURE__ */ import_react77.default.createElement(
|
|
4490
|
+
"button",
|
|
4491
|
+
{
|
|
4492
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
4493
|
+
disabled: currentPage >= totalPages || isLoading || totalPages === 0,
|
|
4494
|
+
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"
|
|
4495
|
+
},
|
|
4496
|
+
/* @__PURE__ */ import_react77.default.createElement(import_react78.HugeiconsIcon, { icon: import_core_free_icons27.ArrowRight01Icon, size: 14 })
|
|
4497
|
+
)))))));
|
|
4498
|
+
};
|
|
4499
|
+
|
|
4500
|
+
// src/components/UniversalMembersPage.tsx
|
|
4501
|
+
var import_react79 = __toESM(require("react"));
|
|
4502
|
+
var import_react80 = require("@hugeicons/react");
|
|
4503
|
+
var import_react_hot_toast13 = __toESM(require("react-hot-toast"));
|
|
4504
|
+
var import_core_free_icons28 = require("@hugeicons/core-free-icons");
|
|
4505
|
+
var MemberAvatar = ({ src, status }) => {
|
|
4506
|
+
const [loaded, setLoaded] = (0, import_react79.useState)(false);
|
|
4507
|
+
const [error, setError] = (0, import_react79.useState)(false);
|
|
4508
|
+
const defaultAvatar = "https://storage.googleapis.com/retina-cloud-v2/assets/images/avatar.avif";
|
|
4509
|
+
const finalSrc = error || !src ? defaultAvatar : src;
|
|
4510
|
+
const getStatusColor = () => {
|
|
4511
|
+
switch (status?.toUpperCase()) {
|
|
4512
|
+
case "ACTIVE":
|
|
4513
|
+
return "bg-emerald-500";
|
|
4514
|
+
case "BUSY":
|
|
4515
|
+
return "bg-amber-500";
|
|
4516
|
+
case "OFFLINE":
|
|
4517
|
+
return "bg-rose-500";
|
|
4518
|
+
case "AWAY":
|
|
4519
|
+
return "bg-neutral-400";
|
|
4520
|
+
default:
|
|
4521
|
+
return "bg-neutral-200";
|
|
4522
|
+
}
|
|
4523
|
+
};
|
|
4524
|
+
return /* @__PURE__ */ import_react79.default.createElement("div", { className: "relative w-10 h-10 shrink-0" }, /* @__PURE__ */ import_react79.default.createElement("div", { className: "w-full h-full rounded-lg bg-neutral-100 flex items-center justify-center overflow-hidden border border-neutral-200" }, !loaded && !error && /* @__PURE__ */ import_react79.default.createElement(import_react80.HugeiconsIcon, { icon: import_core_free_icons28.Loading03Icon, className: "animate-spin text-neutral-400 absolute", size: 14 }), /* @__PURE__ */ import_react79.default.createElement(
|
|
4525
|
+
"img",
|
|
4526
|
+
{
|
|
4527
|
+
src: finalSrc,
|
|
4528
|
+
alt: "Member Avatar",
|
|
4529
|
+
className: `w-full h-full object-cover transition-opacity duration-300 ${loaded || error ? "opacity-100" : "opacity-0"}`,
|
|
4530
|
+
onLoad: () => setLoaded(true),
|
|
4531
|
+
onError: () => setError(true)
|
|
4532
|
+
}
|
|
4533
|
+
)), /* @__PURE__ */ import_react79.default.createElement("div", { className: `absolute -bottom-1 -right-1 w-3.5 h-3.5 rounded-full border-2 border-white z-10 ${getStatusColor()}` }));
|
|
4534
|
+
};
|
|
4535
|
+
var PageSpinner7 = () => /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ import_react79.default.createElement(import_react80.HugeiconsIcon, { icon: import_core_free_icons28.Loading03Icon, size: 32, className: "animate-spin mb-4 text-black" }));
|
|
4536
|
+
var UniversalMembersPage = ({
|
|
4537
|
+
headerTitle,
|
|
4538
|
+
headerDescription,
|
|
4539
|
+
members,
|
|
4540
|
+
isLoading,
|
|
4541
|
+
currentPage,
|
|
4542
|
+
totalPages,
|
|
4543
|
+
onPageChange,
|
|
4544
|
+
searchQuery,
|
|
4545
|
+
onSearchChange,
|
|
4546
|
+
activeStatusFilter,
|
|
4547
|
+
onStatusFilterChange,
|
|
4548
|
+
activeRoleFilter,
|
|
4549
|
+
onRoleFilterChange,
|
|
4550
|
+
actionButtonText,
|
|
4551
|
+
hideAction = false,
|
|
4552
|
+
onRemoveMember
|
|
4553
|
+
}) => {
|
|
4554
|
+
const [expandedId, setExpandedId] = (0, import_react79.useState)(null);
|
|
4555
|
+
const [memberToRemove, setMemberToRemove] = (0, import_react79.useState)(null);
|
|
4556
|
+
const [isRemoving, setIsRemoving] = (0, import_react79.useState)(false);
|
|
4557
|
+
const [localSearchQuery, setLocalSearchQuery] = (0, import_react79.useState)(searchQuery);
|
|
4558
|
+
const [isTyping, setIsTyping] = (0, import_react79.useState)(false);
|
|
4559
|
+
const [isStatusModalOpen, setIsStatusModalOpen] = (0, import_react79.useState)(false);
|
|
4560
|
+
const [isRoleModalOpen, setIsRoleModalOpen] = (0, import_react79.useState)(false);
|
|
4561
|
+
const statusDropdownRef = (0, import_react79.useRef)(null);
|
|
4562
|
+
const roleDropdownRef = (0, import_react79.useRef)(null);
|
|
4563
|
+
(0, import_react79.useEffect)(() => {
|
|
4564
|
+
function handleClickOutside(event) {
|
|
4565
|
+
if (statusDropdownRef.current && !statusDropdownRef.current.contains(event.target)) {
|
|
4566
|
+
setIsStatusModalOpen(false);
|
|
4567
|
+
}
|
|
4568
|
+
if (roleDropdownRef.current && !roleDropdownRef.current.contains(event.target)) {
|
|
4569
|
+
setIsRoleModalOpen(false);
|
|
4570
|
+
}
|
|
4571
|
+
}
|
|
4572
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
4573
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
4574
|
+
}, []);
|
|
4575
|
+
(0, import_react79.useEffect)(() => {
|
|
4576
|
+
setIsTyping(true);
|
|
4577
|
+
const handler = setTimeout(() => {
|
|
4578
|
+
onSearchChange(localSearchQuery);
|
|
4579
|
+
setIsTyping(false);
|
|
4580
|
+
}, 600);
|
|
4581
|
+
return () => clearTimeout(handler);
|
|
4582
|
+
}, [localSearchQuery, onSearchChange]);
|
|
4583
|
+
(0, import_react79.useEffect)(() => {
|
|
4584
|
+
if (searchQuery === "" && localSearchQuery !== "") {
|
|
4585
|
+
setLocalSearchQuery("");
|
|
4586
|
+
}
|
|
4587
|
+
}, [searchQuery]);
|
|
4588
|
+
const handleConfirmRemove = async () => {
|
|
4589
|
+
if (!memberToRemove) return;
|
|
4590
|
+
setIsRemoving(true);
|
|
4591
|
+
try {
|
|
4592
|
+
await onRemoveMember(memberToRemove.id);
|
|
4593
|
+
import_react_hot_toast13.default.success("Member removed successfully.");
|
|
4594
|
+
setExpandedId(null);
|
|
4595
|
+
setMemberToRemove(null);
|
|
4596
|
+
} catch (error) {
|
|
4597
|
+
import_react_hot_toast13.default.error("Failed to remove member.");
|
|
4598
|
+
} finally {
|
|
4599
|
+
setIsRemoving(false);
|
|
4600
|
+
}
|
|
4601
|
+
};
|
|
4602
|
+
const isListLoading = isLoading || isTyping;
|
|
4603
|
+
return /* @__PURE__ */ import_react79.default.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300" }, /* @__PURE__ */ import_react79.default.createElement(ManagedToaster, null), /* @__PURE__ */ import_react79.default.createElement(
|
|
4604
|
+
ConfirmationDialog,
|
|
4605
|
+
{
|
|
4606
|
+
isOpen: !!memberToRemove,
|
|
4607
|
+
title: "Remove Member",
|
|
4608
|
+
message: `Are you sure you want to remove ${memberToRemove?.name}? This action cannot be undone.`,
|
|
4609
|
+
confirmText: "Remove",
|
|
4610
|
+
cancelText: "Cancel",
|
|
4611
|
+
isProcessing: isRemoving,
|
|
4612
|
+
isDestructive: true,
|
|
4613
|
+
onClose: () => setMemberToRemove(null),
|
|
4614
|
+
onConfirm: handleConfirmRemove
|
|
4615
|
+
}
|
|
4616
|
+
), /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex flex-row flex-nowrap mb-4 items-center justify-between gap-4 w-full" }, /* @__PURE__ */ import_react79.default.createElement("div", { className: "relative flex-1 min-w-0 max-w-full" }, /* @__PURE__ */ import_react79.default.createElement("div", { className: "absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none" }, /* @__PURE__ */ import_react79.default.createElement(import_react80.HugeiconsIcon, { icon: import_core_free_icons28.Search01Icon, size: 16, className: "text-neutral-400" })), /* @__PURE__ */ import_react79.default.createElement(
|
|
4617
|
+
"input",
|
|
4618
|
+
{
|
|
4619
|
+
type: "text",
|
|
4620
|
+
placeholder: "Search members...",
|
|
4621
|
+
value: localSearchQuery,
|
|
4622
|
+
onChange: (e) => setLocalSearchQuery(e.target.value),
|
|
4623
|
+
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"
|
|
4624
|
+
}
|
|
4625
|
+
)), /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex items-center gap-3 w-auto pb-0 shrink-0" }, /* @__PURE__ */ import_react79.default.createElement(
|
|
4626
|
+
"button",
|
|
4627
|
+
{
|
|
4628
|
+
onClick: () => setIsStatusModalOpen(true),
|
|
4629
|
+
className: "flex items-center justify-center bg-white w-9 h-9 rounded-full text-neutral-500 hover:text-black transition-colors outline-none"
|
|
4630
|
+
},
|
|
4631
|
+
/* @__PURE__ */ import_react79.default.createElement(import_react80.HugeiconsIcon, { icon: import_core_free_icons28.SearchList02Icon, size: 16 })
|
|
4632
|
+
), /* @__PURE__ */ import_react79.default.createElement(
|
|
4633
|
+
"button",
|
|
4634
|
+
{
|
|
4635
|
+
onClick: () => setIsRoleModalOpen(true),
|
|
4636
|
+
className: "flex items-center justify-center bg-white w-9 h-9 rounded-full text-neutral-500 hover:text-black transition-colors outline-none"
|
|
4637
|
+
},
|
|
4638
|
+
/* @__PURE__ */ import_react79.default.createElement(import_react80.HugeiconsIcon, { icon: import_core_free_icons28.ListSettingIcon, size: 16 })
|
|
4639
|
+
))), /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex flex-col gap-8 p-6 rounded-2xl bg-white w-full" }, /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-4" }, /* @__PURE__ */ import_react79.default.createElement("div", null, /* @__PURE__ */ import_react79.default.createElement("h1", { className: "text-black text-xl mb-1 tracking-tight" }, headerTitle), headerDescription && /* @__PURE__ */ import_react79.default.createElement("p", { className: "text-[12px] text-neutral-500" }, headerDescription))), /* @__PURE__ */ import_react79.default.createElement("div", { className: "w-full overflow-hidden" }, isListLoading ? /* @__PURE__ */ import_react79.default.createElement(PageSpinner7, null) : /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react79.default.createElement("div", null, members.length === 0 ? /* @__PURE__ */ import_react79.default.createElement("p", { className: "text-[12px] text-neutral-400 py-6 text-center" }, "No members found") : members.map((member) => /* @__PURE__ */ import_react79.default.createElement(import_react79.default.Fragment, { key: member.id }, expandedId === member.id ? /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex flex-col p-5 bg-neutral-50 rounded-xl animate-in fade-in zoom-in-95 duration-200 gap-5 my-2" }, /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react79.default.createElement(MemberAvatar, { src: member.avatarUrl, status: member.status }), /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react79.default.createElement("span", { className: "text-[14px] text-black tracking-tight truncate" }, member.name), /* @__PURE__ */ import_react79.default.createElement("span", { className: "text-[12px] text-neutral-500 capitalize" }, member.role.toLowerCase()))), member.departmentName && /* @__PURE__ */ import_react79.default.createElement("div", { className: "pt-3 border-t border-neutral-200" }, /* @__PURE__ */ import_react79.default.createElement("span", { className: "text-[10px] tracking-[0.2em] text-neutral-400 block mb-1" }, "Department"), /* @__PURE__ */ import_react79.default.createElement("span", { className: "text-[13px] text-black truncate block" }, member.departmentName)), /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex gap-3 pt-2" }, !hideAction && /* @__PURE__ */ import_react79.default.createElement(
|
|
4640
|
+
"button",
|
|
4641
|
+
{
|
|
4642
|
+
onClick: () => setMemberToRemove(member),
|
|
4643
|
+
className: "flex-1 py-2.5 bg-white border border-rose-200 text-rose-600 hover:bg-rose-50 rounded-full text-[12px] tracking-wide transition-colors outline-none"
|
|
4644
|
+
},
|
|
4645
|
+
actionButtonText
|
|
4646
|
+
), /* @__PURE__ */ import_react79.default.createElement(
|
|
4647
|
+
"button",
|
|
4648
|
+
{
|
|
4649
|
+
onClick: () => setExpandedId(null),
|
|
4650
|
+
className: "flex-1 py-2.5 bg-white border border-neutral-200 text-black hover:bg-neutral-100 rounded-full text-[12px] tracking-wide transition-colors outline-none"
|
|
4651
|
+
},
|
|
4652
|
+
"Close"
|
|
4653
|
+
))) : /* @__PURE__ */ import_react79.default.createElement(
|
|
4654
|
+
"div",
|
|
4655
|
+
{
|
|
4656
|
+
onClick: () => setExpandedId(member.id),
|
|
4657
|
+
className: "flex items-center justify-between py-3 hover:bg-neutral-50 transition-colors cursor-pointer group min-w-0 px-3 -mx-3 rounded-xl"
|
|
4658
|
+
},
|
|
4659
|
+
/* @__PURE__ */ import_react79.default.createElement("div", { className: "flex items-center gap-4 min-w-0 flex-1" }, /* @__PURE__ */ import_react79.default.createElement(MemberAvatar, { src: member.avatarUrl, status: member.status }), /* @__PURE__ */ import_react79.default.createElement("div", { className: "min-w-0 flex-1 flex flex-col gap-0.5" }, /* @__PURE__ */ import_react79.default.createElement("p", { className: "text-[13px] text-black truncate" }, member.name), /* @__PURE__ */ import_react79.default.createElement("p", { className: "text-[11px] text-neutral-500 capitalize truncate" }, member.role.toLowerCase())))
|
|
4660
|
+
)))), /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex items-center justify-between pt-6 mt-2" }, /* @__PURE__ */ import_react79.default.createElement("span", { className: "text-[11px] text-neutral-400 tracking-[0.2em]" }, "Page ", currentPage, " of ", totalPages === 0 ? 1 : totalPages), /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react79.default.createElement(
|
|
4661
|
+
"button",
|
|
4662
|
+
{
|
|
4663
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
4664
|
+
disabled: currentPage <= 1 || isListLoading,
|
|
4665
|
+
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"
|
|
4666
|
+
},
|
|
4667
|
+
/* @__PURE__ */ import_react79.default.createElement(import_react80.HugeiconsIcon, { icon: import_core_free_icons28.ArrowLeft01Icon, size: 14 })
|
|
4668
|
+
), /* @__PURE__ */ import_react79.default.createElement(
|
|
4669
|
+
"button",
|
|
4670
|
+
{
|
|
4671
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
4672
|
+
disabled: currentPage >= totalPages || isListLoading || totalPages === 0,
|
|
4673
|
+
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"
|
|
4674
|
+
},
|
|
4675
|
+
/* @__PURE__ */ import_react79.default.createElement(import_react80.HugeiconsIcon, { icon: import_core_free_icons28.ArrowRight01Icon, size: 14 })
|
|
4676
|
+
)))))), isStatusModalOpen && /* @__PURE__ */ import_react79.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react79.default.createElement("div", { className: "absolute inset-0 bg-black/40", onClick: () => setIsStatusModalOpen(false) }), /* @__PURE__ */ import_react79.default.createElement("div", { ref: statusDropdownRef, 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__ */ import_react79.default.createElement("div", { className: "p-6 text-center w-full mb-2" }, /* @__PURE__ */ import_react79.default.createElement("h3", { className: "text-[14px] text-black tracking-tight" }, "Status Filter")), /* @__PURE__ */ import_react79.default.createElement("div", { className: "w-full flex flex-col pl-2 pr-2 gap-1" }, ["ALL", "ACTIVE", "BUSY", "OFFLINE", "AWAY"].map((option) => /* @__PURE__ */ import_react79.default.createElement(
|
|
4677
|
+
"button",
|
|
4678
|
+
{
|
|
4679
|
+
key: option,
|
|
4680
|
+
onClick: () => {
|
|
4681
|
+
onStatusFilterChange(option);
|
|
4682
|
+
setIsStatusModalOpen(false);
|
|
4683
|
+
},
|
|
4684
|
+
className: `text-left px-4 py-3 text-[11px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${activeStatusFilter === option ? "bg-neutral-100 text-black" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
|
|
4685
|
+
},
|
|
4686
|
+
/* @__PURE__ */ import_react79.default.createElement("span", { className: "truncate pr-2 capitalize" }, option.toLowerCase())
|
|
4687
|
+
))), /* @__PURE__ */ import_react79.default.createElement("div", { className: "w-full flex mt-2" }, /* @__PURE__ */ import_react79.default.createElement("button", { onClick: () => setIsStatusModalOpen(false), className: "w-full py-4 text-[13px] text-neutral-500 hover:text-black transition-colors outline-none" }, "Cancel")))), isRoleModalOpen && /* @__PURE__ */ import_react79.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react79.default.createElement("div", { className: "absolute inset-0 bg-black/40", onClick: () => setIsRoleModalOpen(false) }), /* @__PURE__ */ import_react79.default.createElement("div", { ref: roleDropdownRef, 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__ */ import_react79.default.createElement("div", { className: "p-6 text-center w-full mb-2" }, /* @__PURE__ */ import_react79.default.createElement("h3", { className: "text-[14px] text-black tracking-tight" }, "Role Filter")), /* @__PURE__ */ import_react79.default.createElement("div", { className: "w-full flex flex-col pl-2 pr-2 gap-1" }, ["ALL", "ADMIN", "MANAGER", "MEMBER", "GUEST"].map((option) => /* @__PURE__ */ import_react79.default.createElement(
|
|
4688
|
+
"button",
|
|
4689
|
+
{
|
|
4690
|
+
key: option,
|
|
4691
|
+
onClick: () => {
|
|
4692
|
+
onRoleFilterChange(option);
|
|
4693
|
+
setIsRoleModalOpen(false);
|
|
4694
|
+
},
|
|
4695
|
+
className: `text-left px-4 py-3 text-[11px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${activeRoleFilter === option ? "bg-neutral-100 text-black" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
|
|
4696
|
+
},
|
|
4697
|
+
/* @__PURE__ */ import_react79.default.createElement("span", { className: "truncate pr-2 capitalize" }, option.toLowerCase())
|
|
4698
|
+
))), /* @__PURE__ */ import_react79.default.createElement("div", { className: "w-full flex mt-2" }, /* @__PURE__ */ import_react79.default.createElement("button", { onClick: () => setIsRoleModalOpen(false), className: "w-full py-4 text-[13px] text-neutral-500 hover:text-black transition-colors outline-none" }, "Cancel")))));
|
|
4699
|
+
};
|
|
4700
|
+
|
|
4701
|
+
// src/components/UniversalHome2.tsx
|
|
4702
|
+
var import_react81 = __toESM(require("react"));
|
|
4703
|
+
var import_navigation6 = require("next/navigation");
|
|
4704
|
+
var import_react82 = require("@hugeicons/react");
|
|
4705
|
+
var import_core_free_icons29 = require("@hugeicons/core-free-icons");
|
|
4706
|
+
var UniversalHome2 = ({
|
|
4707
|
+
fullName = "",
|
|
4708
|
+
avatarSrc,
|
|
4709
|
+
createHuddleAction,
|
|
4710
|
+
joinHuddleAction,
|
|
4711
|
+
notifications = [],
|
|
4712
|
+
notificationPage = 1,
|
|
4713
|
+
notificationTotalPages = 1,
|
|
4714
|
+
isNotifsLoading = false,
|
|
4715
|
+
onNotificationPageChange,
|
|
4716
|
+
onNotificationClick,
|
|
4717
|
+
formatNotifDate,
|
|
4718
|
+
customContent,
|
|
4719
|
+
departmentsProps
|
|
4720
|
+
}) => {
|
|
4721
|
+
const [isAvatarLoaded, setIsAvatarLoaded] = (0, import_react81.useState)(false);
|
|
4722
|
+
const [showNotifDialog, setShowNotifDialog] = (0, import_react81.useState)(false);
|
|
4723
|
+
const [selectedNotif, setSelectedNotif] = (0, import_react81.useState)(null);
|
|
4724
|
+
const router = (0, import_navigation6.useRouter)();
|
|
4725
|
+
const fallbackAvatarUrl = "https://storage.googleapis.com/retina-cloud-v2/assets/images/avatar.avif";
|
|
4726
|
+
const finalAvatarSrc = avatarSrc || fallbackAvatarUrl;
|
|
4727
|
+
const hasUnreadNotifs = notifications.some((n) => !n.isRead);
|
|
4728
|
+
return /* @__PURE__ */ import_react81.default.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300 relative" }, /* @__PURE__ */ import_react81.default.createElement("div", { className: "flex items-center justify-between w-full pb-4" }, /* @__PURE__ */ import_react81.default.createElement("div", { className: "w-10 h-10 shrink-0 cursor-pointer", onClick: () => router.push("/app/account/me") }, /* @__PURE__ */ import_react81.default.createElement("div", { className: "relative w-full h-full rounded-lg overflow-hidden bg-neutral-100 flex items-center justify-center border border-neutral-200" }, !isAvatarLoaded && /* @__PURE__ */ import_react81.default.createElement("div", { className: "absolute inset-0 flex items-center justify-center z-10 bg-neutral-100" }, /* @__PURE__ */ import_react81.default.createElement(import_react82.HugeiconsIcon, { icon: import_core_free_icons29.Loading03Icon, size: 16, className: "animate-spin text-black" })), /* @__PURE__ */ import_react81.default.createElement(
|
|
4729
|
+
"img",
|
|
4730
|
+
{
|
|
4731
|
+
src: finalAvatarSrc,
|
|
4732
|
+
alt: "User Avatar",
|
|
4733
|
+
onLoad: () => setIsAvatarLoaded(true),
|
|
4734
|
+
className: `w-full h-full object-cover transition-opacity duration-300 ${isAvatarLoaded ? "opacity-100" : "opacity-0"}`
|
|
4735
|
+
}
|
|
4736
|
+
))), /* @__PURE__ */ import_react81.default.createElement(
|
|
4737
|
+
"button",
|
|
4738
|
+
{
|
|
4739
|
+
onClick: () => {
|
|
4740
|
+
setShowNotifDialog(true);
|
|
4741
|
+
setSelectedNotif(null);
|
|
4742
|
+
},
|
|
4743
|
+
className: "relative w-10 h-10 flex items-center justify-center rounded-full bg-white outline-none hover:bg-neutral-50 transition-colors"
|
|
4744
|
+
},
|
|
4745
|
+
/* @__PURE__ */ import_react81.default.createElement(import_react82.HugeiconsIcon, { icon: import_core_free_icons29.Notification01Icon, size: 20, className: "text-black" }),
|
|
4746
|
+
hasUnreadNotifs && /* @__PURE__ */ import_react81.default.createElement("span", { className: "absolute top-2.5 right-2.5 w-2 h-2 bg-red-500 rounded-full border border-white" })
|
|
4747
|
+
)), /* @__PURE__ */ import_react81.default.createElement("div", { className: "w-full pb-6 flex flex-col gap-4" }, /* @__PURE__ */ import_react81.default.createElement("div", { className: "grid grid-cols-2 gap-2" }, /* @__PURE__ */ import_react81.default.createElement(
|
|
4748
|
+
"div",
|
|
4749
|
+
{
|
|
4750
|
+
onClick: createHuddleAction?.onClick,
|
|
4751
|
+
className: "bg-[#143731] rounded-2xl p-5 relative overflow-hidden flex flex-col h-32 sm:h-36 cursor-pointer hover:opacity-90 transition-opacity"
|
|
4752
|
+
},
|
|
4753
|
+
/* @__PURE__ */ import_react81.default.createElement("div", { className: "relative z-10 flex flex-col h-full justify-between" }, /* @__PURE__ */ import_react81.default.createElement("p", { className: "text-[15px] sm:text-[15px] text-white leading-tight" }, "Create", /* @__PURE__ */ import_react81.default.createElement("br", null), /* @__PURE__ */ import_react81.default.createElement("span", { className: "text-white/70" }, "Huddle")), /* @__PURE__ */ import_react81.default.createElement("div", { className: "w-8 h-8 rounded-full bg-white/10 flex items-center justify-center" }, /* @__PURE__ */ import_react81.default.createElement(import_react82.HugeiconsIcon, { icon: import_core_free_icons29.ArrowUpRight01Icon, size: 16, className: "text-white" }))),
|
|
4754
|
+
/* @__PURE__ */ import_react81.default.createElement(
|
|
4755
|
+
"img",
|
|
4756
|
+
{
|
|
4757
|
+
src: "https://storage.googleapis.com/retina-cloud-v2/assets/images/cal_a.avif",
|
|
4758
|
+
alt: "Create Huddle",
|
|
4759
|
+
className: "absolute bottom-4 right-2 translate-x-1/4 translate-y-1/2 w-32 h-auto object-contain z-0 pointer-events-none drop-shadow-md"
|
|
4760
|
+
}
|
|
4761
|
+
)
|
|
4762
|
+
), /* @__PURE__ */ import_react81.default.createElement(
|
|
4763
|
+
"div",
|
|
4764
|
+
{
|
|
4765
|
+
onClick: joinHuddleAction?.onClick,
|
|
4766
|
+
className: "bg-[#ceff8a] rounded-2xl p-5 relative overflow-hidden flex flex-col h-32 sm:h-36 cursor-pointer hover:opacity-90 transition-opacity"
|
|
4767
|
+
},
|
|
4768
|
+
/* @__PURE__ */ import_react81.default.createElement("div", { className: "relative z-10 flex flex-col h-full justify-between" }, /* @__PURE__ */ import_react81.default.createElement("p", { className: "text-[15px] sm:text-[15px] text-black leading-tight" }, "Join", /* @__PURE__ */ import_react81.default.createElement("br", null), /* @__PURE__ */ import_react81.default.createElement("span", { className: "text-black/60" }, "Huddle")), /* @__PURE__ */ import_react81.default.createElement("div", { className: "w-8 h-8 rounded-full bg-black/5 flex items-center justify-center" }, /* @__PURE__ */ import_react81.default.createElement(import_react82.HugeiconsIcon, { icon: import_core_free_icons29.ArrowRight01Icon, size: 16, className: "text-black" }))),
|
|
4769
|
+
/* @__PURE__ */ import_react81.default.createElement(
|
|
4770
|
+
"img",
|
|
4771
|
+
{
|
|
4772
|
+
src: "https://storage.googleapis.com/retina-cloud-v2/assets/images/cam_a.avif",
|
|
4773
|
+
alt: "Join Huddle",
|
|
4774
|
+
className: "absolute bottom-4 right-2 translate-x-1/4 translate-y-1/2 w-32 h-auto object-contain z-0 pointer-events-none drop-shadow-md"
|
|
4775
|
+
}
|
|
4776
|
+
)
|
|
4777
|
+
))), customContent && /* @__PURE__ */ import_react81.default.createElement("div", { className: "w-full" }, customContent), /* @__PURE__ */ import_react81.default.createElement("div", { className: "w-full mt-2" }, /* @__PURE__ */ import_react81.default.createElement(
|
|
4778
|
+
UniversalDepartmentsPage,
|
|
4779
|
+
{
|
|
4780
|
+
...departmentsProps
|
|
4781
|
+
}
|
|
4782
|
+
)), showNotifDialog && /* @__PURE__ */ import_react81.default.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react81.default.createElement("div", { className: "absolute inset-0 bg-black/30", onClick: () => setShowNotifDialog(false) }), /* @__PURE__ */ import_react81.default.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 h-[80vh]" }, /* @__PURE__ */ import_react81.default.createElement("div", { className: "flex items-center justify-between p-5 shrink-0" }, selectedNotif ? /* @__PURE__ */ import_react81.default.createElement("button", { onClick: () => setSelectedNotif(null), className: "text-neutral-400 hover:text-black transition-colors outline-none flex items-center gap-2 text-[11px] tracking-widest" }, /* @__PURE__ */ import_react81.default.createElement(import_react82.HugeiconsIcon, { icon: import_core_free_icons29.ArrowLeft01Icon, size: 14 }), " Back") : /* @__PURE__ */ import_react81.default.createElement("h3", { className: "text-[15px] text-black tracking-tight flex items-center gap-2" }, "Notifications", isNotifsLoading && /* @__PURE__ */ import_react81.default.createElement(import_react82.HugeiconsIcon, { icon: import_core_free_icons29.Loading03Icon, size: 14, className: "animate-spin text-neutral-400" })), /* @__PURE__ */ import_react81.default.createElement("button", { onClick: () => setShowNotifDialog(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ import_react81.default.createElement(import_react82.HugeiconsIcon, { icon: import_core_free_icons29.CancelCircleIcon, size: 18 }))), /* @__PURE__ */ import_react81.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-2" }, selectedNotif ? /* @__PURE__ */ import_react81.default.createElement("div", { className: "p-4 text-left" }, /* @__PURE__ */ import_react81.default.createElement("h4", { className: "text-[14px] text-black mb-1" }, selectedNotif.title), /* @__PURE__ */ import_react81.default.createElement("span", { className: "text-[10px] text-neutral-400 tracking-widest mb-4 block" }, formatNotifDate(selectedNotif.createdAt)), /* @__PURE__ */ import_react81.default.createElement("p", { className: "text-[12px] text-neutral-600 leading-relaxed whitespace-pre-wrap" }, selectedNotif.message)) : /* @__PURE__ */ import_react81.default.createElement("div", { className: "flex flex-col divide-y divide-neutral-50/50" }, notifications?.length === 0 && !isNotifsLoading ? /* @__PURE__ */ import_react81.default.createElement("div", { className: "p-8 text-center text-xs text-neutral-400" }, "You have no notifications.") : notifications?.map((notif) => /* @__PURE__ */ import_react81.default.createElement(
|
|
4783
|
+
"div",
|
|
4784
|
+
{
|
|
4785
|
+
key: notif.id,
|
|
4786
|
+
onClick: () => {
|
|
4787
|
+
setSelectedNotif(notif);
|
|
4788
|
+
onNotificationClick?.(notif);
|
|
4789
|
+
},
|
|
4790
|
+
className: `p-3 flex items-start gap-3 rounded-xl cursor-pointer transition-colors ${isNotifsLoading ? "opacity-50 pointer-events-none" : "hover:bg-neutral-50"}`
|
|
4791
|
+
},
|
|
4792
|
+
/* @__PURE__ */ import_react81.default.createElement("div", { className: "mt-1.5 shrink-0" }, !notif.isRead ? /* @__PURE__ */ import_react81.default.createElement("div", { className: "w-1.5 h-1.5 bg-red-500 rounded-full" }) : /* @__PURE__ */ import_react81.default.createElement("div", { className: "w-1.5 h-1.5 bg-transparent" })),
|
|
4793
|
+
/* @__PURE__ */ import_react81.default.createElement("div", { className: "flex-1 min-w-0 text-left" }, /* @__PURE__ */ import_react81.default.createElement("h5", { className: `text-[12px] truncate ${notif.isRead ? "text-neutral-500" : "text-black"}` }, notif.title), /* @__PURE__ */ import_react81.default.createElement("p", { className: "text-[11px] text-neutral-400 truncate mt-0.5" }, notif.message), /* @__PURE__ */ import_react81.default.createElement("span", { className: "text-[9px] text-neutral-400 tracking-widest mt-2 block" }, formatNotifDate(notif.createdAt)))
|
|
4794
|
+
)))), !selectedNotif && /* @__PURE__ */ import_react81.default.createElement("div", { className: "p-4 flex items-center justify-between shrink-0" }, /* @__PURE__ */ import_react81.default.createElement("span", { className: "text-[10px] text-neutral-400 tracking-widest" }, "Page ", notificationPage, " of ", notificationTotalPages === 0 ? 1 : notificationTotalPages), /* @__PURE__ */ import_react81.default.createElement("div", { className: "flex gap-1" }, /* @__PURE__ */ import_react81.default.createElement(
|
|
4795
|
+
"button",
|
|
4796
|
+
{
|
|
4797
|
+
disabled: notificationPage <= 1 || isNotifsLoading,
|
|
4798
|
+
onClick: () => onNotificationPageChange?.(notificationPage - 1),
|
|
4799
|
+
className: "w-7 h-7 flex items-center justify-center rounded-full bg-white border border-neutral-200 text-neutral-600 disabled:opacity-30 outline-none hover:bg-neutral-50 transition-colors"
|
|
4800
|
+
},
|
|
4801
|
+
/* @__PURE__ */ import_react81.default.createElement(import_react82.HugeiconsIcon, { icon: import_core_free_icons29.ArrowLeft01Icon, size: 12 })
|
|
4802
|
+
), /* @__PURE__ */ import_react81.default.createElement(
|
|
4803
|
+
"button",
|
|
4804
|
+
{
|
|
4805
|
+
disabled: notificationPage >= notificationTotalPages || notificationTotalPages === 0 || isNotifsLoading,
|
|
4806
|
+
onClick: () => onNotificationPageChange?.(notificationPage + 1),
|
|
4807
|
+
className: "w-7 h-7 flex items-center justify-center rounded-full bg-white border border-neutral-200 text-neutral-600 disabled:opacity-30 outline-none hover:bg-neutral-50 transition-colors"
|
|
4808
|
+
},
|
|
4809
|
+
/* @__PURE__ */ import_react81.default.createElement(import_react82.HugeiconsIcon, { icon: import_core_free_icons29.ArrowRight01Icon, size: 12 })
|
|
4810
|
+
))))));
|
|
4811
|
+
};
|
|
4455
4812
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4456
4813
|
0 && (module.exports = {
|
|
4457
4814
|
AppBento2,
|
|
@@ -4487,8 +4844,11 @@ var UniversalBuyCryptoPage = ({
|
|
|
4487
4844
|
UniversalBuyCryptoPage,
|
|
4488
4845
|
UniversalCardActionPage,
|
|
4489
4846
|
UniversalCardPage,
|
|
4847
|
+
UniversalDepartmentsPage,
|
|
4490
4848
|
UniversalErrorView,
|
|
4849
|
+
UniversalHome2,
|
|
4491
4850
|
UniversalHomeView,
|
|
4851
|
+
UniversalMembersPage,
|
|
4492
4852
|
UniversalOrganizationPage,
|
|
4493
4853
|
UniversalProfilePage,
|
|
4494
4854
|
UniversalProfileSettings,
|
package/dist/index.mjs
CHANGED
|
@@ -302,8 +302,8 @@ var InputSpinner = () => /* @__PURE__ */ React5.createElement("svg", { className
|
|
|
302
302
|
function AuthFormInner({
|
|
303
303
|
companyName,
|
|
304
304
|
workspaceLabel = "Workspace",
|
|
305
|
-
termsUrl = "
|
|
306
|
-
privacyUrl = "
|
|
305
|
+
termsUrl = "",
|
|
306
|
+
privacyUrl = "",
|
|
307
307
|
requireNames = true,
|
|
308
308
|
requireOrganization = true,
|
|
309
309
|
useRecaptcha = false,
|
|
@@ -317,12 +317,13 @@ function AuthFormInner({
|
|
|
317
317
|
const [mode, setMode] = useState3("LOGIN");
|
|
318
318
|
const [step, setStep] = useState3("INPUT");
|
|
319
319
|
const getInitialSignupStep = () => {
|
|
320
|
-
return "
|
|
320
|
+
if (requireNames) return "NAME";
|
|
321
|
+
if (requireOrganization) return "ORGANIZATION";
|
|
322
|
+
return "EMAIL_ID";
|
|
321
323
|
};
|
|
322
324
|
const [signupStep, setSignupStep] = useState3(getInitialSignupStep());
|
|
323
325
|
const [isSubmitting, setIsSubmitting] = useState3(false);
|
|
324
326
|
const [countdown, setCountdown] = useState3(0);
|
|
325
|
-
const [invitationCode, setInvitationCode] = useState3("");
|
|
326
327
|
const [emailId, setEmailId] = useState3("");
|
|
327
328
|
const [firstName, setFirstName] = useState3("");
|
|
328
329
|
const [lastName, setLastName] = useState3("");
|
|
@@ -378,12 +379,13 @@ function AuthFormInner({
|
|
|
378
379
|
if (useRecaptcha && captchaContext?.executeRecaptcha) {
|
|
379
380
|
recaptchaToken = await captchaContext.executeRecaptcha("auth_request");
|
|
380
381
|
}
|
|
382
|
+
const hasOrg = mode === "SIGNUP" && requireOrganization && orgName.trim().length > 0;
|
|
381
383
|
const res = await onAuthRequest({
|
|
382
384
|
email: emailId,
|
|
383
385
|
firstName: mode === "SIGNUP" && requireNames ? firstName : void 0,
|
|
384
386
|
lastName: mode === "SIGNUP" && requireNames ? lastName : void 0,
|
|
385
|
-
organizationName:
|
|
386
|
-
|
|
387
|
+
organizationName: hasOrg ? orgName.trim() : void 0,
|
|
388
|
+
accountType: hasOrg ? "ORGANIZATION" : "INDIVIDUAL",
|
|
387
389
|
mode,
|
|
388
390
|
recaptchaToken
|
|
389
391
|
});
|
|
@@ -439,11 +441,7 @@ function AuthFormInner({
|
|
|
439
441
|
}
|
|
440
442
|
};
|
|
441
443
|
const handleNextSignupStep = () => {
|
|
442
|
-
if (signupStep === "
|
|
443
|
-
if (requireNames) setSignupStep("NAME");
|
|
444
|
-
else if (requireOrganization) setSignupStep("ORGANIZATION");
|
|
445
|
-
else setSignupStep("EMAIL_ID");
|
|
446
|
-
} else if (signupStep === "NAME") {
|
|
444
|
+
if (signupStep === "NAME") {
|
|
447
445
|
if (requireOrganization) setSignupStep("ORGANIZATION");
|
|
448
446
|
else setSignupStep("EMAIL_ID");
|
|
449
447
|
} else if (signupStep === "ORGANIZATION") {
|
|
@@ -454,7 +452,6 @@ function AuthFormInner({
|
|
|
454
452
|
if (isSubmitting) return true;
|
|
455
453
|
if (mode === "LOGIN") return emailId.length < 3;
|
|
456
454
|
if (mode === "SIGNUP") {
|
|
457
|
-
if (signupStep === "INVITATION") return invitationCode.trim().length > 0 && invitationCode.trim().length < 3;
|
|
458
455
|
if (signupStep === "NAME") return firstName.trim() === "" || lastName.trim() === "";
|
|
459
456
|
if (signupStep === "ORGANIZATION") return orgName.trim().length < 3;
|
|
460
457
|
if (signupStep === "EMAIL_ID") return emailId.length < 3 || !agreedToTerms;
|
|
@@ -466,21 +463,10 @@ function AuthFormInner({
|
|
|
466
463
|
setSignupStep(getInitialSignupStep());
|
|
467
464
|
}, 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) => {
|
|
468
465
|
e.preventDefault();
|
|
469
|
-
if (mode === "SIGNUP" && signupStep === "
|
|
470
|
-
else if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
|
|
466
|
+
if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
|
|
471
467
|
else if (mode === "SIGNUP" && signupStep === "ORGANIZATION") handleNextSignupStep();
|
|
472
468
|
else handleAuthRequestSubmit();
|
|
473
|
-
} }, mode === "SIGNUP" && signupStep === "
|
|
474
|
-
"input",
|
|
475
|
-
{
|
|
476
|
-
type: "text",
|
|
477
|
-
value: invitationCode,
|
|
478
|
-
onChange: (e) => setInvitationCode(e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, "")),
|
|
479
|
-
autoFocus: true,
|
|
480
|
-
className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300 tracking-widest",
|
|
481
|
-
placeholder: "Referral Code (Optional)"
|
|
482
|
-
}
|
|
483
|
-
))), 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("input", { type: "text", value: firstName, onChange: (e) => setFirstName(cleanAlpha(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "First name" })), /* @__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("input", { type: "text", value: lastName, onChange: (e) => setLastName(cleanAlpha(e.target.value)), required: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Last name" }))), 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("input", { type: "text", value: orgName, onChange: (e) => setOrgName(cleanOrgName(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Acme Corporation" }))), (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("input", { type: "email", value: emailId, onChange: (e) => setEmailId(cleanEmailId(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "name@company.com" })), mode === "SIGNUP" && /* @__PURE__ */ React5.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ React5.createElement("input", { type: "checkbox", id: "zairus-terms", checked: agreedToTerms, onChange: (e) => setAgreedToTerms(e.target.checked), className: "mt-0.5 w-4 h-4 bg-white border-neutral-300 rounded text-black focus:ring-black cursor-pointer", required: true }), /* @__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(ThreeDActionButton, { type: "submit", disabled: isContinueDisabled(), isLoading: isSubmitting, className: "w-full mt-10" }, "Continue"))), 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" }, userHas2FA ? "Enter the code from your authenticator app." : `Enter the code sent to ${emailId}`)), /* @__PURE__ */ React5.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
|
|
469
|
+
} }, 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("input", { type: "text", value: firstName, onChange: (e) => setFirstName(cleanAlpha(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "First name" })), /* @__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("input", { type: "text", value: lastName, onChange: (e) => setLastName(cleanAlpha(e.target.value)), required: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Last name" }))), 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("input", { type: "text", value: orgName, onChange: (e) => setOrgName(cleanOrgName(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Acme Corporation" }))), (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("input", { type: "email", value: emailId, onChange: (e) => setEmailId(cleanEmailId(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "name@company.com" })), mode === "SIGNUP" && /* @__PURE__ */ React5.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ React5.createElement("input", { type: "checkbox", id: "zairus-terms", checked: agreedToTerms, onChange: (e) => setAgreedToTerms(e.target.checked), className: "mt-0.5 w-4 h-4 bg-white border-neutral-300 rounded text-black focus:ring-black cursor-pointer", required: true }), /* @__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(ThreeDActionButton, { type: "submit", disabled: isContinueDisabled(), isLoading: isSubmitting, className: "w-full mt-10" }, "Continue"))), 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" }, userHas2FA ? "Enter the code from your authenticator app." : `Enter the code sent to ${emailId}`)), /* @__PURE__ */ React5.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
|
|
484
470
|
e.preventDefault();
|
|
485
471
|
verifyOtpCode(otp.join(""));
|
|
486
472
|
} }, /* @__PURE__ */ React5.createElement("div", { className: "flex justify-between gap-2", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ React5.createElement(
|
|
@@ -4468,6 +4454,388 @@ var UniversalBuyCryptoPage = ({
|
|
|
4468
4454
|
);
|
|
4469
4455
|
}))))));
|
|
4470
4456
|
};
|
|
4457
|
+
|
|
4458
|
+
// src/components/UniversalDepartmentsPage.tsx
|
|
4459
|
+
import React46 from "react";
|
|
4460
|
+
import { HugeiconsIcon as HugeiconsIcon32 } from "@hugeicons/react";
|
|
4461
|
+
import { ArrowLeft01Icon as ArrowLeft01Icon13, ArrowRight01Icon as ArrowRight01Icon9, Loading03Icon as Loading03Icon20 } from "@hugeicons/core-free-icons";
|
|
4462
|
+
var formatMembersCount = (num) => {
|
|
4463
|
+
if (num >= 1e6) return (num / 1e6).toFixed(1) + "m";
|
|
4464
|
+
if (num >= 1e3) return (num / 1e3).toFixed(1) + "k";
|
|
4465
|
+
return num.toString();
|
|
4466
|
+
};
|
|
4467
|
+
var PageSpinner6 = () => /* @__PURE__ */ React46.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ React46.createElement(HugeiconsIcon32, { icon: Loading03Icon20, size: 32, className: "animate-spin mb-4 text-black" }));
|
|
4468
|
+
var UniversalDepartmentsPage = ({
|
|
4469
|
+
headerTitle,
|
|
4470
|
+
headerDescription,
|
|
4471
|
+
departments,
|
|
4472
|
+
isLoading,
|
|
4473
|
+
currentPage,
|
|
4474
|
+
totalPages,
|
|
4475
|
+
onPageChange,
|
|
4476
|
+
onDepartmentClick
|
|
4477
|
+
}) => {
|
|
4478
|
+
return /* @__PURE__ */ React46.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300" }, /* @__PURE__ */ React46.createElement("div", { className: "flex flex-col gap-8 p-6 rounded-2xl bg-white w-full" }, /* @__PURE__ */ React46.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-4" }, /* @__PURE__ */ React46.createElement("div", null, /* @__PURE__ */ React46.createElement("h1", { className: "text-black text-xl mb-1 tracking-tight" }, headerTitle), headerDescription && /* @__PURE__ */ React46.createElement("p", { className: "text-[12px] text-neutral-500" }, headerDescription))), /* @__PURE__ */ React46.createElement("div", { className: "w-full overflow-hidden" }, isLoading ? /* @__PURE__ */ React46.createElement(PageSpinner6, null) : /* @__PURE__ */ React46.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ React46.createElement("div", null, departments.length === 0 ? /* @__PURE__ */ React46.createElement("p", { className: "text-[12px] text-neutral-400 py-6 text-center" }, "No departments available") : departments.map((dept) => /* @__PURE__ */ React46.createElement(
|
|
4479
|
+
"div",
|
|
4480
|
+
{
|
|
4481
|
+
key: dept.id,
|
|
4482
|
+
onClick: () => onDepartmentClick(dept.id),
|
|
4483
|
+
className: "flex flex-col py-4 hover:bg-neutral-50 transition-colors cursor-pointer group min-w-0 px-3 -mx-3 rounded-xl gap-2"
|
|
4484
|
+
},
|
|
4485
|
+
/* @__PURE__ */ React46.createElement("p", { className: "text-[14px] text-black tracking-tight truncate" }, dept.name),
|
|
4486
|
+
/* @__PURE__ */ React46.createElement("div", { className: "flex items-center gap-3 min-w-0" }, dept.avatars && dept.avatars.length > 0 && /* @__PURE__ */ React46.createElement("div", { className: "flex items-center -space-x-2 shrink-0" }, dept.avatars.slice(0, 4).map((src, idx) => /* @__PURE__ */ React46.createElement("div", { key: idx, className: "w-7 h-7 rounded-lg border-2 border-white bg-neutral-100 overflow-hidden shrink-0" }, /* @__PURE__ */ React46.createElement(
|
|
4487
|
+
"img",
|
|
4488
|
+
{
|
|
4489
|
+
src: src || "https://storage.googleapis.com/retina-cloud-v2/assets/images/avatar.avif",
|
|
4490
|
+
alt: "Member",
|
|
4491
|
+
className: "w-full h-full object-cover"
|
|
4492
|
+
}
|
|
4493
|
+
)))), dept.totalMembers > 0 ? /* @__PURE__ */ React46.createElement("span", { className: "text-[11px] text-neutral-500 truncate block" }, formatMembersCount(dept.totalMembers), " ", dept.totalMembers > 4 ? "+" : "") : /* @__PURE__ */ React46.createElement("span", { className: "text-[11px] text-neutral-400 truncate block" }, "Empty"))
|
|
4494
|
+
))), /* @__PURE__ */ React46.createElement("div", { className: "flex items-center justify-between pt-6 mt-2" }, /* @__PURE__ */ React46.createElement("span", { className: "text-[11px] text-neutral-400 tracking-[0.2em]" }, "Page ", currentPage, " of ", totalPages === 0 ? 1 : totalPages), /* @__PURE__ */ React46.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React46.createElement(
|
|
4495
|
+
"button",
|
|
4496
|
+
{
|
|
4497
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
4498
|
+
disabled: currentPage <= 1 || isLoading,
|
|
4499
|
+
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"
|
|
4500
|
+
},
|
|
4501
|
+
/* @__PURE__ */ React46.createElement(HugeiconsIcon32, { icon: ArrowLeft01Icon13, size: 14 })
|
|
4502
|
+
), /* @__PURE__ */ React46.createElement(
|
|
4503
|
+
"button",
|
|
4504
|
+
{
|
|
4505
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
4506
|
+
disabled: currentPage >= totalPages || isLoading || totalPages === 0,
|
|
4507
|
+
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"
|
|
4508
|
+
},
|
|
4509
|
+
/* @__PURE__ */ React46.createElement(HugeiconsIcon32, { icon: ArrowRight01Icon9, size: 14 })
|
|
4510
|
+
)))))));
|
|
4511
|
+
};
|
|
4512
|
+
|
|
4513
|
+
// src/components/UniversalMembersPage.tsx
|
|
4514
|
+
import React47, { useState as useState32, useEffect as useEffect18, useRef as useRef12 } from "react";
|
|
4515
|
+
import { HugeiconsIcon as HugeiconsIcon33 } from "@hugeicons/react";
|
|
4516
|
+
import toast12 from "react-hot-toast";
|
|
4517
|
+
import {
|
|
4518
|
+
ArrowLeft01Icon as ArrowLeft01Icon14,
|
|
4519
|
+
ArrowRight01Icon as ArrowRight01Icon10,
|
|
4520
|
+
Loading03Icon as Loading03Icon21,
|
|
4521
|
+
Search01Icon as Search01Icon3,
|
|
4522
|
+
SearchList02Icon as SearchList02Icon2,
|
|
4523
|
+
ListSettingIcon as ListSettingIcon2
|
|
4524
|
+
} from "@hugeicons/core-free-icons";
|
|
4525
|
+
var MemberAvatar = ({ src, status }) => {
|
|
4526
|
+
const [loaded, setLoaded] = useState32(false);
|
|
4527
|
+
const [error, setError] = useState32(false);
|
|
4528
|
+
const defaultAvatar = "https://storage.googleapis.com/retina-cloud-v2/assets/images/avatar.avif";
|
|
4529
|
+
const finalSrc = error || !src ? defaultAvatar : src;
|
|
4530
|
+
const getStatusColor = () => {
|
|
4531
|
+
switch (status?.toUpperCase()) {
|
|
4532
|
+
case "ACTIVE":
|
|
4533
|
+
return "bg-emerald-500";
|
|
4534
|
+
case "BUSY":
|
|
4535
|
+
return "bg-amber-500";
|
|
4536
|
+
case "OFFLINE":
|
|
4537
|
+
return "bg-rose-500";
|
|
4538
|
+
case "AWAY":
|
|
4539
|
+
return "bg-neutral-400";
|
|
4540
|
+
default:
|
|
4541
|
+
return "bg-neutral-200";
|
|
4542
|
+
}
|
|
4543
|
+
};
|
|
4544
|
+
return /* @__PURE__ */ React47.createElement("div", { className: "relative w-10 h-10 shrink-0" }, /* @__PURE__ */ React47.createElement("div", { className: "w-full h-full rounded-lg bg-neutral-100 flex items-center justify-center overflow-hidden border border-neutral-200" }, !loaded && !error && /* @__PURE__ */ React47.createElement(HugeiconsIcon33, { icon: Loading03Icon21, className: "animate-spin text-neutral-400 absolute", size: 14 }), /* @__PURE__ */ React47.createElement(
|
|
4545
|
+
"img",
|
|
4546
|
+
{
|
|
4547
|
+
src: finalSrc,
|
|
4548
|
+
alt: "Member Avatar",
|
|
4549
|
+
className: `w-full h-full object-cover transition-opacity duration-300 ${loaded || error ? "opacity-100" : "opacity-0"}`,
|
|
4550
|
+
onLoad: () => setLoaded(true),
|
|
4551
|
+
onError: () => setError(true)
|
|
4552
|
+
}
|
|
4553
|
+
)), /* @__PURE__ */ React47.createElement("div", { className: `absolute -bottom-1 -right-1 w-3.5 h-3.5 rounded-full border-2 border-white z-10 ${getStatusColor()}` }));
|
|
4554
|
+
};
|
|
4555
|
+
var PageSpinner7 = () => /* @__PURE__ */ React47.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ React47.createElement(HugeiconsIcon33, { icon: Loading03Icon21, size: 32, className: "animate-spin mb-4 text-black" }));
|
|
4556
|
+
var UniversalMembersPage = ({
|
|
4557
|
+
headerTitle,
|
|
4558
|
+
headerDescription,
|
|
4559
|
+
members,
|
|
4560
|
+
isLoading,
|
|
4561
|
+
currentPage,
|
|
4562
|
+
totalPages,
|
|
4563
|
+
onPageChange,
|
|
4564
|
+
searchQuery,
|
|
4565
|
+
onSearchChange,
|
|
4566
|
+
activeStatusFilter,
|
|
4567
|
+
onStatusFilterChange,
|
|
4568
|
+
activeRoleFilter,
|
|
4569
|
+
onRoleFilterChange,
|
|
4570
|
+
actionButtonText,
|
|
4571
|
+
hideAction = false,
|
|
4572
|
+
onRemoveMember
|
|
4573
|
+
}) => {
|
|
4574
|
+
const [expandedId, setExpandedId] = useState32(null);
|
|
4575
|
+
const [memberToRemove, setMemberToRemove] = useState32(null);
|
|
4576
|
+
const [isRemoving, setIsRemoving] = useState32(false);
|
|
4577
|
+
const [localSearchQuery, setLocalSearchQuery] = useState32(searchQuery);
|
|
4578
|
+
const [isTyping, setIsTyping] = useState32(false);
|
|
4579
|
+
const [isStatusModalOpen, setIsStatusModalOpen] = useState32(false);
|
|
4580
|
+
const [isRoleModalOpen, setIsRoleModalOpen] = useState32(false);
|
|
4581
|
+
const statusDropdownRef = useRef12(null);
|
|
4582
|
+
const roleDropdownRef = useRef12(null);
|
|
4583
|
+
useEffect18(() => {
|
|
4584
|
+
function handleClickOutside(event) {
|
|
4585
|
+
if (statusDropdownRef.current && !statusDropdownRef.current.contains(event.target)) {
|
|
4586
|
+
setIsStatusModalOpen(false);
|
|
4587
|
+
}
|
|
4588
|
+
if (roleDropdownRef.current && !roleDropdownRef.current.contains(event.target)) {
|
|
4589
|
+
setIsRoleModalOpen(false);
|
|
4590
|
+
}
|
|
4591
|
+
}
|
|
4592
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
4593
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
4594
|
+
}, []);
|
|
4595
|
+
useEffect18(() => {
|
|
4596
|
+
setIsTyping(true);
|
|
4597
|
+
const handler = setTimeout(() => {
|
|
4598
|
+
onSearchChange(localSearchQuery);
|
|
4599
|
+
setIsTyping(false);
|
|
4600
|
+
}, 600);
|
|
4601
|
+
return () => clearTimeout(handler);
|
|
4602
|
+
}, [localSearchQuery, onSearchChange]);
|
|
4603
|
+
useEffect18(() => {
|
|
4604
|
+
if (searchQuery === "" && localSearchQuery !== "") {
|
|
4605
|
+
setLocalSearchQuery("");
|
|
4606
|
+
}
|
|
4607
|
+
}, [searchQuery]);
|
|
4608
|
+
const handleConfirmRemove = async () => {
|
|
4609
|
+
if (!memberToRemove) return;
|
|
4610
|
+
setIsRemoving(true);
|
|
4611
|
+
try {
|
|
4612
|
+
await onRemoveMember(memberToRemove.id);
|
|
4613
|
+
toast12.success("Member removed successfully.");
|
|
4614
|
+
setExpandedId(null);
|
|
4615
|
+
setMemberToRemove(null);
|
|
4616
|
+
} catch (error) {
|
|
4617
|
+
toast12.error("Failed to remove member.");
|
|
4618
|
+
} finally {
|
|
4619
|
+
setIsRemoving(false);
|
|
4620
|
+
}
|
|
4621
|
+
};
|
|
4622
|
+
const isListLoading = isLoading || isTyping;
|
|
4623
|
+
return /* @__PURE__ */ React47.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300" }, /* @__PURE__ */ React47.createElement(ManagedToaster, null), /* @__PURE__ */ React47.createElement(
|
|
4624
|
+
ConfirmationDialog,
|
|
4625
|
+
{
|
|
4626
|
+
isOpen: !!memberToRemove,
|
|
4627
|
+
title: "Remove Member",
|
|
4628
|
+
message: `Are you sure you want to remove ${memberToRemove?.name}? This action cannot be undone.`,
|
|
4629
|
+
confirmText: "Remove",
|
|
4630
|
+
cancelText: "Cancel",
|
|
4631
|
+
isProcessing: isRemoving,
|
|
4632
|
+
isDestructive: true,
|
|
4633
|
+
onClose: () => setMemberToRemove(null),
|
|
4634
|
+
onConfirm: handleConfirmRemove
|
|
4635
|
+
}
|
|
4636
|
+
), /* @__PURE__ */ React47.createElement("div", { className: "flex flex-row flex-nowrap mb-4 items-center justify-between gap-4 w-full" }, /* @__PURE__ */ React47.createElement("div", { className: "relative flex-1 min-w-0 max-w-full" }, /* @__PURE__ */ React47.createElement("div", { className: "absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none" }, /* @__PURE__ */ React47.createElement(HugeiconsIcon33, { icon: Search01Icon3, size: 16, className: "text-neutral-400" })), /* @__PURE__ */ React47.createElement(
|
|
4637
|
+
"input",
|
|
4638
|
+
{
|
|
4639
|
+
type: "text",
|
|
4640
|
+
placeholder: "Search members...",
|
|
4641
|
+
value: localSearchQuery,
|
|
4642
|
+
onChange: (e) => setLocalSearchQuery(e.target.value),
|
|
4643
|
+
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"
|
|
4644
|
+
}
|
|
4645
|
+
)), /* @__PURE__ */ React47.createElement("div", { className: "flex items-center gap-3 w-auto pb-0 shrink-0" }, /* @__PURE__ */ React47.createElement(
|
|
4646
|
+
"button",
|
|
4647
|
+
{
|
|
4648
|
+
onClick: () => setIsStatusModalOpen(true),
|
|
4649
|
+
className: "flex items-center justify-center bg-white w-9 h-9 rounded-full text-neutral-500 hover:text-black transition-colors outline-none"
|
|
4650
|
+
},
|
|
4651
|
+
/* @__PURE__ */ React47.createElement(HugeiconsIcon33, { icon: SearchList02Icon2, size: 16 })
|
|
4652
|
+
), /* @__PURE__ */ React47.createElement(
|
|
4653
|
+
"button",
|
|
4654
|
+
{
|
|
4655
|
+
onClick: () => setIsRoleModalOpen(true),
|
|
4656
|
+
className: "flex items-center justify-center bg-white w-9 h-9 rounded-full text-neutral-500 hover:text-black transition-colors outline-none"
|
|
4657
|
+
},
|
|
4658
|
+
/* @__PURE__ */ React47.createElement(HugeiconsIcon33, { icon: ListSettingIcon2, size: 16 })
|
|
4659
|
+
))), /* @__PURE__ */ React47.createElement("div", { className: "flex flex-col gap-8 p-6 rounded-2xl bg-white w-full" }, /* @__PURE__ */ React47.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-4" }, /* @__PURE__ */ React47.createElement("div", null, /* @__PURE__ */ React47.createElement("h1", { className: "text-black text-xl mb-1 tracking-tight" }, headerTitle), headerDescription && /* @__PURE__ */ React47.createElement("p", { className: "text-[12px] text-neutral-500" }, headerDescription))), /* @__PURE__ */ React47.createElement("div", { className: "w-full overflow-hidden" }, isListLoading ? /* @__PURE__ */ React47.createElement(PageSpinner7, null) : /* @__PURE__ */ React47.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ React47.createElement("div", null, members.length === 0 ? /* @__PURE__ */ React47.createElement("p", { className: "text-[12px] text-neutral-400 py-6 text-center" }, "No members found") : members.map((member) => /* @__PURE__ */ React47.createElement(React47.Fragment, { key: member.id }, expandedId === member.id ? /* @__PURE__ */ React47.createElement("div", { className: "flex flex-col p-5 bg-neutral-50 rounded-xl animate-in fade-in zoom-in-95 duration-200 gap-5 my-2" }, /* @__PURE__ */ React47.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React47.createElement(MemberAvatar, { src: member.avatarUrl, status: member.status }), /* @__PURE__ */ React47.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ React47.createElement("span", { className: "text-[14px] text-black tracking-tight truncate" }, member.name), /* @__PURE__ */ React47.createElement("span", { className: "text-[12px] text-neutral-500 capitalize" }, member.role.toLowerCase()))), member.departmentName && /* @__PURE__ */ React47.createElement("div", { className: "pt-3 border-t border-neutral-200" }, /* @__PURE__ */ React47.createElement("span", { className: "text-[10px] tracking-[0.2em] text-neutral-400 block mb-1" }, "Department"), /* @__PURE__ */ React47.createElement("span", { className: "text-[13px] text-black truncate block" }, member.departmentName)), /* @__PURE__ */ React47.createElement("div", { className: "flex gap-3 pt-2" }, !hideAction && /* @__PURE__ */ React47.createElement(
|
|
4660
|
+
"button",
|
|
4661
|
+
{
|
|
4662
|
+
onClick: () => setMemberToRemove(member),
|
|
4663
|
+
className: "flex-1 py-2.5 bg-white border border-rose-200 text-rose-600 hover:bg-rose-50 rounded-full text-[12px] tracking-wide transition-colors outline-none"
|
|
4664
|
+
},
|
|
4665
|
+
actionButtonText
|
|
4666
|
+
), /* @__PURE__ */ React47.createElement(
|
|
4667
|
+
"button",
|
|
4668
|
+
{
|
|
4669
|
+
onClick: () => setExpandedId(null),
|
|
4670
|
+
className: "flex-1 py-2.5 bg-white border border-neutral-200 text-black hover:bg-neutral-100 rounded-full text-[12px] tracking-wide transition-colors outline-none"
|
|
4671
|
+
},
|
|
4672
|
+
"Close"
|
|
4673
|
+
))) : /* @__PURE__ */ React47.createElement(
|
|
4674
|
+
"div",
|
|
4675
|
+
{
|
|
4676
|
+
onClick: () => setExpandedId(member.id),
|
|
4677
|
+
className: "flex items-center justify-between py-3 hover:bg-neutral-50 transition-colors cursor-pointer group min-w-0 px-3 -mx-3 rounded-xl"
|
|
4678
|
+
},
|
|
4679
|
+
/* @__PURE__ */ React47.createElement("div", { className: "flex items-center gap-4 min-w-0 flex-1" }, /* @__PURE__ */ React47.createElement(MemberAvatar, { src: member.avatarUrl, status: member.status }), /* @__PURE__ */ React47.createElement("div", { className: "min-w-0 flex-1 flex flex-col gap-0.5" }, /* @__PURE__ */ React47.createElement("p", { className: "text-[13px] text-black truncate" }, member.name), /* @__PURE__ */ React47.createElement("p", { className: "text-[11px] text-neutral-500 capitalize truncate" }, member.role.toLowerCase())))
|
|
4680
|
+
)))), /* @__PURE__ */ React47.createElement("div", { className: "flex items-center justify-between pt-6 mt-2" }, /* @__PURE__ */ React47.createElement("span", { className: "text-[11px] text-neutral-400 tracking-[0.2em]" }, "Page ", currentPage, " of ", totalPages === 0 ? 1 : totalPages), /* @__PURE__ */ React47.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React47.createElement(
|
|
4681
|
+
"button",
|
|
4682
|
+
{
|
|
4683
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
4684
|
+
disabled: currentPage <= 1 || isListLoading,
|
|
4685
|
+
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"
|
|
4686
|
+
},
|
|
4687
|
+
/* @__PURE__ */ React47.createElement(HugeiconsIcon33, { icon: ArrowLeft01Icon14, size: 14 })
|
|
4688
|
+
), /* @__PURE__ */ React47.createElement(
|
|
4689
|
+
"button",
|
|
4690
|
+
{
|
|
4691
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
4692
|
+
disabled: currentPage >= totalPages || isListLoading || totalPages === 0,
|
|
4693
|
+
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"
|
|
4694
|
+
},
|
|
4695
|
+
/* @__PURE__ */ React47.createElement(HugeiconsIcon33, { icon: ArrowRight01Icon10, size: 14 })
|
|
4696
|
+
)))))), isStatusModalOpen && /* @__PURE__ */ React47.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ React47.createElement("div", { className: "absolute inset-0 bg-black/40", onClick: () => setIsStatusModalOpen(false) }), /* @__PURE__ */ React47.createElement("div", { ref: statusDropdownRef, 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__ */ React47.createElement("div", { className: "p-6 text-center w-full mb-2" }, /* @__PURE__ */ React47.createElement("h3", { className: "text-[14px] text-black tracking-tight" }, "Status Filter")), /* @__PURE__ */ React47.createElement("div", { className: "w-full flex flex-col pl-2 pr-2 gap-1" }, ["ALL", "ACTIVE", "BUSY", "OFFLINE", "AWAY"].map((option) => /* @__PURE__ */ React47.createElement(
|
|
4697
|
+
"button",
|
|
4698
|
+
{
|
|
4699
|
+
key: option,
|
|
4700
|
+
onClick: () => {
|
|
4701
|
+
onStatusFilterChange(option);
|
|
4702
|
+
setIsStatusModalOpen(false);
|
|
4703
|
+
},
|
|
4704
|
+
className: `text-left px-4 py-3 text-[11px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${activeStatusFilter === option ? "bg-neutral-100 text-black" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
|
|
4705
|
+
},
|
|
4706
|
+
/* @__PURE__ */ React47.createElement("span", { className: "truncate pr-2 capitalize" }, option.toLowerCase())
|
|
4707
|
+
))), /* @__PURE__ */ React47.createElement("div", { className: "w-full flex mt-2" }, /* @__PURE__ */ React47.createElement("button", { onClick: () => setIsStatusModalOpen(false), className: "w-full py-4 text-[13px] text-neutral-500 hover:text-black transition-colors outline-none" }, "Cancel")))), isRoleModalOpen && /* @__PURE__ */ React47.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ React47.createElement("div", { className: "absolute inset-0 bg-black/40", onClick: () => setIsRoleModalOpen(false) }), /* @__PURE__ */ React47.createElement("div", { ref: roleDropdownRef, 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__ */ React47.createElement("div", { className: "p-6 text-center w-full mb-2" }, /* @__PURE__ */ React47.createElement("h3", { className: "text-[14px] text-black tracking-tight" }, "Role Filter")), /* @__PURE__ */ React47.createElement("div", { className: "w-full flex flex-col pl-2 pr-2 gap-1" }, ["ALL", "ADMIN", "MANAGER", "MEMBER", "GUEST"].map((option) => /* @__PURE__ */ React47.createElement(
|
|
4708
|
+
"button",
|
|
4709
|
+
{
|
|
4710
|
+
key: option,
|
|
4711
|
+
onClick: () => {
|
|
4712
|
+
onRoleFilterChange(option);
|
|
4713
|
+
setIsRoleModalOpen(false);
|
|
4714
|
+
},
|
|
4715
|
+
className: `text-left px-4 py-3 text-[11px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${activeRoleFilter === option ? "bg-neutral-100 text-black" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
|
|
4716
|
+
},
|
|
4717
|
+
/* @__PURE__ */ React47.createElement("span", { className: "truncate pr-2 capitalize" }, option.toLowerCase())
|
|
4718
|
+
))), /* @__PURE__ */ React47.createElement("div", { className: "w-full flex mt-2" }, /* @__PURE__ */ React47.createElement("button", { onClick: () => setIsRoleModalOpen(false), className: "w-full py-4 text-[13px] text-neutral-500 hover:text-black transition-colors outline-none" }, "Cancel")))));
|
|
4719
|
+
};
|
|
4720
|
+
|
|
4721
|
+
// src/components/UniversalHome2.tsx
|
|
4722
|
+
import React48, { useState as useState33 } from "react";
|
|
4723
|
+
import { useRouter as useRouter3 } from "next/navigation";
|
|
4724
|
+
import { HugeiconsIcon as HugeiconsIcon34 } from "@hugeicons/react";
|
|
4725
|
+
import {
|
|
4726
|
+
Loading03Icon as Loading03Icon22,
|
|
4727
|
+
Notification01Icon as Notification01Icon2,
|
|
4728
|
+
ArrowLeft01Icon as ArrowLeft01Icon15,
|
|
4729
|
+
ArrowRight01Icon as ArrowRight01Icon11,
|
|
4730
|
+
CancelCircleIcon as CancelCircleIcon9,
|
|
4731
|
+
ArrowUpRight01Icon as ArrowUpRight01Icon3
|
|
4732
|
+
} from "@hugeicons/core-free-icons";
|
|
4733
|
+
var UniversalHome2 = ({
|
|
4734
|
+
fullName = "",
|
|
4735
|
+
avatarSrc,
|
|
4736
|
+
createHuddleAction,
|
|
4737
|
+
joinHuddleAction,
|
|
4738
|
+
notifications = [],
|
|
4739
|
+
notificationPage = 1,
|
|
4740
|
+
notificationTotalPages = 1,
|
|
4741
|
+
isNotifsLoading = false,
|
|
4742
|
+
onNotificationPageChange,
|
|
4743
|
+
onNotificationClick,
|
|
4744
|
+
formatNotifDate,
|
|
4745
|
+
customContent,
|
|
4746
|
+
departmentsProps
|
|
4747
|
+
}) => {
|
|
4748
|
+
const [isAvatarLoaded, setIsAvatarLoaded] = useState33(false);
|
|
4749
|
+
const [showNotifDialog, setShowNotifDialog] = useState33(false);
|
|
4750
|
+
const [selectedNotif, setSelectedNotif] = useState33(null);
|
|
4751
|
+
const router = useRouter3();
|
|
4752
|
+
const fallbackAvatarUrl = "https://storage.googleapis.com/retina-cloud-v2/assets/images/avatar.avif";
|
|
4753
|
+
const finalAvatarSrc = avatarSrc || fallbackAvatarUrl;
|
|
4754
|
+
const hasUnreadNotifs = notifications.some((n) => !n.isRead);
|
|
4755
|
+
return /* @__PURE__ */ React48.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300 relative" }, /* @__PURE__ */ React48.createElement("div", { className: "flex items-center justify-between w-full pb-4" }, /* @__PURE__ */ React48.createElement("div", { className: "w-10 h-10 shrink-0 cursor-pointer", onClick: () => router.push("/app/account/me") }, /* @__PURE__ */ React48.createElement("div", { className: "relative w-full h-full rounded-lg overflow-hidden bg-neutral-100 flex items-center justify-center border border-neutral-200" }, !isAvatarLoaded && /* @__PURE__ */ React48.createElement("div", { className: "absolute inset-0 flex items-center justify-center z-10 bg-neutral-100" }, /* @__PURE__ */ React48.createElement(HugeiconsIcon34, { icon: Loading03Icon22, size: 16, className: "animate-spin text-black" })), /* @__PURE__ */ React48.createElement(
|
|
4756
|
+
"img",
|
|
4757
|
+
{
|
|
4758
|
+
src: finalAvatarSrc,
|
|
4759
|
+
alt: "User Avatar",
|
|
4760
|
+
onLoad: () => setIsAvatarLoaded(true),
|
|
4761
|
+
className: `w-full h-full object-cover transition-opacity duration-300 ${isAvatarLoaded ? "opacity-100" : "opacity-0"}`
|
|
4762
|
+
}
|
|
4763
|
+
))), /* @__PURE__ */ React48.createElement(
|
|
4764
|
+
"button",
|
|
4765
|
+
{
|
|
4766
|
+
onClick: () => {
|
|
4767
|
+
setShowNotifDialog(true);
|
|
4768
|
+
setSelectedNotif(null);
|
|
4769
|
+
},
|
|
4770
|
+
className: "relative w-10 h-10 flex items-center justify-center rounded-full bg-white outline-none hover:bg-neutral-50 transition-colors"
|
|
4771
|
+
},
|
|
4772
|
+
/* @__PURE__ */ React48.createElement(HugeiconsIcon34, { icon: Notification01Icon2, size: 20, className: "text-black" }),
|
|
4773
|
+
hasUnreadNotifs && /* @__PURE__ */ React48.createElement("span", { className: "absolute top-2.5 right-2.5 w-2 h-2 bg-red-500 rounded-full border border-white" })
|
|
4774
|
+
)), /* @__PURE__ */ React48.createElement("div", { className: "w-full pb-6 flex flex-col gap-4" }, /* @__PURE__ */ React48.createElement("div", { className: "grid grid-cols-2 gap-2" }, /* @__PURE__ */ React48.createElement(
|
|
4775
|
+
"div",
|
|
4776
|
+
{
|
|
4777
|
+
onClick: createHuddleAction?.onClick,
|
|
4778
|
+
className: "bg-[#143731] rounded-2xl p-5 relative overflow-hidden flex flex-col h-32 sm:h-36 cursor-pointer hover:opacity-90 transition-opacity"
|
|
4779
|
+
},
|
|
4780
|
+
/* @__PURE__ */ React48.createElement("div", { className: "relative z-10 flex flex-col h-full justify-between" }, /* @__PURE__ */ React48.createElement("p", { className: "text-[15px] sm:text-[15px] text-white leading-tight" }, "Create", /* @__PURE__ */ React48.createElement("br", null), /* @__PURE__ */ React48.createElement("span", { className: "text-white/70" }, "Huddle")), /* @__PURE__ */ React48.createElement("div", { className: "w-8 h-8 rounded-full bg-white/10 flex items-center justify-center" }, /* @__PURE__ */ React48.createElement(HugeiconsIcon34, { icon: ArrowUpRight01Icon3, size: 16, className: "text-white" }))),
|
|
4781
|
+
/* @__PURE__ */ React48.createElement(
|
|
4782
|
+
"img",
|
|
4783
|
+
{
|
|
4784
|
+
src: "https://storage.googleapis.com/retina-cloud-v2/assets/images/cal_a.avif",
|
|
4785
|
+
alt: "Create Huddle",
|
|
4786
|
+
className: "absolute bottom-4 right-2 translate-x-1/4 translate-y-1/2 w-32 h-auto object-contain z-0 pointer-events-none drop-shadow-md"
|
|
4787
|
+
}
|
|
4788
|
+
)
|
|
4789
|
+
), /* @__PURE__ */ React48.createElement(
|
|
4790
|
+
"div",
|
|
4791
|
+
{
|
|
4792
|
+
onClick: joinHuddleAction?.onClick,
|
|
4793
|
+
className: "bg-[#ceff8a] rounded-2xl p-5 relative overflow-hidden flex flex-col h-32 sm:h-36 cursor-pointer hover:opacity-90 transition-opacity"
|
|
4794
|
+
},
|
|
4795
|
+
/* @__PURE__ */ React48.createElement("div", { className: "relative z-10 flex flex-col h-full justify-between" }, /* @__PURE__ */ React48.createElement("p", { className: "text-[15px] sm:text-[15px] text-black leading-tight" }, "Join", /* @__PURE__ */ React48.createElement("br", null), /* @__PURE__ */ React48.createElement("span", { className: "text-black/60" }, "Huddle")), /* @__PURE__ */ React48.createElement("div", { className: "w-8 h-8 rounded-full bg-black/5 flex items-center justify-center" }, /* @__PURE__ */ React48.createElement(HugeiconsIcon34, { icon: ArrowRight01Icon11, size: 16, className: "text-black" }))),
|
|
4796
|
+
/* @__PURE__ */ React48.createElement(
|
|
4797
|
+
"img",
|
|
4798
|
+
{
|
|
4799
|
+
src: "https://storage.googleapis.com/retina-cloud-v2/assets/images/cam_a.avif",
|
|
4800
|
+
alt: "Join Huddle",
|
|
4801
|
+
className: "absolute bottom-4 right-2 translate-x-1/4 translate-y-1/2 w-32 h-auto object-contain z-0 pointer-events-none drop-shadow-md"
|
|
4802
|
+
}
|
|
4803
|
+
)
|
|
4804
|
+
))), customContent && /* @__PURE__ */ React48.createElement("div", { className: "w-full" }, customContent), /* @__PURE__ */ React48.createElement("div", { className: "w-full mt-2" }, /* @__PURE__ */ React48.createElement(
|
|
4805
|
+
UniversalDepartmentsPage,
|
|
4806
|
+
{
|
|
4807
|
+
...departmentsProps
|
|
4808
|
+
}
|
|
4809
|
+
)), showNotifDialog && /* @__PURE__ */ React48.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React48.createElement("div", { className: "absolute inset-0 bg-black/30", onClick: () => setShowNotifDialog(false) }), /* @__PURE__ */ React48.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 h-[80vh]" }, /* @__PURE__ */ React48.createElement("div", { className: "flex items-center justify-between p-5 shrink-0" }, selectedNotif ? /* @__PURE__ */ React48.createElement("button", { onClick: () => setSelectedNotif(null), className: "text-neutral-400 hover:text-black transition-colors outline-none flex items-center gap-2 text-[11px] tracking-widest" }, /* @__PURE__ */ React48.createElement(HugeiconsIcon34, { icon: ArrowLeft01Icon15, size: 14 }), " Back") : /* @__PURE__ */ React48.createElement("h3", { className: "text-[15px] text-black tracking-tight flex items-center gap-2" }, "Notifications", isNotifsLoading && /* @__PURE__ */ React48.createElement(HugeiconsIcon34, { icon: Loading03Icon22, size: 14, className: "animate-spin text-neutral-400" })), /* @__PURE__ */ React48.createElement("button", { onClick: () => setShowNotifDialog(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React48.createElement(HugeiconsIcon34, { icon: CancelCircleIcon9, size: 18 }))), /* @__PURE__ */ React48.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-2" }, selectedNotif ? /* @__PURE__ */ React48.createElement("div", { className: "p-4 text-left" }, /* @__PURE__ */ React48.createElement("h4", { className: "text-[14px] text-black mb-1" }, selectedNotif.title), /* @__PURE__ */ React48.createElement("span", { className: "text-[10px] text-neutral-400 tracking-widest mb-4 block" }, formatNotifDate(selectedNotif.createdAt)), /* @__PURE__ */ React48.createElement("p", { className: "text-[12px] text-neutral-600 leading-relaxed whitespace-pre-wrap" }, selectedNotif.message)) : /* @__PURE__ */ React48.createElement("div", { className: "flex flex-col divide-y divide-neutral-50/50" }, notifications?.length === 0 && !isNotifsLoading ? /* @__PURE__ */ React48.createElement("div", { className: "p-8 text-center text-xs text-neutral-400" }, "You have no notifications.") : notifications?.map((notif) => /* @__PURE__ */ React48.createElement(
|
|
4810
|
+
"div",
|
|
4811
|
+
{
|
|
4812
|
+
key: notif.id,
|
|
4813
|
+
onClick: () => {
|
|
4814
|
+
setSelectedNotif(notif);
|
|
4815
|
+
onNotificationClick?.(notif);
|
|
4816
|
+
},
|
|
4817
|
+
className: `p-3 flex items-start gap-3 rounded-xl cursor-pointer transition-colors ${isNotifsLoading ? "opacity-50 pointer-events-none" : "hover:bg-neutral-50"}`
|
|
4818
|
+
},
|
|
4819
|
+
/* @__PURE__ */ React48.createElement("div", { className: "mt-1.5 shrink-0" }, !notif.isRead ? /* @__PURE__ */ React48.createElement("div", { className: "w-1.5 h-1.5 bg-red-500 rounded-full" }) : /* @__PURE__ */ React48.createElement("div", { className: "w-1.5 h-1.5 bg-transparent" })),
|
|
4820
|
+
/* @__PURE__ */ React48.createElement("div", { className: "flex-1 min-w-0 text-left" }, /* @__PURE__ */ React48.createElement("h5", { className: `text-[12px] truncate ${notif.isRead ? "text-neutral-500" : "text-black"}` }, notif.title), /* @__PURE__ */ React48.createElement("p", { className: "text-[11px] text-neutral-400 truncate mt-0.5" }, notif.message), /* @__PURE__ */ React48.createElement("span", { className: "text-[9px] text-neutral-400 tracking-widest mt-2 block" }, formatNotifDate(notif.createdAt)))
|
|
4821
|
+
)))), !selectedNotif && /* @__PURE__ */ React48.createElement("div", { className: "p-4 flex items-center justify-between shrink-0" }, /* @__PURE__ */ React48.createElement("span", { className: "text-[10px] text-neutral-400 tracking-widest" }, "Page ", notificationPage, " of ", notificationTotalPages === 0 ? 1 : notificationTotalPages), /* @__PURE__ */ React48.createElement("div", { className: "flex gap-1" }, /* @__PURE__ */ React48.createElement(
|
|
4822
|
+
"button",
|
|
4823
|
+
{
|
|
4824
|
+
disabled: notificationPage <= 1 || isNotifsLoading,
|
|
4825
|
+
onClick: () => onNotificationPageChange?.(notificationPage - 1),
|
|
4826
|
+
className: "w-7 h-7 flex items-center justify-center rounded-full bg-white border border-neutral-200 text-neutral-600 disabled:opacity-30 outline-none hover:bg-neutral-50 transition-colors"
|
|
4827
|
+
},
|
|
4828
|
+
/* @__PURE__ */ React48.createElement(HugeiconsIcon34, { icon: ArrowLeft01Icon15, size: 12 })
|
|
4829
|
+
), /* @__PURE__ */ React48.createElement(
|
|
4830
|
+
"button",
|
|
4831
|
+
{
|
|
4832
|
+
disabled: notificationPage >= notificationTotalPages || notificationTotalPages === 0 || isNotifsLoading,
|
|
4833
|
+
onClick: () => onNotificationPageChange?.(notificationPage + 1),
|
|
4834
|
+
className: "w-7 h-7 flex items-center justify-center rounded-full bg-white border border-neutral-200 text-neutral-600 disabled:opacity-30 outline-none hover:bg-neutral-50 transition-colors"
|
|
4835
|
+
},
|
|
4836
|
+
/* @__PURE__ */ React48.createElement(HugeiconsIcon34, { icon: ArrowRight01Icon11, size: 12 })
|
|
4837
|
+
))))));
|
|
4838
|
+
};
|
|
4471
4839
|
export {
|
|
4472
4840
|
AppBento2,
|
|
4473
4841
|
CardInfoDialog,
|
|
@@ -4502,8 +4870,11 @@ export {
|
|
|
4502
4870
|
UniversalBuyCryptoPage,
|
|
4503
4871
|
UniversalCardActionPage,
|
|
4504
4872
|
UniversalCardPage,
|
|
4873
|
+
UniversalDepartmentsPage,
|
|
4505
4874
|
UniversalErrorView,
|
|
4875
|
+
UniversalHome2,
|
|
4506
4876
|
UniversalHomeView,
|
|
4877
|
+
UniversalMembersPage,
|
|
4507
4878
|
UniversalOrganizationPage,
|
|
4508
4879
|
UniversalProfilePage,
|
|
4509
4880
|
UniversalProfileSettings,
|