@iblai/iblai-js 1.9.8 → 1.9.10

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.
@@ -7,7 +7,7 @@ import Link$2 from 'next/link';
7
7
  import * as ReactDOM from 'react-dom';
8
8
  import ReactDOM__default from 'react-dom';
9
9
  import { z as z$1 } from 'zod';
10
- import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, useUpdateTenantMetadataMutation, LOGO_ENDPOINTS, useDeleteApiKeyMutation, useGetApiKeysQuery, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetCustomMentorsQuery, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useDisablePaywallMutation, useListPaywallsQuery, useGetAiSearchMentorsQuery, useCreateSessionIdMutation, useGetMentorCategoriesQuery, useGetMentorSettingsQuery, useEditMentorMutation, useDeleteMentorMutation, useForkMentorMutation, useGetToolsQuery, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useDeleteMentorMemoryMutation, useUpdateMentorMemoryMutation, useCreateMentorMemoryMutation, useLazyGetMCPServersQuery, useOauthFindMutation, useLazyStartOAuthFlowQuery, useCreateMCPServerMutation, usePartialUpdateMCPServerMutation, useCreateMCPServerConnectionMutation, usePatchMCPServerConnectionMutation, useGetConnectedServicesQuery, useGetMCPServersQuery, useGetMCPServerConnectionsQuery, useUpdateMCPServerMutation, useDeleteMCPServerMutation, useEditMentorJsonMutation, useDisconnectServiceMutation, useGetPromptCategoriesQuery, useGetMentorPublicSettingsQuery, useGetChatHistoryFilterQuery, useGetChatHistoryQuery, useGetMentorSummariesQuery, useGetConversationMemoriesQuery, useEditTrainingDocumentMutation, useGetTrainingDocumentsQuery, useCreatePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useCreateRedirectTokenMutation, useGetShareableLinkQuery, useCreateShareableLinkMutation, useUpdateShareableLinkMutation, useCreateDisclaimerMutation, useUpdateDisclaimerMutation, useGetDisclaimersQuery, useUpdateRbacMentorAccessMutation, useGetRbacMentorAccessListQuery, useStarMentorMutation, useUnstarMentorMutation, useGetPersonnalizedMentorsQuery, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation } from '@iblai/data-layer';
10
+ import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useGetWatchedGroupsQuery, useCreateWatchedGroupMutation, useUpdateWatchedGroupMutation, useDeleteWatchedGroupMutation, useAddWatchedUserMutation, useRemoveWatchedUserMutation, useAddWatcherMutation, useUpdateWatcherMutation, useDeleteWatcherMutation, useGetWatchedUsersQuery, useGetWatchersQuery, WATCHER_NOTIFICATION_EVENTS, WATCHER_NOTIFICATION_EVENT_LABELS, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, useUpdateTenantMetadataMutation, LOGO_ENDPOINTS, useDeleteApiKeyMutation, useGetApiKeysQuery, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetCustomMentorsQuery, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useGetAiSearchMentorsQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useCreateSessionIdMutation, useGetMentorCategoriesQuery, useGetMentorSettingsQuery, useEditMentorMutation, useDeleteMentorMutation, useForkMentorMutation, useGetToolsQuery, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useDeleteMentorMemoryMutation, useUpdateMentorMemoryMutation, useCreateMentorMemoryMutation, useLazyGetMCPServersQuery, useOauthFindMutation, useLazyStartOAuthFlowQuery, useCreateMCPServerMutation, usePartialUpdateMCPServerMutation, useCreateMCPServerConnectionMutation, usePatchMCPServerConnectionMutation, useGetConnectedServicesQuery, useGetMCPServersQuery, useGetMCPServerConnectionsQuery, useUpdateMCPServerMutation, useDeleteMCPServerMutation, useEditMentorJsonMutation, useDisconnectServiceMutation, useGetPromptCategoriesQuery, useGetMentorPublicSettingsQuery, useGetChatHistoryFilterQuery, useGetChatHistoryQuery, useGetMentorSummariesQuery, useGetConversationMemoriesQuery, useEditTrainingDocumentMutation, useGetTrainingDocumentsQuery, useCreatePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useCreateRedirectTokenMutation, useGetShareableLinkQuery, useCreateShareableLinkMutation, useUpdateShareableLinkMutation, useCreateDisclaimerMutation, useUpdateDisclaimerMutation, useGetDisclaimersQuery, useUpdateRbacMentorAccessMutation, useGetRbacMentorAccessListQuery, useStarMentorMutation, useUnstarMentorMutation, useGetPersonnalizedMentorsQuery, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation } from '@iblai/data-layer';
11
11
  import { toast, Toaster as Toaster$1 } from 'sonner';
12
12
  import { getInitials, useTenantMetadata, isAlphaNumeric32, checkRbacPermission, WithPermissions, useTenantContext, useStripeUpgrade, CHAT_AREA_SIZE, TimeTracker, advancedTabsProperties, defaultSessionIds, chatActions, WithFormPermissions } from '@iblai/web-utils';
13
13
  import { MentorVisibilityEnum, TransportEnum, PromptVisibilityEnum } from '@iblai/iblai-api';
