@iblai/iblai-js 1.9.8 → 1.9.9

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, 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';
@@ -165752,6 +165752,28 @@ const MemsearchConfigContent = ({ platformKey, userId }) => {
165752
165752
  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
165753
  };
165754
165754
 
165755
+ function StringSettingInput({ value, defaultValue, disabled, onSave, }) {
165756
+ const [localValue, setLocalValue] = useState(value || defaultValue);
165757
+ const debounceRef = useRef(null);
165758
+ useEffect(() => {
165759
+ setLocalValue(value || defaultValue);
165760
+ }, [value, defaultValue]);
165761
+ const handleChange = (newValue) => {
165762
+ setLocalValue(newValue);
165763
+ if (debounceRef.current)
165764
+ clearTimeout(debounceRef.current);
165765
+ debounceRef.current = setTimeout(() => {
165766
+ onSave(newValue);
165767
+ }, 800);
165768
+ };
165769
+ useEffect(() => {
165770
+ return () => {
165771
+ if (debounceRef.current)
165772
+ clearTimeout(debounceRef.current);
165773
+ };
165774
+ }, []);
165775
+ 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" }))] }));
165776
+ }
165755
165777
  function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatformBaseDomain, }) {
165756
165778
  const [updateTenantMetadata, { isLoading: isUpdatingTenantMetadata }] = useUpdateTenantMetadataMutation();
165757
165779
  // Mentor search state
@@ -165791,9 +165813,14 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
165791
165813
  const allMetadatas = getAllMetadatas();
165792
165814
  // Include both boolean and string settings, but exclude start screen settings
165793
165815
  // which are handled by the StartScreenContent component
165816
+ const stringSettingSlugs = [
165817
+ 'overall_default_mentor',
165818
+ 'help_center_url',
165819
+ 'monetization_base_path',
165820
+ ];
165794
165821
  const configurableMetadatas = allMetadatas.filter((metadata) => (typeof metadata.defaultValue === 'boolean' ||
165795
165822
  (typeof metadata.defaultValue === 'string' &&
165796
- metadata.slug === 'overall_default_mentor')) &&
165823
+ stringSettingSlugs.includes(metadata.slug))) &&
165797
165824
  !startScreenSlugs.includes(metadata.slug));
165798
165825
  if (currentSPA) {
165799
165826
  // Filter by current SPA if specified (case-insensitive partial matching)
@@ -165898,6 +165925,11 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
165898
165925
  const handleChatAreaSizeError = (message) => {
165899
165926
  toast.error(message);
165900
165927
  };
165928
+ const handleStringSettingUpdate = async (slug, value) => {
165929
+ updateOrganizationMetadata(slug, value, () => {
165930
+ toast.success('Setting updated successfully');
165931
+ });
165932
+ };
165901
165933
  // Helper function to get mentor name from JSON string, object, or unique_id
165902
165934
  const getMentorName = (mentorValue) => {
165903
165935
  var _a;
@@ -165932,7 +165964,8 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
165932
165964
  ? 'None'
165933
165965
  : ((_a = metadataItem.value) !== null && _a !== void 0 ? _a : metadataItem.defaultValue);
165934
165966
  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 () => {
165967
+ const isStringSetting = typeof metadataItem.defaultValue === 'string' && !isMentorSetting;
165968
+ 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
165969
  await handleToggleSetting(metadataItem.slug, currentValue);
165937
165970
  }, 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
165971
  }) })) : (
@@ -165950,7 +165983,8 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
165950
165983
  var _a, _b;
165951
165984
  const currentValue = (_a = metadataItem.value) !== null && _a !== void 0 ? _a : metadataItem.defaultValue;
165952
165985
  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 () => {
165986
+ const isStringSetting = typeof metadataItem.defaultValue === 'string' && !isMentorSetting;
165987
+ 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
165988
  await handleToggleSetting(metadataItem.slug, currentValue);
165955
165989
  }, 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
165990
  }) })] }, spa)));
