@retinalabsllc/zairusjs 20.1.10 → 20.1.20
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 +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +119 -9
- package/dist/index.mjs +119 -9
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1135,11 +1135,18 @@ interface UniversalSettingsProps {
|
|
|
1135
1135
|
onUpdateRole?: (memberId: string, newRole: string) => Promise<void>;
|
|
1136
1136
|
initialOrgName?: string;
|
|
1137
1137
|
initialOrgSlug?: string;
|
|
1138
|
+
initialOrgAvatarUrl?: string;
|
|
1138
1139
|
initialFullName?: string;
|
|
1139
1140
|
initialEmail?: string;
|
|
1141
|
+
initialJobTitle?: string;
|
|
1142
|
+
initialDescription?: string;
|
|
1143
|
+
initialAvatarUrl?: string;
|
|
1140
1144
|
onSaveProfile?: (payload: {
|
|
1141
1145
|
firstName: string;
|
|
1142
1146
|
lastName: string;
|
|
1147
|
+
jobTitle: string;
|
|
1148
|
+
description: string;
|
|
1149
|
+
avatarUrl: string;
|
|
1143
1150
|
}) => Promise<{
|
|
1144
1151
|
success: boolean;
|
|
1145
1152
|
error?: string;
|
|
@@ -1147,6 +1154,7 @@ interface UniversalSettingsProps {
|
|
|
1147
1154
|
onSaveOrganization?: (payload: {
|
|
1148
1155
|
name: string;
|
|
1149
1156
|
slug: string;
|
|
1157
|
+
avatarUrl: string;
|
|
1150
1158
|
}) => Promise<{
|
|
1151
1159
|
success: boolean;
|
|
1152
1160
|
error?: string;
|
|
@@ -1154,6 +1162,9 @@ interface UniversalSettingsProps {
|
|
|
1154
1162
|
onCheckSlugAvailability?: (slug: string) => Promise<{
|
|
1155
1163
|
available: boolean;
|
|
1156
1164
|
}>;
|
|
1165
|
+
onUploadAvatar?: (file: File, type: 'USER' | 'ORGANIZATION') => Promise<{
|
|
1166
|
+
url: string;
|
|
1167
|
+
}>;
|
|
1157
1168
|
aiCredits: string;
|
|
1158
1169
|
isBillingLoading?: boolean;
|
|
1159
1170
|
onTopUp?: () => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1135,11 +1135,18 @@ interface UniversalSettingsProps {
|
|
|
1135
1135
|
onUpdateRole?: (memberId: string, newRole: string) => Promise<void>;
|
|
1136
1136
|
initialOrgName?: string;
|
|
1137
1137
|
initialOrgSlug?: string;
|
|
1138
|
+
initialOrgAvatarUrl?: string;
|
|
1138
1139
|
initialFullName?: string;
|
|
1139
1140
|
initialEmail?: string;
|
|
1141
|
+
initialJobTitle?: string;
|
|
1142
|
+
initialDescription?: string;
|
|
1143
|
+
initialAvatarUrl?: string;
|
|
1140
1144
|
onSaveProfile?: (payload: {
|
|
1141
1145
|
firstName: string;
|
|
1142
1146
|
lastName: string;
|
|
1147
|
+
jobTitle: string;
|
|
1148
|
+
description: string;
|
|
1149
|
+
avatarUrl: string;
|
|
1143
1150
|
}) => Promise<{
|
|
1144
1151
|
success: boolean;
|
|
1145
1152
|
error?: string;
|
|
@@ -1147,6 +1154,7 @@ interface UniversalSettingsProps {
|
|
|
1147
1154
|
onSaveOrganization?: (payload: {
|
|
1148
1155
|
name: string;
|
|
1149
1156
|
slug: string;
|
|
1157
|
+
avatarUrl: string;
|
|
1150
1158
|
}) => Promise<{
|
|
1151
1159
|
success: boolean;
|
|
1152
1160
|
error?: string;
|
|
@@ -1154,6 +1162,9 @@ interface UniversalSettingsProps {
|
|
|
1154
1162
|
onCheckSlugAvailability?: (slug: string) => Promise<{
|
|
1155
1163
|
available: boolean;
|
|
1156
1164
|
}>;
|
|
1165
|
+
onUploadAvatar?: (file: File, type: 'USER' | 'ORGANIZATION') => Promise<{
|
|
1166
|
+
url: string;
|
|
1167
|
+
}>;
|
|
1157
1168
|
aiCredits: string;
|
|
1158
1169
|
isBillingLoading?: boolean;
|
|
1159
1170
|
onTopUp?: () => void;
|
package/dist/index.js
CHANGED
|
@@ -703,7 +703,7 @@ var ReusableOptions = ({
|
|
|
703
703
|
onSelect(opt);
|
|
704
704
|
onClose();
|
|
705
705
|
},
|
|
706
|
-
className: `w-full text-left
|
|
706
|
+
className: `w-full text-left p-4 text-xs tracking-tight rounded-full transition-colors outline-none ${isSelected ? "text-[#d97757] bg-[#d97757]/10" : "text-stone-600 hover:bg-stone-50/50"}`
|
|
707
707
|
},
|
|
708
708
|
opt.charAt(0).toUpperCase() + opt.slice(1).toLowerCase()
|
|
709
709
|
);
|
|
@@ -5422,6 +5422,22 @@ var MemberAvatar3 = ({ src, status, sizeClass = "w-10 h-10" }) => {
|
|
|
5422
5422
|
};
|
|
5423
5423
|
return /* @__PURE__ */ import_react89.default.createElement("div", { className: `relative shrink-0 ${sizeClass}` }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "w-full h-full rounded-lg bg-stone-100 flex items-center justify-center overflow-hidden" }, !loaded && !error && /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.Loading03Icon, className: "animate-spin text-stone-400 absolute", size: 14 }), /* @__PURE__ */ import_react89.default.createElement("img", { src: finalSrc, alt: "Member", className: `w-full h-full object-cover transition-opacity duration-300 ${loaded || error ? "opacity-100" : "opacity-0"}`, onLoad: () => setLoaded(true), onError: () => setError(true) })), /* @__PURE__ */ import_react89.default.createElement("div", { className: `absolute -bottom-1 -right-1 w-3.5 h-3.5 rounded-full border-2 border-white z-10 ${getStatusColor()}` }));
|
|
5424
5424
|
};
|
|
5425
|
+
var OrgAvatar2 = ({ src, sizeClass = "w-10 h-10" }) => {
|
|
5426
|
+
const [loaded, setLoaded] = (0, import_react89.useState)(false);
|
|
5427
|
+
const [error, setError] = (0, import_react89.useState)(false);
|
|
5428
|
+
const defaultAvatar = "https://storage.googleapis.com/retina-cloud-v2/assets/images/office_a.avif";
|
|
5429
|
+
const finalSrc = error || !src ? defaultAvatar : src;
|
|
5430
|
+
return /* @__PURE__ */ import_react89.default.createElement("div", { className: `relative shrink-0 ${sizeClass}` }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "w-full h-full rounded-lg bg-stone-100 flex items-center justify-center overflow-hidden" }, !loaded && !error && /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.Loading03Icon, className: "animate-spin text-stone-400 absolute", size: 14 }), /* @__PURE__ */ import_react89.default.createElement(
|
|
5431
|
+
"img",
|
|
5432
|
+
{
|
|
5433
|
+
src: finalSrc,
|
|
5434
|
+
alt: "Workspace Avatar",
|
|
5435
|
+
className: `w-full h-full object-cover transition-opacity duration-300 ${loaded || error ? "opacity-100" : "opacity-0"}`,
|
|
5436
|
+
onLoad: () => setLoaded(true),
|
|
5437
|
+
onError: () => setError(true)
|
|
5438
|
+
}
|
|
5439
|
+
)));
|
|
5440
|
+
};
|
|
5425
5441
|
var PageSpinner8 = () => /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.Loading03Icon, size: 32, className: "animate-spin mb-4 text-black" }));
|
|
5426
5442
|
var InputSpinner3 = () => /* @__PURE__ */ import_react89.default.createElement("svg", { className: "animate-spin h-4 w-4 text-stone-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ import_react89.default.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ import_react89.default.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
|
|
5427
5443
|
var UniversalSettings = ({
|
|
@@ -5447,11 +5463,16 @@ var UniversalSettings = ({
|
|
|
5447
5463
|
onUpdateRole,
|
|
5448
5464
|
initialOrgName = "",
|
|
5449
5465
|
initialOrgSlug = "",
|
|
5466
|
+
initialOrgAvatarUrl = "",
|
|
5450
5467
|
initialFullName = "",
|
|
5451
5468
|
initialEmail = "",
|
|
5469
|
+
initialJobTitle = "",
|
|
5470
|
+
initialDescription = "",
|
|
5471
|
+
initialAvatarUrl = "",
|
|
5452
5472
|
onSaveProfile,
|
|
5453
5473
|
onSaveOrganization,
|
|
5454
5474
|
onCheckSlugAvailability,
|
|
5475
|
+
onUploadAvatar,
|
|
5455
5476
|
aiCredits,
|
|
5456
5477
|
isBillingLoading = false,
|
|
5457
5478
|
onTopUp,
|
|
@@ -5461,7 +5482,8 @@ var UniversalSettings = ({
|
|
|
5461
5482
|
if (typeof window !== "undefined") window.history.back();
|
|
5462
5483
|
});
|
|
5463
5484
|
const isOrg = accountType === "ORGANIZATION";
|
|
5464
|
-
const
|
|
5485
|
+
const safeRole = String(userRole || "").toUpperCase().trim();
|
|
5486
|
+
const canManage = ["ADMIN", "MANAGER", "OWNER"].includes(safeRole);
|
|
5465
5487
|
const [activeTab, setActiveTab] = (0, import_react89.useState)(isOrg ? "MEMBERS" : "ACCOUNT");
|
|
5466
5488
|
const [expandedId, setExpandedId] = (0, import_react89.useState)(null);
|
|
5467
5489
|
const [memberToRemove, setMemberToRemove] = (0, import_react89.useState)(null);
|
|
@@ -5478,19 +5500,57 @@ var UniversalSettings = ({
|
|
|
5478
5500
|
const [isUpdatingRole, setIsUpdatingRole] = (0, import_react89.useState)(false);
|
|
5479
5501
|
const [orgName, setOrgName] = (0, import_react89.useState)(initialOrgName);
|
|
5480
5502
|
const [orgSlug, setOrgSlug] = (0, import_react89.useState)(initialOrgSlug);
|
|
5503
|
+
const [orgAvatarUrl, setOrgAvatarUrl] = (0, import_react89.useState)(initialOrgAvatarUrl);
|
|
5481
5504
|
const [firstName, setFirstName] = (0, import_react89.useState)("");
|
|
5482
5505
|
const [lastName, setLastName] = (0, import_react89.useState)("");
|
|
5506
|
+
const [jobTitle, setJobTitle] = (0, import_react89.useState)(initialJobTitle);
|
|
5507
|
+
const [description, setDescription] = (0, import_react89.useState)(initialDescription);
|
|
5508
|
+
const [avatarUrl, setAvatarUrl] = (0, import_react89.useState)(initialAvatarUrl);
|
|
5483
5509
|
const [isCheckingSlug, setIsCheckingSlug] = (0, import_react89.useState)(false);
|
|
5484
5510
|
const [slugAvailable, setSlugAvailable] = (0, import_react89.useState)(null);
|
|
5485
5511
|
const [isSavingOrg, setIsSavingOrg] = (0, import_react89.useState)(false);
|
|
5486
5512
|
const [isSavingProfile, setIsSavingProfile] = (0, import_react89.useState)(false);
|
|
5513
|
+
const orgFileInputRef = (0, import_react89.useRef)(null);
|
|
5514
|
+
const userFileInputRef = (0, import_react89.useRef)(null);
|
|
5515
|
+
const [pendingOrgAvatar, setPendingOrgAvatar] = (0, import_react89.useState)(null);
|
|
5516
|
+
const [pendingUserAvatar, setPendingUserAvatar] = (0, import_react89.useState)(null);
|
|
5517
|
+
const [isUploadingOrgAvatar, setIsUploadingOrgAvatar] = (0, import_react89.useState)(false);
|
|
5518
|
+
const [isUploadingUserAvatar, setIsUploadingUserAvatar] = (0, import_react89.useState)(false);
|
|
5487
5519
|
(0, import_react89.useEffect)(() => {
|
|
5488
5520
|
setOrgName(initialOrgName || "");
|
|
5489
5521
|
setOrgSlug(initialOrgSlug || "");
|
|
5522
|
+
setOrgAvatarUrl(initialOrgAvatarUrl || "");
|
|
5490
5523
|
const parts = (initialFullName || "").split(" ");
|
|
5491
5524
|
setFirstName(parts[0] || "");
|
|
5492
5525
|
setLastName(parts.slice(1).join(" ") || "");
|
|
5493
|
-
|
|
5526
|
+
setJobTitle(initialJobTitle || "");
|
|
5527
|
+
setDescription(initialDescription || "");
|
|
5528
|
+
setAvatarUrl(initialAvatarUrl || "");
|
|
5529
|
+
}, [initialOrgName, initialOrgSlug, initialOrgAvatarUrl, initialFullName, initialJobTitle, initialDescription, initialAvatarUrl]);
|
|
5530
|
+
const handleFileSelect = (e, type) => {
|
|
5531
|
+
const file = e.target.files?.[0];
|
|
5532
|
+
if (!file) return;
|
|
5533
|
+
if (file.size > 1024 * 1024) {
|
|
5534
|
+
import_react_hot_toast15.default.error("Image size must be less than 1MB.");
|
|
5535
|
+
e.target.value = "";
|
|
5536
|
+
return;
|
|
5537
|
+
}
|
|
5538
|
+
const validTypes = ["image/jpeg", "image/jpg", "image/png"];
|
|
5539
|
+
if (!validTypes.includes(file.type)) {
|
|
5540
|
+
import_react_hot_toast15.default.error("Only PNG and JPEG images are allowed.");
|
|
5541
|
+
e.target.value = "";
|
|
5542
|
+
return;
|
|
5543
|
+
}
|
|
5544
|
+
const previewUrl = URL.createObjectURL(file);
|
|
5545
|
+
if (type === "USER") {
|
|
5546
|
+
setPendingUserAvatar(file);
|
|
5547
|
+
setAvatarUrl(previewUrl);
|
|
5548
|
+
} else if (type === "ORGANIZATION") {
|
|
5549
|
+
setPendingOrgAvatar(file);
|
|
5550
|
+
setOrgAvatarUrl(previewUrl);
|
|
5551
|
+
}
|
|
5552
|
+
e.target.value = "";
|
|
5553
|
+
};
|
|
5494
5554
|
(0, import_react89.useEffect)(() => {
|
|
5495
5555
|
if (activeTab !== "MEMBERS") return;
|
|
5496
5556
|
if (isFirstSearchMount.current) {
|
|
@@ -5581,13 +5641,32 @@ var UniversalSettings = ({
|
|
|
5581
5641
|
if (orgSlug !== initialOrgSlug && slugAvailable === false) return import_react_hot_toast15.default.error("Address handle unavailable.");
|
|
5582
5642
|
setIsSavingOrg(true);
|
|
5583
5643
|
try {
|
|
5584
|
-
|
|
5644
|
+
let finalAvatarUrl = orgAvatarUrl;
|
|
5645
|
+
if (pendingOrgAvatar && onUploadAvatar) {
|
|
5646
|
+
setIsUploadingOrgAvatar(true);
|
|
5647
|
+
try {
|
|
5648
|
+
const res2 = await onUploadAvatar(pendingOrgAvatar, "ORGANIZATION");
|
|
5649
|
+
if (res2?.url) {
|
|
5650
|
+
finalAvatarUrl = res2.url;
|
|
5651
|
+
setOrgAvatarUrl(finalAvatarUrl);
|
|
5652
|
+
}
|
|
5653
|
+
} catch (err) {
|
|
5654
|
+
import_react_hot_toast15.default.error("Failed to securely upload workspace avatar.");
|
|
5655
|
+
setIsSavingOrg(false);
|
|
5656
|
+
setIsUploadingOrgAvatar(false);
|
|
5657
|
+
return;
|
|
5658
|
+
}
|
|
5659
|
+
setPendingOrgAvatar(null);
|
|
5660
|
+
setIsUploadingOrgAvatar(false);
|
|
5661
|
+
}
|
|
5662
|
+
const res = await onSaveOrganization({ name: orgName, slug: orgSlug, avatarUrl: finalAvatarUrl });
|
|
5585
5663
|
if (res.success) import_react_hot_toast15.default.success("Workspace updated successfully.");
|
|
5586
5664
|
else import_react_hot_toast15.default.error(res.error || "Failed to update workspace.");
|
|
5587
5665
|
} catch (error) {
|
|
5588
5666
|
import_react_hot_toast15.default.error("Service unavailable.");
|
|
5589
5667
|
} finally {
|
|
5590
5668
|
setIsSavingOrg(false);
|
|
5669
|
+
setIsUploadingOrgAvatar(false);
|
|
5591
5670
|
}
|
|
5592
5671
|
};
|
|
5593
5672
|
const handleSaveProfile = async (e) => {
|
|
@@ -5595,18 +5674,37 @@ var UniversalSettings = ({
|
|
|
5595
5674
|
if (isSavingProfile || !onSaveProfile) return;
|
|
5596
5675
|
setIsSavingProfile(true);
|
|
5597
5676
|
try {
|
|
5598
|
-
|
|
5677
|
+
let finalAvatarUrl = avatarUrl;
|
|
5678
|
+
if (pendingUserAvatar && onUploadAvatar) {
|
|
5679
|
+
setIsUploadingUserAvatar(true);
|
|
5680
|
+
try {
|
|
5681
|
+
const res2 = await onUploadAvatar(pendingUserAvatar, "USER");
|
|
5682
|
+
if (res2?.url) {
|
|
5683
|
+
finalAvatarUrl = res2.url;
|
|
5684
|
+
setAvatarUrl(finalAvatarUrl);
|
|
5685
|
+
}
|
|
5686
|
+
} catch (err) {
|
|
5687
|
+
import_react_hot_toast15.default.error("Failed to securely upload profile avatar.");
|
|
5688
|
+
setIsSavingProfile(false);
|
|
5689
|
+
setIsUploadingUserAvatar(false);
|
|
5690
|
+
return;
|
|
5691
|
+
}
|
|
5692
|
+
setPendingUserAvatar(null);
|
|
5693
|
+
setIsUploadingUserAvatar(false);
|
|
5694
|
+
}
|
|
5695
|
+
const res = await onSaveProfile({ firstName, lastName, jobTitle, description, avatarUrl: finalAvatarUrl });
|
|
5599
5696
|
if (res.success) import_react_hot_toast15.default.success("Identity updated successfully.");
|
|
5600
5697
|
else import_react_hot_toast15.default.error(res.error || "Failed to update identity.");
|
|
5601
5698
|
} catch (error) {
|
|
5602
5699
|
import_react_hot_toast15.default.error("Service unavailable.");
|
|
5603
5700
|
} finally {
|
|
5604
5701
|
setIsSavingProfile(false);
|
|
5702
|
+
setIsUploadingUserAvatar(false);
|
|
5605
5703
|
}
|
|
5606
5704
|
};
|
|
5607
|
-
const hasOrgChanges = orgName !== initialOrgName || orgSlug !== initialOrgSlug;
|
|
5705
|
+
const hasOrgChanges = orgName !== initialOrgName || orgSlug !== initialOrgSlug || orgAvatarUrl !== initialOrgAvatarUrl;
|
|
5608
5706
|
const isOrgSaveDisabled = isSavingOrg || !canManage || isCheckingSlug || !hasOrgChanges || orgName.length < 3 || orgSlug.length < 3 || orgSlug !== initialOrgSlug && slugAvailable === false;
|
|
5609
|
-
const hasProfileChanges = `${firstName} ${lastName}`.trim() !== initialFullName;
|
|
5707
|
+
const hasProfileChanges = `${firstName} ${lastName}`.trim() !== initialFullName || jobTitle !== initialJobTitle || description !== initialDescription || avatarUrl !== initialAvatarUrl;
|
|
5610
5708
|
const isProfileSaveDisabled = isSavingProfile || !hasProfileChanges || firstName.length < 2 || lastName.length < 2;
|
|
5611
5709
|
return /* @__PURE__ */ import_react89.default.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300" }, /* @__PURE__ */ import_react89.default.createElement(ManagedToaster, null), /* @__PURE__ */ import_react89.default.createElement("div", { className: "mb-6 flex w-full items-center px-1" }, /* @__PURE__ */ import_react89.default.createElement("button", { onClick: onBackHandler, className: "flex items-center gap-2 text-[#d97757] hover:text-[#d97757] transition-colors text-sm outline-none" }, /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.ArrowLeft01Icon, size: 16 }), " Back")), /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex flex-col gap-1 mb-8 px-1" }, /* @__PURE__ */ import_react89.default.createElement("h1", { className: "text-black text-xl tracking-tight" }, "System Settings"), /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-xs text-stone-500" }, "Manage your workspace identity, team configurations, and AI billing parameters.")), /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center gap-6 mb-6 overflow-x-auto custom-scrollbar px-1" }, isOrg && /* @__PURE__ */ import_react89.default.createElement("button", { onClick: () => {
|
|
5612
5710
|
setActiveTab("MEMBERS");
|
|
@@ -5645,10 +5743,22 @@ var UniversalSettings = ({
|
|
|
5645
5743
|
))))))) : /* @__PURE__ */ import_react89.default.createElement(import_react89.default.Fragment, null, /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex flex-row items-center justify-between gap-4" }, /* @__PURE__ */ import_react89.default.createElement("h2", { className: "text-black text-xl tracking-tight" }, isInviteMode ? "Add Member" : "Team Directory"), !isInviteMode && canManage && /* @__PURE__ */ import_react89.default.createElement("button", { onClick: () => setIsInviteMode(true), className: "shrink-0 px-4 py-1.5 border border-stone-200 text-black text-xs tracking-wide rounded-full hover:bg-stone-50 transition-colors outline-none" }, "Invite Team")), !isInviteMode && /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-xs text-stone-500" }, "Manage members and access controls across your organization.")), /* @__PURE__ */ import_react89.default.createElement("div", { className: "w-full overflow-hidden" }, isInviteMode ? /* @__PURE__ */ import_react89.default.createElement("form", { onSubmit: handleInviteSubmit, className: "flex flex-col gap-8 animate-in fade-in duration-300" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "space-y-1.5 mt-2" }, /* @__PURE__ */ import_react89.default.createElement("label", { className: "text-xs text-stone-400 tracking-[0.2em] block" }, "Email Address"), /* @__PURE__ */ import_react89.default.createElement("input", { type: "email", value: inviteEmail, onChange: (e) => setInviteEmail(cleanEmailId(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-stone-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "name@company.com" })), /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ import_react89.default.createElement(ThreeDActionButton, { type: "submit", disabled: inviteEmail.length < 5 || isInviting, isLoading: isInviting, className: "w-full" }, "Send Invitation"), /* @__PURE__ */ import_react89.default.createElement("button", { type: "button", onClick: () => {
|
|
5646
5744
|
setIsInviteMode(false);
|
|
5647
5745
|
setInviteEmail("");
|
|
5648
|
-
}, disabled: isInviting, className: "w-full flex items-center justify-center py-2.5 rounded-full border border-stone-200 text-black hover:bg-stone-50 transition-colors outline-none text-xs tracking-wide" }, "Cancel"))) : isMembersLoading || isTyping ? /* @__PURE__ */ import_react89.default.createElement(PageSpinner8, null) : /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex flex-col min-w-0 animate-in fade-in duration-300" }, /* @__PURE__ */ import_react89.default.createElement("div", null, members.length === 0 ? /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-xs text-stone-400 py-6 text-center" }, "No members found") : members.map((member) => /* @__PURE__ */ import_react89.default.createElement("div", { key: member.id, onClick: () => setExpandedId(member.id), className: "flex items-center justify-between py-3 hover:bg-stone-50 transition-colors cursor-pointer group min-w-0 px-3 -mx-3 rounded-xl" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center gap-4 min-w-0 flex-1" }, /* @__PURE__ */ import_react89.default.createElement(MemberAvatar3, { src: member.avatarUrl, status: member.status }), /* @__PURE__ */ import_react89.default.createElement("div", { className: "min-w-0 flex-1 flex flex-col gap-0.5" }, /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-sm text-black truncate" }, member.fullName), /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-xs text-stone-500 capitalize truncate" }, member.role.toLowerCase())))))), /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center justify-between pt-6 mt-2 " }, /* @__PURE__ */ import_react89.default.createElement("span", { className: "text-xs text-stone-400 tracking-[0.2em]" }, "Page ", membersCurrentPage, " of ", membersTotalPages === 0 ? 1 : membersTotalPages), /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react89.default.createElement("button", { onClick: () => onMembersPageChange(membersCurrentPage - 1), disabled: membersCurrentPage <= 1 || isMembersLoading, className: "p-2 bg-white border border-stone-200 rounded-full text-black hover:bg-stone-50 disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none" }, /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.ArrowLeft01Icon, size: 14 })), /* @__PURE__ */ import_react89.default.createElement("button", { onClick: () => onMembersPageChange(membersCurrentPage + 1), disabled: membersCurrentPage >= membersTotalPages || isMembersLoading || membersTotalPages === 0, className: "p-2 bg-white border border-stone-200 rounded-full text-black hover:bg-stone-50 disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none" }, /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.ArrowRight01Icon, size: 14 })))))))), /* @__PURE__ */ import_react89.default.createElement(ReusableOptions, { isOpen: isStatusModalOpen, onClose: () => setIsStatusModalOpen(false), title: "Status Filter", options: ["ALL", "ACTIVE", "BUSY", "OFFLINE", "AWAY"], selectedOption: activeStatusFilter, onSelect: (status) => onStatusFilterChange(status) }), /* @__PURE__ */ import_react89.default.createElement(ReusableOptions, { isOpen: isRoleModalOpen, onClose: () => setIsRoleModalOpen(false), title: "Role Filter", options: ["ALL", "OWNER", "ADMIN", "MANAGER", "MEMBER", "GUEST"], selectedOption: activeRoleFilter, onSelect: (role) => onRoleFilterChange(role) }), /* @__PURE__ */ import_react89.default.createElement(ReusableOptions, { isOpen: !!roleEditTarget, onClose: () => setRoleEditTarget(null), title: "Modify Access Role", options: ["ADMIN", "MANAGER", "MEMBER"], selectedOption: roleEditTarget?.role || "", onSelect: handleRoleUpdate })), activeTab === "ORGANIZATION" && isOrg && /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex flex-col gap-8 animate-in rounded-2xl p-6 bg-white fade-in duration-300" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react89.default.createElement("div", null, /* @__PURE__ */ import_react89.default.createElement("h2", { className: "text-black text-xl mb-1 tracking-tight" }, "Workspace Details"), /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-xs text-stone-500" }, "Manage your organizational identity and handles.")), !canManage && /* @__PURE__ */ import_react89.default.createElement("span", { className: "p-2 w-9 h-9 bg-stone-100 text-stone-400 rounded-full shrink-0" }, /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.CircleLock02Icon, size: 18, className: "text-current" }))), /* @__PURE__ */ import_react89.default.createElement("form", { className: "flex flex-col gap-8 w-full max-w-5xl", onSubmit: handleSaveOrganization, autoComplete: "off" }, /* @__PURE__ */ import_react89.default.createElement(TextInput, { label: "Workspace Name", value: orgName, onChange: handleOrgNameChange, disabled: !canManage || isSavingOrg, placeholder: "Acme Corporation", maxLength: 50 }), /* @__PURE__ */ import_react89.default.createElement("div", { className: "space-y-1.5 relative w-full" }, /* @__PURE__ */ import_react89.default.createElement("label", { className: "text-xs text-stone-400 tracking-[0.2em] block" }, "Workspace Handle"), /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center relative w-full border-b border-stone-200 focus-within:border-black transition-all duration-300 overflow-hidden" }, /* @__PURE__ */ import_react89.default.createElement("input", { type: "text", value: orgSlug, disabled: !canManage || isSavingOrg, onChange: (e) => handleOrgSlugChange(e.target.value), spellCheck: "false", autoComplete: "off", className: "w-full pr-10 pl-0 py-3 text-sm bg-transparent text-black outline-none disabled:opacity-50 disabled:cursor-not-allowed", placeholder: "workspace-handle" }), /* @__PURE__ */ import_react89.default.createElement("div", { className: "absolute right-2 top-1/2 -translate-y-1/2" }, isCheckingSlug && /* @__PURE__ */ import_react89.default.createElement(InputSpinner3, null), !isCheckingSlug && canManage && orgSlug !== initialOrgSlug && orgSlug.length >= 3 && slugAvailable === false && /* @__PURE__ */ import_react89.default.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-[#d97757]/10" }, /* @__PURE__ */ import_react89.default.createElement("svg", { className: "w-2 h-2 text-[#d97757]", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react89.default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" }))), !isCheckingSlug && canManage && orgSlug !== initialOrgSlug && orgSlug.length >= 3 && slugAvailable === true && /* @__PURE__ */ import_react89.default.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-green-100" }, /* @__PURE__ */ import_react89.default.createElement("svg", { className: "w-2 h-2 text-green-600", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react89.default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M16.707 5.293a1 1 0 00-1.414 0L8 12.586 4.707 9.293a1 1 0 10-1.414 1.414l4 4a1 1 0 001.414 0l8-8a1 1 0 000-1.414z" })))))), /* @__PURE__ */ import_react89.default.createElement("div", { className: "pt-8 mt-2 flex items-center gap-4" }, /* @__PURE__ */ import_react89.default.createElement(ThreeDActionButton, { type: "submit", disabled: isOrgSaveDisabled, isLoading: isSavingOrg, className: "min-w-32" }, "Save Changes"), hasOrgChanges && !isSavingOrg && canManage && /* @__PURE__ */ import_react89.default.createElement("button", { type: "button", onClick: () => {
|
|
5746
|
+
}, disabled: isInviting, className: "w-full flex items-center justify-center py-2.5 rounded-full border border-stone-200 text-black hover:bg-stone-50 transition-colors outline-none text-xs tracking-wide" }, "Cancel"))) : isMembersLoading || isTyping ? /* @__PURE__ */ import_react89.default.createElement(PageSpinner8, null) : /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex flex-col min-w-0 animate-in fade-in duration-300" }, /* @__PURE__ */ import_react89.default.createElement("div", null, members.length === 0 ? /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-xs text-stone-400 py-6 text-center" }, "No members found") : members.map((member) => /* @__PURE__ */ import_react89.default.createElement("div", { key: member.id, onClick: () => setExpandedId(member.id), className: "flex items-center justify-between py-3 hover:bg-stone-50 transition-colors cursor-pointer group min-w-0 px-3 -mx-3 rounded-xl" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center gap-4 min-w-0 flex-1" }, /* @__PURE__ */ import_react89.default.createElement(MemberAvatar3, { src: member.avatarUrl, status: member.status }), /* @__PURE__ */ import_react89.default.createElement("div", { className: "min-w-0 flex-1 flex flex-col gap-0.5" }, /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-sm text-black truncate" }, member.fullName), /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-xs text-stone-500 capitalize truncate" }, member.role.toLowerCase())))))), /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center justify-between pt-6 mt-2 " }, /* @__PURE__ */ import_react89.default.createElement("span", { className: "text-xs text-stone-400 tracking-[0.2em]" }, "Page ", membersCurrentPage, " of ", membersTotalPages === 0 ? 1 : membersTotalPages), /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react89.default.createElement("button", { onClick: () => onMembersPageChange(membersCurrentPage - 1), disabled: membersCurrentPage <= 1 || isMembersLoading, className: "p-2 bg-white border border-stone-200 rounded-full text-black hover:bg-stone-50 disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none" }, /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.ArrowLeft01Icon, size: 14 })), /* @__PURE__ */ import_react89.default.createElement("button", { onClick: () => onMembersPageChange(membersCurrentPage + 1), disabled: membersCurrentPage >= membersTotalPages || isMembersLoading || membersTotalPages === 0, className: "p-2 bg-white border border-stone-200 rounded-full text-black hover:bg-stone-50 disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none" }, /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.ArrowRight01Icon, size: 14 })))))))), /* @__PURE__ */ import_react89.default.createElement(ReusableOptions, { isOpen: isStatusModalOpen, onClose: () => setIsStatusModalOpen(false), title: "Status Filter", options: ["ALL", "ACTIVE", "BUSY", "OFFLINE", "AWAY"], selectedOption: activeStatusFilter, onSelect: (status) => onStatusFilterChange(status) }), /* @__PURE__ */ import_react89.default.createElement(ReusableOptions, { isOpen: isRoleModalOpen, onClose: () => setIsRoleModalOpen(false), title: "Role Filter", options: ["ALL", "OWNER", "ADMIN", "MANAGER", "MEMBER", "GUEST"], selectedOption: activeRoleFilter, onSelect: (role) => onRoleFilterChange(role) }), /* @__PURE__ */ import_react89.default.createElement(ReusableOptions, { isOpen: !!roleEditTarget, onClose: () => setRoleEditTarget(null), title: "Modify Access Role", options: ["ADMIN", "MANAGER", "MEMBER"], selectedOption: roleEditTarget?.role || "", onSelect: handleRoleUpdate })), activeTab === "ORGANIZATION" && isOrg && /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex flex-col gap-8 animate-in rounded-2xl p-6 bg-white fade-in duration-300" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "relative group cursor-pointer shrink-0", onClick: () => canManage && !isSavingOrg ? orgFileInputRef.current?.click() : void 0 }, /* @__PURE__ */ import_react89.default.createElement(OrgAvatar2, { src: orgAvatarUrl, sizeClass: "w-14 h-14" }), canManage && /* @__PURE__ */ import_react89.default.createElement("div", { className: "absolute -bottom-1 -right-1 w-6 h-6 bg-white border border-stone-200 rounded-full flex items-center justify-center text-stone-500 group-hover:text-black transition-colors z-10" }, isUploadingOrgAvatar ? /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.Loading03Icon, size: 12, className: "animate-spin" }) : /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.PlusSignIcon, size: 14 })), /* @__PURE__ */ import_react89.default.createElement("input", { type: "file", ref: orgFileInputRef, className: "hidden", accept: ".png, .jpg, .jpeg", onChange: (e) => handleFileSelect(e, "ORGANIZATION") })), /* @__PURE__ */ import_react89.default.createElement("div", null, /* @__PURE__ */ import_react89.default.createElement("h2", { className: "text-black text-xl mb-1 tracking-tight" }, "Workspace Details"), /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-xs text-stone-500" }, "Manage your organizational identity and handles."))), !canManage && /* @__PURE__ */ import_react89.default.createElement("span", { className: "p-2 w-9 h-9 bg-stone-100 text-stone-400 rounded-full shrink-0" }, /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.CircleLock02Icon, size: 18, className: "text-current" }))), /* @__PURE__ */ import_react89.default.createElement("form", { className: "flex flex-col gap-8 w-full max-w-5xl", onSubmit: handleSaveOrganization, autoComplete: "off" }, /* @__PURE__ */ import_react89.default.createElement(TextInput, { label: "Workspace Name", value: orgName, onChange: handleOrgNameChange, disabled: !canManage || isSavingOrg, placeholder: "Acme Corporation", maxLength: 50 }), /* @__PURE__ */ import_react89.default.createElement("div", { className: "space-y-1.5 relative w-full" }, /* @__PURE__ */ import_react89.default.createElement("label", { className: "text-xs text-stone-400 tracking-[0.2em] block" }, "Workspace Handle"), /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center relative w-full border-b border-stone-200 focus-within:border-black transition-all duration-300 overflow-hidden" }, /* @__PURE__ */ import_react89.default.createElement("input", { type: "text", value: orgSlug, disabled: !canManage || isSavingOrg, onChange: (e) => handleOrgSlugChange(e.target.value), spellCheck: "false", autoComplete: "off", className: "w-full pr-10 pl-0 py-3 text-sm bg-transparent text-black outline-none disabled:opacity-50 disabled:cursor-not-allowed", placeholder: "workspace-handle" }), /* @__PURE__ */ import_react89.default.createElement("div", { className: "absolute right-2 top-1/2 -translate-y-1/2" }, isCheckingSlug && /* @__PURE__ */ import_react89.default.createElement(InputSpinner3, null), !isCheckingSlug && canManage && orgSlug !== initialOrgSlug && orgSlug.length >= 3 && slugAvailable === false && /* @__PURE__ */ import_react89.default.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-[#d97757]/10" }, /* @__PURE__ */ import_react89.default.createElement("svg", { className: "w-2 h-2 text-[#d97757]", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react89.default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" }))), !isCheckingSlug && canManage && orgSlug !== initialOrgSlug && orgSlug.length >= 3 && slugAvailable === true && /* @__PURE__ */ import_react89.default.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-green-100" }, /* @__PURE__ */ import_react89.default.createElement("svg", { className: "w-2 h-2 text-green-600", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react89.default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M16.707 5.293a1 1 0 00-1.414 0L8 12.586 4.707 9.293a1 1 0 10-1.414 1.414l4 4a1 1 0 001.414 0l8-8a1 1 0 000-1.414z" })))))), /* @__PURE__ */ import_react89.default.createElement("div", { className: "pt-8 mt-2 flex items-center gap-4" }, /* @__PURE__ */ import_react89.default.createElement(ThreeDActionButton, { type: "submit", disabled: isOrgSaveDisabled, isLoading: isSavingOrg, className: "min-w-32" }, "Save Changes"), hasOrgChanges && !isSavingOrg && canManage && /* @__PURE__ */ import_react89.default.createElement("button", { type: "button", onClick: () => {
|
|
5649
5747
|
setOrgName(initialOrgName || "");
|
|
5650
5748
|
setOrgSlug(initialOrgSlug || "");
|
|
5651
|
-
|
|
5749
|
+
setOrgAvatarUrl(initialOrgAvatarUrl || "");
|
|
5750
|
+
setPendingOrgAvatar(null);
|
|
5751
|
+
}, className: "text-xs tracking-widest text-stone-400 hover:text-black transition-colors outline-none" }, "Cancel")))), activeTab === "ACCOUNT" && /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex flex-col gap-6 animate-in fade-in duration-300" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex flex-col gap-8 rounded-2xl p-6 bg-white w-full" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "relative group cursor-pointer shrink-0", onClick: () => !isSavingProfile ? userFileInputRef.current?.click() : void 0 }, /* @__PURE__ */ import_react89.default.createElement(MemberAvatar3, { src: avatarUrl, status: "ACTIVE", sizeClass: "w-14 h-14" }), /* @__PURE__ */ import_react89.default.createElement("div", { className: "absolute -bottom-1 -right-1 w-6 h-6 bg-white border border-stone-200 rounded-full flex items-center justify-center text-stone-500 group-hover:text-black transition-colors z-20" }, isUploadingUserAvatar ? /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.Loading03Icon, size: 12, className: "animate-spin" }) : /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.PlusSignIcon, size: 14 })), /* @__PURE__ */ import_react89.default.createElement("input", { type: "file", ref: userFileInputRef, className: "hidden", accept: ".png, .jpg, .jpeg", onChange: (e) => handleFileSelect(e, "USER") })), /* @__PURE__ */ import_react89.default.createElement("div", null, /* @__PURE__ */ import_react89.default.createElement("h2", { className: "text-black text-xl mb-1 tracking-tight" }, "Personal Identity"), /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-xs text-stone-500" }, "Update your system display name and contact email.")))), /* @__PURE__ */ import_react89.default.createElement("form", { className: "flex flex-col gap-6 w-full max-w-5xl", onSubmit: handleSaveProfile, autoComplete: "off" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-6" }, /* @__PURE__ */ import_react89.default.createElement(TextInput, { label: "First Name", value: firstName, onChange: (v) => setFirstName(v.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50)), disabled: isSavingProfile, placeholder: "First name", maxLength: 50 }), /* @__PURE__ */ import_react89.default.createElement(TextInput, { label: "Last Name", value: lastName, onChange: (v) => setLastName(v.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50)), disabled: isSavingProfile, placeholder: "Last name", maxLength: 50 })), /* @__PURE__ */ import_react89.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-6" }, /* @__PURE__ */ import_react89.default.createElement(TextInput, { label: "Job Title", value: jobTitle, onChange: (v) => setJobTitle(v.substring(0, 50)), disabled: isSavingProfile, placeholder: "e.g. HR Manager, CEO", maxLength: 50 }), /* @__PURE__ */ import_react89.default.createElement("div", { className: "space-y-1.5 w-full" }, /* @__PURE__ */ import_react89.default.createElement("label", { className: "text-xs text-stone-400 tracking-[0.2em] block" }, "Email Address"), /* @__PURE__ */ import_react89.default.createElement("input", { type: "email", value: initialEmail, disabled: true, className: "w-full pb-3 pt-3 text-sm bg-transparent text-stone-400 border-b border-stone-200 outline-none cursor-not-allowed" }))), /* @__PURE__ */ import_react89.default.createElement("div", { className: "space-y-1.5 w-full" }, /* @__PURE__ */ import_react89.default.createElement("label", { className: "text-xs text-stone-400 tracking-[0.2em] block" }, "About Me"), /* @__PURE__ */ import_react89.default.createElement(
|
|
5752
|
+
"textarea",
|
|
5753
|
+
{
|
|
5754
|
+
value: description,
|
|
5755
|
+
onChange: (e) => setDescription(e.target.value.substring(0, 300)),
|
|
5756
|
+
disabled: isSavingProfile,
|
|
5757
|
+
placeholder: "A short shout about yourself...",
|
|
5758
|
+
className: "w-full pb-3 pt-3 text-sm bg-transparent text-black border-b border-stone-200 outline-none focus:border-black transition-all duration-300 resize-none h-20 custom-scrollbar",
|
|
5759
|
+
maxLength: 300
|
|
5760
|
+
}
|
|
5761
|
+
)), /* @__PURE__ */ import_react89.default.createElement("div", { className: "pt-4 flex items-center gap-4" }, /* @__PURE__ */ import_react89.default.createElement(ThreeDActionButton, { type: "submit", disabled: isProfileSaveDisabled, isLoading: isSavingProfile, className: "min-w-32" }, "Update Identity")))), /* @__PURE__ */ import_react89.default.createElement("div", { className: "bg-white rounded-2xl p-6 w-full flex flex-col sm:flex-row sm:items-center justify-between gap-6 border border-stone-100" }, /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex flex-col items-start max-w-sm" }, /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-xs text-stone-400 tracking-[0.2em] mb-2 uppercase" }, "AI Credits Balance"), isBillingLoading ? /* @__PURE__ */ import_react89.default.createElement("div", { className: "h-8 w-32 bg-stone-100 animate-pulse rounded mt-1" }) : /* @__PURE__ */ import_react89.default.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.Coins01Icon, size: 28, className: "text-[#d97757]" }), /* @__PURE__ */ import_react89.default.createElement("span", { className: "text-3xl text-black tracking-tight" }, aiCredits)), /* @__PURE__ */ import_react89.default.createElement("p", { className: "text-xs text-stone-500 mt-4 leading-relaxed" }, "AI credits are consumed when generating intelligent summaries, transcriptions, and automated huddle insights.")), /* @__PURE__ */ import_react89.default.createElement("button", { onClick: onTopUp, className: "w-12 h-12 rounded-full border border-stone-200 flex items-center justify-center text-black hover:bg-stone-50 transition-colors outline-none shrink-0", "aria-label": "Top Up Credits" }, /* @__PURE__ */ import_react89.default.createElement(import_react90.HugeiconsIcon, { icon: import_core_free_icons33.PlusSignIcon, size: 20 })))));
|
|
5652
5762
|
};
|
|
5653
5763
|
|
|
5654
5764
|
// src/components/UniversalCreateHuddle.tsx
|
package/dist/index.mjs
CHANGED
|
@@ -625,7 +625,7 @@ var ReusableOptions = ({
|
|
|
625
625
|
onSelect(opt);
|
|
626
626
|
onClose();
|
|
627
627
|
},
|
|
628
|
-
className: `w-full text-left
|
|
628
|
+
className: `w-full text-left p-4 text-xs tracking-tight rounded-full transition-colors outline-none ${isSelected ? "text-[#d97757] bg-[#d97757]/10" : "text-stone-600 hover:bg-stone-50/50"}`
|
|
629
629
|
},
|
|
630
630
|
opt.charAt(0).toUpperCase() + opt.slice(1).toLowerCase()
|
|
631
631
|
);
|
|
@@ -5477,6 +5477,22 @@ var MemberAvatar3 = ({ src, status, sizeClass = "w-10 h-10" }) => {
|
|
|
5477
5477
|
};
|
|
5478
5478
|
return /* @__PURE__ */ React52.createElement("div", { className: `relative shrink-0 ${sizeClass}` }, /* @__PURE__ */ React52.createElement("div", { className: "w-full h-full rounded-lg bg-stone-100 flex items-center justify-center overflow-hidden" }, !loaded && !error && /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: Loading03Icon25, className: "animate-spin text-stone-400 absolute", size: 14 }), /* @__PURE__ */ React52.createElement("img", { src: finalSrc, alt: "Member", className: `w-full h-full object-cover transition-opacity duration-300 ${loaded || error ? "opacity-100" : "opacity-0"}`, onLoad: () => setLoaded(true), onError: () => setError(true) })), /* @__PURE__ */ React52.createElement("div", { className: `absolute -bottom-1 -right-1 w-3.5 h-3.5 rounded-full border-2 border-white z-10 ${getStatusColor()}` }));
|
|
5479
5479
|
};
|
|
5480
|
+
var OrgAvatar2 = ({ src, sizeClass = "w-10 h-10" }) => {
|
|
5481
|
+
const [loaded, setLoaded] = useState38(false);
|
|
5482
|
+
const [error, setError] = useState38(false);
|
|
5483
|
+
const defaultAvatar = "https://storage.googleapis.com/retina-cloud-v2/assets/images/office_a.avif";
|
|
5484
|
+
const finalSrc = error || !src ? defaultAvatar : src;
|
|
5485
|
+
return /* @__PURE__ */ React52.createElement("div", { className: `relative shrink-0 ${sizeClass}` }, /* @__PURE__ */ React52.createElement("div", { className: "w-full h-full rounded-lg bg-stone-100 flex items-center justify-center overflow-hidden" }, !loaded && !error && /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: Loading03Icon25, className: "animate-spin text-stone-400 absolute", size: 14 }), /* @__PURE__ */ React52.createElement(
|
|
5486
|
+
"img",
|
|
5487
|
+
{
|
|
5488
|
+
src: finalSrc,
|
|
5489
|
+
alt: "Workspace Avatar",
|
|
5490
|
+
className: `w-full h-full object-cover transition-opacity duration-300 ${loaded || error ? "opacity-100" : "opacity-0"}`,
|
|
5491
|
+
onLoad: () => setLoaded(true),
|
|
5492
|
+
onError: () => setError(true)
|
|
5493
|
+
}
|
|
5494
|
+
)));
|
|
5495
|
+
};
|
|
5480
5496
|
var PageSpinner8 = () => /* @__PURE__ */ React52.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: Loading03Icon25, size: 32, className: "animate-spin mb-4 text-black" }));
|
|
5481
5497
|
var InputSpinner3 = () => /* @__PURE__ */ React52.createElement("svg", { className: "animate-spin h-4 w-4 text-stone-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ React52.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React52.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
|
|
5482
5498
|
var UniversalSettings = ({
|
|
@@ -5502,11 +5518,16 @@ var UniversalSettings = ({
|
|
|
5502
5518
|
onUpdateRole,
|
|
5503
5519
|
initialOrgName = "",
|
|
5504
5520
|
initialOrgSlug = "",
|
|
5521
|
+
initialOrgAvatarUrl = "",
|
|
5505
5522
|
initialFullName = "",
|
|
5506
5523
|
initialEmail = "",
|
|
5524
|
+
initialJobTitle = "",
|
|
5525
|
+
initialDescription = "",
|
|
5526
|
+
initialAvatarUrl = "",
|
|
5507
5527
|
onSaveProfile,
|
|
5508
5528
|
onSaveOrganization,
|
|
5509
5529
|
onCheckSlugAvailability,
|
|
5530
|
+
onUploadAvatar,
|
|
5510
5531
|
aiCredits,
|
|
5511
5532
|
isBillingLoading = false,
|
|
5512
5533
|
onTopUp,
|
|
@@ -5516,7 +5537,8 @@ var UniversalSettings = ({
|
|
|
5516
5537
|
if (typeof window !== "undefined") window.history.back();
|
|
5517
5538
|
});
|
|
5518
5539
|
const isOrg = accountType === "ORGANIZATION";
|
|
5519
|
-
const
|
|
5540
|
+
const safeRole = String(userRole || "").toUpperCase().trim();
|
|
5541
|
+
const canManage = ["ADMIN", "MANAGER", "OWNER"].includes(safeRole);
|
|
5520
5542
|
const [activeTab, setActiveTab] = useState38(isOrg ? "MEMBERS" : "ACCOUNT");
|
|
5521
5543
|
const [expandedId, setExpandedId] = useState38(null);
|
|
5522
5544
|
const [memberToRemove, setMemberToRemove] = useState38(null);
|
|
@@ -5533,19 +5555,57 @@ var UniversalSettings = ({
|
|
|
5533
5555
|
const [isUpdatingRole, setIsUpdatingRole] = useState38(false);
|
|
5534
5556
|
const [orgName, setOrgName] = useState38(initialOrgName);
|
|
5535
5557
|
const [orgSlug, setOrgSlug] = useState38(initialOrgSlug);
|
|
5558
|
+
const [orgAvatarUrl, setOrgAvatarUrl] = useState38(initialOrgAvatarUrl);
|
|
5536
5559
|
const [firstName, setFirstName] = useState38("");
|
|
5537
5560
|
const [lastName, setLastName] = useState38("");
|
|
5561
|
+
const [jobTitle, setJobTitle] = useState38(initialJobTitle);
|
|
5562
|
+
const [description, setDescription] = useState38(initialDescription);
|
|
5563
|
+
const [avatarUrl, setAvatarUrl] = useState38(initialAvatarUrl);
|
|
5538
5564
|
const [isCheckingSlug, setIsCheckingSlug] = useState38(false);
|
|
5539
5565
|
const [slugAvailable, setSlugAvailable] = useState38(null);
|
|
5540
5566
|
const [isSavingOrg, setIsSavingOrg] = useState38(false);
|
|
5541
5567
|
const [isSavingProfile, setIsSavingProfile] = useState38(false);
|
|
5568
|
+
const orgFileInputRef = useRef14(null);
|
|
5569
|
+
const userFileInputRef = useRef14(null);
|
|
5570
|
+
const [pendingOrgAvatar, setPendingOrgAvatar] = useState38(null);
|
|
5571
|
+
const [pendingUserAvatar, setPendingUserAvatar] = useState38(null);
|
|
5572
|
+
const [isUploadingOrgAvatar, setIsUploadingOrgAvatar] = useState38(false);
|
|
5573
|
+
const [isUploadingUserAvatar, setIsUploadingUserAvatar] = useState38(false);
|
|
5542
5574
|
useEffect21(() => {
|
|
5543
5575
|
setOrgName(initialOrgName || "");
|
|
5544
5576
|
setOrgSlug(initialOrgSlug || "");
|
|
5577
|
+
setOrgAvatarUrl(initialOrgAvatarUrl || "");
|
|
5545
5578
|
const parts = (initialFullName || "").split(" ");
|
|
5546
5579
|
setFirstName(parts[0] || "");
|
|
5547
5580
|
setLastName(parts.slice(1).join(" ") || "");
|
|
5548
|
-
|
|
5581
|
+
setJobTitle(initialJobTitle || "");
|
|
5582
|
+
setDescription(initialDescription || "");
|
|
5583
|
+
setAvatarUrl(initialAvatarUrl || "");
|
|
5584
|
+
}, [initialOrgName, initialOrgSlug, initialOrgAvatarUrl, initialFullName, initialJobTitle, initialDescription, initialAvatarUrl]);
|
|
5585
|
+
const handleFileSelect = (e, type) => {
|
|
5586
|
+
const file = e.target.files?.[0];
|
|
5587
|
+
if (!file) return;
|
|
5588
|
+
if (file.size > 1024 * 1024) {
|
|
5589
|
+
toast14.error("Image size must be less than 1MB.");
|
|
5590
|
+
e.target.value = "";
|
|
5591
|
+
return;
|
|
5592
|
+
}
|
|
5593
|
+
const validTypes = ["image/jpeg", "image/jpg", "image/png"];
|
|
5594
|
+
if (!validTypes.includes(file.type)) {
|
|
5595
|
+
toast14.error("Only PNG and JPEG images are allowed.");
|
|
5596
|
+
e.target.value = "";
|
|
5597
|
+
return;
|
|
5598
|
+
}
|
|
5599
|
+
const previewUrl = URL.createObjectURL(file);
|
|
5600
|
+
if (type === "USER") {
|
|
5601
|
+
setPendingUserAvatar(file);
|
|
5602
|
+
setAvatarUrl(previewUrl);
|
|
5603
|
+
} else if (type === "ORGANIZATION") {
|
|
5604
|
+
setPendingOrgAvatar(file);
|
|
5605
|
+
setOrgAvatarUrl(previewUrl);
|
|
5606
|
+
}
|
|
5607
|
+
e.target.value = "";
|
|
5608
|
+
};
|
|
5549
5609
|
useEffect21(() => {
|
|
5550
5610
|
if (activeTab !== "MEMBERS") return;
|
|
5551
5611
|
if (isFirstSearchMount.current) {
|
|
@@ -5636,13 +5696,32 @@ var UniversalSettings = ({
|
|
|
5636
5696
|
if (orgSlug !== initialOrgSlug && slugAvailable === false) return toast14.error("Address handle unavailable.");
|
|
5637
5697
|
setIsSavingOrg(true);
|
|
5638
5698
|
try {
|
|
5639
|
-
|
|
5699
|
+
let finalAvatarUrl = orgAvatarUrl;
|
|
5700
|
+
if (pendingOrgAvatar && onUploadAvatar) {
|
|
5701
|
+
setIsUploadingOrgAvatar(true);
|
|
5702
|
+
try {
|
|
5703
|
+
const res2 = await onUploadAvatar(pendingOrgAvatar, "ORGANIZATION");
|
|
5704
|
+
if (res2?.url) {
|
|
5705
|
+
finalAvatarUrl = res2.url;
|
|
5706
|
+
setOrgAvatarUrl(finalAvatarUrl);
|
|
5707
|
+
}
|
|
5708
|
+
} catch (err) {
|
|
5709
|
+
toast14.error("Failed to securely upload workspace avatar.");
|
|
5710
|
+
setIsSavingOrg(false);
|
|
5711
|
+
setIsUploadingOrgAvatar(false);
|
|
5712
|
+
return;
|
|
5713
|
+
}
|
|
5714
|
+
setPendingOrgAvatar(null);
|
|
5715
|
+
setIsUploadingOrgAvatar(false);
|
|
5716
|
+
}
|
|
5717
|
+
const res = await onSaveOrganization({ name: orgName, slug: orgSlug, avatarUrl: finalAvatarUrl });
|
|
5640
5718
|
if (res.success) toast14.success("Workspace updated successfully.");
|
|
5641
5719
|
else toast14.error(res.error || "Failed to update workspace.");
|
|
5642
5720
|
} catch (error) {
|
|
5643
5721
|
toast14.error("Service unavailable.");
|
|
5644
5722
|
} finally {
|
|
5645
5723
|
setIsSavingOrg(false);
|
|
5724
|
+
setIsUploadingOrgAvatar(false);
|
|
5646
5725
|
}
|
|
5647
5726
|
};
|
|
5648
5727
|
const handleSaveProfile = async (e) => {
|
|
@@ -5650,18 +5729,37 @@ var UniversalSettings = ({
|
|
|
5650
5729
|
if (isSavingProfile || !onSaveProfile) return;
|
|
5651
5730
|
setIsSavingProfile(true);
|
|
5652
5731
|
try {
|
|
5653
|
-
|
|
5732
|
+
let finalAvatarUrl = avatarUrl;
|
|
5733
|
+
if (pendingUserAvatar && onUploadAvatar) {
|
|
5734
|
+
setIsUploadingUserAvatar(true);
|
|
5735
|
+
try {
|
|
5736
|
+
const res2 = await onUploadAvatar(pendingUserAvatar, "USER");
|
|
5737
|
+
if (res2?.url) {
|
|
5738
|
+
finalAvatarUrl = res2.url;
|
|
5739
|
+
setAvatarUrl(finalAvatarUrl);
|
|
5740
|
+
}
|
|
5741
|
+
} catch (err) {
|
|
5742
|
+
toast14.error("Failed to securely upload profile avatar.");
|
|
5743
|
+
setIsSavingProfile(false);
|
|
5744
|
+
setIsUploadingUserAvatar(false);
|
|
5745
|
+
return;
|
|
5746
|
+
}
|
|
5747
|
+
setPendingUserAvatar(null);
|
|
5748
|
+
setIsUploadingUserAvatar(false);
|
|
5749
|
+
}
|
|
5750
|
+
const res = await onSaveProfile({ firstName, lastName, jobTitle, description, avatarUrl: finalAvatarUrl });
|
|
5654
5751
|
if (res.success) toast14.success("Identity updated successfully.");
|
|
5655
5752
|
else toast14.error(res.error || "Failed to update identity.");
|
|
5656
5753
|
} catch (error) {
|
|
5657
5754
|
toast14.error("Service unavailable.");
|
|
5658
5755
|
} finally {
|
|
5659
5756
|
setIsSavingProfile(false);
|
|
5757
|
+
setIsUploadingUserAvatar(false);
|
|
5660
5758
|
}
|
|
5661
5759
|
};
|
|
5662
|
-
const hasOrgChanges = orgName !== initialOrgName || orgSlug !== initialOrgSlug;
|
|
5760
|
+
const hasOrgChanges = orgName !== initialOrgName || orgSlug !== initialOrgSlug || orgAvatarUrl !== initialOrgAvatarUrl;
|
|
5663
5761
|
const isOrgSaveDisabled = isSavingOrg || !canManage || isCheckingSlug || !hasOrgChanges || orgName.length < 3 || orgSlug.length < 3 || orgSlug !== initialOrgSlug && slugAvailable === false;
|
|
5664
|
-
const hasProfileChanges = `${firstName} ${lastName}`.trim() !== initialFullName;
|
|
5762
|
+
const hasProfileChanges = `${firstName} ${lastName}`.trim() !== initialFullName || jobTitle !== initialJobTitle || description !== initialDescription || avatarUrl !== initialAvatarUrl;
|
|
5665
5763
|
const isProfileSaveDisabled = isSavingProfile || !hasProfileChanges || firstName.length < 2 || lastName.length < 2;
|
|
5666
5764
|
return /* @__PURE__ */ React52.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300" }, /* @__PURE__ */ React52.createElement(ManagedToaster, null), /* @__PURE__ */ React52.createElement("div", { className: "mb-6 flex w-full items-center px-1" }, /* @__PURE__ */ React52.createElement("button", { onClick: onBackHandler, className: "flex items-center gap-2 text-[#d97757] hover:text-[#d97757] transition-colors text-sm outline-none" }, /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: ArrowLeft01Icon18, size: 16 }), " Back")), /* @__PURE__ */ React52.createElement("div", { className: "flex flex-col gap-1 mb-8 px-1" }, /* @__PURE__ */ React52.createElement("h1", { className: "text-black text-xl tracking-tight" }, "System Settings"), /* @__PURE__ */ React52.createElement("p", { className: "text-xs text-stone-500" }, "Manage your workspace identity, team configurations, and AI billing parameters.")), /* @__PURE__ */ React52.createElement("div", { className: "flex items-center gap-6 mb-6 overflow-x-auto custom-scrollbar px-1" }, isOrg && /* @__PURE__ */ React52.createElement("button", { onClick: () => {
|
|
5667
5765
|
setActiveTab("MEMBERS");
|
|
@@ -5700,10 +5798,22 @@ var UniversalSettings = ({
|
|
|
5700
5798
|
))))))) : /* @__PURE__ */ React52.createElement(React52.Fragment, null, /* @__PURE__ */ React52.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React52.createElement("div", { className: "flex flex-row items-center justify-between gap-4" }, /* @__PURE__ */ React52.createElement("h2", { className: "text-black text-xl tracking-tight" }, isInviteMode ? "Add Member" : "Team Directory"), !isInviteMode && canManage && /* @__PURE__ */ React52.createElement("button", { onClick: () => setIsInviteMode(true), className: "shrink-0 px-4 py-1.5 border border-stone-200 text-black text-xs tracking-wide rounded-full hover:bg-stone-50 transition-colors outline-none" }, "Invite Team")), !isInviteMode && /* @__PURE__ */ React52.createElement("p", { className: "text-xs text-stone-500" }, "Manage members and access controls across your organization.")), /* @__PURE__ */ React52.createElement("div", { className: "w-full overflow-hidden" }, isInviteMode ? /* @__PURE__ */ React52.createElement("form", { onSubmit: handleInviteSubmit, className: "flex flex-col gap-8 animate-in fade-in duration-300" }, /* @__PURE__ */ React52.createElement("div", { className: "space-y-1.5 mt-2" }, /* @__PURE__ */ React52.createElement("label", { className: "text-xs text-stone-400 tracking-[0.2em] block" }, "Email Address"), /* @__PURE__ */ React52.createElement("input", { type: "email", value: inviteEmail, onChange: (e) => setInviteEmail(cleanEmailId(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-stone-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "name@company.com" })), /* @__PURE__ */ React52.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React52.createElement(ThreeDActionButton, { type: "submit", disabled: inviteEmail.length < 5 || isInviting, isLoading: isInviting, className: "w-full" }, "Send Invitation"), /* @__PURE__ */ React52.createElement("button", { type: "button", onClick: () => {
|
|
5701
5799
|
setIsInviteMode(false);
|
|
5702
5800
|
setInviteEmail("");
|
|
5703
|
-
}, disabled: isInviting, className: "w-full flex items-center justify-center py-2.5 rounded-full border border-stone-200 text-black hover:bg-stone-50 transition-colors outline-none text-xs tracking-wide" }, "Cancel"))) : isMembersLoading || isTyping ? /* @__PURE__ */ React52.createElement(PageSpinner8, null) : /* @__PURE__ */ React52.createElement("div", { className: "flex flex-col min-w-0 animate-in fade-in duration-300" }, /* @__PURE__ */ React52.createElement("div", null, members.length === 0 ? /* @__PURE__ */ React52.createElement("p", { className: "text-xs text-stone-400 py-6 text-center" }, "No members found") : members.map((member) => /* @__PURE__ */ React52.createElement("div", { key: member.id, onClick: () => setExpandedId(member.id), className: "flex items-center justify-between py-3 hover:bg-stone-50 transition-colors cursor-pointer group min-w-0 px-3 -mx-3 rounded-xl" }, /* @__PURE__ */ React52.createElement("div", { className: "flex items-center gap-4 min-w-0 flex-1" }, /* @__PURE__ */ React52.createElement(MemberAvatar3, { src: member.avatarUrl, status: member.status }), /* @__PURE__ */ React52.createElement("div", { className: "min-w-0 flex-1 flex flex-col gap-0.5" }, /* @__PURE__ */ React52.createElement("p", { className: "text-sm text-black truncate" }, member.fullName), /* @__PURE__ */ React52.createElement("p", { className: "text-xs text-stone-500 capitalize truncate" }, member.role.toLowerCase())))))), /* @__PURE__ */ React52.createElement("div", { className: "flex items-center justify-between pt-6 mt-2 " }, /* @__PURE__ */ React52.createElement("span", { className: "text-xs text-stone-400 tracking-[0.2em]" }, "Page ", membersCurrentPage, " of ", membersTotalPages === 0 ? 1 : membersTotalPages), /* @__PURE__ */ React52.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React52.createElement("button", { onClick: () => onMembersPageChange(membersCurrentPage - 1), disabled: membersCurrentPage <= 1 || isMembersLoading, className: "p-2 bg-white border border-stone-200 rounded-full text-black hover:bg-stone-50 disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none" }, /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: ArrowLeft01Icon18, size: 14 })), /* @__PURE__ */ React52.createElement("button", { onClick: () => onMembersPageChange(membersCurrentPage + 1), disabled: membersCurrentPage >= membersTotalPages || isMembersLoading || membersTotalPages === 0, className: "p-2 bg-white border border-stone-200 rounded-full text-black hover:bg-stone-50 disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none" }, /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: ArrowRight01Icon13, size: 14 })))))))), /* @__PURE__ */ React52.createElement(ReusableOptions, { isOpen: isStatusModalOpen, onClose: () => setIsStatusModalOpen(false), title: "Status Filter", options: ["ALL", "ACTIVE", "BUSY", "OFFLINE", "AWAY"], selectedOption: activeStatusFilter, onSelect: (status) => onStatusFilterChange(status) }), /* @__PURE__ */ React52.createElement(ReusableOptions, { isOpen: isRoleModalOpen, onClose: () => setIsRoleModalOpen(false), title: "Role Filter", options: ["ALL", "OWNER", "ADMIN", "MANAGER", "MEMBER", "GUEST"], selectedOption: activeRoleFilter, onSelect: (role) => onRoleFilterChange(role) }), /* @__PURE__ */ React52.createElement(ReusableOptions, { isOpen: !!roleEditTarget, onClose: () => setRoleEditTarget(null), title: "Modify Access Role", options: ["ADMIN", "MANAGER", "MEMBER"], selectedOption: roleEditTarget?.role || "", onSelect: handleRoleUpdate })), activeTab === "ORGANIZATION" && isOrg && /* @__PURE__ */ React52.createElement("div", { className: "flex flex-col gap-8 animate-in rounded-2xl p-6 bg-white fade-in duration-300" }, /* @__PURE__ */ React52.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ React52.createElement("div", null, /* @__PURE__ */ React52.createElement("h2", { className: "text-black text-xl mb-1 tracking-tight" }, "Workspace Details"), /* @__PURE__ */ React52.createElement("p", { className: "text-xs text-stone-500" }, "Manage your organizational identity and handles.")), !canManage && /* @__PURE__ */ React52.createElement("span", { className: "p-2 w-9 h-9 bg-stone-100 text-stone-400 rounded-full shrink-0" }, /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: CircleLock02Icon3, size: 18, className: "text-current" }))), /* @__PURE__ */ React52.createElement("form", { className: "flex flex-col gap-8 w-full max-w-5xl", onSubmit: handleSaveOrganization, autoComplete: "off" }, /* @__PURE__ */ React52.createElement(TextInput, { label: "Workspace Name", value: orgName, onChange: handleOrgNameChange, disabled: !canManage || isSavingOrg, placeholder: "Acme Corporation", maxLength: 50 }), /* @__PURE__ */ React52.createElement("div", { className: "space-y-1.5 relative w-full" }, /* @__PURE__ */ React52.createElement("label", { className: "text-xs text-stone-400 tracking-[0.2em] block" }, "Workspace Handle"), /* @__PURE__ */ React52.createElement("div", { className: "flex items-center relative w-full border-b border-stone-200 focus-within:border-black transition-all duration-300 overflow-hidden" }, /* @__PURE__ */ React52.createElement("input", { type: "text", value: orgSlug, disabled: !canManage || isSavingOrg, onChange: (e) => handleOrgSlugChange(e.target.value), spellCheck: "false", autoComplete: "off", className: "w-full pr-10 pl-0 py-3 text-sm bg-transparent text-black outline-none disabled:opacity-50 disabled:cursor-not-allowed", placeholder: "workspace-handle" }), /* @__PURE__ */ React52.createElement("div", { className: "absolute right-2 top-1/2 -translate-y-1/2" }, isCheckingSlug && /* @__PURE__ */ React52.createElement(InputSpinner3, null), !isCheckingSlug && canManage && orgSlug !== initialOrgSlug && orgSlug.length >= 3 && slugAvailable === false && /* @__PURE__ */ React52.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-[#d97757]/10" }, /* @__PURE__ */ React52.createElement("svg", { className: "w-2 h-2 text-[#d97757]", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React52.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" }))), !isCheckingSlug && canManage && orgSlug !== initialOrgSlug && orgSlug.length >= 3 && slugAvailable === true && /* @__PURE__ */ React52.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-green-100" }, /* @__PURE__ */ React52.createElement("svg", { className: "w-2 h-2 text-green-600", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React52.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M16.707 5.293a1 1 0 00-1.414 0L8 12.586 4.707 9.293a1 1 0 10-1.414 1.414l4 4a1 1 0 001.414 0l8-8a1 1 0 000-1.414z" })))))), /* @__PURE__ */ React52.createElement("div", { className: "pt-8 mt-2 flex items-center gap-4" }, /* @__PURE__ */ React52.createElement(ThreeDActionButton, { type: "submit", disabled: isOrgSaveDisabled, isLoading: isSavingOrg, className: "min-w-32" }, "Save Changes"), hasOrgChanges && !isSavingOrg && canManage && /* @__PURE__ */ React52.createElement("button", { type: "button", onClick: () => {
|
|
5801
|
+
}, disabled: isInviting, className: "w-full flex items-center justify-center py-2.5 rounded-full border border-stone-200 text-black hover:bg-stone-50 transition-colors outline-none text-xs tracking-wide" }, "Cancel"))) : isMembersLoading || isTyping ? /* @__PURE__ */ React52.createElement(PageSpinner8, null) : /* @__PURE__ */ React52.createElement("div", { className: "flex flex-col min-w-0 animate-in fade-in duration-300" }, /* @__PURE__ */ React52.createElement("div", null, members.length === 0 ? /* @__PURE__ */ React52.createElement("p", { className: "text-xs text-stone-400 py-6 text-center" }, "No members found") : members.map((member) => /* @__PURE__ */ React52.createElement("div", { key: member.id, onClick: () => setExpandedId(member.id), className: "flex items-center justify-between py-3 hover:bg-stone-50 transition-colors cursor-pointer group min-w-0 px-3 -mx-3 rounded-xl" }, /* @__PURE__ */ React52.createElement("div", { className: "flex items-center gap-4 min-w-0 flex-1" }, /* @__PURE__ */ React52.createElement(MemberAvatar3, { src: member.avatarUrl, status: member.status }), /* @__PURE__ */ React52.createElement("div", { className: "min-w-0 flex-1 flex flex-col gap-0.5" }, /* @__PURE__ */ React52.createElement("p", { className: "text-sm text-black truncate" }, member.fullName), /* @__PURE__ */ React52.createElement("p", { className: "text-xs text-stone-500 capitalize truncate" }, member.role.toLowerCase())))))), /* @__PURE__ */ React52.createElement("div", { className: "flex items-center justify-between pt-6 mt-2 " }, /* @__PURE__ */ React52.createElement("span", { className: "text-xs text-stone-400 tracking-[0.2em]" }, "Page ", membersCurrentPage, " of ", membersTotalPages === 0 ? 1 : membersTotalPages), /* @__PURE__ */ React52.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React52.createElement("button", { onClick: () => onMembersPageChange(membersCurrentPage - 1), disabled: membersCurrentPage <= 1 || isMembersLoading, className: "p-2 bg-white border border-stone-200 rounded-full text-black hover:bg-stone-50 disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none" }, /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: ArrowLeft01Icon18, size: 14 })), /* @__PURE__ */ React52.createElement("button", { onClick: () => onMembersPageChange(membersCurrentPage + 1), disabled: membersCurrentPage >= membersTotalPages || isMembersLoading || membersTotalPages === 0, className: "p-2 bg-white border border-stone-200 rounded-full text-black hover:bg-stone-50 disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none" }, /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: ArrowRight01Icon13, size: 14 })))))))), /* @__PURE__ */ React52.createElement(ReusableOptions, { isOpen: isStatusModalOpen, onClose: () => setIsStatusModalOpen(false), title: "Status Filter", options: ["ALL", "ACTIVE", "BUSY", "OFFLINE", "AWAY"], selectedOption: activeStatusFilter, onSelect: (status) => onStatusFilterChange(status) }), /* @__PURE__ */ React52.createElement(ReusableOptions, { isOpen: isRoleModalOpen, onClose: () => setIsRoleModalOpen(false), title: "Role Filter", options: ["ALL", "OWNER", "ADMIN", "MANAGER", "MEMBER", "GUEST"], selectedOption: activeRoleFilter, onSelect: (role) => onRoleFilterChange(role) }), /* @__PURE__ */ React52.createElement(ReusableOptions, { isOpen: !!roleEditTarget, onClose: () => setRoleEditTarget(null), title: "Modify Access Role", options: ["ADMIN", "MANAGER", "MEMBER"], selectedOption: roleEditTarget?.role || "", onSelect: handleRoleUpdate })), activeTab === "ORGANIZATION" && isOrg && /* @__PURE__ */ React52.createElement("div", { className: "flex flex-col gap-8 animate-in rounded-2xl p-6 bg-white fade-in duration-300" }, /* @__PURE__ */ React52.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ React52.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React52.createElement("div", { className: "relative group cursor-pointer shrink-0", onClick: () => canManage && !isSavingOrg ? orgFileInputRef.current?.click() : void 0 }, /* @__PURE__ */ React52.createElement(OrgAvatar2, { src: orgAvatarUrl, sizeClass: "w-14 h-14" }), canManage && /* @__PURE__ */ React52.createElement("div", { className: "absolute -bottom-1 -right-1 w-6 h-6 bg-white border border-stone-200 rounded-full flex items-center justify-center text-stone-500 group-hover:text-black transition-colors z-10" }, isUploadingOrgAvatar ? /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: Loading03Icon25, size: 12, className: "animate-spin" }) : /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: PlusSignIcon3, size: 14 })), /* @__PURE__ */ React52.createElement("input", { type: "file", ref: orgFileInputRef, className: "hidden", accept: ".png, .jpg, .jpeg", onChange: (e) => handleFileSelect(e, "ORGANIZATION") })), /* @__PURE__ */ React52.createElement("div", null, /* @__PURE__ */ React52.createElement("h2", { className: "text-black text-xl mb-1 tracking-tight" }, "Workspace Details"), /* @__PURE__ */ React52.createElement("p", { className: "text-xs text-stone-500" }, "Manage your organizational identity and handles."))), !canManage && /* @__PURE__ */ React52.createElement("span", { className: "p-2 w-9 h-9 bg-stone-100 text-stone-400 rounded-full shrink-0" }, /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: CircleLock02Icon3, size: 18, className: "text-current" }))), /* @__PURE__ */ React52.createElement("form", { className: "flex flex-col gap-8 w-full max-w-5xl", onSubmit: handleSaveOrganization, autoComplete: "off" }, /* @__PURE__ */ React52.createElement(TextInput, { label: "Workspace Name", value: orgName, onChange: handleOrgNameChange, disabled: !canManage || isSavingOrg, placeholder: "Acme Corporation", maxLength: 50 }), /* @__PURE__ */ React52.createElement("div", { className: "space-y-1.5 relative w-full" }, /* @__PURE__ */ React52.createElement("label", { className: "text-xs text-stone-400 tracking-[0.2em] block" }, "Workspace Handle"), /* @__PURE__ */ React52.createElement("div", { className: "flex items-center relative w-full border-b border-stone-200 focus-within:border-black transition-all duration-300 overflow-hidden" }, /* @__PURE__ */ React52.createElement("input", { type: "text", value: orgSlug, disabled: !canManage || isSavingOrg, onChange: (e) => handleOrgSlugChange(e.target.value), spellCheck: "false", autoComplete: "off", className: "w-full pr-10 pl-0 py-3 text-sm bg-transparent text-black outline-none disabled:opacity-50 disabled:cursor-not-allowed", placeholder: "workspace-handle" }), /* @__PURE__ */ React52.createElement("div", { className: "absolute right-2 top-1/2 -translate-y-1/2" }, isCheckingSlug && /* @__PURE__ */ React52.createElement(InputSpinner3, null), !isCheckingSlug && canManage && orgSlug !== initialOrgSlug && orgSlug.length >= 3 && slugAvailable === false && /* @__PURE__ */ React52.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-[#d97757]/10" }, /* @__PURE__ */ React52.createElement("svg", { className: "w-2 h-2 text-[#d97757]", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React52.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" }))), !isCheckingSlug && canManage && orgSlug !== initialOrgSlug && orgSlug.length >= 3 && slugAvailable === true && /* @__PURE__ */ React52.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-green-100" }, /* @__PURE__ */ React52.createElement("svg", { className: "w-2 h-2 text-green-600", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React52.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M16.707 5.293a1 1 0 00-1.414 0L8 12.586 4.707 9.293a1 1 0 10-1.414 1.414l4 4a1 1 0 001.414 0l8-8a1 1 0 000-1.414z" })))))), /* @__PURE__ */ React52.createElement("div", { className: "pt-8 mt-2 flex items-center gap-4" }, /* @__PURE__ */ React52.createElement(ThreeDActionButton, { type: "submit", disabled: isOrgSaveDisabled, isLoading: isSavingOrg, className: "min-w-32" }, "Save Changes"), hasOrgChanges && !isSavingOrg && canManage && /* @__PURE__ */ React52.createElement("button", { type: "button", onClick: () => {
|
|
5704
5802
|
setOrgName(initialOrgName || "");
|
|
5705
5803
|
setOrgSlug(initialOrgSlug || "");
|
|
5706
|
-
|
|
5804
|
+
setOrgAvatarUrl(initialOrgAvatarUrl || "");
|
|
5805
|
+
setPendingOrgAvatar(null);
|
|
5806
|
+
}, className: "text-xs tracking-widest text-stone-400 hover:text-black transition-colors outline-none" }, "Cancel")))), activeTab === "ACCOUNT" && /* @__PURE__ */ React52.createElement("div", { className: "flex flex-col gap-6 animate-in fade-in duration-300" }, /* @__PURE__ */ React52.createElement("div", { className: "flex flex-col gap-8 rounded-2xl p-6 bg-white w-full" }, /* @__PURE__ */ React52.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ React52.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React52.createElement("div", { className: "relative group cursor-pointer shrink-0", onClick: () => !isSavingProfile ? userFileInputRef.current?.click() : void 0 }, /* @__PURE__ */ React52.createElement(MemberAvatar3, { src: avatarUrl, status: "ACTIVE", sizeClass: "w-14 h-14" }), /* @__PURE__ */ React52.createElement("div", { className: "absolute -bottom-1 -right-1 w-6 h-6 bg-white border border-stone-200 rounded-full flex items-center justify-center text-stone-500 group-hover:text-black transition-colors z-20" }, isUploadingUserAvatar ? /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: Loading03Icon25, size: 12, className: "animate-spin" }) : /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: PlusSignIcon3, size: 14 })), /* @__PURE__ */ React52.createElement("input", { type: "file", ref: userFileInputRef, className: "hidden", accept: ".png, .jpg, .jpeg", onChange: (e) => handleFileSelect(e, "USER") })), /* @__PURE__ */ React52.createElement("div", null, /* @__PURE__ */ React52.createElement("h2", { className: "text-black text-xl mb-1 tracking-tight" }, "Personal Identity"), /* @__PURE__ */ React52.createElement("p", { className: "text-xs text-stone-500" }, "Update your system display name and contact email.")))), /* @__PURE__ */ React52.createElement("form", { className: "flex flex-col gap-6 w-full max-w-5xl", onSubmit: handleSaveProfile, autoComplete: "off" }, /* @__PURE__ */ React52.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-6" }, /* @__PURE__ */ React52.createElement(TextInput, { label: "First Name", value: firstName, onChange: (v) => setFirstName(v.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50)), disabled: isSavingProfile, placeholder: "First name", maxLength: 50 }), /* @__PURE__ */ React52.createElement(TextInput, { label: "Last Name", value: lastName, onChange: (v) => setLastName(v.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50)), disabled: isSavingProfile, placeholder: "Last name", maxLength: 50 })), /* @__PURE__ */ React52.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-6" }, /* @__PURE__ */ React52.createElement(TextInput, { label: "Job Title", value: jobTitle, onChange: (v) => setJobTitle(v.substring(0, 50)), disabled: isSavingProfile, placeholder: "e.g. HR Manager, CEO", maxLength: 50 }), /* @__PURE__ */ React52.createElement("div", { className: "space-y-1.5 w-full" }, /* @__PURE__ */ React52.createElement("label", { className: "text-xs text-stone-400 tracking-[0.2em] block" }, "Email Address"), /* @__PURE__ */ React52.createElement("input", { type: "email", value: initialEmail, disabled: true, className: "w-full pb-3 pt-3 text-sm bg-transparent text-stone-400 border-b border-stone-200 outline-none cursor-not-allowed" }))), /* @__PURE__ */ React52.createElement("div", { className: "space-y-1.5 w-full" }, /* @__PURE__ */ React52.createElement("label", { className: "text-xs text-stone-400 tracking-[0.2em] block" }, "About Me"), /* @__PURE__ */ React52.createElement(
|
|
5807
|
+
"textarea",
|
|
5808
|
+
{
|
|
5809
|
+
value: description,
|
|
5810
|
+
onChange: (e) => setDescription(e.target.value.substring(0, 300)),
|
|
5811
|
+
disabled: isSavingProfile,
|
|
5812
|
+
placeholder: "A short shout about yourself...",
|
|
5813
|
+
className: "w-full pb-3 pt-3 text-sm bg-transparent text-black border-b border-stone-200 outline-none focus:border-black transition-all duration-300 resize-none h-20 custom-scrollbar",
|
|
5814
|
+
maxLength: 300
|
|
5815
|
+
}
|
|
5816
|
+
)), /* @__PURE__ */ React52.createElement("div", { className: "pt-4 flex items-center gap-4" }, /* @__PURE__ */ React52.createElement(ThreeDActionButton, { type: "submit", disabled: isProfileSaveDisabled, isLoading: isSavingProfile, className: "min-w-32" }, "Update Identity")))), /* @__PURE__ */ React52.createElement("div", { className: "bg-white rounded-2xl p-6 w-full flex flex-col sm:flex-row sm:items-center justify-between gap-6 border border-stone-100" }, /* @__PURE__ */ React52.createElement("div", { className: "flex flex-col items-start max-w-sm" }, /* @__PURE__ */ React52.createElement("p", { className: "text-xs text-stone-400 tracking-[0.2em] mb-2 uppercase" }, "AI Credits Balance"), isBillingLoading ? /* @__PURE__ */ React52.createElement("div", { className: "h-8 w-32 bg-stone-100 animate-pulse rounded mt-1" }) : /* @__PURE__ */ React52.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: Coins01Icon, size: 28, className: "text-[#d97757]" }), /* @__PURE__ */ React52.createElement("span", { className: "text-3xl text-black tracking-tight" }, aiCredits)), /* @__PURE__ */ React52.createElement("p", { className: "text-xs text-stone-500 mt-4 leading-relaxed" }, "AI credits are consumed when generating intelligent summaries, transcriptions, and automated huddle insights.")), /* @__PURE__ */ React52.createElement("button", { onClick: onTopUp, className: "w-12 h-12 rounded-full border border-stone-200 flex items-center justify-center text-black hover:bg-stone-50 transition-colors outline-none shrink-0", "aria-label": "Top Up Credits" }, /* @__PURE__ */ React52.createElement(HugeiconsIcon38, { icon: PlusSignIcon3, size: 20 })))));
|
|
5707
5817
|
};
|
|
5708
5818
|
|
|
5709
5819
|
// src/components/UniversalCreateHuddle.tsx
|