@@ -163131,8 +163131,419 @@ function PoliciesTab({ tenant }) {
163131
163131
  }), className: "w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700", children: jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: group.name }) }, group.id))) }))] })] })] })] }), jsxs(DialogFooter, { className: "mt-6", children: [jsx(Button$1, { variant: "outline", onClick: () => setIsOpen(false), children: "Cancel" }), jsx(TooltipProvider, { children: jsxs(Tooltip, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, children: jsx(Button$1, { onClick: onSubmit, disabled: policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", children: editing ? 'Save Policy' : 'Create Policy' }) }) }), editing && (policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: "Cannot edit internal policies" }) }))] }) })] })] }) })] }));
163132
163132
  }
163133
163133
 
163134
- const Admin = ({ tenant, onInviteClick, hasUserTabPermission = false, hasGroupsTabPermission = false, hasRolesTabPermission = false, hasPoliciesTabPermission = false, hasTeamsTabPermission = false, hasInviteUserPermission = false, hasCreateTeamPermission = false, onLoadGroupPermissions, rbacPermissions = {}, enableRbac = false, }) => {
163135
- return (jsx("div", { className: "border border-gray-200 rounded-lg p-6", children: jsxs(Tabs, { defaultValue: "users", "aria-label": "RBAC Management Tabs", children: [jsxs(TabsList, { "aria-label": "Management tabs", className: "max-w-full overflow-x-auto justify-start px-1", children: [hasUserTabPermission && jsx(TabsTrigger, { value: "users", children: "Users" }), hasGroupsTabPermission && jsx(TabsTrigger, { value: "groups", children: "Groups" }), hasRolesTabPermission && jsx(TabsTrigger, { value: "roles", children: "Roles" }), hasPoliciesTabPermission && jsx(TabsTrigger, { value: "policies", children: "Policies" }), hasTeamsTabPermission && jsx(TabsTrigger, { value: "teams", children: "Teams" })] }), hasUserTabPermission && (jsx(TabsContent, { value: "users", children: jsx(UsersTab, { tenant: tenant, onInviteClick: onInviteClick }) })), hasGroupsTabPermission && (jsx(TabsContent, { value: "groups", children: jsx(GroupsTab, { tenant: tenant }) })), hasRolesTabPermission && (jsx(TabsContent, { value: "roles", children: jsx(RolesTab, { tenant: tenant }) })), hasPoliciesTabPermission && (jsx(TabsContent, { value: "policies", children: jsx(PoliciesTab, { tenant: tenant }) })), hasTeamsTabPermission && (jsx(TabsContent, { value: "teams", children: jsx(GroupsTab, { tenant: tenant, isTeam: true, onInviteClick: onInviteClick, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac }) }))] }) }));
163134
+ const PAGE_SIZE$1 = 10;
163135
+ function normalizeEvents(events) {
163136
+ if (!events)
163137
+ return [];
163138
+ if (Array.isArray(events))
163139
+ return events;
163140
+ // The API may serialize the list as a python-style string e.g. "['A', 'B']"
163141
+ const trimmed = events.trim();
163142
+ if (!trimmed)
163143
+ return [];
163144
+ try {
163145
+ const jsonish = trimmed.replace(/'/g, '"');
163146
+ const parsed = JSON.parse(jsonish);
163147
+ if (Array.isArray(parsed))
163148
+ return parsed.map((v) => String(v));
163149
+ }
163150
+ catch (_a) {
163151
+ // fall through
163152
+ }
163153
+ return trimmed
163154
+ .replace(/[[\]'"]/g, '')
163155
+ .split(',')
163156
+ .map((s) => s.trim())
163157
+ .filter(Boolean);
163158
+ }
163159
+ function AlertsTab({ tenant }) {
163160
+ var _a;
163161
+ const [page, setPage] = useState(1);
163162
+ const [searchQuery, setSearchQuery] = useState('');
163163
+ const [debouncedSearchQuery, setDebouncedSearchQuery] = useState('');
163164
+ useEffect(() => {
163165
+ const handler = setTimeout(() => {
163166
+ if (searchQuery.length > 3) {
163167
+ setDebouncedSearchQuery(searchQuery);
163168
+ setPage(1);
163169
+ }
163170
+ else {
163171
+ setDebouncedSearchQuery('');
163172
+ if (searchQuery.length === 0) {
163173
+ setPage(1);
163174
+ }
163175
+ }
163176
+ }, 300);
163177
+ return () => clearTimeout(handler);
163178
+ }, [searchQuery]);
163179
+ const { data: watchedGroupsData, isLoading, isError, refetch, } = useGetWatchedGroupsQuery({
163180
+ params: {
163181
+ platform_key: tenant,
163182
+ limit: PAGE_SIZE$1,
163183
+ offset: (page - 1) * PAGE_SIZE$1,
163184
+ },
163185
+ });
163186
+ const groups = useMemo(() => {
163187
+ var _a;
163188
+ const results = (_a = watchedGroupsData === null || watchedGroupsData === void 0 ? void 0 : watchedGroupsData.results) !== null && _a !== void 0 ? _a : [];
163189
+ if (debouncedSearchQuery) {
163190
+ const needle = debouncedSearchQuery.toLowerCase();
163191
+ return results.filter((g) => { var _a; return ((_a = g.name) !== null && _a !== void 0 ? _a : '').toLowerCase().includes(needle); });
163192
+ }
163193
+ return results;
163194
+ }, [watchedGroupsData, debouncedSearchQuery]);
163195
+ const totalPages = watchedGroupsData
163196
+ ? Math.max(1, Math.ceil(watchedGroupsData.count / PAGE_SIZE$1))
163197
+ : 0;
163198
+ const handlePageChange = async (newPage) => {
163199
+ setPage(newPage);
163200
+ await refetch();
163201
+ };
163202
+ const [createWatchedGroup] = useCreateWatchedGroupMutation();
163203
+ const [updateWatchedGroup] = useUpdateWatchedGroupMutation();
163204
+ const [deleteWatchedGroup] = useDeleteWatchedGroupMutation();
163205
+ const [addWatchedUser] = useAddWatchedUserMutation();
163206
+ const [removeWatchedUser] = useRemoveWatchedUserMutation();
163207
+ const [addWatcher] = useAddWatcherMutation();
163208
+ const [updateWatcher] = useUpdateWatcherMutation();
163209
+ const [deleteWatcher] = useDeleteWatcherMutation();
163210
+ const [isOpen, setIsOpen] = useState(false);
163211
+ const [editingGroup, setEditingGroup] = useState(null);
163212
+ const [deletingGroupId, setDeletingGroupId] = useState(null);
163213
+ const [formError, setFormError] = useState(null);
163214
+ const [isSubmitting, setIsSubmitting] = useState(false);
163215
+ const [name, setName] = useState('');
163216
+ const [watchedUsers, setWatchedUsers] = useState([]);
163217
+ const [originalWatchedUserIds, setOriginalWatchedUserIds] = useState([]);
163218
+ const [watchedUserLinkIds, setWatchedUserLinkIds] = useState({});
163219
+ const [watchers, setWatchers] = useState([]);
163220
+ const [originalWatchers, setOriginalWatchers] = useState([]);
163221
+ const [watchedUserSearch, setWatchedUserSearch] = useState('');
163222
+ const [showWatchedUserSearch, setShowWatchedUserSearch] = useState(false);
163223
+ const [watcherSearch, setWatcherSearch] = useState('');
163224
+ const [showWatcherSearch, setShowWatcherSearch] = useState(false);
163225
+ const [openEventsPopover, setOpenEventsPopover] = useState(null);
163226
+ const editingGroupId = (_a = editingGroup === null || editingGroup === void 0 ? void 0 : editingGroup.id) !== null && _a !== void 0 ? _a : null;
163227
+ // Pre-populate the dialog with nested data when an existing group is opened.
163228
+ const { data: nestedWatchedUsersData } = useGetWatchedUsersQuery({ watchedGroupPk: editingGroupId, params: { limit: 100 } }, { skip: !editingGroupId || !isOpen });
163229
+ const { data: nestedWatchersData } = useGetWatchersQuery({ watchedGroupPk: editingGroupId, params: { limit: 100 } }, { skip: !editingGroupId || !isOpen });
163230
+ useEffect(() => {
163231
+ var _a;
163232
+ if (!editingGroupId || !isOpen)
163233
+ return;
163234
+ const results = (_a = nestedWatchedUsersData === null || nestedWatchedUsersData === void 0 ? void 0 : nestedWatchedUsersData.results) !== null && _a !== void 0 ? _a : [];
163235
+ const mapped = results.map((u) => {
163236
+ var _a, _b, _c;
163237
+ return ({
163238
+ id: u.id,
163239
+ name: (_a = u.username) !== null && _a !== void 0 ? _a : '',
163240
+ username: (_b = u.username) !== null && _b !== void 0 ? _b : '',
163241
+ email: (_c = u.email) !== null && _c !== void 0 ? _c : '',
163242
+ });
163243
+ });
163244
+ const linkMap = {};
163245
+ results.forEach((u) => {
163246
+ var _a;
163247
+ // Some backends return the link id as `id` and the user id as `user_id`.
163248
+ // Treat the response `id` as the link id; if `user_id` is missing, the
163249
+ // link id equals the user id (sufficient for DELETE-by-user semantics).
163250
+ const userId = (_a = u.user_id) !== null && _a !== void 0 ? _a : u.id;
163251
+ linkMap[userId] = u.id;
163252
+ });
163253
+ setWatchedUsers(mapped);
163254
+ setOriginalWatchedUserIds(mapped.map((u) => u.id));
163255
+ setWatchedUserLinkIds(linkMap);
163256
+ }, [nestedWatchedUsersData, editingGroupId, isOpen]);
163257
+ useEffect(() => {
163258
+ var _a;
163259
+ if (!editingGroupId || !isOpen)
163260
+ return;
163261
+ const results = (_a = nestedWatchersData === null || nestedWatchersData === void 0 ? void 0 : nestedWatchersData.results) !== null && _a !== void 0 ? _a : [];
163262
+ const mapped = results.map((w) => {
163263
+ var _a, _b, _c;
163264
+ return ({
163265
+ id: w.id,
163266
+ user: {
163267
+ id: w.id,
163268
+ name: (_a = w.username) !== null && _a !== void 0 ? _a : '',
163269
+ username: (_b = w.username) !== null && _b !== void 0 ? _b : '',
163270
+ email: (_c = w.email) !== null && _c !== void 0 ? _c : '',
163271
+ },
163272
+ events: normalizeEvents(w.events),
163273
+ });
163274
+ });
163275
+ setWatchers(mapped);
163276
+ setOriginalWatchers(mapped);
163277
+ }, [nestedWatchersData, editingGroupId, isOpen]);
163278
+ // User picker
163279
+ const { data: usersData } = usePlatformUsersQuery({
163280
+ page: 1,
163281
+ page_size: 50,
163282
+ platform_key: tenant,
163283
+ platform_org: tenant,
163284
+ query: watchedUserSearch.length > 2 ? watchedUserSearch : '',
163285
+ return_policies: 'false',
163286
+ });
163287
+ const { data: watcherUsersData } = usePlatformUsersQuery({
163288
+ page: 1,
163289
+ page_size: 50,
163290
+ platform_key: tenant,
163291
+ platform_org: tenant,
163292
+ query: watcherSearch.length > 2 ? watcherSearch : '',
163293
+ return_policies: 'false',
163294
+ });
163295
+ const availableWatchedUsers = useMemo(() => {
163296
+ var _a, _b, _c;
163297
+ const data = (_c = (_b = (_a = usersData === null || usersData === void 0 ? void 0 : usersData.results) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : usersData === null || usersData === void 0 ? void 0 : usersData.results) !== null && _c !== void 0 ? _c : [];
163298
+ return data.filter((u) => {
163299
+ var _a;
163300
+ const userId = (_a = u.user_id) !== null && _a !== void 0 ? _a : u.id;
163301
+ return !watchedUsers.find((m) => m.id === userId);
163302
+ });
163303
+ }, [usersData, watchedUsers]);
163304
+ const availableWatcherUsers = useMemo(() => {
163305
+ var _a, _b, _c;
163306
+ const data = (_c = (_b = (_a = watcherUsersData === null || watcherUsersData === void 0 ? void 0 : watcherUsersData.results) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : watcherUsersData === null || watcherUsersData === void 0 ? void 0 : watcherUsersData.results) !== null && _c !== void 0 ? _c : [];
163307
+ return data.filter((u) => {
163308
+ var _a;
163309
+ const userId = (_a = u.user_id) !== null && _a !== void 0 ? _a : u.id;
163310
+ return !watchers.find((w) => w.user.id === userId);
163311
+ });
163312
+ }, [watcherUsersData, watchers]);
163313
+ function resetForm() {
163314
+ setName('');
163315
+ setWatchedUsers([]);
163316
+ setOriginalWatchedUserIds([]);
163317
+ setWatchedUserLinkIds({});
163318
+ setWatchers([]);
163319
+ setOriginalWatchers([]);
163320
+ setWatchedUserSearch('');
163321
+ setShowWatchedUserSearch(false);
163322
+ setWatcherSearch('');
163323
+ setShowWatcherSearch(false);
163324
+ setFormError(null);
163325
+ }
163326
+ function openNew() {
163327
+ setEditingGroup(null);
163328
+ resetForm();
163329
+ setIsOpen(true);
163330
+ }
163331
+ function openEdit(g) {
163332
+ var _a;
163333
+ setEditingGroup(g);
163334
+ setName((_a = g.name) !== null && _a !== void 0 ? _a : '');
163335
+ // Nested data will be loaded via the queries above.
163336
+ setWatchedUsers([]);
163337
+ setOriginalWatchedUserIds([]);
163338
+ setWatchedUserLinkIds({});
163339
+ setWatchers([]);
163340
+ setOriginalWatchers([]);
163341
+ setWatchedUserSearch('');
163342
+ setShowWatchedUserSearch(false);
163343
+ setWatcherSearch('');
163344
+ setShowWatcherSearch(false);
163345
+ setFormError(null);
163346
+ setIsOpen(true);
163347
+ }
163348
+ function addWatchedUserDraft(u) {
163349
+ if (watchedUsers.find((m) => m.id === u.id))
163350
+ return;
163351
+ setWatchedUsers((prev) => [...prev, u]);
163352
+ setWatchedUserSearch('');
163353
+ setShowWatchedUserSearch(false);
163354
+ }
163355
+ function removeWatchedUserDraft(id) {
163356
+ setWatchedUsers((prev) => prev.filter((m) => m.id !== id));
163357
+ }
163358
+ function addWatcherDraft(u) {
163359
+ if (watchers.find((w) => w.user.id === u.id))
163360
+ return;
163361
+ setWatchers((prev) => [...prev, { user: u, events: [] }]);
163362
+ setWatcherSearch('');
163363
+ setShowWatcherSearch(false);
163364
+ }
163365
+ function removeWatcherDraft(userId) {
163366
+ setWatchers((prev) => prev.filter((w) => w.user.id !== userId));
163367
+ }
163368
+ function toggleWatcherEvent(userId, event) {
163369
+ setWatchers((prev) => prev.map((w) => {
163370
+ if (w.user.id !== userId)
163371
+ return w;
163372
+ const has = w.events.includes(event);
163373
+ return {
163374
+ ...w,
163375
+ events: has ? w.events.filter((e) => e !== event) : [...w.events, event],
163376
+ };
163377
+ }));
163378
+ }
163379
+ async function onSubmit() {
163380
+ var _a, _b;
163381
+ setFormError(null);
163382
+ if (!name.trim()) {
163383
+ setFormError('Name is required');
163384
+ return;
163385
+ }
163386
+ for (const w of watchers) {
163387
+ if (w.events.length === 0) {
163388
+ setFormError(`Watcher "${w.user.username || w.user.name}" must subscribe to at least one event`);
163389
+ return;
163390
+ }
163391
+ }
163392
+ setIsSubmitting(true);
163393
+ try {
163394
+ if (editingGroup) {
163395
+ // 1. Update name if changed
163396
+ if (name !== editingGroup.name) {
163397
+ await updateWatchedGroup({
163398
+ id: editingGroup.id,
163399
+ body: { name },
163400
+ params: { platform_key: tenant },
163401
+ }).unwrap();
163402
+ }
163403
+ // 2. Sync watched users
163404
+ const newIds = new Set(watchedUsers.map((u) => u.id));
163405
+ const oldIds = new Set(originalWatchedUserIds);
163406
+ const toAdd = [...newIds].filter((id) => !oldIds.has(id));
163407
+ const toRemove = [...oldIds].filter((id) => !newIds.has(id));
163408
+ await Promise.all(toAdd.map((id) => addWatchedUser({
163409
+ watchedGroupPk: editingGroup.id,
163410
+ body: { user_id: id },
163411
+ params: { platform_key: tenant },
163412
+ }).unwrap()));
163413
+ await Promise.all(toRemove.map((userId) => {
163414
+ var _a;
163415
+ const linkId = (_a = watchedUserLinkIds[userId]) !== null && _a !== void 0 ? _a : userId;
163416
+ return removeWatchedUser({
163417
+ watchedGroupPk: editingGroup.id,
163418
+ id: linkId,
163419
+ params: { platform_key: tenant },
163420
+ }).unwrap();
163421
+ }));
163422
+ // 3. Sync watchers
163423
+ const originalById = new Map(originalWatchers.map((w) => [w.user.id, w]));
163424
+ const currentById = new Map(watchers.map((w) => [w.user.id, w]));
163425
+ const watcherToAdd = watchers.filter((w) => !originalById.has(w.user.id));
163426
+ const watcherToRemove = originalWatchers.filter((w) => !currentById.has(w.user.id));
163427
+ const watcherToUpdate = watchers.filter((w) => {
163428
+ const orig = originalById.get(w.user.id);
163429
+ if (!orig)
163430
+ return false;
163431
+ const a = [...orig.events].sort().join(',');
163432
+ const b = [...w.events].sort().join(',');
163433
+ return a !== b;
163434
+ });
163435
+ await Promise.all(watcherToAdd.map((w) => addWatcher({
163436
+ watchedGroupPk: editingGroup.id,
163437
+ body: { watcher_id: w.user.id, events: w.events },
163438
+ params: { platform_key: tenant },
163439
+ }).unwrap()));
163440
+ await Promise.all(watcherToRemove.map((w) => {
163441
+ var _a;
163442
+ return deleteWatcher({
163443
+ watchedGroupPk: editingGroup.id,
163444
+ id: (_a = w.id) !== null && _a !== void 0 ? _a : w.user.id,
163445
+ params: { platform_key: tenant },
163446
+ }).unwrap();
163447
+ }));
163448
+ await Promise.all(watcherToUpdate.map((w) => {
163449
+ var _a;
163450
+ return updateWatcher({
163451
+ watchedGroupPk: editingGroup.id,
163452
+ id: (_a = w.id) !== null && _a !== void 0 ? _a : w.user.id,
163453
+ body: { events: w.events },
163454
+ params: { platform_key: tenant },
163455
+ }).unwrap();
163456
+ }));
163457
+ toast.success('Alert updated');
163458
+ }
163459
+ else {
163460
+ await createWatchedGroup({
163461
+ body: {
163462
+ name,
163463
+ watched_users: watchedUsers.map((u) => u.id),
163464
+ watchers: watchers.map((w) => ({ watcher_id: w.user.id, events: w.events })),
163465
+ },
163466
+ params: {
163467
+ platform_key: tenant,
163468
+ watched_user_limit: Math.min(watchedUsers.length, 100),
163469
+ watcher_limit: Math.min(watchers.length, 100),
163470
+ },
163471
+ }).unwrap();
163472
+ toast.success('Alert created');
163473
+ }
163474
+ setIsOpen(false);
163475
+ setEditingGroup(null);
163476
+ resetForm();
163477
+ await refetch();
163478
+ }
163479
+ catch (e) {
163480
+ const message = ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.detail) || ((_b = e === null || e === void 0 ? void 0 : e.data) === null || _b === void 0 ? void 0 : _b.message) || (e === null || e === void 0 ? void 0 : e.message);
163481
+ const fallback = editingGroup ? 'Failed to update alert' : 'Failed to create alert';
163482
+ setFormError(message || fallback);
163483
+ toast.error(message || fallback);
163484
+ }
163485
+ finally {
163486
+ setIsSubmitting(false);
163487
+ }
163488
+ }
163489
+ async function onDelete(g) {
163490
+ var _a, _b;
163491
+ setDeletingGroupId(g.id);
163492
+ try {
163493
+ await deleteWatchedGroup({ id: g.id, params: { platform_key: tenant } }).unwrap();
163494
+ toast.success('Alert deleted');
163495
+ }
163496
+ catch (e) {
163497
+ toast.error(((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.detail) || ((_b = e === null || e === void 0 ? void 0 : e.data) === null || _b === void 0 ? void 0 : _b.message) || (e === null || e === void 0 ? void 0 : e.message) || 'Failed to delete alert');
163498
+ }
163499
+ finally {
163500
+ setDeletingGroupId(null);
163501
+ }
163502
+ }
163503
+ return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex mb-6 gap-2 flex-row items-center justify-between", children: [jsxs("div", { className: "relative max-w-sm w-full sm:w-auto", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: "Search alerts", "aria-label": "Search alerts", className: "pl-10 pr-10 focus:ring-blue-500 focus:border-blue-500 h-[35px]" }), isLoading && (jsx(LoaderCircle, { "data-testid": "search-spinner", className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 animate-spin", "aria-hidden": "true" }))] }), jsx("div", { className: "flex gap-2", children: jsx(Button$1, { onClick: openNew, "aria-label": "New alert", className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: "New Alert" }) })] }), isLoading && (jsx("div", { className: "flex justify-center items-center h-64", children: jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400", children: "Loading\u2026" }) })), isError && (jsx("div", { className: "py-8 text-center text-sm text-red-500", children: "Failed to load alerts" })), !isLoading && !isError && (jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: "Name" }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[120px]" })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [groups.map((g) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm", children: g.name }), jsx("td", { className: "px-6 py-4", children: jsxs("div", { className: "flex gap-2 justify-end", children: [jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => openEdit(g), disabled: deletingGroupId === g.id, "aria-label": `Edit alert ${g.name}`, children: jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => onDelete(g), className: "text-red-600 hover:text-red-700", disabled: deletingGroupId === g.id, "aria-label": `Delete alert ${g.name}`, children: deletingGroupId === g.id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" })) : (jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" })) })] }) })] }, g.id))), groups.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 2, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: "No alerts found" }) }))] })] }) })), !isLoading && !isError && totalPages > 1 && (jsx("div", { className: "mt-6", children: jsx(AdvancedPagination, { totalPages: totalPages, currentPage: page, onPageChange: (newPage) => handlePageChange(newPage) }) })), jsx(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: jsxs(DialogContent, { "aria-describedby": undefined, className: "max-w-2xl max-h-[90vh] overflow-y-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: editingGroup ? 'Edit Alert' : 'New Alert' }) }), jsxs("div", { className: "space-y-5", children: [jsxs("div", { className: "grid gap-1.5", children: [jsx(Label, { htmlFor: "wg-name", children: "Name" }), jsx(Input, { id: "wg-name", value: name, onChange: (e) => setName(e.target.value), placeholder: "Enter alert name", required: true })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label, { children: "Watched Users" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Users whose activity is monitored." }), watchedUsers.length > 0 ? (jsx("div", { className: "space-y-2 max-h-48 overflow-y-auto border border-gray-200 dark:border-gray-700 rounded-md p-2", children: watchedUsers.map((user) => (jsxs("div", { className: "flex items-center justify-between bg-gray-50 dark:bg-gray-800 p-2 rounded-md", children: [jsxs("div", { className: "flex flex-col", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: user.name || user.username }), user.email && (jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: user.email }))] }), jsx(Button$1, { type: "button", variant: "ghost", size: "sm", onClick: () => removeWatchedUserDraft(user.id), className: "h-8 w-8 p-0 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", "aria-label": `Remove watched user ${user.username}`, children: jsx(X$1, { className: "h-4 w-4" }) })] }, user.id))) })) : (jsx("div", { className: "text-sm text-gray-500 dark:text-gray-400 p-4 text-center border border-dashed border-gray-300 dark:border-gray-600 rounded-md", children: "No watched users added yet" })), jsxs("div", { className: "relative", children: [jsx(Input, { value: watchedUserSearch, onChange: (e) => {
163504
+ setWatchedUserSearch(e.target.value);
163505
+ setShowWatchedUserSearch(e.target.value.length > 0);
163506
+ }, onFocus: () => setShowWatchedUserSearch(watchedUserSearch.length > 0), placeholder: "Type to add watched users...", className: "w-full" }), showWatchedUserSearch && availableWatchedUsers.length > 0 && (jsx("div", { className: "absolute top-full left-0 right-0 mt-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg max-h-48 overflow-y-auto z-50", children: availableWatchedUsers.map((user) => {
163507
+ var _a;
163508
+ return (jsxs("button", { type: "button", onClick: () => {
163509
+ var _a, _b;
163510
+ return addWatchedUserDraft({
163511
+ id: (_a = user.user_id) !== null && _a !== void 0 ? _a : user.id,
163512
+ name: (_b = user.name) !== null && _b !== void 0 ? _b : '',
163513
+ email: user.email,
163514
+ username: user.username,
163515
+ });
163516
+ }, className: "w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 flex flex-col", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: user.name || user.username }), jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: user.email })] }, (_a = user.user_id) !== null && _a !== void 0 ? _a : user.id));
163517
+ }) })), showWatchedUserSearch &&
163518
+ watchedUserSearch.length > 2 &&
163519
+ availableWatchedUsers.length === 0 && (jsx("div", { className: "absolute top-full left-0 right-0 mt-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg p-3 z-50", children: jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: "No users found" }) }))] })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label, { children: "Watchers" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Users who receive notifications when watched users perform selected actions." }), watchers.length > 0 ? (jsx("div", { className: "space-y-3 max-h-72 overflow-y-auto border border-gray-200 dark:border-gray-700 rounded-md p-2", children: watchers.map((w) => (jsx("div", { className: "bg-gray-50 dark:bg-gray-800 p-3 rounded-md", children: jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsxs("div", { className: "flex flex-col min-w-0", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 truncate", children: w.user.name || w.user.username }), w.user.email && (jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400 truncate", children: w.user.email }))] }), jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [jsxs(Popover, { modal: true, open: openEventsPopover === w.user.id, onOpenChange: (open) => setOpenEventsPopover(open ? w.user.id : null), children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", role: "combobox", "aria-expanded": openEventsPopover === w.user.id, "aria-label": `Select events for ${w.user.username || w.user.name}`, className: "w-44 justify-between text-sm h-9 font-normal", children: [jsx("span", { className: "truncate", children: w.events.length > 0
163520
+ ? `${w.events.length} events selected`
163521
+ : 'No events' }), openEventsPopover === w.user.id ? (jsx(ChevronUp, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })) : (jsx(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" }))] }) }), jsx(PopoverContent, { className: "w-72 p-3 max-h-64 overflow-y-auto", align: "end", onWheel: (e) => e.stopPropagation(), onTouchMove: (e) => e.stopPropagation(), children: jsxs("div", { className: "space-y-2", children: [jsx("div", { className: "text-sm font-medium mb-2", children: "Select Events" }), WATCHER_NOTIFICATION_EVENTS.map((event) => {
163522
+ var _a;
163523
+ const checkboxId = `watcher-${w.user.id}-${event}`;
163524
+ const checked = w.events.includes(event);
163525
+ return (jsxs("div", { className: "flex items-center space-x-2 cursor-pointer rounded px-1 py-0.5 hover:bg-gray-100 dark:hover:bg-gray-700", onClick: () => toggleWatcherEvent(w.user.id, event), children: [jsx(Checkbox, { id: checkboxId, checked: checked, tabIndex: -1, className: "pointer-events-none", "aria-label": `Toggle ${event} for ${w.user.username || w.user.name}` }), jsx("span", { className: "text-sm font-normal select-none", children: (_a = WATCHER_NOTIFICATION_EVENT_LABELS[event]) !== null && _a !== void 0 ? _a : event })] }, event));
163526
+ })] }) })] }), jsx(Button$1, { type: "button", variant: "ghost", size: "sm", onClick: () => removeWatcherDraft(w.user.id), className: "h-8 w-8 p-0 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", "aria-label": `Remove watcher ${w.user.username}`, children: jsx(X$1, { className: "h-4 w-4" }) })] })] }) }, w.user.id))) })) : (jsx("div", { className: "text-sm text-gray-500 dark:text-gray-400 p-4 text-center border border-dashed border-gray-300 dark:border-gray-600 rounded-md", children: "No watchers added yet" })), jsxs("div", { className: "relative", children: [jsx(Input, { value: watcherSearch, onChange: (e) => {
163527
+ setWatcherSearch(e.target.value);
163528
+ setShowWatcherSearch(e.target.value.length > 0);
163529
+ }, onFocus: () => setShowWatcherSearch(watcherSearch.length > 0), placeholder: "Type to add watchers...", className: "w-full" }), showWatcherSearch && availableWatcherUsers.length > 0 && (jsx("div", { className: "absolute top-full left-0 right-0 mt-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg max-h-48 overflow-y-auto z-50", children: availableWatcherUsers.map((user) => {
163530
+ var _a;
163531
+ return (jsxs("button", { type: "button", onClick: () => {
163532
+ var _a, _b;
163533
+ return addWatcherDraft({
163534
+ id: (_a = user.user_id) !== null && _a !== void 0 ? _a : user.id,
163535
+ name: (_b = user.name) !== null && _b !== void 0 ? _b : '',
163536
+ email: user.email,
163537
+ username: user.username,
163538
+ });
163539
+ }, className: "w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2", children: [jsx(Plus, { className: "h-3 w-3 text-gray-400" }), jsxs("div", { className: "flex flex-col", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: user.name || user.username }), jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: user.email })] })] }, (_a = user.user_id) !== null && _a !== void 0 ? _a : user.id));
163540
+ }) })), showWatcherSearch &&
163541
+ watcherSearch.length > 2 &&
163542
+ availableWatcherUsers.length === 0 && (jsx("div", { className: "absolute top-full left-0 right-0 mt-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg p-3 z-50", children: jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: "No users found" }) }))] })] })] }), formError && (jsx("div", { className: "mt-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md", children: jsx("p", { className: "text-sm text-red-600 dark:text-red-400", children: formError }) })), jsxs(DialogFooter, { className: "mt-6", children: [jsx(Button$1, { variant: "outline", onClick: () => setIsOpen(false), children: "Cancel" }), jsxs(Button$1, { onClick: onSubmit, disabled: isSubmitting, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", children: [isSubmitting ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin mr-2", "aria-hidden": "true" })) : null, editingGroup ? 'Save Alert' : 'Create Alert'] })] })] }) })] }));
163543
+ }
163544
+
163545
+ const Admin = ({ tenant, onInviteClick, hasUserTabPermission = false, hasGroupsTabPermission = false, hasRolesTabPermission = false, hasPoliciesTabPermission = false, hasTeamsTabPermission = false, hasAlertsTabPermission = false, hasInviteUserPermission = false, hasCreateTeamPermission = false, onLoadGroupPermissions, rbacPermissions = {}, enableRbac = false, }) => {
163546
+ return (jsx("div", { className: "border border-gray-200 rounded-lg p-6", children: jsxs(Tabs, { defaultValue: "users", "aria-label": "RBAC Management Tabs", children: [jsxs(TabsList, { "aria-label": "Management tabs", className: "max-w-full overflow-x-auto justify-start px-1", children: [hasUserTabPermission && jsx(TabsTrigger, { value: "users", children: "Users" }), hasGroupsTabPermission && jsx(TabsTrigger, { value: "groups", children: "Groups" }), hasRolesTabPermission && jsx(TabsTrigger, { value: "roles", children: "Roles" }), hasPoliciesTabPermission && jsx(TabsTrigger, { value: "policies", children: "Policies" }), hasTeamsTabPermission && jsx(TabsTrigger, { value: "teams", children: "Teams" }), hasAlertsTabPermission && jsx(TabsTrigger, { value: "alerts", children: "Alerts" })] }), hasUserTabPermission && (jsx(TabsContent, { value: "users", children: jsx(UsersTab, { tenant: tenant, onInviteClick: onInviteClick }) })), hasGroupsTabPermission && (jsx(TabsContent, { value: "groups", children: jsx(GroupsTab, { tenant: tenant }) })), hasRolesTabPermission && (jsx(TabsContent, { value: "roles", children: jsx(RolesTab, { tenant: tenant }) })), hasPoliciesTabPermission && (jsx(TabsContent, { value: "policies", children: jsx(PoliciesTab, { tenant: tenant }) })), hasTeamsTabPermission && (jsx(TabsContent, { value: "teams", children: jsx(GroupsTab, { tenant: tenant, isTeam: true, onInviteClick: onInviteClick, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac }) })), hasAlertsTabPermission && (jsx(TabsContent, { value: "alerts", children: jsx(AlertsTab, { tenant: tenant }) }))] }) }));
163136
163547
  };