@@ -166014,6 +166048,166 @@ function StripeConnect({ platformKey }) {
166014
166048
  : 'Connect Stripe'] })) })] }) }) }));
166015
166049
  }
166016
166050
 
166051
+ function slugify(text) {
166052
+ return text
166053
+ .toLowerCase()
166054
+ .trim()
166055
+ .replace(/[^\w\s-]/g, '')
166056
+ .replace(/[\s_]+/g, '-')
166057
+ .replace(/-+/g, '-')
166058
+ .replace(/^-+|-+$/g, '');
166059
+ }
166060
+ function useDebounce(value, delay) {
166061
+ const [debouncedValue, setDebouncedValue] = useState(value);
166062
+ useEffect(() => {
166063
+ const timer = setTimeout(() => setDebouncedValue(value), delay);
166064
+ return () => clearTimeout(timer);
166065
+ }, [value, delay]);
166066
+ return debouncedValue;
166067
+ }
166068
+ function displayItemType(itemType) {
166069
+ const stripped = itemType.replace(/^custom:/i, '');
166070
+ if (stripped.toLowerCase() === 'mentor')
166071
+ return 'Agent';
166072
+ return stripped;
166073
+ }
166074
+ function getAuthURLExtension(authURL) {
166075
+ try {
166076
+ const { hostname } = new URL(authURL);
166077
+ const parts = hostname.split('.');
166078
+ if (parts.length > 2)
166079
+ parts.shift();
166080
+ return parts.join('.');
166081
+ }
166082
+ catch (_a) {
166083
+ return '';
166084
+ }
166085
+ }
166086
+ function buildOnSuccessfulPaymentUrl({ authURL, itemType, itemId, platformKey, isCustom, customProductUrl, }) {
166087
+ if (isCustom) {
166088
+ const trimmed = customProductUrl === null || customProductUrl === void 0 ? void 0 : customProductUrl.trim();
166089
+ return trimmed || undefined;
166090
+ }
166091
+ const ext = getAuthURLExtension(authURL);
166092
+ if (!ext)
166093
+ return undefined;
166094
+ const normalized = itemType.toLowerCase();
166095
+ if (normalized === 'mentor' || normalized === 'agent') {
166096
+ return `https://mentorai.${ext}/platform/${platformKey}/${itemId}`;
166097
+ }
166098
+ if (normalized === 'course') {
166099
+ return `https://skillsai.${ext}/courses/${itemId}`;
166100
+ }
166101
+ if (normalized === 'program') {
166102
+ return `https://skillsai.${ext}/programs/${itemId}`;
166103
+ }
166104
+ return undefined;
166105
+ }
166106
+
166107
+ function ItemSearchDropdown({ platformKey, onSelect, }) {
166108
+ var _a, _b, _c;
166109
+ const [searchQuery, setSearchQuery] = useState('');
166110
+ const [isOpen, setIsOpen] = useState(false);
166111
+ const dropdownRef = useRef(null);
166112
+ const debouncedSearch = useDebounce(searchQuery, 300);
166113
+ // Mentor search
166114
+ const { data: mentors, isFetching: isFetchingMentors } = useGetAiSearchMentorsQuery({
166115
+ platform_key: platformKey,
166116
+ query: debouncedSearch || undefined,
166117
+ limit: 6,
166118
+ include_main_public_mentors: false,
166119
+ }, { skip: !platformKey });
166120
+ // Course and program search
166121
+ const { data: coursesData, isFetching: isFetchingCourses } = useGetPersonnalizedSearchQuery([
166122
+ {
166123
+ username: getUserName$1(),
166124
+ content: ['courses', 'programs'],
166125
+ tenant: platformKey,
166126
+ query: debouncedSearch || '',
166127
+ returnItems: false,
166128
+ returnFacet: false,
166129
+ allowSkillSearch: false,
166130
+ limit: 6,
166131
+ },
166132
+ ]);
166133
+ const isFetching = isFetchingMentors || isFetchingCourses;
166134
+ // Normalize and merge results
166135
+ const mentorItems = ((_a = mentors === null || mentors === void 0 ? void 0 : mentors.results) !== null && _a !== void 0 ? _a : []).map((m) => {
166136
+ var _a;
166137
+ return ({
166138
+ itemType: 'mentor',
166139
+ id: (_a = m.unique_id) !== null && _a !== void 0 ? _a : '',
166140
+ name: m.name,
166141
+ badge: m.slug,
166142
+ });
166143
+ });
166144
+ const courseItems = ((_b = coursesData === null || coursesData === void 0 ? void 0 : coursesData.results) !== null && _b !== void 0 ? _b : [])
166145
+ .filter((item) => item.type === 'course')
166146
+ .map((item) => {
166147
+ var _a, _b, _c, _d, _e, _f;
166148
+ return ({
166149
+ itemType: 'course',
166150
+ 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 : '',
166151
+ name: (_f = (_e = item.data) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : '',
166152
+ });
166153
+ });
166154
+ const programItems = ((_c = coursesData === null || coursesData === void 0 ? void 0 : coursesData.results) !== null && _c !== void 0 ? _c : [])
166155
+ .filter((item) => item.type === 'program')
166156
+ .map((item) => {
166157
+ var _a, _b, _c, _d, _e, _f;
166158
+ return ({
166159
+ itemType: 'program',
166160
+ 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 : '',
166161
+ name: (_f = (_e = item.data) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : '',
166162
+ });
166163
+ });
166164
+ const items = [...mentorItems, ...courseItems, ...programItems];
166165
+ // Close dropdown on outside click
166166
+ useEffect(() => {
166167
+ const handleClickOutside = (e) => {
166168
+ if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
166169
+ setIsOpen(false);
166170
+ }
166171
+ };
166172
+ document.addEventListener('mousedown', handleClickOutside);
166173
+ return () => document.removeEventListener('mousedown', handleClickOutside);
166174
+ }, []);
166175
+ 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) => {
166176
+ setSearchQuery(e.target.value);
166177
+ setIsOpen(true);
166178
+ }, 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: () => {
166179
+ onSelect(item.itemType, item.id, item.name);
166180
+ setSearchQuery('');
166181
+ setIsOpen(false);
166182
+ }, 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" })) }))] }));
166183
+ }
166184
+
166185
+ function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
166186
+ const [page, setPage] = useState(1);
166187
+ const [statusFilter, setStatusFilter] = useState('all');
166188
+ const { data: paywalls, isLoading } = useListPaywallsQuery({
166189
+ platform_key: platformKey,
166190
+ page,
166191
+ page_size: 8,
166192
+ ...(statusFilter !== 'all' && { is_enabled: statusFilter === 'active' }),
166193
+ }, { refetchOnMountOrArgChange: true });
166194
+ 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) => {
166195
+ setStatusFilter(v);
166196
+ setPage(1);
166197
+ }, 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) => {
166198
+ var _a;
166199
+ 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 &&
166200
+ (() => {
166201
+ const activeCount = pw.prices.filter((p) => p.is_active).length;
166202
+ return activeCount > 0 ? (jsxs("span", { className: "text-xs text-gray-400", children: [activeCount, " price", activeCount !== 1 ? 's' : ''] })) : null;
166203
+ })()] })] }) }), jsx(Badge, { className: pw.is_enabled
166204
+ ? 'bg-blue-100 text-blue-700 border-blue-200 hover:bg-blue-100'
166205
+ : '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}`));
166206
+ }), (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'
166207
+ ? `No ${statusFilter} items found.`
166208
+ : 'No items configured yet. Search and select an agent above.' }))] })] }));
166209
+ }
166210
+
166017
166211
  const EMPTY_FORM = {
166018
166212
  name: '',
166019
166213
  amount: '',
@@ -166167,194 +166361,183 @@ function PriceManagement({ platformKey, itemType, itemId }) {
166167
166361
  }) })) : (jsx("p", { className: "text-xs text-gray-400 text-center py-4", children: "No pricing tiers yet. Add one to start accepting payments." }))] }));
