@iblai/iblai-js 1.25.3 → 1.26.0

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.
@@ -52891,7 +52891,7 @@ function useCallbackRef$1(initialValue, callback) {
52891
52891
  return ref.facade;
52892
52892
  }
52893
52893
 
52894
- var useIsomorphicLayoutEffect$2 = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
52894
+ var useIsomorphicLayoutEffect$3 = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
52895
52895
  var currentValues = new WeakMap();
52896
52896
  /**
52897
52897
  * Merges two or more refs together providing a single interface to set their value
@@ -52912,7 +52912,7 @@ function useMergeRefs(refs, defaultValue) {
52912
52912
  return refs.forEach(function (ref) { return assignRef(ref, newValue); });
52913
52913
  });
52914
52914
  // handle refs changes - added or removed
52915
- useIsomorphicLayoutEffect$2(function () {
52915
+ useIsomorphicLayoutEffect$3(function () {
52916
52916
  var oldValue = currentValues.get(callbackRef);
52917
52917
  if (oldValue) {
52918
52918
  var prevRefs_1 = new Set(oldValue);
@@ -59731,6 +59731,7 @@ var advancePagination$3 = {
59731
59731
  var advancedAdvanced$3 = {
59732
59732
  failedToUpdateSetting: "Failed to update setting",
59733
59733
  settingUpdatedSuccessfully: "Setting updated successfully",
59734
+ save: "Save",
59734
59735
  agentSettingUpdatedSuccessfully: "Agent setting updated successfully",
59735
59736
  chatAreaSizeUpdatedSuccessfully: "Chat area size updated successfully",
59736
59737
  moreInfoAbout: "More info about {label}",
@@ -62308,7 +62309,8 @@ var modalsPaywallModal$3 = {
62308
62309
  subscribeToGetAccess: "Subscribe to get access to {itemName}",
62309
62310
  redirecting: "Redirecting...",
62310
62311
  pay: "Pay",
62311
- thisIncludes: "This includes:"
62312
+ thisIncludes: "This includes:",
62313
+ secureCheckout: "Secure checkout"
62312
62314
  };
62313
62315
  var modalsPromptGalleryModal$3 = {
62314
62316
  promptGallery: "Prompt Gallery",
@@ -65110,6 +65112,7 @@ var advancePagination$2 = {
65110
65112
  var advancedAdvanced$2 = {
65111
65113
  failedToUpdateSetting: "Échec de la mise à jour du paramètre",
65112
65114
  settingUpdatedSuccessfully: "Paramètre mis à jour avec succès",
65115
+ save: "Enregistrer",
65113
65116
  agentSettingUpdatedSuccessfully: "Paramètre de l'agent mis à jour avec succès",
65114
65117
  chatAreaSizeUpdatedSuccessfully: "Taille de la zone de discussion mise à jour avec succès",
65115
65118
  moreInfoAbout: "Plus d'informations sur {label}",
@@ -67687,7 +67690,8 @@ var modalsPaywallModal$2 = {
67687
67690
  subscribeToGetAccess: "Abonnez-vous pour accéder à {itemName}",
67688
67691
  redirecting: "Redirection en cours...",
67689
67692
  pay: "Payer",
67690
- thisIncludes: "Cela comprend :"
67693
+ thisIncludes: "Cela comprend :",
67694
+ secureCheckout: "Paiement sécurisé"
67691
67695
  };
67692
67696
  var modalsPromptGalleryModal$2 = {
67693
67697
  promptGallery: "Galerie d'invites",
@@ -70489,6 +70493,7 @@ var advancePagination$1 = {
70489
70493
  var advancedAdvanced$1 = {
70490
70494
  failedToUpdateSetting: "Error al actualizar la configuración",
70491
70495
  settingUpdatedSuccessfully: "Configuración actualizada correctamente",
70496
+ save: "Guardar",
70492
70497
  agentSettingUpdatedSuccessfully: "Configuración del agente actualizada correctamente",
70493
70498
  chatAreaSizeUpdatedSuccessfully: "Tamaño del área de chat actualizado correctamente",
70494
70499
  moreInfoAbout: "Más información sobre {label}",
@@ -73066,7 +73071,8 @@ var modalsPaywallModal$1 = {
73066
73071
  subscribeToGetAccess: "Suscríbete para acceder a {itemName}",
73067
73072
  redirecting: "Redirigiendo...",
73068
73073
  pay: "Pagar",
73069
- thisIncludes: "Esto incluye:"
73074
+ thisIncludes: "Esto incluye:",
73075
+ secureCheckout: "Pago seguro"
73070
73076
  };
73071
73077
  var modalsPromptGalleryModal$1 = {
73072
73078
  promptGallery: "Galería de instrucciones",
@@ -75868,6 +75874,7 @@ var advancePagination = {
75868
75874
  var advancedAdvanced = {
75869
75875
  failedToUpdateSetting: "更新设置失败",
75870
75876
  settingUpdatedSuccessfully: "设置已成功更新",
75877
+ save: "保存",
75871
75878
  agentSettingUpdatedSuccessfully: "代理设置已成功更新",
75872
75879
  chatAreaSizeUpdatedSuccessfully: "聊天区域大小已成功更新",
75873
75880
  moreInfoAbout: "关于 {label} 的更多信息",
@@ -78445,7 +78452,8 @@ var modalsPaywallModal = {
78445
78452
  subscribeToGetAccess: "订阅以获取 {itemName} 的访问权限",
78446
78453
  redirecting: "正在跳转...",
78447
78454
  pay: "支付",
78448
- thisIncludes: "包含以下内容:"
78455
+ thisIncludes: "包含以下内容:",
78456
+ secureCheckout: "安全结账"
78449
78457
  };
78450
78458
  var modalsPromptGalleryModal = {
78451
78459
  promptGallery: "提示库",
@@ -83530,7 +83538,7 @@ function getOwnKeys(obj) {
83530
83538
  );
83531
83539
  }
83532
83540
 
83533
- const useIsomorphicLayoutEffect$1 = typeof window !== "undefined" ? useLayoutEffect : useEffect;
83541
+ const useIsomorphicLayoutEffect$2 = typeof window !== "undefined" ? useLayoutEffect : useEffect;
83534
83542
 
83535
83543
  function useField(opts) {
83536
83544
  const [fieldApi] = useState(() => {
@@ -83543,8 +83551,8 @@ function useField(opts) {
83543
83551
  extendedApi.Field = Field;
83544
83552
  return extendedApi;
83545
83553
  });
83546
- useIsomorphicLayoutEffect$1(fieldApi.mount, [fieldApi]);
83547
- useIsomorphicLayoutEffect$1(() => {
83554
+ useIsomorphicLayoutEffect$2(fieldApi.mount, [fieldApi]);
83555
+ useIsomorphicLayoutEffect$2(() => {
83548
83556
  fieldApi.update(opts);
83549
83557
  });
83550
83558
  useStore(
@@ -83603,9 +83611,9 @@ function useForm(opts) {
83603
83611
  };
83604
83612
  return extendedApi;
83605
83613
  });
83606
- useIsomorphicLayoutEffect$1(formApi.mount, []);
83614
+ useIsomorphicLayoutEffect$2(formApi.mount, []);
83607
83615
  useStore(formApi.store, (state) => state.isSubmitting);
83608
- useIsomorphicLayoutEffect$1(() => {
83616
+ useIsomorphicLayoutEffect$2(() => {
83609
83617
  formApi.update(opts);
83610
83618
  });
83611
83619
  return formApi;
@@ -138896,6 +138904,10 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
138896
138904
  : activeTab === 'experience' && experienceSubTab === 'resume'
138897
138905
  ? { onClick: handleAddResume, upload: true, ariaLabel: t('profileIndex.ariaAddResume') }
138898
138906
  : null;
138907
+ // Rendered inline on the sub-tabs row (education/experience/resume), pushed to
138908
+ // the far right. `headerAdd` already encodes which sub-tab is active, so this
138909
+ // only appears on the sub-tabs that support adding/uploading.
138910
+ const headerAddButton = headerAdd && (jsx(Button$1, { size: "icon", onClick: headerAdd.onClick, className: "text-gray-700 bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white flex-shrink-0", "aria-label": headerAdd.ariaLabel, children: headerAdd.upload ? jsx(Upload, { className: "h-4 w-4" }) : jsx(Plus, { className: "h-4 w-4" }) }));
138899
138911
  const tabDescription = (id) => {
138900
138912
  const key = (isReadOnly && TAB_DESC_PREVIEW_KEYS[id]) || TAB_DESC_KEYS[id];
138901
138913
  return key ? t(`profileIndex.${key}`) : '';
@@ -138910,10 +138922,10 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
138910
138922
  ? 'bg-blue-50 text-blue-700 font-medium'
138911
138923
  : 'hover:bg-gray-50 text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100'}`, children: [jsx(tab.renderIcon, { className: "h-5 w-5 mr-3 flex-shrink-0", "aria-hidden": "true" }), jsx("span", { className: "truncate", children: tab.label })] }, tab.id))) }) }) })] }), jsx("nav", { className: "lg:hidden", "aria-label": t('profileIndex.ariaProfileTabsMobile'), children: jsx("div", { className: "w-full justify-start px-6 py-2 bg-white border-b border-gray-200 rounded-none h-auto overflow-x-auto", children: jsx("div", { className: "flex space-x-2", role: "tablist", "aria-orientation": "horizontal", children: TABS.map((tab) => (jsxs("button", { role: "tab", "aria-selected": activeTab === tab.id, "aria-controls": `${tab.id}-tabpanel`, id: `${tab.id}-tab-mobile`, onClick: () => setActiveTab(tab.id), className: `flex items-center gap-2 px-3 py-2 rounded-lg whitespace-nowrap text-sm transition-all ${activeTab === tab.id
138912
138924
  ? 'bg-blue-50 text-blue-600 font-medium'
138913
- : 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(tab.renderIcon, { className: "h-4 w-4", "aria-hidden": "true" }), jsx("span", { className: "hidden sm:inline", children: tab.label }), jsx("span", { className: "sm:hidden", children: tab.label })] }, tab.id))) }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsx("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_f = (_e = TABS.find((t) => t.id === activeTab)) === null || _e === void 0 ? void 0 : _e.label) !== null && _f !== void 0 ? _f : activeTab }), jsx("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: tabDescription(activeTab) })] }), headerAdd && (jsx(Button$1, { size: "icon", onClick: headerAdd.onClick, className: "text-gray-700 bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white mr-4", "aria-label": headerAdd.ariaLabel, children: headerAdd.upload ? jsx(Upload, { className: "h-4 w-4" }) : jsx(Plus, { className: "h-4 w-4" }) }))] }) }), jsxs("div", { className: "flex-1 p-6 space-y-6", style: {
138925
+ : 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(tab.renderIcon, { className: "h-4 w-4", "aria-hidden": "true" }), jsx("span", { className: "hidden sm:inline", children: tab.label }), jsx("span", { className: "sm:hidden", children: tab.label })] }, tab.id))) }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsx("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: jsx("div", { className: "flex items-center justify-between", children: jsxs("div", { children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_f = (_e = TABS.find((t) => t.id === activeTab)) === null || _e === void 0 ? void 0 : _e.label) !== null && _f !== void 0 ? _f : activeTab }), jsx("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: tabDescription(activeTab) })] }) }) }), jsxs("div", { className: "flex-1 p-6 space-y-6", style: {
138914
138926
  overflowY: 'auto',
138915
138927
  overflowX: 'hidden',
138916
- }, role: "tabpanel", id: `${activeTab}-tabpanel`, "aria-labelledby": `${activeTab}-tab`, tabIndex: 0, children: [jsx("div", { className: "lg:hidden mb-6", children: jsxs("div", { className: "flex flex-row items-center sm:justify-between gap-3", children: [jsxs("div", { children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_h = (_g = TABS.find((t) => t.id === activeTab)) === null || _g === void 0 ? void 0 : _g.label) !== null && _h !== void 0 ? _h : activeTab }), jsx("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: tabDescription(activeTab) })] }), headerAdd && (jsx(Button$1, { size: "icon", onClick: headerAdd.onClick, className: "text-gray-700 bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", "aria-label": headerAdd.ariaLabel, children: headerAdd.upload ? jsx(Upload, { className: "h-4 w-4" }) : jsx(Plus, { className: "h-4 w-4" }) }))] }) }), activeTab === 'basic' && (jsx("div", { className: "space-y-6", children: jsxs("form", { onSubmit: (formEvent) => {
138928
+ }, role: "tabpanel", id: `${activeTab}-tabpanel`, "aria-labelledby": `${activeTab}-tab`, tabIndex: 0, children: [jsx("div", { className: "lg:hidden mb-6", children: jsx("div", { className: "flex flex-row items-center sm:justify-between gap-3", children: jsxs("div", { children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_h = (_g = TABS.find((t) => t.id === activeTab)) === null || _g === void 0 ? void 0 : _g.label) !== null && _h !== void 0 ? _h : activeTab }), jsx("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: tabDescription(activeTab) })] }) }) }), activeTab === 'basic' && (jsx("div", { className: "space-y-6", children: jsxs("form", { onSubmit: (formEvent) => {
138917
138929
  formEvent.preventDefault();
138918
138930
  formEvent.stopPropagation();
138919
138931
  if (isReadOnly)
@@ -138988,7 +139000,7 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
138988
139000
  var _a;
138989
139001
  return (jsxs(Fragment$1, { children: [jsxs("div", { className: "relative mb-0", children: [jsx("div", { className: "absolute inset-y-0 left-4 flex items-center pointer-events-none", "aria-hidden": "true", children: jsx("div", { className: "bg-black text-white rounded w-8 h-8 flex items-center justify-center", children: jsx("span", { className: "font-bold text-sm", children: "X" }) }) }), jsx(Input, { id: "x", className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-base py-3 pl-16 h-10", placeholder: t('profileIndex.placeholderX'), value: field.state.value, onChange: (e) => handleSocialLinkChange(e.target.value, field.handleChange, X_URL_PREFIX), disabled: socialForm.state.isSubmitting || isReadOnly })] }), jsx("p", { className: "text-red-500 dark:text-gray-400 text-sm", role: ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) ? 'alert' : undefined, "aria-live": "polite", children: field.state.meta.errors })] }));
138990
139002
  },
138991
- })] })] }) })), activeTab === 'education' && (jsxs(Tabs, { value: educationSubTab, onValueChange: setEducationSubTab, className: "space-y-4", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "education", children: t('profileIndex.tabEducation') }), jsx(TabsTrigger, { value: "credentials", children: t('gradebookGradebookTab.typeCredentials') }), jsx(TabsTrigger, { value: "skills", children: t('gradebookGradebookTab.typeSkills') })] }), jsx(TabsContent, { value: "education", children: jsx(EducationTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "credentials", children: jsx(CredentialsList, { org: tenant, username: username }) }), jsx(TabsContent, { value: "skills", children: jsx(SkillsList, { org: tenant, username: username }) })] })), activeTab === 'gradebook' && jsx(GradebookTab, { org: tenant, username: username }), activeTab === 'experience' && (jsxs(Tabs, { value: experienceSubTab, onValueChange: setExperienceSubTab, className: "space-y-4", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "experience", children: t('profileIndex.tabExperience') }), jsx(TabsTrigger, { value: "resume", children: t('profileIndex.tabResume') })] }), jsx(TabsContent, { value: "experience", children: jsx(ExperienceTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "resume", children: jsx(ResumeTab, { org: tenant, username: username }) })] })), activeTab === 'purchases' && jsx(PurchasesTab, { org: tenant, username: username }), activeTab === 'memory' && jsx(MemoryTab, { org: tenant, username: username }), activeTab === 'privacy' && jsx(ChatPrivacyTab, { org: tenant, username: username }), !isReadOnly && activeTab === 'security' && (jsx(Security, { app: currentSPA || '', email: (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email) || '', platformKey: tenant, onAccountDeleted: onAccountDeleted })), activeTab === 'advanced' && (localLLMProps || systemControlProps) && (jsxs("div", { className: "space-y-6", children: [localLLMProps && (jsx(LocalModelsContent, { isAvailable: localLLMProps.isAvailable, state: localLLMProps.state, ollamaStatus: localLLMProps.ollamaStatus, systemMemory: localLLMProps.systemMemory, isUsingFoundry: localLLMProps.isUsingFoundry, foundryModels: localLLMProps.foundryModels, selectedFoundryModel: localLLMProps.selectedFoundryModel, foundryStatus: localLLMProps.foundryStatus, onStartDownload: localLLMProps.onStartDownload, onCancelDownload: localLLMProps.onCancelDownload, onInstallOllama: localLLMProps.onInstallOllama, onStopManager: localLLMProps.onStopManager, onInstallFoundry: localLLMProps.onInstallFoundry, onCheckStatus: localLLMProps.onCheckStatus, onResetState: localLLMProps.onResetState, onSelectFoundryModel: localLLMProps.onSelectFoundryModel })), systemControlProps && (jsx(SystemControlContent, { isAvailable: systemControlProps.isAvailable, state: systemControlProps.state, status: systemControlProps.status, requiredSizeGb: systemControlProps.requiredSizeGb, ollamaStatus: systemControlProps.ollamaStatus, systemMemory: systemControlProps.systemMemory, accessibilityPermission: systemControlProps.accessibilityPermission, onInstall: systemControlProps.onInstall, onStop: systemControlProps.onStop, onCheckStatus: systemControlProps.onCheckStatus, onResetState: systemControlProps.onResetState, onRequestAccessibilityPermission: systemControlProps.onRequestAccessibilityPermission, onDownloadModel: systemControlProps.onDownloadModel }))] }))] }), !isReadOnly && ['basic', 'social'].includes(activeTab) && (jsx("div", { className: "flex-shrink-0 border-t border-gray-200 p-6 bg-white dark:bg-gray-900", children: jsxs("div", { className: "flex justify-end gap-3", children: [jsx(Button$1, { onClick: onClose, variant: "outline", children: t('profileIndex.buttonCancel') }), jsx(Button$1, { onClick: () => {
139003
+ })] })] }) })), activeTab === 'education' && (jsxs(Tabs, { value: educationSubTab, onValueChange: setEducationSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "education", children: t('profileIndex.tabEducation') }), jsx(TabsTrigger, { value: "credentials", children: t('gradebookGradebookTab.typeCredentials') }), jsx(TabsTrigger, { value: "skills", children: t('gradebookGradebookTab.typeSkills') })] }), headerAddButton] }), jsx(TabsContent, { value: "education", children: jsx(EducationTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "credentials", children: jsx(CredentialsList, { org: tenant, username: username }) }), jsx(TabsContent, { value: "skills", children: jsx(SkillsList, { org: tenant, username: username }) })] })), activeTab === 'gradebook' && jsx(GradebookTab, { org: tenant, username: username }), activeTab === 'experience' && (jsxs(Tabs, { value: experienceSubTab, onValueChange: setExperienceSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "experience", children: t('profileIndex.tabExperience') }), jsx(TabsTrigger, { value: "resume", children: t('profileIndex.tabResume') })] }), headerAddButton] }), jsx(TabsContent, { value: "experience", children: jsx(ExperienceTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "resume", children: jsx(ResumeTab, { org: tenant, username: username }) })] })), activeTab === 'purchases' && jsx(PurchasesTab, { org: tenant, username: username }), activeTab === 'memory' && jsx(MemoryTab, { org: tenant, username: username }), activeTab === 'privacy' && jsx(ChatPrivacyTab, { org: tenant, username: username }), !isReadOnly && activeTab === 'security' && (jsx(Security, { app: currentSPA || '', email: (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email) || '', platformKey: tenant, onAccountDeleted: onAccountDeleted })), activeTab === 'advanced' && (localLLMProps || systemControlProps) && (jsxs("div", { className: "space-y-6", children: [localLLMProps && (jsx(LocalModelsContent, { isAvailable: localLLMProps.isAvailable, state: localLLMProps.state, ollamaStatus: localLLMProps.ollamaStatus, systemMemory: localLLMProps.systemMemory, isUsingFoundry: localLLMProps.isUsingFoundry, foundryModels: localLLMProps.foundryModels, selectedFoundryModel: localLLMProps.selectedFoundryModel, foundryStatus: localLLMProps.foundryStatus, onStartDownload: localLLMProps.onStartDownload, onCancelDownload: localLLMProps.onCancelDownload, onInstallOllama: localLLMProps.onInstallOllama, onStopManager: localLLMProps.onStopManager, onInstallFoundry: localLLMProps.onInstallFoundry, onCheckStatus: localLLMProps.onCheckStatus, onResetState: localLLMProps.onResetState, onSelectFoundryModel: localLLMProps.onSelectFoundryModel })), systemControlProps && (jsx(SystemControlContent, { isAvailable: systemControlProps.isAvailable, state: systemControlProps.state, status: systemControlProps.status, requiredSizeGb: systemControlProps.requiredSizeGb, ollamaStatus: systemControlProps.ollamaStatus, systemMemory: systemControlProps.systemMemory, accessibilityPermission: systemControlProps.accessibilityPermission, onInstall: systemControlProps.onInstall, onStop: systemControlProps.onStop, onCheckStatus: systemControlProps.onCheckStatus, onResetState: systemControlProps.onResetState, onRequestAccessibilityPermission: systemControlProps.onRequestAccessibilityPermission, onDownloadModel: systemControlProps.onDownloadModel }))] }))] }), !isReadOnly && ['basic', 'social'].includes(activeTab) && (jsx("div", { className: "flex-shrink-0 border-t border-gray-200 p-6 bg-white dark:bg-gray-900", children: jsxs("div", { className: "flex justify-end gap-3", children: [jsx(Button$1, { onClick: onClose, variant: "outline", children: t('profileIndex.buttonCancel') }), jsx(Button$1, { onClick: () => {
138992
139004
  if (activeTab === 'basic') {
138993
139005
  basicForm.handleSubmit();
138994
139006
  }
@@ -148987,26 +148999,19 @@ const ChatPrivacyContent = ({ platformKey, username }) => {
148987
148999
  };
148988
149000
 
148989
149001
  function StringSettingInput({ value, defaultValue, disabled, onSave, }) {
148990
- const [localValue, setLocalValue] = useState(value || defaultValue);
148991
- const debounceRef = useRef(null);
149002
+ const t = useT();
149003
+ const savedValue = value || defaultValue;
149004
+ const [localValue, setLocalValue] = useState(savedValue);
148992
149005
  useEffect(() => {
148993
- setLocalValue(value || defaultValue);
148994
- }, [value, defaultValue]);
148995
- const handleChange = (newValue) => {
148996
- setLocalValue(newValue);
148997
- if (debounceRef.current)
148998
- clearTimeout(debounceRef.current);
148999
- debounceRef.current = setTimeout(() => {
149000
- onSave(newValue);
149001
- }, 800);
149006
+ setLocalValue(savedValue);
149007
+ }, [savedValue]);
149008
+ const isDirty = localValue !== savedValue;
149009
+ const handleSave = () => {
149010
+ if (!isDirty || disabled)
149011
+ return;
149012
+ onSave(localValue);
149002
149013
  };
149003
- useEffect(() => {
149004
- return () => {
149005
- if (debounceRef.current)
149006
- clearTimeout(debounceRef.current);
149007
- };
149008
- }, []);
149009
- 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" }))] }));
149014
+ return (jsxs("div", { className: "flex items-center gap-2", children: [isDirty && (jsx(Button$1, { type: "button", size: "sm", onClick: handleSave, disabled: disabled, className: "h-8 bg-blue-500 hover:bg-blue-600 text-white", children: t('advancedAdvanced.save') })), jsx(Input, { value: localValue, onChange: (e) => setLocalValue(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" }))] }));
149010
149015
  }
149011
149016
  function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatformBaseDomain, }) {
149012
149017
  const t = useT();
@@ -149052,6 +149057,7 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
149052
149057
  'overall_default_mentor',
149053
149058
  'help_center_url',
149054
149059
  'monetization_base_path',
149060
+ 'skills_welcome_tagline',
149055
149061
  ];
149056
149062
  const configurableMetadatas = allMetadatas.filter((metadata) => (typeof metadata.defaultValue === 'boolean' ||
149057
149063
  (typeof metadata.defaultValue === 'string' &&
@@ -169827,7 +169833,7 @@ var EditorContentWithKey = forwardRef(
169827
169833
  }
169828
169834
  );
169829
169835
  var EditorContent = React__default.memo(EditorContentWithKey);
169830
- var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
169836
+ var useIsomorphicLayoutEffect$1 = typeof window !== "undefined" ? useLayoutEffect : useEffect;
169831
169837
  var EditorStateManager = class {
169832
169838
  constructor(initialEditor) {
169833
169839
  this.transactionNumber = 0;
@@ -169895,7 +169901,7 @@ function useEditorState(options) {
169895
169901
  options.selector,
169896
169902
  (_a = options.equalityFn) != null ? _a : deepEqual
169897
169903
  );
169898
- useIsomorphicLayoutEffect(() => {
169904
+ useIsomorphicLayoutEffect$1(() => {
169899
169905
  return editorStateManager.watch(options.editor);
169900
169906
  }, [options.editor, editorStateManager]);
169901
169907
  useDebugValue(selectedState);
@@ -223008,11 +223014,44 @@ function formatInterval(interval) {
223008
223014
  return '';
223009
223015
  return `/${interval}`;
223010
223016
  }
223017
+ // Avoids the SSR warning while still measuring/aligning before the browser paints.
223018
+ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
223011
223019
  function PaywallModal({ pricing, platformKey, itemId, itemType, open, onClose, closable = true, buttonClassName, }) {
223012
223020
  const t = useT();
223013
223021
  const [createCheckout, { isLoading: isCheckoutLoading }] = useCreateCheckoutMutation();
223014
223022
  const [selectedPriceId, setSelectedPriceId] = useState(null);
223015
223023
  const activePrices = pricing.prices;
223024
+ // Keep the title/description block the same height on every card (the tallest
223025
+ // one's height) so the price + Pay button below always line up, regardless of
223026
+ // how long each plan's title or description is.
223027
+ const gridRef = useRef(null);
223028
+ const headerRefs = useRef([]);
223029
+ headerRefs.current.length = activePrices.length;
223030
+ const equalizeHeaderHeights = useCallback(() => {
223031
+ const headers = headerRefs.current.filter((el) => el != null && el.isConnected);
223032
+ // Reset first so we measure each header's natural height, not a stale value.
223033
+ headers.forEach((el) => {
223034
+ el.style.minHeight = '';
223035
+ });
223036
+ if (headers.length <= 1)
223037
+ return;
223038
+ const maxHeight = headers.reduce((max, el) => Math.max(max, el.offsetHeight), 0);
223039
+ headers.forEach((el) => {
223040
+ el.style.minHeight = `${maxHeight}px`;
223041
+ });
223042
+ }, []);
223043
+ useIsomorphicLayoutEffect(() => {
223044
+ if (!open)
223045
+ return;
223046
+ equalizeHeaderHeights();
223047
+ const grid = gridRef.current;
223048
+ if (!grid || typeof ResizeObserver === 'undefined')
223049
+ return;
223050
+ // Re-run when the grid resizes (viewport changes wrap the descriptions).
223051
+ const observer = new ResizeObserver(() => equalizeHeaderHeights());
223052
+ observer.observe(grid);
223053
+ return () => observer.disconnect();
223054
+ }, [open, activePrices, equalizeHeaderHeights]);
223016
223055
  const handleCheckout = async (price) => {
223017
223056
  setSelectedPriceId(price.id);
223018
223057
  try {
@@ -223032,16 +223071,35 @@ function PaywallModal({ pricing, platformKey, itemId, itemType, open, onClose, c
223032
223071
  setSelectedPriceId(null);
223033
223072
  }
223034
223073
  };
223074
+ const preventClose = (e) => {
223075
+ if (!closable)
223076
+ e.preventDefault();
223077
+ };
223078
+ // Single pricing tier: render the focused, card-style layout that matches
223079
+ // UpgradePackageModal instead of a lone card floating in the wide grid modal.
223080
+ if (activePrices.length === 1) {
223081
+ const price = activePrices[0];
223082
+ const isThisLoading = isCheckoutLoading && selectedPriceId === price.id;
223083
+ return (jsx(Dialog, { open: open, onOpenChange: (isOpen) => {
223084
+ if (!isOpen && closable)
223085
+ onClose();
223086
+ }, children: jsxs(DialogContent, { className: cn('max-w-md gap-0 p-0 overflow-hidden rounded-[10px] border border-[#e5e5e5] shadow-[0_10px_15px_-3px_rgba(0,0,0,0.1),0_4px_6px_-4px_rgba(0,0,0,0.1)]', !closable && '[&>button.absolute]:hidden'), onPointerDownOutside: preventClose, onEscapeKeyDown: preventClose, children: [jsxs("div", { className: "relative flex flex-col items-center px-6 pt-8 pb-6 bg-[linear-gradient(135deg,#f5f8ff_0%,#ffffff_100%)] border-b border-[#e5e7eb]", children: [jsx("div", { className: "flex h-12 w-12 items-center justify-center rounded-full mb-4", style: {
223087
+ background: 'linear-gradient(to right, rgb(56, 161, 229), rgb(114, 132, 255))',
223088
+ boxShadow: '0 4px 12px -2px rgba(56, 161, 229, 0.4)',
223089
+ }, children: jsx(Sparkles, { className: "h-6 w-6 text-white" }) }), jsxs("span", { className: "inline-flex items-baseline gap-1 rounded-full px-3 py-1 text-[13px] font-semibold leading-4 mb-3", style: {
223090
+ backgroundColor: '#f5f8ff',
223091
+ color: '#155dfc',
223092
+ border: '1px solid #d0e0ff',
223093
+ }, children: [formatPrice(price.amount, price.currency), price.interval !== 'one_time' && (jsx("span", { className: "text-[11px] font-normal opacity-80", children: formatInterval(price.interval) }))] }), jsxs(DialogHeader, { className: "text-center sm:text-center space-y-2", children: [jsx(DialogTitle, { className: "text-[18px] font-medium leading-7 text-[#101828] tracking-tight", children: price.name || t('modalsPaywallModal.chooseYourPlan') }), jsx(DialogDescription, { className: "text-[14px] font-normal leading-[22.75px] text-[#4a5565] max-w-[320px] mx-auto", children: price.description ||
223094
+ t('modalsPaywallModal.subscribeToGetAccess', { itemName: pricing.item_name }) })] })] }), jsxs("div", { className: "px-6 py-5", children: [price.features.length > 0 && (jsx("ul", { className: "space-y-3 mb-6", children: price.features.map((feature, idx) => (jsxs("li", { className: "flex items-start gap-3 text-[14px] leading-5 text-[#364153]", children: [jsx("span", { className: "mt-0.5 flex h-5 w-5 items-center justify-center rounded-full bg-[#f5f8ff] shrink-0", children: jsx(Check, { className: "h-3 w-3 text-[#155dfc]", strokeWidth: 3 }) }), jsx("span", { className: "font-normal", children: feature })] }, idx))) })), jsx(Button$1, { type: "button", onClick: () => handleCheckout(price), disabled: isCheckoutLoading, className: cn('w-full h-9 px-6 py-2 rounded-lg border-0 text-white text-[14px] font-medium leading-5 bg-[linear-gradient(to_right,rgb(56,161,229),rgb(114,132,255))] hover:opacity-90 transition-opacity disabled:opacity-70', buttonClassName), children: isThisLoading ? (jsxs(Fragment$1, { children: [jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }), jsx("span", { children: t('modalsPaywallModal.redirecting') })] })) : (t('modalsPaywallModal.pay')) }), jsxs("div", { className: "mt-3 flex items-center justify-center gap-1.5 text-[12px] font-normal leading-4 text-[#6a7282]", children: [jsx(CreditCard, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), jsx("span", { children: t('modalsPaywallModal.secureCheckout') })] })] })] }) }));
223095
+ }
223035
223096
  return (jsx(Dialog, { open: open, onOpenChange: (isOpen) => {
223036
223097
  if (!isOpen && closable)
223037
223098
  onClose();
223038
- }, children: jsxs(DialogContent, { className: cn('max-w-5xl gap-0 overflow-y-auto max-h-[90vh] p-8', !closable && '[&>button.absolute]:hidden'), onPointerDownOutside: (e) => {
223039
- if (!closable)
223040
- e.preventDefault();
223041
- }, onEscapeKeyDown: (e) => {
223042
- if (!closable)
223043
- e.preventDefault();
223044
- }, children: [jsxs(DialogHeader, { className: "text-center sm:text-center mb-8", children: [jsx(DialogTitle, { className: "text-3xl font-bold tracking-tight", children: t('modalsPaywallModal.chooseYourPlan') }), jsx(DialogDescription, { className: "text-base text-muted-foreground mt-2", children: t('modalsPaywallModal.subscribeToGetAccess', { itemName: pricing.item_name }) })] }), jsx("div", { className: cn('grid gap-5', activePrices.length === 1 && 'grid-cols-1 max-w-sm mx-auto', activePrices.length === 2 && 'grid-cols-1 sm:grid-cols-2 max-w-2xl mx-auto', activePrices.length === 3 && 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3', activePrices.length >= 4 && 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4'), children: activePrices.map((price) => (jsxs("div", { className: "rounded-xl bg-muted/50 p-6 flex flex-col gap-5", children: [jsxs("div", { children: [jsx("h3", { className: "text-xl font-bold", children: price.name }), price.description && (jsx("p", { className: "text-sm text-muted-foreground mt-2 leading-relaxed", children: price.description }))] }), jsxs("div", { className: "flex items-baseline gap-1", children: [jsx("span", { className: "text-4xl font-bold tracking-tight", children: formatPrice(price.amount, price.currency) }), price.interval !== 'one_time' && (jsx("span", { className: "text-sm text-muted-foreground", children: formatInterval(price.interval) }))] }), jsx(Button$1, { onClick: () => handleCheckout(price), disabled: isCheckoutLoading, className: cn('w-full h-11 text-sm font-medium', buttonClassName), children: isCheckoutLoading && selectedPriceId === price.id
223099
+ }, children: jsxs(DialogContent, { className: cn('max-w-5xl gap-0 overflow-y-auto max-h-[90vh] p-8', !closable && '[&>button.absolute]:hidden'), onPointerDownOutside: preventClose, onEscapeKeyDown: preventClose, children: [jsxs(DialogHeader, { className: "text-center sm:text-center mb-8", children: [jsx(DialogTitle, { className: "text-3xl font-bold tracking-tight", children: t('modalsPaywallModal.chooseYourPlan') }), jsx(DialogDescription, { className: "text-base text-muted-foreground mt-2", children: t('modalsPaywallModal.subscribeToGetAccess', { itemName: pricing.item_name }) })] }), jsx("div", { ref: gridRef, className: cn('grid gap-5 items-stretch', activePrices.length === 2 &&
223100
+ 'grid-cols-1 sm:grid-cols-2 sm:auto-cols-fr max-w-2xl mx-auto', activePrices.length === 3 && 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3', activePrices.length >= 4 && 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4'), children: activePrices.map((price, index) => (jsxs("div", { className: "rounded-xl bg-muted/50 p-6 flex flex-col gap-5 min-w-[16rem]", children: [jsxs("div", { ref: (el) => {
223101
+ headerRefs.current[index] = el;
223102
+ }, children: [jsx("h3", { className: "text-xl font-bold", children: price.name }), price.description && (jsx("p", { className: "text-sm text-muted-foreground mt-2 leading-relaxed", children: price.description }))] }), jsxs("div", { className: "flex items-baseline gap-1", children: [jsx("span", { className: "text-4xl font-bold tracking-tight", children: formatPrice(price.amount, price.currency) }), price.interval !== 'one_time' && (jsx("span", { className: "text-sm text-muted-foreground", children: formatInterval(price.interval) }))] }), jsx(Button$1, { onClick: () => handleCheckout(price), disabled: isCheckoutLoading, className: cn('w-full h-11 text-sm font-medium', buttonClassName), children: isCheckoutLoading && selectedPriceId === price.id
223045
223103
  ? t('modalsPaywallModal.redirecting')
223046
223104
  : t('modalsPaywallModal.pay') }), price.features.length > 0 && (jsxs("div", { children: [jsx("p", { className: "text-sm font-medium mb-3", children: t('modalsPaywallModal.thisIncludes') }), jsx("ul", { className: "space-y-3", children: price.features.map((feature, idx) => (jsxs("li", { className: "flex items-start gap-2.5 text-sm", children: [jsx(CircleCheckBig, { className: "h-4 w-4 text-primary shrink-0 mt-0.5" }), jsx("span", { className: "leading-snug", children: feature })] }, idx))) })] }))] }, price.id))) })] }) }));
223047
223105
  }
@@ -96962,6 +96962,7 @@ var advancePagination$3 = {
96962
96962
  var advancedAdvanced$3 = {
96963
96963
  failedToUpdateSetting: "Failed to update setting",
96964
96964
  settingUpdatedSuccessfully: "Setting updated successfully",
96965
+ save: "Save",
96965
96966
  agentSettingUpdatedSuccessfully: "Agent setting updated successfully",
96966
96967
  chatAreaSizeUpdatedSuccessfully: "Chat area size updated successfully",
96967
96968
  moreInfoAbout: "More info about {label}",
@@ -99539,7 +99540,8 @@ var modalsPaywallModal$3 = {
99539
99540
  subscribeToGetAccess: "Subscribe to get access to {itemName}",
99540
99541
  redirecting: "Redirecting...",
99541
99542
  pay: "Pay",
99542
- thisIncludes: "This includes:"
99543
+ thisIncludes: "This includes:",
99544
+ secureCheckout: "Secure checkout"
99543
99545
  };
99544
99546
  var modalsPromptGalleryModal$3 = {
99545
99547
  promptGallery: "Prompt Gallery",
@@ -102341,6 +102343,7 @@ var advancePagination$2 = {
102341
102343
  var advancedAdvanced$2 = {
102342
102344
  failedToUpdateSetting: "Échec de la mise à jour du paramètre",
102343
102345
  settingUpdatedSuccessfully: "Paramètre mis à jour avec succès",
102346
+ save: "Enregistrer",
102344
102347
  agentSettingUpdatedSuccessfully: "Paramètre de l'agent mis à jour avec succès",
102345
102348
  chatAreaSizeUpdatedSuccessfully: "Taille de la zone de discussion mise à jour avec succès",
102346
102349
  moreInfoAbout: "Plus d'informations sur {label}",
@@ -104918,7 +104921,8 @@ var modalsPaywallModal$2 = {
104918
104921
  subscribeToGetAccess: "Abonnez-vous pour accéder à {itemName}",
104919
104922
  redirecting: "Redirection en cours...",
104920
104923
  pay: "Payer",
104921
- thisIncludes: "Cela comprend :"
104924
+ thisIncludes: "Cela comprend :",
104925
+ secureCheckout: "Paiement sécurisé"
104922
104926
  };
104923
104927
  var modalsPromptGalleryModal$2 = {
104924
104928
  promptGallery: "Galerie d'invites",
@@ -107720,6 +107724,7 @@ var advancePagination$1 = {
107720
107724
  var advancedAdvanced$1 = {
107721
107725
  failedToUpdateSetting: "Error al actualizar la configuración",
107722
107726
  settingUpdatedSuccessfully: "Configuración actualizada correctamente",
107727
+ save: "Guardar",
107723
107728
  agentSettingUpdatedSuccessfully: "Configuración del agente actualizada correctamente",
107724
107729
  chatAreaSizeUpdatedSuccessfully: "Tamaño del área de chat actualizado correctamente",
107725
107730
  moreInfoAbout: "Más información sobre {label}",
@@ -110297,7 +110302,8 @@ var modalsPaywallModal$1 = {
110297
110302
  subscribeToGetAccess: "Suscríbete para acceder a {itemName}",
110298
110303
  redirecting: "Redirigiendo...",
110299
110304
  pay: "Pagar",
110300
- thisIncludes: "Esto incluye:"
110305
+ thisIncludes: "Esto incluye:",
110306
+ secureCheckout: "Pago seguro"
110301
110307
  };
110302
110308
  var modalsPromptGalleryModal$1 = {
110303
110309
  promptGallery: "Galería de instrucciones",
@@ -113099,6 +113105,7 @@ var advancePagination = {
113099
113105
  var advancedAdvanced = {
113100
113106
  failedToUpdateSetting: "更新设置失败",
113101
113107
  settingUpdatedSuccessfully: "设置已成功更新",
113108
+ save: "保存",
113102
113109
  agentSettingUpdatedSuccessfully: "代理设置已成功更新",
113103
113110
  chatAreaSizeUpdatedSuccessfully: "聊天区域大小已成功更新",
113104
113111
  moreInfoAbout: "关于 {label} 的更多信息",
@@ -115676,7 +115683,8 @@ var modalsPaywallModal = {
115676
115683
  subscribeToGetAccess: "订阅以获取 {itemName} 的访问权限",
115677
115684
  redirecting: "正在跳转...",
115678
115685
  pay: "支付",
115679
- thisIncludes: "包含以下内容:"
115686
+ thisIncludes: "包含以下内容:",
115687
+ secureCheckout: "安全结账"
115680
115688
  };
115681
115689
  var modalsPromptGalleryModal = {
115682
115690
  promptGallery: "提示库",
@@ -173722,6 +173730,10 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
173722
173730
  : activeTab === 'experience' && experienceSubTab === 'resume'
173723
173731
  ? { onClick: handleAddResume, upload: true, ariaLabel: t('profileIndex.ariaAddResume') }
173724
173732
  : null;
173733
+ // Rendered inline on the sub-tabs row (education/experience/resume), pushed to
173734
+ // the far right. `headerAdd` already encodes which sub-tab is active, so this
173735
+ // only appears on the sub-tabs that support adding/uploading.
173736
+ const headerAddButton = headerAdd && (jsx(Button$1, { size: "icon", onClick: headerAdd.onClick, className: "text-gray-700 bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white flex-shrink-0", "aria-label": headerAdd.ariaLabel, children: headerAdd.upload ? jsx(Upload, { className: "h-4 w-4" }) : jsx(Plus, { className: "h-4 w-4" }) }));
173725
173737
  const tabDescription = (id) => {
173726
173738
  const key = (isReadOnly && TAB_DESC_PREVIEW_KEYS[id]) || TAB_DESC_KEYS[id];
173727
173739
  return key ? t(`profileIndex.${key}`) : '';
@@ -173736,10 +173748,10 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
173736
173748
  ? 'bg-blue-50 text-blue-700 font-medium'
173737
173749
  : 'hover:bg-gray-50 text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100'}`, children: [jsx(tab.renderIcon, { className: "h-5 w-5 mr-3 flex-shrink-0", "aria-hidden": "true" }), jsx("span", { className: "truncate", children: tab.label })] }, tab.id))) }) }) })] }), jsx("nav", { className: "lg:hidden", "aria-label": t('profileIndex.ariaProfileTabsMobile'), children: jsx("div", { className: "w-full justify-start px-6 py-2 bg-white border-b border-gray-200 rounded-none h-auto overflow-x-auto", children: jsx("div", { className: "flex space-x-2", role: "tablist", "aria-orientation": "horizontal", children: TABS.map((tab) => (jsxs("button", { role: "tab", "aria-selected": activeTab === tab.id, "aria-controls": `${tab.id}-tabpanel`, id: `${tab.id}-tab-mobile`, onClick: () => setActiveTab(tab.id), className: `flex items-center gap-2 px-3 py-2 rounded-lg whitespace-nowrap text-sm transition-all ${activeTab === tab.id
173738
173750
  ? 'bg-blue-50 text-blue-600 font-medium'
173739
- : 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(tab.renderIcon, { className: "h-4 w-4", "aria-hidden": "true" }), jsx("span", { className: "hidden sm:inline", children: tab.label }), jsx("span", { className: "sm:hidden", children: tab.label })] }, tab.id))) }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsx("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_f = (_e = TABS.find((t) => t.id === activeTab)) === null || _e === void 0 ? void 0 : _e.label) !== null && _f !== void 0 ? _f : activeTab }), jsx("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: tabDescription(activeTab) })] }), headerAdd && (jsx(Button$1, { size: "icon", onClick: headerAdd.onClick, className: "text-gray-700 bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white mr-4", "aria-label": headerAdd.ariaLabel, children: headerAdd.upload ? jsx(Upload, { className: "h-4 w-4" }) : jsx(Plus, { className: "h-4 w-4" }) }))] }) }), jsxs("div", { className: "flex-1 p-6 space-y-6", style: {
173751
+ : 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(tab.renderIcon, { className: "h-4 w-4", "aria-hidden": "true" }), jsx("span", { className: "hidden sm:inline", children: tab.label }), jsx("span", { className: "sm:hidden", children: tab.label })] }, tab.id))) }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsx("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: jsx("div", { className: "flex items-center justify-between", children: jsxs("div", { children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_f = (_e = TABS.find((t) => t.id === activeTab)) === null || _e === void 0 ? void 0 : _e.label) !== null && _f !== void 0 ? _f : activeTab }), jsx("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: tabDescription(activeTab) })] }) }) }), jsxs("div", { className: "flex-1 p-6 space-y-6", style: {
173740
173752
  overflowY: 'auto',
173741
173753
  overflowX: 'hidden',
173742
- }, role: "tabpanel", id: `${activeTab}-tabpanel`, "aria-labelledby": `${activeTab}-tab`, tabIndex: 0, children: [jsx("div", { className: "lg:hidden mb-6", children: jsxs("div", { className: "flex flex-row items-center sm:justify-between gap-3", children: [jsxs("div", { children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_h = (_g = TABS.find((t) => t.id === activeTab)) === null || _g === void 0 ? void 0 : _g.label) !== null && _h !== void 0 ? _h : activeTab }), jsx("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: tabDescription(activeTab) })] }), headerAdd && (jsx(Button$1, { size: "icon", onClick: headerAdd.onClick, className: "text-gray-700 bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", "aria-label": headerAdd.ariaLabel, children: headerAdd.upload ? jsx(Upload, { className: "h-4 w-4" }) : jsx(Plus, { className: "h-4 w-4" }) }))] }) }), activeTab === 'basic' && (jsx("div", { className: "space-y-6", children: jsxs("form", { onSubmit: (formEvent) => {
173754
+ }, role: "tabpanel", id: `${activeTab}-tabpanel`, "aria-labelledby": `${activeTab}-tab`, tabIndex: 0, children: [jsx("div", { className: "lg:hidden mb-6", children: jsx("div", { className: "flex flex-row items-center sm:justify-between gap-3", children: jsxs("div", { children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_h = (_g = TABS.find((t) => t.id === activeTab)) === null || _g === void 0 ? void 0 : _g.label) !== null && _h !== void 0 ? _h : activeTab }), jsx("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: tabDescription(activeTab) })] }) }) }), activeTab === 'basic' && (jsx("div", { className: "space-y-6", children: jsxs("form", { onSubmit: (formEvent) => {
173743
173755
  formEvent.preventDefault();
173744
173756
  formEvent.stopPropagation();
173745
173757
  if (isReadOnly)
@@ -173814,7 +173826,7 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
173814
173826
  var _a;
173815
173827
  return (jsxs(Fragment$1, { children: [jsxs("div", { className: "relative mb-0", children: [jsx("div", { className: "absolute inset-y-0 left-4 flex items-center pointer-events-none", "aria-hidden": "true", children: jsx("div", { className: "bg-black text-white rounded w-8 h-8 flex items-center justify-center", children: jsx("span", { className: "font-bold text-sm", children: "X" }) }) }), jsx(Input, { id: "x", className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-base py-3 pl-16 h-10", placeholder: t('profileIndex.placeholderX'), value: field.state.value, onChange: (e) => handleSocialLinkChange(e.target.value, field.handleChange, X_URL_PREFIX), disabled: socialForm.state.isSubmitting || isReadOnly })] }), jsx("p", { className: "text-red-500 dark:text-gray-400 text-sm", role: ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) ? 'alert' : undefined, "aria-live": "polite", children: field.state.meta.errors })] }));
173816
173828
  },
173817
- })] })] }) })), activeTab === 'education' && (jsxs(Tabs, { value: educationSubTab, onValueChange: setEducationSubTab, className: "space-y-4", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "education", children: t('profileIndex.tabEducation') }), jsx(TabsTrigger, { value: "credentials", children: t('gradebookGradebookTab.typeCredentials') }), jsx(TabsTrigger, { value: "skills", children: t('gradebookGradebookTab.typeSkills') })] }), jsx(TabsContent, { value: "education", children: jsx(EducationTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "credentials", children: jsx(CredentialsList, { org: tenant, username: username }) }), jsx(TabsContent, { value: "skills", children: jsx(SkillsList, { org: tenant, username: username }) })] })), activeTab === 'gradebook' && jsx(GradebookTab, { org: tenant, username: username }), activeTab === 'experience' && (jsxs(Tabs, { value: experienceSubTab, onValueChange: setExperienceSubTab, className: "space-y-4", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "experience", children: t('profileIndex.tabExperience') }), jsx(TabsTrigger, { value: "resume", children: t('profileIndex.tabResume') })] }), jsx(TabsContent, { value: "experience", children: jsx(ExperienceTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "resume", children: jsx(ResumeTab, { org: tenant, username: username }) })] })), activeTab === 'purchases' && jsx(PurchasesTab, { org: tenant, username: username }), activeTab === 'memory' && jsx(MemoryTab, { org: tenant, username: username }), activeTab === 'privacy' && jsx(ChatPrivacyTab, { org: tenant, username: username }), !isReadOnly && activeTab === 'security' && (jsx(Security, { app: currentSPA || '', email: (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email) || '', platformKey: tenant, onAccountDeleted: onAccountDeleted })), activeTab === 'advanced' && (localLLMProps || systemControlProps) && (jsxs("div", { className: "space-y-6", children: [localLLMProps && (jsx(LocalModelsContent, { isAvailable: localLLMProps.isAvailable, state: localLLMProps.state, ollamaStatus: localLLMProps.ollamaStatus, systemMemory: localLLMProps.systemMemory, isUsingFoundry: localLLMProps.isUsingFoundry, foundryModels: localLLMProps.foundryModels, selectedFoundryModel: localLLMProps.selectedFoundryModel, foundryStatus: localLLMProps.foundryStatus, onStartDownload: localLLMProps.onStartDownload, onCancelDownload: localLLMProps.onCancelDownload, onInstallOllama: localLLMProps.onInstallOllama, onStopManager: localLLMProps.onStopManager, onInstallFoundry: localLLMProps.onInstallFoundry, onCheckStatus: localLLMProps.onCheckStatus, onResetState: localLLMProps.onResetState, onSelectFoundryModel: localLLMProps.onSelectFoundryModel })), systemControlProps && (jsx(SystemControlContent, { isAvailable: systemControlProps.isAvailable, state: systemControlProps.state, status: systemControlProps.status, requiredSizeGb: systemControlProps.requiredSizeGb, ollamaStatus: systemControlProps.ollamaStatus, systemMemory: systemControlProps.systemMemory, accessibilityPermission: systemControlProps.accessibilityPermission, onInstall: systemControlProps.onInstall, onStop: systemControlProps.onStop, onCheckStatus: systemControlProps.onCheckStatus, onResetState: systemControlProps.onResetState, onRequestAccessibilityPermission: systemControlProps.onRequestAccessibilityPermission, onDownloadModel: systemControlProps.onDownloadModel }))] }))] }), !isReadOnly && ['basic', 'social'].includes(activeTab) && (jsx("div", { className: "flex-shrink-0 border-t border-gray-200 p-6 bg-white dark:bg-gray-900", children: jsxs("div", { className: "flex justify-end gap-3", children: [jsx(Button$1, { onClick: onClose, variant: "outline", children: t('profileIndex.buttonCancel') }), jsx(Button$1, { onClick: () => {
173829
+ })] })] }) })), activeTab === 'education' && (jsxs(Tabs, { value: educationSubTab, onValueChange: setEducationSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "education", children: t('profileIndex.tabEducation') }), jsx(TabsTrigger, { value: "credentials", children: t('gradebookGradebookTab.typeCredentials') }), jsx(TabsTrigger, { value: "skills", children: t('gradebookGradebookTab.typeSkills') })] }), headerAddButton] }), jsx(TabsContent, { value: "education", children: jsx(EducationTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "credentials", children: jsx(CredentialsList, { org: tenant, username: username }) }), jsx(TabsContent, { value: "skills", children: jsx(SkillsList, { org: tenant, username: username }) })] })), activeTab === 'gradebook' && jsx(GradebookTab, { org: tenant, username: username }), activeTab === 'experience' && (jsxs(Tabs, { value: experienceSubTab, onValueChange: setExperienceSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "experience", children: t('profileIndex.tabExperience') }), jsx(TabsTrigger, { value: "resume", children: t('profileIndex.tabResume') })] }), headerAddButton] }), jsx(TabsContent, { value: "experience", children: jsx(ExperienceTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "resume", children: jsx(ResumeTab, { org: tenant, username: username }) })] })), activeTab === 'purchases' && jsx(PurchasesTab, { org: tenant, username: username }), activeTab === 'memory' && jsx(MemoryTab, { org: tenant, username: username }), activeTab === 'privacy' && jsx(ChatPrivacyTab, { org: tenant, username: username }), !isReadOnly && activeTab === 'security' && (jsx(Security, { app: currentSPA || '', email: (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email) || '', platformKey: tenant, onAccountDeleted: onAccountDeleted })), activeTab === 'advanced' && (localLLMProps || systemControlProps) && (jsxs("div", { className: "space-y-6", children: [localLLMProps && (jsx(LocalModelsContent, { isAvailable: localLLMProps.isAvailable, state: localLLMProps.state, ollamaStatus: localLLMProps.ollamaStatus, systemMemory: localLLMProps.systemMemory, isUsingFoundry: localLLMProps.isUsingFoundry, foundryModels: localLLMProps.foundryModels, selectedFoundryModel: localLLMProps.selectedFoundryModel, foundryStatus: localLLMProps.foundryStatus, onStartDownload: localLLMProps.onStartDownload, onCancelDownload: localLLMProps.onCancelDownload, onInstallOllama: localLLMProps.onInstallOllama, onStopManager: localLLMProps.onStopManager, onInstallFoundry: localLLMProps.onInstallFoundry, onCheckStatus: localLLMProps.onCheckStatus, onResetState: localLLMProps.onResetState, onSelectFoundryModel: localLLMProps.onSelectFoundryModel })), systemControlProps && (jsx(SystemControlContent, { isAvailable: systemControlProps.isAvailable, state: systemControlProps.state, status: systemControlProps.status, requiredSizeGb: systemControlProps.requiredSizeGb, ollamaStatus: systemControlProps.ollamaStatus, systemMemory: systemControlProps.systemMemory, accessibilityPermission: systemControlProps.accessibilityPermission, onInstall: systemControlProps.onInstall, onStop: systemControlProps.onStop, onCheckStatus: systemControlProps.onCheckStatus, onResetState: systemControlProps.onResetState, onRequestAccessibilityPermission: systemControlProps.onRequestAccessibilityPermission, onDownloadModel: systemControlProps.onDownloadModel }))] }))] }), !isReadOnly && ['basic', 'social'].includes(activeTab) && (jsx("div", { className: "flex-shrink-0 border-t border-gray-200 p-6 bg-white dark:bg-gray-900", children: jsxs("div", { className: "flex justify-end gap-3", children: [jsx(Button$1, { onClick: onClose, variant: "outline", children: t('profileIndex.buttonCancel') }), jsx(Button$1, { onClick: () => {
173818
173830
  if (activeTab === 'basic') {
173819
173831
  basicForm.handleSubmit();
173820
173832
  }
@@ -183813,26 +183825,19 @@ const ChatPrivacyContent = ({ platformKey, username }) => {
183813
183825
  };
183814
183826
 
183815
183827
  function StringSettingInput({ value, defaultValue, disabled, onSave, }) {
183816
- const [localValue, setLocalValue] = useState(value || defaultValue);
183817
- const debounceRef = useRef(null);
183828
+ const t = useT();
183829
+ const savedValue = value || defaultValue;
183830
+ const [localValue, setLocalValue] = useState(savedValue);
183818
183831
  useEffect(() => {
183819
- setLocalValue(value || defaultValue);
183820
- }, [value, defaultValue]);
183821
- const handleChange = (newValue) => {
183822
- setLocalValue(newValue);
183823
- if (debounceRef.current)
183824
- clearTimeout(debounceRef.current);
183825
- debounceRef.current = setTimeout(() => {
183826
- onSave(newValue);
183827
- }, 800);
183832
+ setLocalValue(savedValue);
183833
+ }, [savedValue]);
183834
+ const isDirty = localValue !== savedValue;
183835
+ const handleSave = () => {
183836
+ if (!isDirty || disabled)
183837
+ return;
183838
+ onSave(localValue);
183828
183839
  };
183829
- useEffect(() => {
183830
- return () => {
183831
- if (debounceRef.current)
183832
- clearTimeout(debounceRef.current);
183833
- };
183834
- }, []);
183835
- 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" }))] }));
183840
+ return (jsxs("div", { className: "flex items-center gap-2", children: [isDirty && (jsx(Button$1, { type: "button", size: "sm", onClick: handleSave, disabled: disabled, className: "h-8 bg-blue-500 hover:bg-blue-600 text-white", children: t('advancedAdvanced.save') })), jsx(Input, { value: localValue, onChange: (e) => setLocalValue(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" }))] }));
183836
183841
  }
183837
183842
  function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatformBaseDomain, }) {
183838
183843
  const t = useT();
@@ -183878,6 +183883,7 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
183878
183883
  'overall_default_mentor',
183879
183884
  'help_center_url',
183880
183885
  'monetization_base_path',
183886
+ 'skills_welcome_tagline',
183881
183887
  ];
183882
183888
  const configurableMetadatas = allMetadatas.filter((metadata) => (typeof metadata.defaultValue === 'boolean' ||
183883
183889
  (typeof metadata.defaultValue === 'string' &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iblai/iblai-js",
3
- "version": "1.25.3",
3
+ "version": "1.26.0",
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": {
@@ -68,8 +68,8 @@
68
68
  "winston": "3.19.0",
69
69
  "@iblai/data-layer": "1.9.3",
70
70
  "@iblai/mcp": "1.8.0",
71
- "@iblai/web-containers": "1.14.1",
72
- "@iblai/web-utils": "1.12.1"
71
+ "@iblai/web-containers": "1.15.0",
72
+ "@iblai/web-utils": "1.13.0"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@radix-ui/react-dialog": "^1.1.7",