163137
163548
 
163138
163549
  function OrganizationTab({ platformKey, setOrganizationLogoFromOutside, tenant, onTenantUpdate, }) {
@@ -165752,6 +166163,28 @@ const MemsearchConfigContent = ({ platformKey, userId }) => {
165752
166163
  return (jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-6", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: "Memory System" }), jsx(TooltipProvider, { children: jsxs(Tooltip, { children: [jsx(TooltipTrigger, { "aria-label": "More info about memory system", className: "hidden sm:block", children: jsx(Info, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "rounded-lg bg-gray-700 px-3 py-2 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-opacity duration-300 z-50", children: jsx("p", { children: "Enable the AI memory system for this platform. Disabling will stop all memory capture and usage." }) })] }) })] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Switch, { checked: (_a = memsearchConfig === null || memsearchConfig === void 0 ? void 0 : memsearchConfig.enable_memsearch) !== null && _a !== void 0 ? _a : false, onCheckedChange: handleToggleMemsearch, disabled: isUpdating, "aria-label": `Memory system ${(memsearchConfig === null || memsearchConfig === void 0 ? void 0 : memsearchConfig.enable_memsearch) ? 'enabled' : 'disabled'}`, className: "cursor-pointer data-[state=checked]:bg-blue-500" }), isUpdating && (jsx("div", { className: "w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" }))] })] }));
165753
166164
  };
165754
166165
 
166166
+ function StringSettingInput({ value, defaultValue, disabled, onSave, }) {
166167
+ const [localValue, setLocalValue] = useState(value || defaultValue);
166168
+ const debounceRef = useRef(null);
166169
+ useEffect(() => {
166170
+ setLocalValue(value || defaultValue);
166171
+ }, [value, defaultValue]);
166172
+ const handleChange = (newValue) => {
166173
+ setLocalValue(newValue);
166174
+ if (debounceRef.current)
166175
+ clearTimeout(debounceRef.current);
166176
+ debounceRef.current = setTimeout(() => {
166177
+ onSave(newValue);
166178
+ }, 800);
166179
+ };
166180
+ useEffect(() => {
166181
+ return () => {
166182
+ if (debounceRef.current)
166183
+ clearTimeout(debounceRef.current);
166184
+ };
166185
+ }, []);
166186
+ return (jsxs("div", { className: "flex items-center gap-2", children: [jsx(Input, { value: localValue, onChange: (e) => handleChange(e.target.value), disabled: disabled, className: "max-w-[240px] w-[110px] sm:w-[230px] font-medium text-[#646464] text-sm" }), disabled && (jsx("div", { className: "w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" }))] }));
166187
+ }
165755
166188
  function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatformBaseDomain, }) {
165756
166189
  const [updateTenantMetadata, { isLoading: isUpdatingTenantMetadata }] = useUpdateTenantMetadataMutation();
165757
166190
  // Mentor search state
@@ -165791,9 +166224,14 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
165791
166224
  const allMetadatas = getAllMetadatas();
165792
166225
  // Include both boolean and string settings, but exclude start screen settings
165793
166226
  // which are handled by the StartScreenContent component
166227
+ const stringSettingSlugs = [
166228
+ 'overall_default_mentor',
166229
+ 'help_center_url',
166230
+ 'monetization_base_path',
166231
+ ];
165794
166232
  const configurableMetadatas = allMetadatas.filter((metadata) => (typeof metadata.defaultValue === 'boolean' ||
165795
166233
  (typeof metadata.defaultValue === 'string' &&
165796
- metadata.slug === 'overall_default_mentor')) &&
166234
+ stringSettingSlugs.includes(metadata.slug))) &&
165797
166235
  !startScreenSlugs.includes(metadata.slug));