166168
166362
  }
166169
166363
 
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.' }))] })] }));
166364
+ function WizardStepIndicator({ steps, currentStep, onStepClick, }) {
166365
+ const currentIndex = steps.findIndex((s) => s.key === currentStep);
166366
+ return (jsx("div", { className: "flex items-center w-full mb-4", children: steps.map((step, i) => {
166367
+ const isClickable = !!onStepClick;
166368
+ 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
166369
+ ? 'text-blue-500'
166370
+ : i === currentIndex
166371
+ ? 'text-gray-900 dark:text-gray-100'
166372
+ : 'text-gray-400'}`, children: [jsx("span", { className: `flex items-center justify-center w-5 h-5 rounded-full text-[10px] font-semibold ${i < currentIndex
166373
+ ? 'bg-blue-100 text-blue-600'
166374
+ : i === currentIndex
166375
+ ? 'bg-blue-500 text-white'
166376
+ : '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));
166377
+ }) }));
166270
166378
  }
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();
166379
+
166380
+ function PaywallDetail({ platformKey, authURL, itemType, itemId, itemName, isCustom, onBack, }) {
166381
+ const { data: config, isLoading, refetch: refetchConfig, } = useGetPaywallConfigQuery({ platform_key: platformKey, item_type: itemType, item_id: itemId }, { refetchOnMountOrArgChange: true, skip: isCustom });
166382
+ const [enablePaywall, { isLoading: isCreating }] = useEnablePaywallMutation();
166383
+ const [updatePaywall, { isLoading: isUpdating }] = useUpdatePaywallMutation();
166384
+ const isSaving = isCreating || isUpdating;
166385
+ // Wizard step
166386
+ const [currentStep, setCurrentStep] = useState(isCustom ? 'custom-item' : 'paywall');
166387
+ // Track whether the item has been created (custom flow) or already exists (non-custom)
166388
+ const [itemCreated, setItemCreated] = useState(!isCustom);
166276
166389
  const [isEnabled, setIsEnabled] = useState(false);
166277
166390
  const [allowFreeTier, setAllowFreeTier] = useState(false);
166278
166391
  const [trialDays, setTrialDays] = useState(0);
166279
166392
  const [grandfathering, setGrandfathering] = useState('free_forever');
166393
+ // Custom item fields
166394
+ const [customItemType, setCustomItemType] = useState('');
166395
+ const [customItemName, setCustomItemName] = useState('');
166396
+ const [customDescription, setCustomDescription] = useState('');
166397
+ const [customProductUrl, setCustomProductUrl] = useState('');
166398
+ // Resolved item params (updated after custom item creation)
166399
+ const [resolvedItemType, setResolvedItemType] = useState(itemType);
166400
+ const [resolvedItemId, setResolvedItemId] = useState(itemId);
166401
+ const [paywallUniqueId, setPaywallUniqueId] = useState(null);
166402
+ // Copy URL state
166403
+ const [copied, setCopied] = useState(false);
166404
+ const copyTimerRef = useRef(null);
166405
+ const handleCopyUrl = async () => {
166406
+ /* istanbul ignore next: button is not rendered without paywallUniqueId */
166407
+ if (!paywallUniqueId)
166408
+ return;
166409
+ const basePath = authURL.endsWith('/') ? authURL : `${authURL}/`;
166410
+ const url = `${basePath}buy/${paywallUniqueId}`;
166411
+ await navigator.clipboard.writeText(url);
166412
+ toast.success('URL copied to clipboard');
166413
+ setCopied(true);
166414
+ if (copyTimerRef.current)
166415
+ clearTimeout(copyTimerRef.current);
166416
+ copyTimerRef.current = setTimeout(() => setCopied(false), 2500);
166417
+ };
166418
+ useEffect(() => {
166419
+ return () => {
166420
+ if (copyTimerRef.current)
166421
+ clearTimeout(copyTimerRef.current);
166422
+ };
166423
+ }, []);
166280
166424
  useEffect(() => {
166281
166425
  if (config) {
166282
166426
  setIsEnabled(config.is_enabled);
166283
166427
  setAllowFreeTier(config.allow_free_tier);
166284
166428
  setTrialDays(config.trial_period_days);
166285
166429
  setGrandfathering(config.grandfathering_strategy);
166430
+ setPaywallUniqueId(config.unique_id);
166286
166431
  }
166287
166432
  }, [config]);
166288
- const handleTogglePaywall = async (enabled) => {
166433
+ const wizardSteps = [
166434
+ ...(isCustom ? [{ key: 'custom-item', label: 'Item Details' }] : []),
166435
+ { key: 'paywall', label: 'Paywall' },
166436
+ { key: 'pricing', label: 'Pricing' },
166437
+ ];
166438
+ const displayName = isCustom
166439
+ ? customItemName || 'New Custom Item'
166440
+ : (config === null || config === void 0 ? void 0 : config.item_name) || itemName || itemId;
166441
+ const handleCreateCustomItem = async () => {
166442
+ /* istanbul ignore next: Create button is disabled when either field is empty */
166443
+ if (!customItemType.trim() || !customItemName.trim()) {
166444
+ toast.error('Item type and item name are required');
166445
+ return;
166446
+ }
166289
166447
  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();
166448
+ const sluggedType = slugify(customItemType);
166449
+ const sluggedId = slugify(customItemName);
166450
+ const result = await enablePaywall({
166451
+ platform_key: platformKey,
166452
+ item_type: sluggedType,
166453
+ item_id: sluggedId,
166454
+ is_enabled: false,
166455
+ allow_free_tier: false,
166456
+ trial_period_days: 0,
166457
+ grandfathering_strategy: 'free_forever',
166458
+ item_name: customItemName,
166459
+ description: customDescription,
166460
+ on_successful_payment: buildOnSuccessfulPaymentUrl({
166461
+ authURL,
166462
+ itemType: sluggedType,
166463
+ itemId: sluggedId,
166464
+ platformKey,
166465
+ isCustom: true,
166466
+ customProductUrl,
166467
+ }),
166468
+ }).unwrap();
166469
+ toast.success('Custom item created');
166470
+ setResolvedItemType(sluggedType);
166471
+ setResolvedItemId(sluggedId);
166472
+ setPaywallUniqueId(result.unique_id);
166473
+ setItemCreated(true);
166474
+ setCurrentStep('paywall');
166312
166475
  }
166313
166476
  catch (_a) {
166314
- toast.error(`Failed to ${enabled ? 'enable' : 'disable'} paywall`);
166477
+ toast.error('Failed to create custom item');
166315
166478
  }
166316
166479
  };
166317
166480
  const handleSaveConfig = async () => {
166318
166481
  try {
166319
- await enablePaywall({
166482
+ const mutate = itemCreated ? updatePaywall : enablePaywall;
166483
+ await mutate({
166320
166484
  platform_key: platformKey,
166321
- item_type: itemType,
166322
- item_id: itemId,
166485
+ item_type: resolvedItemType,
166486
+ item_id: resolvedItemId,
166323
166487
  is_enabled: isEnabled,
166324
166488
  allow_free_tier: allowFreeTier,
166325
166489
  trial_period_days: trialDays,
166326
166490
  grandfathering_strategy: grandfathering,
166491
+ // TODO: remove item_name once the backend fixes the 400 when updating custom items
166492
+ item_name: displayName,
166493
+ on_successful_payment: buildOnSuccessfulPaymentUrl({
166494
+ authURL,
166495
+ itemType: resolvedItemType,
166496
+ itemId: resolvedItemId,
166497
+ platformKey,
166498
+ isCustom,
166499
+ customProductUrl,
166500
+ }),
166327
166501
  }).unwrap();
166328
- toast.success('Paywall configuration updated');
166329
- refetchConfig();
166502
+ toast.success('Paywall configuration saved');
166503
+ if (!isCustom)
166504
+ refetchConfig();
166505
+ setCurrentStep('pricing');
166330
166506
  }
166331
166507
  catch (_a) {
166332
- toast.error('Failed to update paywall configuration');
166508
+ toast.error('Failed to save paywall configuration');
166333
166509
  }
166334
166510
  };
166335
- if (isLoading) {
166511
+ if (!isCustom && isLoading) {
166336
166512
  return (jsxs("div", { className: "space-y-4", children: [jsx(Skeleton, { className: "h-8 w-48" }), jsx(Skeleton, { className: "h-64 w-full" })] }));
166337
166513
  }
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 }))] }));
166514
+ 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
166515
+ ? setCurrentStep
166516
+ : (step) => {
166517
+ // During creation, only allow navigating back to already-completed steps
166518
+ const targetIndex = wizardSteps.findIndex((s) => s.key === step);
166519
+ const currentIndex = wizardSteps.findIndex((s) => s.key === currentStep);
166520
+ if (targetIndex < currentIndex)
166521
+ setCurrentStep(step);
166522
+ } }), 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
166523
  }
166341
- // ── Main Export ──
166342
- function PaywallConfig({ platformKey, disabled }) {
166524
+
166525
+ function PaywallConfig({ platformKey, authURL, disabled }) {
166343
166526
  const [selectedItem, setSelectedItem] = useState(null);
166344
166527
  if (disabled) {
166345
166528
  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
166529
  }
166347
166530
  if (selectedItem) {
166348
- return (jsx(PaywallDetail, { platformKey: platformKey, itemType: selectedItem.type, itemId: selectedItem.id, itemName: selectedItem.name, onBack: () => setSelectedItem(null) }));
166531
+ return (jsx(PaywallDetail, { platformKey: platformKey, authURL: authURL, itemType: selectedItem.type, itemId: selectedItem.id, itemName: selectedItem.name, isCustom: selectedItem.isCustom, onBack: () => setSelectedItem(null) }));
166349
166532
  }
166350
- return (jsx(PaywalledItemsList, { platformKey: platformKey, onSelectItem: (type, id, name) => setSelectedItem({ type, id, name }) }));
166533
+ return (jsx(PaywalledItemsList, { platformKey: platformKey, onSelectItem: (type, id, name) => setSelectedItem({ type, id, name }), onAddCustomItem: () => setSelectedItem({ type: '', id: '', name: '', isCustom: true }) }));
166351
166534
  }
166352
166535
 
166353
- function MonetizationTab({ platformKey }) {
166536
+ function MonetizationTab({ platformKey, authURL }) {
166354
166537
  var _a;
166355
166538
  const { data: stripeStatus } = useGetStripeConnectStatusQuery({ platform_key: platformKey }, { refetchOnMountOrArgChange: true });
166356
166539
  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 })] }));
166540
+ 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
166541
  }
166359
166542
 
166360
166543
  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, }) {
@@ -166448,7 +166631,7 @@ function Account({ tenant, tenants = [], username, onInviteClick, email, mainPla
166448
166631
  : '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
166632
  overflowY: 'auto',
166450
166633
  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, {})] }));
166634
+ }, 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, authURL: authURL })), activeTab === 'advanced' && (jsx(AdvancedTab, { platformKey: tenant, currentSPA: currentSPA, username: username, authURL: authURL, currentPlatformBaseDomain: currentPlatformBaseDomain }))] })] }), jsx(ToastProvider, {})] }));
166452
166635
  }
166453
166636
 
166454
166637
  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.9",
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.4",
65
+ "@iblai/web-containers": "1.6.10",
66
+ "@iblai/mcp": "1.4.7",
67
+ "@iblai/web-utils": "1.6.6"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "@radix-ui/react-dialog": "^1.1.7",