165798
166236
  if (currentSPA) {
165799
166237
  // Filter by current SPA if specified (case-insensitive partial matching)
@@ -165898,6 +166336,11 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
165898
166336
  const handleChatAreaSizeError = (message) => {
165899
166337
  toast.error(message);
165900
166338
  };
166339
+ const handleStringSettingUpdate = async (slug, value) => {
166340
+ updateOrganizationMetadata(slug, value, () => {
166341
+ toast.success('Setting updated successfully');
166342
+ });
166343
+ };
165901
166344
  // Helper function to get mentor name from JSON string, object, or unique_id
165902
166345
  const getMentorName = (mentorValue) => {
165903
166346
  var _a;
@@ -165932,7 +166375,8 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
165932
166375
  ? 'None'
165933
166376
  : ((_a = metadataItem.value) !== null && _a !== void 0 ? _a : metadataItem.defaultValue);
165934
166377
  const isMentorSetting = metadataItem.slug === 'overall_default_mentor';
165935
- return (jsxs("div", { className: `flex items-center justify-between rounded-lg border px-6 ${isMentorSetting ? 'py-4' : 'py-6'}`, style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: metadataItem.label }), jsx(TooltipProvider, { children: jsxs(Tooltip, { children: [jsx(TooltipTrigger, { "aria-label": `More info about ${metadataItem.label}`, className: "hidden sm:block", children: jsx(Info, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "rounded-lg bg-gray-700 px-3 py-2 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-opacity duration-300 z-50", children: jsx("p", { children: metadataItem.description || 'No description available' }) })] }) })] }), jsx("div", { className: "flex items-center gap-2", children: isMentorSetting ? (jsxs("div", { className: "flex items-center gap-2", children: [jsxs(Select$1, { value: currentValue || '', onValueChange: (value) => handleMentorSelection(metadataItem.slug, value), disabled: isUpdatingTenantMetadata, children: [jsx(SelectTrigger, { className: "max-w-[240px] w-[110px] sm:w-[230px] font-medium text-[#646464]", children: jsx(SelectValue, { placeholder: "Select mentor", children: currentValue ? getMentorName(currentValue) : '' }) }), jsxs(SelectContent, { className: "font-medium text-[#646464]", children: [jsx("div", { className: "p-2", children: jsx(Input, { placeholder: "Search mentors...", value: mentorSearchQuery, onChange: (e) => handleMentorSearch(e.target.value), className: "mb-2 font-medium text-[#646464]" }) }), jsx(SelectItem, { value: "none", children: "None" }), isMentorsLoading ? (jsx(SelectItem, { "aria-label": "Loading mentors...", value: "loading", disabled: true, children: "Loading mentors..." })) : ((_b = mentorsData === null || mentorsData === void 0 ? void 0 : mentorsData.results) === null || _b === void 0 ? void 0 : _b.length) ? (mentorsData.results.map((mentor) => (jsx(SelectItem, { value: mentor.unique_id, children: mentor.name }, mentor.unique_id)))) : (jsx(SelectItem, { value: "no-results", disabled: true, children: "No mentors found" }))] })] }), isUpdatingTenantMetadata && (jsx("div", { "aria-label": "Updating mentor selection...", role: "status", className: "w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" }))] })) : (jsxs(Fragment$1, { children: [jsx(Switch, { checked: currentValue, onCheckedChange: async () => {
166378
+ const isStringSetting = typeof metadataItem.defaultValue === 'string' && !isMentorSetting;
166379
+ return (jsxs("div", { className: `flex items-center justify-between rounded-lg border px-6 ${isMentorSetting || isStringSetting ? 'py-4' : 'py-6'}`, style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: metadataItem.label }), jsx(TooltipProvider, { children: jsxs(Tooltip, { children: [jsx(TooltipTrigger, { "aria-label": `More info about ${metadataItem.label}`, className: "hidden sm:block", children: jsx(Info, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "rounded-lg bg-gray-700 px-3 py-2 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-opacity duration-300 z-50", children: jsx("p", { children: metadataItem.description || 'No description available' }) })] }) })] }), jsx("div", { className: "flex items-center gap-2", children: isMentorSetting ? (jsxs("div", { className: "flex items-center gap-2", children: [jsxs(Select$1, { value: currentValue || '', onValueChange: (value) => handleMentorSelection(metadataItem.slug, value), disabled: isUpdatingTenantMetadata, children: [jsx(SelectTrigger, { className: "max-w-[240px] w-[110px] sm:w-[230px] font-medium text-[#646464]", children: jsx(SelectValue, { placeholder: "Select mentor", children: currentValue ? getMentorName(currentValue) : '' }) }), jsxs(SelectContent, { className: "font-medium text-[#646464]", children: [jsx("div", { className: "p-2", children: jsx(Input, { placeholder: "Search mentors...", value: mentorSearchQuery, onChange: (e) => handleMentorSearch(e.target.value), className: "mb-2 font-medium text-[#646464]" }) }), jsx(SelectItem, { value: "none", children: "None" }), isMentorsLoading ? (jsx(SelectItem, { "aria-label": "Loading mentors...", value: "loading", disabled: true, children: "Loading mentors..." })) : ((_b = mentorsData === null || mentorsData === void 0 ? void 0 : mentorsData.results) === null || _b === void 0 ? void 0 : _b.length) ? (mentorsData.results.map((mentor) => (jsx(SelectItem, { value: mentor.unique_id, children: mentor.name }, mentor.unique_id)))) : (jsx(SelectItem, { value: "no-results", disabled: true, children: "No mentors found" }))] })] }), isUpdatingTenantMetadata && (jsx("div", { "aria-label": "Updating mentor selection...", role: "status", className: "w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" }))] })) : isStringSetting ? (jsx(StringSettingInput, { value: currentValue, defaultValue: metadataItem.defaultValue, disabled: isUpdatingTenantMetadata, onSave: (value) => handleStringSettingUpdate(metadataItem.slug, value) })) : (jsxs(Fragment$1, { children: [jsx(Switch, { checked: currentValue, onCheckedChange: async () => {
165936
166380
  await handleToggleSetting(metadataItem.slug, currentValue);
165937
166381
  }, disabled: isUpdatingTenantMetadata, "aria-label": `${metadataItem.label} ${currentValue ? 'enabled' : 'disabled'}`, className: "cursor-pointer data-[state=checked]:bg-blue-500" }), isUpdatingTenantMetadata && (jsx("div", { className: "w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" }))] })) })] }, metadataItem.slug));
165938
166382
  }) })) : (
@@ -165950,7 +166394,8 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
165950
166394
  var _a, _b;
165951
166395
  const currentValue = (_a = metadataItem.value) !== null && _a !== void 0 ? _a : metadataItem.defaultValue;
165952
166396
  const isMentorSetting = metadataItem.slug === 'overall_default_mentor';
165953
- return (jsxs("div", { className: `flex items-center justify-between rounded-lg border px-6 ${isMentorSetting ? 'py-4' : 'py-6'}`, style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: metadataItem.label }), jsx(TooltipProvider, { children: jsxs(Tooltip, { children: [jsx(TooltipTrigger, { "aria-label": `More info about ${metadataItem.label}`, className: "hidden sm:block", children: jsx(Info, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "ibl-tooltip-content", children: jsx("p", { children: metadataItem.description || 'No description available' }) })] }) })] }), jsx("div", { className: "flex items-center gap-2", children: isMentorSetting ? (jsxs("div", { className: "flex items-center gap-2", children: [jsxs(Select$1, { value: currentValue || '', onValueChange: (value) => handleMentorSelection(metadataItem.slug, value), disabled: isUpdatingTenantMetadata, children: [jsx(SelectTrigger, { className: "max-w-[240px] w-[230px] sm:w-[150px] font-medium text-[#646464]", children: jsx(SelectValue, { placeholder: "Select mentor", children: currentValue ? getMentorName(currentValue) : '' }) }), jsxs(SelectContent, { className: "font-medium text-[#646464]", children: [jsx("div", { className: "p-2", children: jsx(Input, { placeholder: "Search mentors...", value: mentorSearchQuery, onChange: (e) => handleMentorSearch(e.target.value), className: "mb-2 font-medium text-[#646464]" }) }), jsx(SelectItem, { value: "none", children: "None" }), isMentorsLoading ? (jsx(SelectItem, { value: "loading", disabled: true, children: "Loading mentors..." })) : ((_b = mentorsData === null || mentorsData === void 0 ? void 0 : mentorsData.results) === null || _b === void 0 ? void 0 : _b.length) ? (mentorsData.results.map((mentor) => (jsx(SelectItem, { value: mentor.unique_id, children: mentor.name }, mentor.unique_id)))) : (jsx(SelectItem, { value: "no-results", disabled: true, children: "No mentors found" }))] })] }), isUpdatingTenantMetadata && (jsx("div", { className: "w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" }))] })) : (jsxs(Fragment$1, { children: [jsx(Switch, { checked: currentValue, onCheckedChange: async () => {
166397
+ const isStringSetting = typeof metadataItem.defaultValue === 'string' && !isMentorSetting;
166398
+ return (jsxs("div", { className: `flex items-center justify-between rounded-lg border px-6 ${isMentorSetting || isStringSetting ? 'py-4' : 'py-6'}`, style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: metadataItem.label }), jsx(TooltipProvider, { children: jsxs(Tooltip, { children: [jsx(TooltipTrigger, { "aria-label": `More info about ${metadataItem.label}`, className: "hidden sm:block", children: jsx(Info, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "ibl-tooltip-content", children: jsx("p", { children: metadataItem.description || 'No description available' }) })] }) })] }), jsx("div", { className: "flex items-center gap-2", children: isMentorSetting ? (jsxs("div", { className: "flex items-center gap-2", children: [jsxs(Select$1, { value: currentValue || '', onValueChange: (value) => handleMentorSelection(metadataItem.slug, value), disabled: isUpdatingTenantMetadata, children: [jsx(SelectTrigger, { className: "max-w-[240px] w-[230px] sm:w-[150px] font-medium text-[#646464]", children: jsx(SelectValue, { placeholder: "Select mentor", children: currentValue ? getMentorName(currentValue) : '' }) }), jsxs(SelectContent, { className: "font-medium text-[#646464]", children: [jsx("div", { className: "p-2", children: jsx(Input, { placeholder: "Search mentors...", value: mentorSearchQuery, onChange: (e) => handleMentorSearch(e.target.value), className: "mb-2 font-medium text-[#646464]" }) }), jsx(SelectItem, { value: "none", children: "None" }), isMentorsLoading ? (jsx(SelectItem, { value: "loading", disabled: true, children: "Loading mentors..." })) : ((_b = mentorsData === null || mentorsData === void 0 ? void 0 : mentorsData.results) === null || _b === void 0 ? void 0 : _b.length) ? (mentorsData.results.map((mentor) => (jsx(SelectItem, { value: mentor.unique_id, children: mentor.name }, mentor.unique_id)))) : (jsx(SelectItem, { value: "no-results", disabled: true, children: "No mentors found" }))] })] }), isUpdatingTenantMetadata && (jsx("div", { className: "w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" }))] })) : isStringSetting ? (jsx(StringSettingInput, { value: currentValue, defaultValue: metadataItem.defaultValue, disabled: isUpdatingTenantMetadata, onSave: (value) => handleStringSettingUpdate(metadataItem.slug, value) })) : (jsxs(Fragment$1, { children: [jsx(Switch, { checked: currentValue, onCheckedChange: async () => {
165954
166399
  await handleToggleSetting(metadataItem.slug, currentValue);
165955
166400
  }, disabled: isUpdatingTenantMetadata, "aria-label": `${metadataItem.label} ${currentValue ? 'enabled' : 'disabled'}`, className: "cursor-pointer data-[state=checked]:bg-blue-500" }), isUpdatingTenantMetadata && (jsx("div", { className: "w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" }))] })) })] }, metadataItem.slug));
165956
166401
  }) })] }, spa)));
@@ -166014,6 +166459,166 @@ function StripeConnect({ platformKey }) {
166014
166459
  : 'Connect Stripe'] })) })] }) }) }));
166015
166460
  }
166016
166461
 
166462
+ function slugify(text) {
166463
+ return text
166464
+ .toLowerCase()
166465
+ .trim()
166466
+ .replace(/[^\w\s-]/g, '')
166467
+ .replace(/[\s_]+/g, '-')
166468
+ .replace(/-+/g, '-')
166469
+ .replace(/^-+|-+$/g, '');
166470
+ }
166471
+ function useDebounce(value, delay) {
166472
+ const [debouncedValue, setDebouncedValue] = useState(value);
166473
+ useEffect(() => {
166474
+ const timer = setTimeout(() => setDebouncedValue(value), delay);
166475
+ return () => clearTimeout(timer);
166476
+ }, [value, delay]);
166477
+ return debouncedValue;
166478
+ }
166479
+ function displayItemType(itemType) {
166480
+ const stripped = itemType.replace(/^custom:/i, '');
166481
+ if (stripped.toLowerCase() === 'mentor')
166482
+ return 'Agent';
166483
+ return stripped;
166484
+ }
166485
+ function getAuthURLExtension(authURL) {
166486
+ try {
166487
+ const { hostname } = new URL(authURL);
166488
+ const parts = hostname.split('.');
166489
+ if (parts.length > 2)
166490
+ parts.shift();
166491
+ return parts.join('.');
166492
+ }
166493
+ catch (_a) {
166494
+ return '';
166495
+ }
166496
+ }
166497
+ function buildOnSuccessfulPaymentUrl({ authURL, itemType, itemId, platformKey, isCustom, customProductUrl, }) {
166498
+ if (isCustom) {
166499
+ const trimmed = customProductUrl === null || customProductUrl === void 0 ? void 0 : customProductUrl.trim();
166500
+ return trimmed || undefined;
166501
+ }
166502
+ const ext = getAuthURLExtension(authURL);
166503
+ if (!ext)
166504
+ return undefined;
166505
+ const normalized = itemType.toLowerCase();
166506
+ if (normalized === 'mentor' || normalized === 'agent') {
166507
+ return `https://mentorai.${ext}/platform/${platformKey}/${itemId}`;
166508
+ }
166509
+ if (normalized === 'course') {
166510
+ return `https://skillsai.${ext}/courses/${itemId}`;
166511
+ }
166512
+ if (normalized === 'program') {
166513
+ return `https://skillsai.${ext}/programs/${itemId}`;
166514
+ }
166515
+ return undefined;
166516
+ }
166517
+
166518
+ function ItemSearchDropdown({ platformKey, onSelect, }) {
166519
+ var _a, _b, _c;
166520
+ const [searchQuery, setSearchQuery] = useState('');
166521
+ const [isOpen, setIsOpen] = useState(false);
166522
+ const dropdownRef = useRef(null);
166523
+ const debouncedSearch = useDebounce(searchQuery, 300);
166524
+ // Mentor search
166525
+ const { data: mentors, isFetching: isFetchingMentors } = useGetAiSearchMentorsQuery({
166526
+ platform_key: platformKey,
166527
+ query: debouncedSearch || undefined,
166528
+ limit: 6,
166529
+ include_main_public_mentors: false,
166530
+ }, { skip: !platformKey });
166531
+ // Course and program search
166532
+ const { data: coursesData, isFetching: isFetchingCourses } = useGetPersonnalizedSearchQuery([
166533
+ {
166534
+ username: getUserName$1(),
166535
+ content: ['courses', 'programs'],
166536
+ tenant: platformKey,
166537
+ query: debouncedSearch || '',
166538
+ returnItems: false,
166539
+ returnFacet: false,
166540
+ allowSkillSearch: false,
166541
+ limit: 6,
166542
+ },
166543
+ ]);
166544
+ const isFetching = isFetchingMentors || isFetchingCourses;
166545
+ // Normalize and merge results
166546
+ const mentorItems = ((_a = mentors === null || mentors === void 0 ? void 0 : mentors.results) !== null && _a !== void 0 ? _a : []).map((m) => {
166547
+ var _a;
166548
+ return ({
166549
+ itemType: 'mentor',
166550
+ id: (_a = m.unique_id) !== null && _a !== void 0 ? _a : '',
166551
+ name: m.name,
166552
+ badge: m.slug,
166553
+ });
166554
+ });
166555
+ const courseItems = ((_b = coursesData === null || coursesData === void 0 ? void 0 : coursesData.results) !== null && _b !== void 0 ? _b : [])
166556
+ .filter((item) => item.type === 'course')
166557
+ .map((item) => {
166558
+ var _a, _b, _c, _d, _e, _f;
166559
+ return ({
166560
+ itemType: 'course',
166561
+ id: (_d = (_b = (_a = item.data) === null || _a === void 0 ? void 0 : _a.course_id) !== null && _b !== void 0 ? _b : (_c = item.data) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : '',
166562
+ name: (_f = (_e = item.data) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : '',
166563
+ });
166564
+ });
166565
+ const programItems = ((_c = coursesData === null || coursesData === void 0 ? void 0 : coursesData.results) !== null && _c !== void 0 ? _c : [])
166566
+ .filter((item) => item.type === 'program')
166567
+ .map((item) => {
166568
+ var _a, _b, _c, _d, _e, _f;
166569
+ return ({
166570
+ itemType: 'program',
166571
+ id: (_d = (_b = (_a = item.data) === null || _a === void 0 ? void 0 : _a.program_key) !== null && _b !== void 0 ? _b : (_c = item.data) === null || _c === void 0 ? void 0 : _c.program_id) !== null && _d !== void 0 ? _d : '',
166572
+ name: (_f = (_e = item.data) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : '',
166573
+ });
166574
+ });
166575
+ const items = [...mentorItems, ...courseItems, ...programItems];
166576
+ // Close dropdown on outside click
166577
+ useEffect(() => {
166578
+ const handleClickOutside = (e) => {
166579
+ if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
166580
+ setIsOpen(false);
166581
+ }
166582
+ };
166583
+ document.addEventListener('mousedown', handleClickOutside);
166584
+ return () => document.removeEventListener('mousedown', handleClickOutside);
166585
+ }, []);
166586
+ return (jsxs("div", { ref: dropdownRef, className: "relative flex-1", children: [jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => {
166587
+ setSearchQuery(e.target.value);
166588
+ setIsOpen(true);
166589
+ }, onFocus: () => setIsOpen(true), placeholder: "Search items", className: "pl-9" }), isFetching && (jsx(LoaderCircle, { className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 animate-spin text-gray-400" }))] }), isOpen && (jsx("div", { className: "absolute z-50 mt-1 w-full max-h-60 overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-900", style: { borderColor: 'oklch(.922 0 0)' }, children: items.length > 0 ? (items.map((item) => (jsxs("button", { type: "button", className: "flex w-full items-center gap-3 px-3 py-2 text-left hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors", onClick: () => {
166590
+ onSelect(item.itemType, item.id, item.name);
166591
+ setSearchQuery('');
166592
+ setIsOpen(false);
166593
+ }, children: [jsx("div", { className: "flex-1 min-w-0", children: jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 block truncate", children: item.name }) }), jsx(Badge, { variant: "secondary", className: "text-xs shrink-0 capitalize", children: displayItemType(item.itemType) })] }, `${item.itemType}-${item.id}`)))) : isFetching ? (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-400", children: "Searching..." })) : (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-400", children: "No items found" })) }))] }));
166594
+ }
166595
+
166596
+ function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
166597
+ const [page, setPage] = useState(1);
166598
+ const [statusFilter, setStatusFilter] = useState('all');
166599
+ const { data: paywalls, isLoading } = useListPaywallsQuery({
166600
+ platform_key: platformKey,
166601
+ page,
166602
+ page_size: 8,
166603
+ ...(statusFilter !== 'all' && { is_enabled: statusFilter === 'active' }),
166604
+ }, { refetchOnMountOrArgChange: true });
166605
+ return (jsxs("div", { className: "space-y-4", children: [jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", children: [jsx("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 mb-3", children: "Configure item for sale" }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(ItemSearchDropdown, { platformKey: platformKey, onSelect: (itemType, uniqueId, name) => onSelectItem(itemType, uniqueId, name) }), jsx(Button$1, { variant: "outline", size: "icon", onClick: onAddCustomItem, className: "shrink-0 cursor-pointer", title: "Add custom item", children: jsx(Plus, { className: "h-4 w-4" }) })] })] }) }), jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-medium text-gray-500", children: "Configured Items" }), jsxs(Select$1, { value: statusFilter, onValueChange: (v) => {
166606
+ setStatusFilter(v);
166607
+ setPage(1);
166608
+ }, children: [jsx(SelectTrigger, { className: "w-[130px] h-8 text-xs", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: "All" }), jsx(SelectItem, { value: "active", children: "Active" }), jsx(SelectItem, { value: "disabled", children: "Disabled" })] })] })] }), isLoading ? (jsx("div", { className: "space-y-2", children: [1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-16 w-full" }, i))) })) : (paywalls === null || paywalls === void 0 ? void 0 : paywalls.results) && paywalls.results.length > 0 ? (jsxs(Fragment$1, { children: [paywalls.results.map((pw) => {
166609
+ var _a;
166610
+ return (jsx(Card, { className: "shadow-sm border hover:border-blue-200 transition-colors cursor-pointer", style: { borderColor: 'oklch(.922 0 0)' }, onClick: () => onSelectItem(pw.item_type, pw.item_id, pw.item_name), children: jsxs(CardContent, { className: "p-4 flex items-center justify-between", children: [jsx("div", { className: "flex items-center gap-3", children: jsxs("div", { children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: pw.item_name || pw.item_id }), jsxs("div", { className: "flex items-center gap-2 mt-0.5", children: [jsx(Badge, { variant: "secondary", className: "text-xs capitalize", children: displayItemType(pw.item_type) }), ((_a = pw.prices) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
166611
+ (() => {
166612
+ const activeCount = pw.prices.filter((p) => p.is_active).length;
166613
+ return activeCount > 0 ? (jsxs("span", { className: "text-xs text-gray-400", children: [activeCount, " price", activeCount !== 1 ? 's' : ''] })) : null;
166614
+ })()] })] }) }), jsx(Badge, { className: pw.is_enabled
166615
+ ? 'bg-blue-100 text-blue-700 border-blue-200 hover:bg-blue-100'
166616
+ : 'bg-gray-100 text-gray-500 border-gray-200 hover:bg-gray-100', children: pw.is_enabled ? 'Active' : 'Disabled' })] }) }, `${pw.item_type}-${pw.item_id}`));
166617
+ }), (paywalls.previous_page !== null || paywalls.next_page !== null) && (jsxs("div", { className: "flex items-center justify-between pt-2", children: [jsxs("span", { className: "text-xs text-gray-400", children: [paywalls.count, " item", paywalls.count !== 1 ? 's' : '', " total"] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button$1, { variant: "outline", size: "sm", disabled: paywalls.previous_page === null, onClick: () => paywalls.previous_page !== null && setPage(paywalls.previous_page), className: "h-7 text-xs cursor-pointer", children: "Previous" }), jsxs("span", { className: "text-xs text-gray-500", children: ["Page ", page] }), jsx(Button$1, { variant: "outline", size: "sm", disabled: paywalls.next_page === null, onClick: () => paywalls.next_page !== null && setPage(paywalls.next_page), className: "h-7 text-xs cursor-pointer", children: "Next" })] })] }))] })) : (jsx("p", { className: "text-sm text-gray-400 text-center py-6", children: statusFilter !== 'all'
166618
+ ? `No ${statusFilter} items found.`
166619
+ : 'No items configured yet. Search and select an agent above.' }))] })] }));
166620
+ }
166621
+
166017
166622
  const EMPTY_FORM = {
166018
166623
  name: '',
166019
166624
  amount: '',
@@ -166167,194 +166772,183 @@ function PriceManagement({ platformKey, itemType, itemId }) {
166167
166772
  }) })) : (jsx("p", { className: "text-xs text-gray-400 text-center py-4", children: "No pricing tiers yet. Add one to start accepting payments." }))] }));
166168
166773
  }
166169
166774
 
166170
- function useDebounce(value, delay) {
166171
- const [debouncedValue, setDebouncedValue] = useState(value);
166172
- useEffect(() => {
166173
- const timer = setTimeout(() => setDebouncedValue(value), delay);
166174
- return () => clearTimeout(timer);
166175
- }, [value, delay]);
166176
- return debouncedValue;
166177
- }
166178
- // ── Item Selector ──
166179
- function ItemSearchDropdown({ platformKey, onSelect, }) {
166180
- var _a, _b;
166181
- const [searchQuery, setSearchQuery] = useState('');
166182
- const [isOpen, setIsOpen] = useState(false);
166183
- const dropdownRef = useRef(null);
166184
- const debouncedSearch = useDebounce(searchQuery, 300);
166185
- // Mentor search
166186
- const { data: mentors, isFetching: isFetchingMentors } = useGetAiSearchMentorsQuery({
166187
- platform_key: platformKey,
166188
- query: debouncedSearch || undefined,
166189
- limit: 6,
166190
- include_main_public_mentors: false,
166191
- }, { skip: !platformKey });
166192
- // Course search
166193
- const { data: coursesData, isFetching: isFetchingCourses } = useGetPersonnalizedSearchQuery([
166194
- {
166195
- username: getUserName$1(),
166196
- content: ['courses'],
166197
- tenant: platformKey,
166198
- query: debouncedSearch || '',
166199
- returnItems: false,
166200
- returnFacet: false,
166201
- allowSkillSearch: false,
166202
- limit: 6,
166203
- },
166204
- ]);
166205
- const isFetching = isFetchingMentors || isFetchingCourses;
166206
- // Normalize and merge results
166207
- const mentorItems = ((_a = mentors === null || mentors === void 0 ? void 0 : mentors.results) !== null && _a !== void 0 ? _a : []).map((m) => {
166208
- var _a;
166209
- return ({
166210
- itemType: 'mentor',
166211
- id: (_a = m.unique_id) !== null && _a !== void 0 ? _a : '',
166212
- name: m.name,
166213
- badge: m.slug,
166214
- });
166215
- });
166216
- const courseItems = ((_b = coursesData === null || coursesData === void 0 ? void 0 : coursesData.results) !== null && _b !== void 0 ? _b : [])
166217
- .filter((item) => item.type === 'course')
166218
- .map((item) => {
166219
- var _a, _b, _c, _d, _e, _f;
166220
- return ({
166221
- itemType: 'course',
166222
- id: (_d = (_b = (_a = item.data) === null || _a === void 0 ? void 0 : _a.course_id) !== null && _b !== void 0 ? _b : (_c = item.data) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : '',
166223
- name: (_f = (_e = item.data) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : '',
166224
- });
166225
- });
166226
- const items = [...mentorItems, ...courseItems];
166227
- // Close dropdown on outside click
166228
- useEffect(() => {
166229
- const handleClickOutside = (e) => {
166230
- if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
166231
- setIsOpen(false);
166232
- }
166233
- };
166234
- document.addEventListener('mousedown', handleClickOutside);
166235
- return () => document.removeEventListener('mousedown', handleClickOutside);
166236
- }, []);
166237
- return (jsxs("div", { ref: dropdownRef, className: "relative flex-1", children: [jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => {
166238
- setSearchQuery(e.target.value);
166239
- setIsOpen(true);
166240
- }, onFocus: () => setIsOpen(true), placeholder: "Search items", className: "pl-9" }), isFetching && (jsx(LoaderCircle, { className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 animate-spin text-gray-400" }))] }), isOpen && (jsx("div", { className: "absolute z-50 mt-1 w-full max-h-60 overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-900", style: { borderColor: 'oklch(.922 0 0)' }, children: items.length > 0 ? (items.map((item) => (jsxs("button", { type: "button", className: "flex w-full items-center gap-3 px-3 py-2 text-left hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors", onClick: () => {
166241
- onSelect(item.itemType, item.id, item.name);
166242
- setSearchQuery('');
166243
- setIsOpen(false);
166244
- }, children: [jsx("div", { className: "flex-1 min-w-0", children: jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 block truncate", children: item.name }) }), jsx(Badge, { variant: "secondary", className: "text-xs shrink-0 capitalize", children: item.itemType })] }, `${item.itemType}-${item.id}`)))) : isFetching ? (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-400", children: "Searching..." })) : (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-400", children: "No items found" })) }))] }));
166245
- }
166246
- function PaywalledItemsList({ platformKey, onSelectItem, }) {
166247
- const [page, setPage] = useState(1);
166248
- const [statusFilter, setStatusFilter] = useState('all');
166249
- const { data: paywalls, isLoading } = useListPaywallsQuery({
166250
- platform_key: platformKey,
166251
- page,
166252
- page_size: 8,
166253
- ...(statusFilter !== 'all' && { is_enabled: statusFilter === 'active' }),
166254
- }, { refetchOnMountOrArgChange: true });
166255
- return (jsxs("div", { className: "space-y-4", children: [jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", children: [jsx("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 mb-3", children: "Configure item for sale" }), jsx(ItemSearchDropdown, { platformKey: platformKey, onSelect: (itemType, uniqueId, name) => onSelectItem(itemType, uniqueId, name) })] }) }), jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-medium text-gray-500", children: "Configured Items" }), jsxs(Select$1, { value: statusFilter, onValueChange: (v) => {
166256
- setStatusFilter(v);
166257
- setPage(1);
166258
- }, children: [jsx(SelectTrigger, { className: "w-[130px] h-8 text-xs", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: "All" }), jsx(SelectItem, { value: "active", children: "Active" }), jsx(SelectItem, { value: "disabled", children: "Disabled" })] })] })] }), isLoading ? (jsx("div", { className: "space-y-2", children: [1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-16 w-full" }, i))) })) : (paywalls === null || paywalls === void 0 ? void 0 : paywalls.results) && paywalls.results.length > 0 ? (jsxs(Fragment$1, { children: [paywalls.results.map((pw) => {
166259
- var _a;
166260
- return (jsx(Card, { className: "shadow-sm border hover:border-blue-200 transition-colors cursor-pointer", style: { borderColor: 'oklch(.922 0 0)' }, onClick: () => onSelectItem(pw.item_type, pw.item_id, pw.item_name), children: jsxs(CardContent, { className: "p-4 flex items-center justify-between", children: [jsx("div", { className: "flex items-center gap-3", children: jsxs("div", { children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: pw.item_name || pw.item_id }), jsxs("div", { className: "flex items-center gap-2 mt-0.5", children: [jsx(Badge, { variant: "secondary", className: "text-xs capitalize", children: pw.item_type }), ((_a = pw.prices) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
166261
- (() => {
166262
- const activeCount = pw.prices.filter((p) => p.is_active).length;
166263
- return activeCount > 0 ? (jsxs("span", { className: "text-xs text-gray-400", children: [activeCount, " price", activeCount !== 1 ? 's' : ''] })) : null;
166264
- })()] })] }) }), jsx(Badge, { className: pw.is_enabled
166265
- ? 'bg-blue-100 text-blue-700 border-blue-200 hover:bg-blue-100'
166266
- : 'bg-gray-100 text-gray-500 border-gray-200 hover:bg-gray-100', children: pw.is_enabled ? 'Active' : 'Disabled' })] }) }, `${pw.item_type}-${pw.item_id}`));
166267
- }), (paywalls.previous_page !== null || paywalls.next_page !== null) && (jsxs("div", { className: "flex items-center justify-between pt-2", children: [jsxs("span", { className: "text-xs text-gray-400", children: [paywalls.count, " item", paywalls.count !== 1 ? 's' : '', " total"] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button$1, { variant: "outline", size: "sm", disabled: paywalls.previous_page === null, onClick: () => paywalls.previous_page !== null && setPage(paywalls.previous_page), className: "h-7 text-xs cursor-pointer", children: "Previous" }), jsxs("span", { className: "text-xs text-gray-500", children: ["Page ", page] }), jsx(Button$1, { variant: "outline", size: "sm", disabled: paywalls.next_page === null, onClick: () => paywalls.next_page !== null && setPage(paywalls.next_page), className: "h-7 text-xs cursor-pointer", children: "Next" })] })] }))] })) : (jsx("p", { className: "text-sm text-gray-400 text-center py-6", children: statusFilter !== 'all'
166268
- ? `No ${statusFilter} items found.`
166269
- : 'No items configured yet. Search and select a mentor above.' }))] })] }));
166775
+ function WizardStepIndicator({ steps, currentStep, onStepClick, }) {
166776
+ const currentIndex = steps.findIndex((s) => s.key === currentStep);
166777
+ return (jsx("div", { className: "flex items-center w-full mb-4", children: steps.map((step, i) => {
166778
+ const isClickable = !!onStepClick;
166779
+ return (jsxs("div", { className: `flex items-center${i > 0 ? ' flex-1' : ''}`, children: [i > 0 && jsx("div", { className: "flex-1 h-px bg-gray-300 dark:bg-gray-600 mx-2" }), jsxs("button", { type: "button", disabled: !isClickable, onClick: () => onStepClick === null || onStepClick === void 0 ? void 0 : onStepClick(step.key), className: `flex items-center gap-1.5 text-xs font-medium ${isClickable ? 'cursor-pointer hover:opacity-80' : 'cursor-default'} ${i < currentIndex
166780
+ ? 'text-blue-500'
166781
+ : i === currentIndex
166782
+ ? 'text-gray-900 dark:text-gray-100'
166783
+ : 'text-gray-400'}`, children: [jsx("span", { className: `flex items-center justify-center w-5 h-5 rounded-full text-[10px] font-semibold ${i < currentIndex
166784
+ ? 'bg-blue-100 text-blue-600'
166785
+ : i === currentIndex
166786
+ ? 'bg-blue-500 text-white'
166787
+ : 'bg-gray-200 text-gray-400 dark:bg-gray-700'}`, children: i < currentIndex ? jsx(Check, { className: "h-3 w-3" }) : i + 1 }), step.label] })] }, step.key));
166788
+ }) }));
166270
166789
  }
166271
- // ── Paywall Detail Editor ──
166272
- function PaywallDetail({ platformKey, itemType, itemId, itemName, onBack, }) {
166273
- const { data: config, isLoading, refetch: refetchConfig, } = useGetPaywallConfigQuery({ platform_key: platformKey, item_type: itemType, item_id: itemId }, { refetchOnMountOrArgChange: true });
166274
- const [enablePaywall, { isLoading: isEnabling }] = useEnablePaywallMutation();
166275
- const [disablePaywall, { isLoading: isDisabling }] = useDisablePaywallMutation();
166790
+
166791
+ function PaywallDetail({ platformKey, authURL, itemType, itemId, itemName, isCustom, onBack, }) {
166792
+ const { data: config, isLoading, refetch: refetchConfig, } = useGetPaywallConfigQuery({ platform_key: platformKey, item_type: itemType, item_id: itemId }, { refetchOnMountOrArgChange: true, skip: isCustom });
166793
+ const [enablePaywall, { isLoading: isCreating }] = useEnablePaywallMutation();
166794
+ const [updatePaywall, { isLoading: isUpdating }] = useUpdatePaywallMutation();
166795
+ const isSaving = isCreating || isUpdating;
166796
+ // Wizard step
166797
+ const [currentStep, setCurrentStep] = useState(isCustom ? 'custom-item' : 'paywall');
166798
+ // Track whether the item has been created (custom flow) or already exists (non-custom)
166799
+ const [itemCreated, setItemCreated] = useState(!isCustom);
166276
166800
  const [isEnabled, setIsEnabled] = useState(false);
166277
166801
  const [allowFreeTier, setAllowFreeTier] = useState(false);
166278
166802
  const [trialDays, setTrialDays] = useState(0);
166279
166803
  const [grandfathering, setGrandfathering] = useState('free_forever');
166804
+ // Custom item fields
166805
+ const [customItemType, setCustomItemType] = useState('');
166806
+ const [customItemName, setCustomItemName] = useState('');
166807
+ const [customDescription, setCustomDescription] = useState('');
166808
+ const [customProductUrl, setCustomProductUrl] = useState('');
166809
+ // Resolved item params (updated after custom item creation)
166810
+ const [resolvedItemType, setResolvedItemType] = useState(itemType);
166811
+ const [resolvedItemId, setResolvedItemId] = useState(itemId);
166812
+ const [paywallUniqueId, setPaywallUniqueId] = useState(null);
166813
+ // Copy URL state
166814
+ const [copied, setCopied] = useState(false);
166815
+ const copyTimerRef = useRef(null);
166816
+ const handleCopyUrl = async () => {
166817
+ /* istanbul ignore next: button is not rendered without paywallUniqueId */
166818
+ if (!paywallUniqueId)
166819
+ return;
166820
+ const basePath = authURL.endsWith('/') ? authURL : `${authURL}/`;
166821
+ const url = `${basePath}buy/${paywallUniqueId}`;
166822
+ await navigator.clipboard.writeText(url);
166823
+ toast.success('URL copied to clipboard');
166824
+ setCopied(true);
166825
+ if (copyTimerRef.current)
166826
+ clearTimeout(copyTimerRef.current);
166827
+ copyTimerRef.current = setTimeout(() => setCopied(false), 2500);
166828
+ };
166829
+ useEffect(() => {
166830
+ return () => {
166831
+ if (copyTimerRef.current)
166832
+ clearTimeout(copyTimerRef.current);
166833
+ };
166834
+ }, []);
166280
166835
  useEffect(() => {
166281
166836
  if (config) {
166282
166837
  setIsEnabled(config.is_enabled);
166283
166838
  setAllowFreeTier(config.allow_free_tier);
166284
166839
  setTrialDays(config.trial_period_days);
166285
166840
  setGrandfathering(config.grandfathering_strategy);
166841
+ setPaywallUniqueId(config.unique_id);
166286
166842
  }
166287
166843
  }, [config]);
166288
- const handleTogglePaywall = async (enabled) => {
166844
+ const wizardSteps = [
166845
+ ...(isCustom ? [{ key: 'custom-item', label: 'Item Details' }] : []),
166846
+ { key: 'paywall', label: 'Paywall' },
166847
+ { key: 'pricing', label: 'Pricing' },
166848
+ ];
166849
+ const displayName = isCustom
166850
+ ? customItemName || 'New Custom Item'
166851
+ : (config === null || config === void 0 ? void 0 : config.item_name) || itemName || itemId;
166852
+ const handleCreateCustomItem = async () => {
166853
+ /* istanbul ignore next: Create button is disabled when either field is empty */
166854
+ if (!customItemType.trim() || !customItemName.trim()) {
166855
+ toast.error('Item type and item name are required');
166856
+ return;
166857
+ }
166289
166858
  try {
166290
- if (enabled) {
166291
- await enablePaywall({
166292
- platform_key: platformKey,
166293
- item_type: itemType,
166294
- item_id: itemId,
166295
- is_enabled: true,
166296
- allow_free_tier: allowFreeTier,
166297
- trial_period_days: trialDays,
166298
- grandfathering_strategy: grandfathering,
166299
- }).unwrap();
166300
- toast.success('Paywall enabled');
166301
- }
166302
- else {
166303
- await disablePaywall({
166304
- platform_key: platformKey,
166305
- item_type: itemType,
166306
- item_id: itemId,
166307
- }).unwrap();
166308
- toast.success('Paywall disabled');
166309
- }
166310
- setIsEnabled(enabled);
166311
- refetchConfig();
166859
+ const sluggedType = slugify(customItemType);
166860
+ const sluggedId = slugify(customItemName);
166861
+ const result = await enablePaywall({
166862
+ platform_key: platformKey,
166863
+ item_type: sluggedType,
166864
+ item_id: sluggedId,
166865
+ is_enabled: false,
166866
+ allow_free_tier: false,
166867
+ trial_period_days: 0,
166868
+ grandfathering_strategy: 'free_forever',
166869
+ item_name: customItemName,
166870
+ description: customDescription,
166871
+ on_successful_payment: buildOnSuccessfulPaymentUrl({
166872
+ authURL,
166873
+ itemType: sluggedType,
166874
+ itemId: sluggedId,
166875
+ platformKey,
166876
+ isCustom: true,
166877
+ customProductUrl,
166878
+ }),
166879
+ }).unwrap();
166880
+ toast.success('Custom item created');
166881
+ setResolvedItemType(sluggedType);
166882
+ setResolvedItemId(sluggedId);
166883
+ setPaywallUniqueId(result.unique_id);
166884
+ setItemCreated(true);
166885
+ setCurrentStep('paywall');
166312
166886
  }
166313
166887
  catch (_a) {
166314
- toast.error(`Failed to ${enabled ? 'enable' : 'disable'} paywall`);
166888
+ toast.error('Failed to create custom item');
166315
166889
  }
166316
166890
  };
166317
166891
  const handleSaveConfig = async () => {
166318
166892
  try {
166319
- await enablePaywall({
166893
+ const mutate = itemCreated ? updatePaywall : enablePaywall;
166894
+ await mutate({
166320
166895
  platform_key: platformKey,
166321
- item_type: itemType,
166322
- item_id: itemId,
166896
+ item_type: resolvedItemType,
166897
+ item_id: resolvedItemId,
166323
166898
  is_enabled: isEnabled,
166324
166899
  allow_free_tier: allowFreeTier,
166325
166900
  trial_period_days: trialDays,
166326
166901
  grandfathering_strategy: grandfathering,
166902
+ // TODO: remove item_name once the backend fixes the 400 when updating custom items
166903
+ item_name: displayName,
166904
+ on_successful_payment: buildOnSuccessfulPaymentUrl({
166905
+ authURL,
166906
+ itemType: resolvedItemType,
166907
+ itemId: resolvedItemId,
166908
+ platformKey,
166909
+ isCustom,
166910
+ customProductUrl,
166911
+ }),
166327
166912
  }).unwrap();
166328
- toast.success('Paywall configuration updated');
166329
- refetchConfig();
166913
+ toast.success('Paywall configuration saved');
166914
+ if (!isCustom)
166915
+ refetchConfig();
166916
+ setCurrentStep('pricing');
166330
166917
  }
166331
166918
  catch (_a) {
166332
- toast.error('Failed to update paywall configuration');
166919
+ toast.error('Failed to save paywall configuration');
166333
166920
  }
166334
166921
  };
166335
- if (isLoading) {
166922
+ if (!isCustom && isLoading) {
166336
166923
  return (jsxs("div", { className: "space-y-4", children: [jsx(Skeleton, { className: "h-8 w-48" }), jsx(Skeleton, { className: "h-64 w-full" })] }));
166337
166924
  }
166338
- const displayName = (config === null || config === void 0 ? void 0 : config.item_name) || itemName || itemId;
166339
- return (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsxs(Button$1, { variant: "ghost", size: "sm", onClick: onBack, className: "cursor-pointer", children: [jsx(ChevronLeft, { className: "h-4 w-4 mr-1" }), "Back"] }), jsxs("div", { children: [jsx("h4", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: displayName }), jsx("span", { className: "text-xs text-gray-400 capitalize", children: itemType })] })] }), jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-6 space-y-5", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Paywall Enabled" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "Require payment to access this item" })] }), jsx(Switch, { checked: isEnabled, onCheckedChange: handleTogglePaywall, disabled: isEnabling || isDisabling, className: "cursor-pointer data-[state=checked]:bg-blue-500" })] }), jsxs("div", { className: !isEnabled ? 'opacity-50 pointer-events-none' : '', children: [jsxs("div", { className: "flex items-center justify-between py-3 border-t", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Allow Free Tier" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "Let users access basic features without paying" })] }), jsx(Switch, { checked: allowFreeTier, onCheckedChange: setAllowFreeTier, className: "cursor-pointer data-[state=checked]:bg-blue-500" })] }), jsxs("div", { className: "flex items-center justify-between py-3 border-t", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Trial Period (days)" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "Free trial before charging subscribers" })] }), jsx(Input, { type: "number", min: 0, value: trialDays, onChange: (e) => setTrialDays(parseInt(e.target.value) || 0), className: "w-24 text-right" })] }), jsxs("div", { className: "flex items-center justify-between py-3 border-t", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Existing Users" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "How to treat users who had access before the paywall" })] }), jsxs(Select$1, { value: grandfathering, onValueChange: (v) => setGrandfathering(v), children: [jsx(SelectTrigger, { className: "w-[180px]", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "free_forever", children: "Free Forever" }), jsx(SelectItem, { value: "require_subscription", children: "Require Subscription" })] })] })] }), jsx("div", { className: "pt-3 border-t", children: jsxs(Button$1, { onClick: handleSaveConfig, disabled: isEnabling, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white cursor-pointer", children: [isEnabling ? (jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" })) : (jsx(Check, { className: "h-4 w-4 mr-2" })), "Save Configuration"] }) })] })] }) }), isEnabled && (jsx(PriceManagement, { platformKey: platformKey, itemType: itemType, itemId: itemId }))] }));
166925
+ return (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsxs(Button$1, { variant: "ghost", size: "sm", onClick: onBack, className: "cursor-pointer", children: [jsx(ChevronLeft, { className: "h-4 w-4 mr-1" }), "Back"] }), jsxs("div", { children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("h4", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: displayName }), paywallUniqueId && (jsx("button", { type: "button", onClick: handleCopyUrl, className: "p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors cursor-pointer", title: "Copy paywall URL", children: copied ? (jsx(Check, { className: "h-4 w-4 text-green-500" })) : (jsx(Copy, { className: "h-4 w-4 text-gray-400" })) }))] }), !isCustom && (jsx("span", { className: "text-xs text-gray-400 capitalize", children: displayItemType(itemType) }))] })] }), jsx(WizardStepIndicator, { steps: wizardSteps, currentStep: currentStep, onStepClick: !isCustom
166926
+ ? setCurrentStep
166927
+ : (step) => {
166928
+ // During creation, only allow navigating back to already-completed steps
166929
+ const targetIndex = wizardSteps.findIndex((s) => s.key === step);
166930
+ const currentIndex = wizardSteps.findIndex((s) => s.key === currentStep);
166931
+ if (targetIndex < currentIndex)
166932
+ setCurrentStep(step);
166933
+ } }), currentStep === 'custom-item' && isCustom && (jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-6 space-y-4", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300", children: "Item Details" }), jsxs("div", { className: "space-y-3", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Item Type" }), jsx(Input, { value: customItemType, onChange: (e) => setCustomItemType(e.target.value), placeholder: "e.g. tool, resource", className: "mt-1", disabled: itemCreated }), customItemType && (jsxs("p", { className: "text-xs text-gray-400 mt-1", children: ["Slug: ", slugify(customItemType)] }))] }), jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Item Name" }), jsx(Input, { value: customItemName, onChange: (e) => setCustomItemName(e.target.value), placeholder: "e.g. Advanced AI Course", className: "mt-1", disabled: itemCreated }), customItemName && (jsxs("p", { className: "text-xs text-gray-400 mt-1", children: ["ID: ", slugify(customItemName)] }))] }), jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Description" }), jsx(Textarea, { value: customDescription, onChange: (e) => setCustomDescription(e.target.value), placeholder: "Describe this item...", className: "mt-1", rows: 3 })] }), jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Product URL (optional)" }), jsx(Input, { type: "url", value: customProductUrl, onChange: (e) => setCustomProductUrl(e.target.value), placeholder: "https://example.com/product", className: "mt-1", disabled: itemCreated }), jsx("p", { className: "text-xs text-gray-400 mt-1", children: "Where users land after a successful payment." })] })] }), jsx("div", { className: "pt-3 border-t flex justify-end", children: jsxs(Button$1, { onClick: handleCreateCustomItem, disabled: isSaving || !customItemType.trim() || !customItemName.trim(), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white cursor-pointer", children: [isCreating ? (jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" })) : (jsx(ChevronRight, { className: "h-4 w-4 mr-2" })), "Create & Continue"] }) })] }) })), currentStep === 'paywall' && (jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-6 space-y-5", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Paywall Enabled" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "Require payment to access this item" })] }), jsx(Switch, { checked: isEnabled, onCheckedChange: setIsEnabled, className: "cursor-pointer data-[state=checked]:bg-blue-500" })] }), jsxs("div", { className: !isEnabled ? 'opacity-50 pointer-events-none' : '', children: [jsxs("div", { className: "flex items-center justify-between py-3 border-t", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Allow Free Tier" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "Let users access basic features without paying" })] }), jsx(Switch, { checked: allowFreeTier, onCheckedChange: setAllowFreeTier, className: "cursor-pointer data-[state=checked]:bg-blue-500" })] }), jsxs("div", { className: "flex items-center justify-between py-3 border-t", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Trial Period (days)" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "Free trial before charging subscribers" })] }), jsx(Input, { type: "number", min: 0, value: trialDays, onChange: (e) => setTrialDays(parseInt(e.target.value) || 0), className: "w-24 text-right" })] }), jsxs("div", { className: "flex items-center justify-between py-3 border-t", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Existing Users" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "How to treat users who had access before the paywall" })] }), jsxs(Select$1, { value: grandfathering, onValueChange: (v) => setGrandfathering(v), children: [jsx(SelectTrigger, { className: "w-[180px]", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "free_forever", children: "Free Forever" }), jsx(SelectItem, { value: "require_subscription", children: "Require Subscription" })] })] })] })] }), jsx("div", { className: "pt-3 border-t flex justify-end", children: jsxs(Button$1, { onClick: handleSaveConfig, disabled: isSaving, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white cursor-pointer", children: [isSaving ? (jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" })) : (jsx(Check, { className: "h-4 w-4 mr-2" })), "Save Configuration"] }) })] }) })), currentStep === 'pricing' && (jsx(PriceManagement, { platformKey: platformKey, itemType: resolvedItemType, itemId: resolvedItemId }))] }));
166340
166934
  }
166341
- // ── Main Export ──
166342
- function PaywallConfig({ platformKey, disabled }) {
166935
+
166936
+ function PaywallConfig({ platformKey, authURL, disabled }) {
166343
166937
  const [selectedItem, setSelectedItem] = useState(null);
166344
166938
  if (disabled) {
166345
166939
  return (jsx(Card, { className: "shadow-sm border border-dashed", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-8 text-center", children: [jsx(Shield, { className: "h-10 w-10 mx-auto text-gray-300 mb-3" }), jsx("p", { className: "text-sm text-gray-400", children: "Connect Stripe first to configure paywalls." })] }) }));
166346
166940
  }
166347
166941
  if (selectedItem) {
166348
- return (jsx(PaywallDetail, { platformKey: platformKey, itemType: selectedItem.type, itemId: selectedItem.id, itemName: selectedItem.name, onBack: () => setSelectedItem(null) }));
166942
+ return (jsx(PaywallDetail, { platformKey: platformKey, authURL: authURL, itemType: selectedItem.type, itemId: selectedItem.id, itemName: selectedItem.name, isCustom: selectedItem.isCustom, onBack: () => setSelectedItem(null) }));
166349
166943
  }
166350
- return (jsx(PaywalledItemsList, { platformKey: platformKey, onSelectItem: (type, id, name) => setSelectedItem({ type, id, name }) }));
166944
+ return (jsx(PaywalledItemsList, { platformKey: platformKey, onSelectItem: (type, id, name) => setSelectedItem({ type, id, name }), onAddCustomItem: () => setSelectedItem({ type: '', id: '', name: '', isCustom: true }) }));
166351
166945
  }
166352
166946
 
166353
- function MonetizationTab({ platformKey }) {
166947
+ function MonetizationTab({ platformKey, authURL }) {
166354
166948
  var _a;
166355
166949
  const { data: stripeStatus } = useGetStripeConnectStatusQuery({ platform_key: platformKey }, { refetchOnMountOrArgChange: true });
166356
166950
  const isStripeReady = (_a = stripeStatus === null || stripeStatus === void 0 ? void 0 : stripeStatus.is_ready_for_payments) !== null && _a !== void 0 ? _a : false;
166357
- return (jsxs("div", { className: "container mx-auto max-w-7xl !mt-0 space-y-6", children: [jsx(StripeConnect, { platformKey: platformKey }), jsx(PaywallConfig, { platformKey: platformKey, disabled: !isStripeReady })] }));
166951
+ return (jsxs("div", { className: "container mx-auto max-w-7xl !mt-0 space-y-6", children: [jsx(StripeConnect, { platformKey: platformKey }), jsx(PaywallConfig, { platformKey: platformKey, authURL: authURL, disabled: !isStripeReady })] }));
166358
166952
  }
166359
166953
 
166360
166954
  function Account({ tenant, tenants = [], username, onInviteClick, email, mainPlatformKey, userActiveApp = null, showPlatformName = false, isAdmin = false, targetTab = 'basic', currentPlan: _currentPlan = '', currentSPA = '', authURL, onTenantUpdate, currentPlatformBaseDomain = '', enableRbac = false, rbacPermissions = {}, onLoadGroupPermissions, onTabChange, }) {
@@ -166377,11 +166971,13 @@ function Account({ tenant, tenants = [], username, onInviteClick, email, mainPla
166377
166971
  const hasTeamsTabPermission = checkRbacPermission(rbacPermissions, `/usergroups/#list|/platforms/${tenant}/#can_invite`, enableRbac);
166378
166972
  const hasInviteUserPermission = checkRbacPermission(rbacPermissions, `/platforms/${tenant}/#can_invite`, enableRbac);
166379
166973
  const hasCreateTeamPermission = checkRbacPermission(rbacPermissions, `/usergroups/#list`, enableRbac);
166974
+ const hasAlertsTabPermission = checkRbacPermission(rbacPermissions, `/watchedgroups/#list`, enableRbac);
166380
166975
  const hasManagementPermissions = hasUserTabPermission ||
166381
166976
  hasGroupsTabPermission ||
166382
166977
  hasPoliciesTabPermission ||
166383
166978
  hasRolesTabPermission ||
166384
- hasTeamsTabPermission;
166979
+ hasTeamsTabPermission ||
166980
+ hasAlertsTabPermission;
166385
166981
  useEffect(() => {
166386
166982
  const firstInput = document.getElementById('fullName');
166387
166983
  if (firstInput) {
@@ -166448,7 +167044,7 @@ function Account({ tenant, tenants = [], username, onInviteClick, email, mainPla
166448
167044
  : 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(CreditCard, { className: "h-4 w-4" }), jsx("span", { className: "hidden sm:inline", children: "Billing" }), jsx("span", { className: "sm:hidden", children: "Billing" })] }, 'billing'))] }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsxs("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'management' && 'Manage users and their permissions in the system.', activeTab === 'organization' && 'Manage your organization settings.', activeTab === 'integrations' && 'Manage your integrations with other services.', activeTab === 'billing' && 'Manage your billing and subscription.', activeTab === 'monetization' && 'Configure paywalls, pricing, and revenue.', activeTab === 'advanced' && 'Configure advanced organization settings.'] })] }), jsxs("div", { className: "flex-1 p-6 space-y-6", style: {
166449
167045
  overflowY: 'auto',
166450
167046
  overflowX: 'hidden',
166451
- }, children: [jsxs("div", { className: "lg:hidden mb-6", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'basic' && 'Manage your basic account information and preferences.', activeTab === 'social' && 'Connect and manage your social media accounts.', activeTab === 'security' && 'Update your security settings and password.', activeTab === 'management' && 'Manage users and their permissions in the system.', activeTab === 'organization' && 'Manage your organization settings.', activeTab === 'monetization' && 'Configure paywalls, pricing, and revenue.', activeTab === 'advanced' && 'Configure advanced organization settings.'] })] }), activeTab === 'management' && hasManagementPermissions && (jsx(Admin, { onInviteClick: onInviteClick, tenant: tenant, hasUserTabPermission: hasUserTabPermission, hasGroupsTabPermission: hasGroupsTabPermission, hasPoliciesTabPermission: hasPoliciesTabPermission, hasRolesTabPermission: hasRolesTabPermission, hasTeamsTabPermission: hasTeamsTabPermission, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac })), activeTab === 'organization' && (jsx(OrganizationTab, { platformKey: tenant, tenant: tenants.find((t) => t.key === tenant), onTenantUpdate: onTenantUpdate, setOrganizationLogoFromOutside: setOrganizationLogo })), activeTab === 'integrations' && (jsx(IntegrationsTab, { tenantKey: tenant, username: username })), activeTab === 'billing' && (jsx(BillingTab, { tenant: tenant, userActiveApp: userActiveApp, username: username, currentUserEmail: email, mainPlatformKey: mainPlatformKey })), activeTab === 'monetization' && jsx(MonetizationTab, { platformKey: tenant }), activeTab === 'advanced' && (jsx(AdvancedTab, { platformKey: tenant, currentSPA: currentSPA, username: username, authURL: authURL, currentPlatformBaseDomain: currentPlatformBaseDomain }))] })] }), jsx(ToastProvider, {})] }));
167047
+ }, children: [jsxs("div", { className: "lg:hidden mb-6", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'basic' && 'Manage your basic account information and preferences.', activeTab === 'social' && 'Connect and manage your social media accounts.', activeTab === 'security' && 'Update your security settings and password.', activeTab === 'management' && 'Manage users and their permissions in the system.', activeTab === 'organization' && 'Manage your organization settings.', activeTab === 'monetization' && 'Configure paywalls, pricing, and revenue.', activeTab === 'advanced' && 'Configure advanced organization settings.'] })] }), activeTab === 'management' && hasManagementPermissions && (jsx(Admin, { onInviteClick: onInviteClick, tenant: tenant, hasUserTabPermission: hasUserTabPermission, hasGroupsTabPermission: hasGroupsTabPermission, hasPoliciesTabPermission: hasPoliciesTabPermission, hasRolesTabPermission: hasRolesTabPermission, hasTeamsTabPermission: hasTeamsTabPermission, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, hasAlertsTabPermission: hasAlertsTabPermission, rbacPermissions: rbacPermissions, enableRbac: enableRbac })), activeTab === 'organization' && (jsx(OrganizationTab, { platformKey: tenant, tenant: tenants.find((t) => t.key === tenant), onTenantUpdate: onTenantUpdate, setOrganizationLogoFromOutside: setOrganizationLogo })), activeTab === 'integrations' && (jsx(IntegrationsTab, { tenantKey: tenant, username: username })), activeTab === 'billing' && (jsx(BillingTab, { tenant: tenant, userActiveApp: userActiveApp, username: username, currentUserEmail: email, mainPlatformKey: mainPlatformKey })), activeTab === 'monetization' && (jsx(MonetizationTab, { platformKey: tenant, authURL: authURL })), activeTab === 'advanced' && (jsx(AdvancedTab, { platformKey: tenant, currentSPA: currentSPA, username: username, authURL: authURL, currentPlatformBaseDomain: currentPlatformBaseDomain }))] })] }), jsx(ToastProvider, {})] }));
166452
167048
  }
166453
167049
 
166454
167050
  function UserProfileModal({ isOpen, onClose, params, email, mainPlatformKey, showMentorAIDisplayCheckbox = false, showLeaderboardDisplayCheckbox = false, showUsernameField = false, showPlatformName = false, useGravatarPicFallback = true, enableCatalogInvite = false, targetTab = 'basic', currentPlan = '', currentSPA = '', userActiveApp = null, authURL, tenants = [], onTenantUpdate, currentPlatformBaseDomain = '', rbacPermissions = {}, enableRbac = false, onLoadGroupPermissions, onTabChange, onBillingTabRequest, onAccountDeleted, enableMemoryTab = false, localLLMProps, }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iblai/iblai-js",
3
- "version": "1.9.8",
3
+ "version": "1.9.10",
4
4
  "description": "Unified JavaScript SDK for IBL.ai — re-exports data-layer, web-containers, and web-utils under a single package",
5
5
  "type": "module",
6
6
  "engines": {
@@ -61,10 +61,10 @@
61
61
  "axios": "1.13.6",
62
62
  "dotenv": "16.6.1",
63
63
  "winston": "3.19.0",
64
- "@iblai/data-layer": "1.5.3",
65
- "@iblai/web-containers": "1.6.9",
66
- "@iblai/web-utils": "1.6.5",
67
- "@iblai/mcp": "1.4.7"
64
+ "@iblai/data-layer": "1.5.5",
65
+ "@iblai/mcp": "1.4.8",
66
+ "@iblai/web-containers": "1.6.11",
67
+ "@iblai/web-utils": "1.6.7"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "@radix-ui/react-dialog": "^1.1.7",