@iblai/iblai-js 2.17.1 → 2.18.1

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.
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
- import React__default, { useRef, useEffect, useMemo, useCallback, useState, createContext, useContext, forwardRef, createElement as createElement$1, useLayoutEffect, useReducer, useImperativeHandle, isValidElement, Children, PureComponent, cloneElement, Component, useId as useId$2, useDebugValue, lazy, Suspense } from 'react';
2
+ import React__default, { useRef, useEffect, useMemo, useCallback, useState, createContext, useContext, forwardRef, createElement as createElement$1, useLayoutEffect, useReducer, useImperativeHandle, isValidElement, Children, PureComponent, cloneElement, Component, Fragment as Fragment$2, useId as useId$2, useDebugValue, lazy, Suspense } from 'react';
3
3
  import * as dataLayer from '@iblai/data-layer';
4
- import { useGetLlmsQuery, useCreateSessionIdMutation, useTimeTrackingMutation, useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useGetUserProfileSummaryQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useGetLearnerDetailsQuery, useGetUserEnrolledCoursesQuery, useGetUserEnrolledProgramsQuery, useGetUserCatalogPathwaysQuery, useGetUsersAsAssertionsQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateGlobalMemoryMutation, useUpdateGlobalMemoryMutation, useUpdateMentorMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useGetAllMentorMemoriesQuery, useDeleteGlobalMemoryMutation, useDeleteMentorMemoryMutation, useGetAiSearchMentorsQuery, useGetUserChatHistoryReportsQuery, USER_CHAT_HISTORY_REPORT_ACTIVE_STATES, useCreateUserChatHistoryReportMutation, useLazyGetDownloadReportFromURLQuery, useGetUserChatHistoryReportStatusQuery, userChatHistoryApiSlice, USER_CHAT_HISTORY_QUERY_KEYS, useGetUserChatHistoryQuery, useGetUserChatHistoryFilterQuery, useGetMentorsQuery, useGetUserChatHistorySessionQuery, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useGetVectorDocumentsQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, useGetAccessibleUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacActionsDefinitionQuery, useGetRbacResourceDiscoveryQuery, useGetRbacResourceListQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useGetWatchedGroupsQuery, useCreateWatchedGroupMutation, useUpdateWatchedGroupMutation, useDeleteWatchedGroupMutation, useAddWatchedUserMutation, useRemoveWatchedUserMutation, useAddWatcherMutation, useUpdateWatcherMutation, useDeleteWatcherMutation, useGetWatchedUsersQuery, useGetWatchersQuery, WATCHER_NOTIFICATION_EVENTS, WATCHER_NOTIFICATION_EVENT_LABELS, useGetApplicationFormsQuery, useGetApplicationFormDetailQuery, useCreateApplicationFormMutation, useUpdateApplicationFormMutation, useGetApplicationAdminDetailQuery, useInviteApplicationCandidateMutation, useLazyGetApplicationAttachmentFileQuery, useCreateApplicationWaiverMutation, useDeleteApplicationWaiverMutation, useSubmitApplicationOverrideMutation, useUpdateApplicationPlacementMutation, useDeleteApplicationCourseAssignmentMutation, useCreateApplicationNoteMutation, useUpdateApplicationNoteMutation, useDeleteApplicationNoteMutation, useTransitionApplicationMutation, useLinkApplicationCandidateMutation, useCreateApplicationPlacementsMutation, useGetCustomMentorsQuery, useCreateApplicationCourseAssignmentsMutation, useGetApplicationBlocksQuery, useDeleteApplicationBlockMutation, useGetApplicationsPipelineStatsQuery, useGetApplicationsPipelineQuery, useGetTenantMetadataQuery, useUpdateTenantMetadataMutation, useLazyGetTenantMetadataQuery, useDeleteApiKeyMutation, useGetApiKeyQuery, useGetApiKeyFieldPermissionsQuery, useUpdateApiKeyMutation, useGetApiKeysQuery, unwrapApiTokenList, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useGetAgentSpendCapQuery, useGetTenantSpendCapQuery, useListAgentUserSpendCapsQuery, useUpsertAgentSpendCapMutation, useDeleteAgentSpendCapMutation, useUpsertTenantSpendCapMutation, useDeleteTenantSpendCapMutation, useUpsertUserSpendCapMutation, useDeleteUserSpendCapMutation, useGetLlmUsageMetricsQuery, useListAgentSpendCapsQuery, useGetCreditTransactionsQuery, 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, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useCreateMentorMemoryMutation, useGetNotificationsCountQuery, useLazyGetNotificationsQuery, useMarkAllAsReadMutation, useCreateNotificationPreviewMutation, useSendNotificationMutation, USER_PROGRESS_DATA_POINTS, useResetTemplateMutation, useSendTestTemplateEmailMutation, useUpdateTemplateMutation, useGetTemplateDetailsQuery, USER_PROGRESS_SUMMARY_TYPE, useGetTemplatesQuery, useLazyGetTemplateDetailsQuery, useToggleTemplateMutation, useGetLlmUsageTracesQuery, useGetLlmUsageObservationsQuery, useGetTopicsStatsQuery, useGetUsersStatsQuery, useGetSessionStatsQuery, useGetTopicsDetailsStatsQuery, useGetTranscriptsConversationHeadlineQuery, useGetAccessTimeHeatmapQuery, useGetUserDetailsStatsQuery, useGetAverageRatingQuery, useGetModelCostsQuery, useGetPerUserCostsQuery, useGetTenantCostQuery, useGetAgentCostQuery, useGetTranscriptsMessagesDetailsQuery, useGetTranscriptsMessagesQuery, useGetReportDetailQuery, useGetMentorPublicSettingsQuery, useGetReportsQuery, useCreateReportMutation, useGetContentAnalyticsQuery, useGetContentAnalyticsDetailsQuery, useGetRevenueQuery, useListSubscribersQuery, useGetAuditLogsQuery, useGetPlatformAuditLogsQuery, PLATFORM_AUDIT_EVENT_TYPES, PLATFORM_AUDIT_ACTION_CODES, useGetMentorMemoriesQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetUserEnrolledCoursesQuery, useLazyGetUserAssignedCoursesQuery, useLazyGetUserCredentialsQuery, useLazyGetOverTimeActivityQuery, useLazyGetCatalogSearchQuery, useCreateOrUpdateUserReportedSkillMutation, useCreateOrUpdateUserDesiredSkillMutation, useLazyGetPathwayListQuery, useLazyGetUserAssignedPathwaysQuery, useLazyGetUserEnrolledPathwaysQuery, useLazyGetPathwayCompletionQuery, useLazyGetProgramListQuery, useLazyGetProgramCompletionQuery, useLazyGetUserEnrolledProgramsQuery, useLazyGetAssignedProgramsQuery, useLazyGetUserSkillsPointsQuery, useLazyGetUserReportedSkillsQuery, useLazyGetUserDesiredSkillsQuery, useLazyGetUserCatalogPathwaysQuery, useLazyGetPerLearnerInfoQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useLazyGetPersonnalizedSearchQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetMentorSettingsQuery, useEditMentorMutation, useGetClawMentorConfigQuery, useGetClawInstancesQuery, useGetAgentConfigQuery, useUpdateClawMentorConfigMutation, useCreateClawMentorConfigMutation, useDeleteClawMentorConfigMutation, usePushClawConfigMutation, useCreateClawInstanceMutation, useDeleteClawInstanceMutation, useUpdateAgentConfigMutation, useHealthCheckClawInstanceMutation, useTestConnectivityClawInstanceMutation, useUpdateClawInstanceMutation, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetMentorSkillAssignmentsQuery, useGetAgentSkillsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, filterSlashSkills, useGetMentorSkillAssignmentsInfiniteQuery, MENTOR_SKILL_ASSIGNMENTS_PAGE_SIZE, useCreateCheckoutMutation, useGetUserProjectsQuery, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorCategoriesQuery, useCreateMentorMutation, useUpdateUserPlatformMetadataMutation, useGetApplicationStatusQuery, useListOwnApplicationsQuery, useGetApplicationFormQuery, useWithdrawApplicationMutation, useRenewApplicationMutation, useCreateApplicationDraftMutation, useSubmitApplicationMutation, useUpdateApplicationMutation, useUploadApplicationAttachmentMutation, useDeleteApplicationAttachmentMutation, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useGetPromptCategoriesQuery, useCreatePromptMutation, useDeletePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation } from '@iblai/data-layer';
4
+ import { useGetLlmsQuery, useCreateSessionIdMutation, useTimeTrackingMutation, useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useGetUserProfileSummaryQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useGetLearnerDetailsQuery, useGetUserEnrolledCoursesQuery, useGetUserEnrolledProgramsQuery, useGetUserCatalogPathwaysQuery, useGetUsersAsAssertionsQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateGlobalMemoryMutation, useUpdateGlobalMemoryMutation, useUpdateMentorMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useGetAllMentorMemoriesQuery, useDeleteGlobalMemoryMutation, useDeleteMentorMemoryMutation, useGetAiSearchMentorsQuery, useGetUserChatHistoryReportsQuery, USER_CHAT_HISTORY_REPORT_ACTIVE_STATES, useCreateUserChatHistoryReportMutation, useLazyGetDownloadReportFromURLQuery, useGetUserChatHistoryReportStatusQuery, userChatHistoryApiSlice, USER_CHAT_HISTORY_QUERY_KEYS, useGetUserChatHistoryQuery, useGetUserChatHistoryFilterQuery, useGetMentorsQuery, useGetUserChatHistorySessionQuery, useUserLlmUsageSummary, useUserLlmSpendOverTime, useUserLlmCostByModel, useUserLlmCostByService, useUserLlmRecentActivity, USER_LLM_RECENT_ACTIVITY_PAGE_SIZE, useUserLlmTraceObservations, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useGetVectorDocumentsQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, useGetAccessibleUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacActionsDefinitionQuery, useGetRbacResourceDiscoveryQuery, useGetRbacResourceListQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useGetWatchedGroupsQuery, useCreateWatchedGroupMutation, useUpdateWatchedGroupMutation, useDeleteWatchedGroupMutation, useAddWatchedUserMutation, useRemoveWatchedUserMutation, useAddWatcherMutation, useUpdateWatcherMutation, useDeleteWatcherMutation, useGetWatchedUsersQuery, useGetWatchersQuery, WATCHER_NOTIFICATION_EVENTS, WATCHER_NOTIFICATION_EVENT_LABELS, useGetApplicationFormsQuery, useGetApplicationFormDetailQuery, useCreateApplicationFormMutation, useUpdateApplicationFormMutation, useGetApplicationAdminDetailQuery, useInviteApplicationCandidateMutation, useLazyGetApplicationAttachmentFileQuery, useCreateApplicationWaiverMutation, useDeleteApplicationWaiverMutation, useSubmitApplicationOverrideMutation, useUpdateApplicationPlacementMutation, useDeleteApplicationCourseAssignmentMutation, useCreateApplicationNoteMutation, useUpdateApplicationNoteMutation, useDeleteApplicationNoteMutation, useTransitionApplicationMutation, useLinkApplicationCandidateMutation, useCreateApplicationPlacementsMutation, useGetCustomMentorsQuery, useCreateApplicationCourseAssignmentsMutation, useGetApplicationBlocksQuery, useDeleteApplicationBlockMutation, useGetApplicationsPipelineStatsQuery, useGetApplicationsPipelineQuery, useGetTenantMetadataQuery, useUpdateTenantMetadataMutation, useLazyGetTenantMetadataQuery, useDeleteApiKeyMutation, useGetApiKeyQuery, useGetApiKeyFieldPermissionsQuery, useUpdateApiKeyMutation, useGetApiKeysQuery, unwrapApiTokenList, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useGetAgentSpendCapQuery, useGetTenantSpendCapQuery, useListAgentUserSpendCapsQuery, useUpsertAgentSpendCapMutation, useDeleteAgentSpendCapMutation, useUpsertTenantSpendCapMutation, useDeleteTenantSpendCapMutation, useUpsertUserSpendCapMutation, useDeleteUserSpendCapMutation, useGetLlmUsageMetricsQuery, useListAgentSpendCapsQuery, useGetCreditTransactionsQuery, 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, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useCreateMentorMemoryMutation, useGetNotificationsCountQuery, useLazyGetNotificationsQuery, useMarkAllAsReadMutation, useCreateNotificationPreviewMutation, useSendNotificationMutation, USER_PROGRESS_DATA_POINTS, useResetTemplateMutation, useSendTestTemplateEmailMutation, useUpdateTemplateMutation, useGetTemplateDetailsQuery, USER_PROGRESS_SUMMARY_TYPE, useGetTemplatesQuery, useLazyGetTemplateDetailsQuery, useToggleTemplateMutation, useGetLlmUsageTracesQuery, useGetLlmUsageObservationsQuery, useGetTopicsStatsQuery, useGetUsersStatsQuery, useGetSessionStatsQuery, useGetTopicsDetailsStatsQuery, useGetTranscriptsConversationHeadlineQuery, useGetAccessTimeHeatmapQuery, useGetUserDetailsStatsQuery, useGetAverageRatingQuery, useGetModelCostsQuery, useGetPerUserCostsQuery, useGetTenantCostQuery, useGetAgentCostQuery, useGetTranscriptsMessagesDetailsQuery, useGetTranscriptsMessagesQuery, useGetReportDetailQuery, useGetMentorPublicSettingsQuery, useGetReportsQuery, useCreateReportMutation, useGetContentAnalyticsQuery, useGetContentAnalyticsDetailsQuery, useGetRevenueQuery, useListSubscribersQuery, useGetAuditLogsQuery, useGetPlatformAuditLogsQuery, PLATFORM_AUDIT_EVENT_TYPES, PLATFORM_AUDIT_ACTION_CODES, useGetMentorMemoriesQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetUserEnrolledCoursesQuery, useLazyGetUserAssignedCoursesQuery, useLazyGetUserCredentialsQuery, useLazyGetOverTimeActivityQuery, useLazyGetCatalogSearchQuery, useCreateOrUpdateUserReportedSkillMutation, useCreateOrUpdateUserDesiredSkillMutation, useLazyGetPathwayListQuery, useLazyGetUserAssignedPathwaysQuery, useLazyGetUserEnrolledPathwaysQuery, useLazyGetPathwayCompletionQuery, useLazyGetProgramListQuery, useLazyGetProgramCompletionQuery, useLazyGetUserEnrolledProgramsQuery, useLazyGetAssignedProgramsQuery, useLazyGetUserSkillsPointsQuery, useLazyGetUserReportedSkillsQuery, useLazyGetUserDesiredSkillsQuery, useLazyGetUserCatalogPathwaysQuery, useLazyGetPerLearnerInfoQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useLazyGetPersonnalizedSearchQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetMentorSettingsQuery, useEditMentorMutation, useGetClawMentorConfigQuery, useGetClawInstancesQuery, useGetAgentConfigQuery, useUpdateClawMentorConfigMutation, useCreateClawMentorConfigMutation, useDeleteClawMentorConfigMutation, usePushClawConfigMutation, useCreateClawInstanceMutation, useDeleteClawInstanceMutation, useUpdateAgentConfigMutation, useHealthCheckClawInstanceMutation, useTestConnectivityClawInstanceMutation, useUpdateClawInstanceMutation, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetMentorSkillAssignmentsQuery, useGetAgentSkillsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, filterSlashSkills, useGetMentorSkillAssignmentsInfiniteQuery, MENTOR_SKILL_ASSIGNMENTS_PAGE_SIZE, useCreateCheckoutMutation, useGetUserProjectsQuery, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorCategoriesQuery, useCreateMentorMutation, useUpdateUserPlatformMetadataMutation, useGetApplicationStatusQuery, useListOwnApplicationsQuery, useGetApplicationFormQuery, useWithdrawApplicationMutation, useRenewApplicationMutation, useCreateApplicationDraftMutation, useSubmitApplicationMutation, useUpdateApplicationMutation, useUploadApplicationAttachmentMutation, useDeleteApplicationAttachmentMutation, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useGetPromptCategoriesQuery, useCreatePromptMutation, useDeletePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation } from '@iblai/data-layer';
5
5
  import { useDispatch, useSelector } from 'react-redux';
6
- import { selectSessionId, selectActiveChatMessages, useCachedSessionId, chatActions, LOCAL_STORAGE_KEYS, TimeTracker, selectRbacPermissions, useCurrentTenant, canViewOtherUsersChatHistory, getInitials, useTenantMetadata, useUsername, selectStreaming, isLoggedIn, TOOL_NAME_MAP, WRITE_TODOS_TOOL, isPureWatcher, WithPermissions, canWriteField, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, getTimeAgo, REQUIRED_ACTIONS_FOR_GROUPS, getVisibleAnalyticsTabs, getUserName as getUserName$2, formatRelativeTime as formatRelativeTime$2, ANONYMOUS_USERNAME, combineCSVData, WATCHER_HIDDEN_REPORTS, canViewPlatformAuditLogs, redirectToAuthSpaJoinTenant, redirectToAuthSpa, getAuthSpaJoinUrl, useOS, selectNumberOfActiveChatMessages, TOOLS, hasRemoteAiConfig, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat, useShowFreeTrialDialog, useEmbedMode, chatInputSliceSelectors, useResponsive, useAccessingPublicRoute, useVisitingTenant, useModelFileUploadCapabilities, useChatFileUpload, useVoiceChat, selectAttachedFiles, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, chatInputSliceActions, removeFile, WithFormPermissions, MENTOR_VISIBILITY } from '@iblai/web-utils';
6
+ import { selectSessionId, selectActiveChatMessages, useCachedSessionId, chatActions, LOCAL_STORAGE_KEYS, TimeTracker, selectRbacPermissions, useCurrentTenant, canViewOtherUsersChatHistory, isPureWatcher, getInitials, useTenantMetadata, useUsername, selectStreaming, isLoggedIn, TOOL_NAME_MAP, WRITE_TODOS_TOOL, WithPermissions, canWriteField, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, getTimeAgo, REQUIRED_ACTIONS_FOR_GROUPS, getVisibleAnalyticsTabs, getUserName as getUserName$2, formatRelativeTime as formatRelativeTime$2, ANONYMOUS_USERNAME, combineCSVData, WATCHER_HIDDEN_REPORTS, canViewPlatformAuditLogs, redirectToAuthSpaJoinTenant, redirectToAuthSpa, getAuthSpaJoinUrl, useOS, selectNumberOfActiveChatMessages, TOOLS, hasRemoteAiConfig, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat, useShowFreeTrialDialog, useEmbedMode, chatInputSliceSelectors, useResponsive, useAccessingPublicRoute, useVisitingTenant, useModelFileUploadCapabilities, useChatFileUpload, useVoiceChat, selectAttachedFiles, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, chatInputSliceActions, removeFile, WithFormPermissions, MENTOR_VISIBILITY } from '@iblai/web-utils';
7
7
  import { toast } from 'sonner';
8
8
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
9
9
  import * as ReactDOM from 'react-dom';
@@ -5165,7 +5165,13 @@ var profileAccount$3 = {
5165
5165
  tabBenchmarks: "Benchmarks",
5166
5166
  descBenchmarks: "Build benchmark suites of test inputs to evaluate agents.",
5167
5167
  tabMemory: "Memory",
5168
- descMemory: "Manage user global memories and agent memories."
5168
+ descMemory: "Manage user global memories and agent memories.",
5169
+ groupWorkspace: "Workspace",
5170
+ groupAiData: "AI & data",
5171
+ groupSystem: "System",
5172
+ ariaSettingsNav: "Organization settings",
5173
+ ariaSettingsNavMobile: "Organization settings (mobile)",
5174
+ groupFinance: "Finance"
5169
5175
  };
5170
5176
  var profileAddCreditsModal$3 = {
5171
5177
  title: "Add Credits",
@@ -5361,7 +5367,6 @@ var profileIndex$3 = {
5361
5367
  langSpanish: "Spanish",
5362
5368
  langFrench: "French",
5363
5369
  checkboxDisplayMentorAI: "Display Agent Sidebar",
5364
- checkboxDisplayLeaderboard: "Display Leaderboard",
5365
5370
  labelFacebook: "Facebook",
5366
5371
  placeholderFacebook: "Facebook",
5367
5372
  labelLinkedIn: "LinkedIn",
@@ -5382,7 +5387,16 @@ var profileIndex$3 = {
5382
5387
  descChatHistoryPreview: "Conversations with AI agents.",
5383
5388
  ariaAddEducation: "Add education",
5384
5389
  ariaAddExperience: "Add experience",
5385
- ariaAddResume: "Add resume"
5390
+ ariaAddResume: "Add resume",
5391
+ tabLlmUsage: "Usage",
5392
+ descLlmUsage: "See how much AI you have used: spend, tokens and requests across your conversations.",
5393
+ groupProfile: "Profile",
5394
+ groupAiData: "AI & data",
5395
+ groupAccount: "Account",
5396
+ groupRecords: "Records",
5397
+ descLlmUsagePreview: "Spend, tokens and requests across conversations.",
5398
+ sectionFeatures: "Features",
5399
+ tooltipDisplayMentorAI: "Keeps the AI agent panel beside whatever you are working on, so you can ask questions without leaving the page."
5386
5400
  };
5387
5401
  var profileInviteUserContent$3 = {
5388
5402
  inviteUsersTitle: "Invite Users",
@@ -8407,6 +8421,81 @@ var analyticsTraces$3 = {
8407
8421
  mentorScopeTitle: "Agent scope narrows the trace list only.",
8408
8422
  mentorScopeBody: "Row-level observations cannot be filtered to a single agent upstream — open a trace to see its own calls."
8409
8423
  };
8424
+ var profileLlmUsage$3 = {
8425
+ rangeLabel: "Date range",
8426
+ rangeToday: "Today",
8427
+ range7d: "7 days",
8428
+ range30d: "30 days",
8429
+ range90d: "90 days",
8430
+ rangeAllTime: "All time",
8431
+ periodToday: "Today",
8432
+ period7d: "Last 7 days",
8433
+ period30d: "Last 30 days",
8434
+ period90d: "Last 90 days",
8435
+ periodAllTime: "All time",
8436
+ scopeSelf: "Only your own activity is shown",
8437
+ refresh: "Refresh usage",
8438
+ kpiSpend: "Spend",
8439
+ kpiTokens: "Tokens",
8440
+ kpiRequests: "Requests",
8441
+ kpiAvgCost: "Avg cost per request",
8442
+ kpiTokensSub: "{value} per request",
8443
+ kpiRequestsSub: "AI calls",
8444
+ kpiAvgCostSub: "Spend divided by requests",
8445
+ chartTitle: "Spend over time",
8446
+ chartSubtitleDay: "Daily spend in US dollars",
8447
+ chartSubtitleWeek: "Weekly spend in US dollars",
8448
+ chartSubtitleMonth: "Monthly spend in US dollars",
8449
+ chartAria: "Spend over time. Use the left and right arrow keys to read each bar.",
8450
+ chartNoData: "No spend in this period.",
8451
+ chartTableCaption: "Spend per period",
8452
+ colPeriod: "Period",
8453
+ colCost: "Cost",
8454
+ byModelTitle: "By model",
8455
+ byModelSubtitle: "Share of your spend per model",
8456
+ byServiceTitle: "By service",
8457
+ byServiceSubtitle: "Where your spend comes from",
8458
+ otherRow: "Other",
8459
+ unknownModel: "Unknown model",
8460
+ unknownService: "Other service",
8461
+ breakdownEmpty: "Nothing to break down in this period.",
8462
+ sectionError: "This section couldn't be loaded.",
8463
+ activityTitle: "Recent activity",
8464
+ activitySubtitle: "Your latest AI requests, newest first. Open one to see each step.",
8465
+ activityEmpty: "No requests in this period.",
8466
+ colWhen: "When",
8467
+ colService: "Service",
8468
+ colSession: "Session",
8469
+ colLatency: "Latency",
8470
+ colDetails: "Details",
8471
+ showSteps: "Show steps for {when}",
8472
+ hideSteps: "Hide steps for {when}",
8473
+ stepsLoading: "Loading steps…",
8474
+ stepsEmpty: "No steps were recorded for this request.",
8475
+ stepsError: "The steps for this request couldn't be loaded.",
8476
+ colStep: "Step",
8477
+ colModel: "Model",
8478
+ colInput: "Input",
8479
+ colOutput: "Output",
8480
+ colTotal: "Total",
8481
+ paginationSummary: "Showing {from}–{to} of {total}",
8482
+ previous: "Previous",
8483
+ next: "Next",
8484
+ emptyTitle: "No AI usage in this period",
8485
+ emptyBody: "Chats, memory and other AI requests show up here once they happen. Try a longer range.",
8486
+ emptyAction90: "Show last 90 days",
8487
+ emptyActionAll: "Show all time",
8488
+ errorForbiddenTitle: "Usage isn't available",
8489
+ errorForbiddenBody: "We couldn't load usage for this account.",
8490
+ errorUnavailableTitle: "Usage is temporarily unavailable",
8491
+ errorUnavailableBody: "Please try again in a few minutes.",
8492
+ errorUnauthorizedTitle: "Your session has expired",
8493
+ errorUnauthorizedBody: "Sign in again to see your usage.",
8494
+ errorUnknownTitle: "Something went wrong",
8495
+ errorUnknownBody: "We couldn't load your usage.",
8496
+ tryAgain: "Try again",
8497
+ scopeUser: "Usage for {username}"
8498
+ };
8410
8499
  var en = {
8411
8500
  accessTabAddAccess: accessTabAddAccess$3,
8412
8501
  accessTabLabels: accessTabLabels$3,
@@ -8691,7 +8780,8 @@ var en = {
8691
8780
  analyticsChartCard: analyticsChartCard$3,
8692
8781
  analyticsCostTabs: analyticsCostTabs$3,
8693
8782
  analyticsLlmUsage: analyticsLlmUsage$3,
8694
- analyticsTraces: analyticsTraces$3
8783
+ analyticsTraces: analyticsTraces$3,
8784
+ profileLlmUsage: profileLlmUsage$3
8695
8785
  };
8696
8786
 
8697
8787
  var accessTabAddAccess$2 = {
@@ -12522,7 +12612,13 @@ var profileAccount$2 = {
12522
12612
  tabBenchmarks: "Benchmarks",
12523
12613
  descBenchmarks: "Créez des suites de benchmarks d'entrées de test pour évaluer les agents.",
12524
12614
  tabMemory: "Mémoire",
12525
- descMemory: "Gérez les mémoires globales des utilisateurs et les mémoires des agents."
12615
+ descMemory: "Gérez les mémoires globales des utilisateurs et les mémoires des agents.",
12616
+ groupWorkspace: "Espace de travail",
12617
+ groupAiData: "IA et données",
12618
+ groupSystem: "Système",
12619
+ ariaSettingsNav: "Paramètres de l'organisation",
12620
+ ariaSettingsNavMobile: "Paramètres de l'organisation (mobile)",
12621
+ groupFinance: "Finance"
12526
12622
  };
12527
12623
  var profileAddCreditsModal$2 = {
12528
12624
  title: "Ajouter des crédits",
@@ -12718,7 +12814,6 @@ var profileIndex$2 = {
12718
12814
  langSpanish: "Espagnol",
12719
12815
  langFrench: "Français",
12720
12816
  checkboxDisplayMentorAI: "Afficher la barre latérale de l'agent",
12721
- checkboxDisplayLeaderboard: "Afficher le classement",
12722
12817
  labelFacebook: "Facebook",
12723
12818
  placeholderFacebook: "Facebook",
12724
12819
  labelLinkedIn: "LinkedIn",
@@ -12739,7 +12834,16 @@ var profileIndex$2 = {
12739
12834
  descChatHistoryPreview: "Conversations avec les agents IA.",
12740
12835
  ariaAddEducation: "Ajouter une formation",
12741
12836
  ariaAddExperience: "Ajouter une expérience",
12742
- ariaAddResume: "Ajouter un CV"
12837
+ ariaAddResume: "Ajouter un CV",
12838
+ tabLlmUsage: "Utilisation",
12839
+ descLlmUsage: "Voyez combien d'IA vous avez utilisé : dépenses, jetons et requêtes dans vos conversations.",
12840
+ groupProfile: "Profil",
12841
+ groupAiData: "IA et données",
12842
+ groupAccount: "Compte",
12843
+ groupRecords: "Dossiers",
12844
+ descLlmUsagePreview: "Dépenses, jetons et requêtes dans les conversations.",
12845
+ sectionFeatures: "Fonctionnalités",
12846
+ tooltipDisplayMentorAI: "Garde le panneau de l'agent IA à côté de ce que vous faites, pour poser des questions sans quitter la page."
12743
12847
  };
12744
12848
  var profileInviteUserContent$2 = {
12745
12849
  inviteUsersTitle: "Inviter des utilisateurs",
@@ -15598,6 +15702,81 @@ var analyticsTraces$2 = {
15598
15702
  mentorScopeTitle: "La portée par agent ne restreint que la liste des traces.",
15599
15703
  mentorScopeBody: "Les observations au niveau ligne ne peuvent pas être filtrées sur un seul agent — ouvrez une trace pour voir ses propres appels."
15600
15704
  };
15705
+ var profileLlmUsage$2 = {
15706
+ rangeLabel: "Période",
15707
+ rangeToday: "Aujourd'hui",
15708
+ range7d: "7 jours",
15709
+ range30d: "30 jours",
15710
+ range90d: "90 jours",
15711
+ rangeAllTime: "Tout",
15712
+ periodToday: "Aujourd'hui",
15713
+ period7d: "7 derniers jours",
15714
+ period30d: "30 derniers jours",
15715
+ period90d: "90 derniers jours",
15716
+ periodAllTime: "Depuis le début",
15717
+ scopeSelf: "Seule votre propre activité est affichée",
15718
+ refresh: "Actualiser l'utilisation",
15719
+ kpiSpend: "Dépenses",
15720
+ kpiTokens: "Jetons",
15721
+ kpiRequests: "Requêtes",
15722
+ kpiAvgCost: "Coût moyen par requête",
15723
+ kpiTokensSub: "{value} par requête",
15724
+ kpiRequestsSub: "Appels à l'IA",
15725
+ kpiAvgCostSub: "Dépenses divisées par les requêtes",
15726
+ chartTitle: "Dépenses dans le temps",
15727
+ chartSubtitleDay: "Dépenses quotidiennes en dollars américains",
15728
+ chartSubtitleWeek: "Dépenses hebdomadaires en dollars américains",
15729
+ chartSubtitleMonth: "Dépenses mensuelles en dollars américains",
15730
+ chartAria: "Dépenses dans le temps. Utilisez les flèches gauche et droite pour lire chaque barre.",
15731
+ chartNoData: "Aucune dépense sur cette période.",
15732
+ chartTableCaption: "Dépenses par période",
15733
+ colPeriod: "Période",
15734
+ colCost: "Coût",
15735
+ byModelTitle: "Par modèle",
15736
+ byModelSubtitle: "Part de vos dépenses par modèle",
15737
+ byServiceTitle: "Par service",
15738
+ byServiceSubtitle: "D'où viennent vos dépenses",
15739
+ otherRow: "Autres",
15740
+ unknownModel: "Modèle inconnu",
15741
+ unknownService: "Autre service",
15742
+ breakdownEmpty: "Rien à détailler sur cette période.",
15743
+ sectionError: "Cette section n'a pas pu être chargée.",
15744
+ activityTitle: "Activité récente",
15745
+ activitySubtitle: "Vos dernières requêtes d'IA, les plus récentes d'abord. Ouvrez-en une pour voir chaque étape.",
15746
+ activityEmpty: "Aucune requête sur cette période.",
15747
+ colWhen: "Quand",
15748
+ colService: "Service",
15749
+ colSession: "Session",
15750
+ colLatency: "Latence",
15751
+ colDetails: "Détails",
15752
+ showSteps: "Afficher les étapes du {when}",
15753
+ hideSteps: "Masquer les étapes du {when}",
15754
+ stepsLoading: "Chargement des étapes…",
15755
+ stepsEmpty: "Aucune étape n'a été enregistrée pour cette requête.",
15756
+ stepsError: "Les étapes de cette requête n'ont pas pu être chargées.",
15757
+ colStep: "Étape",
15758
+ colModel: "Modèle",
15759
+ colInput: "Entrée",
15760
+ colOutput: "Sortie",
15761
+ colTotal: "Total",
15762
+ paginationSummary: "{from}–{to} sur {total}",
15763
+ previous: "Précédent",
15764
+ next: "Suivant",
15765
+ emptyTitle: "Aucune utilisation de l'IA sur cette période",
15766
+ emptyBody: "Les discussions, la mémoire et les autres requêtes d'IA apparaissent ici dès qu'elles ont lieu. Essayez une période plus longue.",
15767
+ emptyAction90: "Afficher les 90 derniers jours",
15768
+ emptyActionAll: "Tout afficher",
15769
+ errorForbiddenTitle: "L'utilisation n'est pas disponible",
15770
+ errorForbiddenBody: "Nous n'avons pas pu charger l'utilisation de ce compte.",
15771
+ errorUnavailableTitle: "L'utilisation est temporairement indisponible",
15772
+ errorUnavailableBody: "Veuillez réessayer dans quelques minutes.",
15773
+ errorUnauthorizedTitle: "Votre session a expiré",
15774
+ errorUnauthorizedBody: "Reconnectez-vous pour voir votre utilisation.",
15775
+ errorUnknownTitle: "Un problème est survenu",
15776
+ errorUnknownBody: "Nous n'avons pas pu charger votre utilisation.",
15777
+ tryAgain: "Réessayer",
15778
+ scopeUser: "Utilisation de {username}"
15779
+ };
15601
15780
  var fr = {
15602
15781
  accessTabAddAccess: accessTabAddAccess$2,
15603
15782
  accessTabLabels: accessTabLabels$2,
@@ -15882,7 +16061,8 @@ var fr = {
15882
16061
  analyticsChartCard: analyticsChartCard$2,
15883
16062
  analyticsCostTabs: analyticsCostTabs$2,
15884
16063
  analyticsLlmUsage: analyticsLlmUsage$2,
15885
- analyticsTraces: analyticsTraces$2
16064
+ analyticsTraces: analyticsTraces$2,
16065
+ profileLlmUsage: profileLlmUsage$2
15886
16066
  };
15887
16067
 
15888
16068
  var accessTabAddAccess$1 = {
@@ -19713,7 +19893,13 @@ var profileAccount$1 = {
19713
19893
  tabBenchmarks: "Benchmarks",
19714
19894
  descBenchmarks: "Cree suites de benchmarks con entradas de prueba para evaluar agentes.",
19715
19895
  tabMemory: "Memoria",
19716
- descMemory: "Gestiona las memorias globales de los usuarios y las memorias de los agentes."
19896
+ descMemory: "Gestiona las memorias globales de los usuarios y las memorias de los agentes.",
19897
+ groupWorkspace: "Espacio de trabajo",
19898
+ groupAiData: "IA y datos",
19899
+ groupSystem: "Sistema",
19900
+ ariaSettingsNav: "Configuración de la organización",
19901
+ ariaSettingsNavMobile: "Configuración de la organización (móvil)",
19902
+ groupFinance: "Finanzas"
19717
19903
  };
19718
19904
  var profileAddCreditsModal$1 = {
19719
19905
  title: "Agregar créditos",
@@ -19909,7 +20095,6 @@ var profileIndex$1 = {
19909
20095
  langSpanish: "Español",
19910
20096
  langFrench: "Francés",
19911
20097
  checkboxDisplayMentorAI: "Mostrar barra lateral del agente",
19912
- checkboxDisplayLeaderboard: "Mostrar tabla de clasificación",
19913
20098
  labelFacebook: "Facebook",
19914
20099
  placeholderFacebook: "Facebook",
19915
20100
  labelLinkedIn: "LinkedIn",
@@ -19930,7 +20115,16 @@ var profileIndex$1 = {
19930
20115
  descChatHistoryPreview: "Conversaciones con agentes de IA.",
19931
20116
  ariaAddEducation: "Añadir educación",
19932
20117
  ariaAddExperience: "Añadir experiencia",
19933
- ariaAddResume: "Añadir currículum"
20118
+ ariaAddResume: "Añadir currículum",
20119
+ tabLlmUsage: "Uso",
20120
+ descLlmUsage: "Consulta cuánta IA has usado: gasto, tokens y solicitudes en tus conversaciones.",
20121
+ groupProfile: "Perfil",
20122
+ groupAiData: "IA y datos",
20123
+ groupAccount: "Cuenta",
20124
+ groupRecords: "Registros",
20125
+ descLlmUsagePreview: "Gasto, tokens y solicitudes en las conversaciones.",
20126
+ sectionFeatures: "Funciones",
20127
+ tooltipDisplayMentorAI: "Mantiene el panel del agente de IA junto a lo que estés haciendo, para que puedas preguntar sin salir de la página."
19934
20128
  };
19935
20129
  var profileInviteUserContent$1 = {
19936
20130
  inviteUsersTitle: "Invitar usuarios",
@@ -22789,6 +22983,81 @@ var analyticsTraces$1 = {
22789
22983
  mentorScopeTitle: "El alcance por agente solo acota la lista de trazas.",
22790
22984
  mentorScopeBody: "Las observaciones a nivel de fila no pueden filtrarse por un solo agente — abre una traza para ver sus propias llamadas."
22791
22985
  };
22986
+ var profileLlmUsage$1 = {
22987
+ rangeLabel: "Rango de fechas",
22988
+ rangeToday: "Hoy",
22989
+ range7d: "7 días",
22990
+ range30d: "30 días",
22991
+ range90d: "90 días",
22992
+ rangeAllTime: "Todo",
22993
+ periodToday: "Hoy",
22994
+ period7d: "Últimos 7 días",
22995
+ period30d: "Últimos 30 días",
22996
+ period90d: "Últimos 90 días",
22997
+ periodAllTime: "Todo el tiempo",
22998
+ scopeSelf: "Solo se muestra tu propia actividad",
22999
+ refresh: "Actualizar uso",
23000
+ kpiSpend: "Gasto",
23001
+ kpiTokens: "Tokens",
23002
+ kpiRequests: "Solicitudes",
23003
+ kpiAvgCost: "Costo promedio por solicitud",
23004
+ kpiTokensSub: "{value} por solicitud",
23005
+ kpiRequestsSub: "Llamadas a la IA",
23006
+ kpiAvgCostSub: "Gasto dividido entre solicitudes",
23007
+ chartTitle: "Gasto a lo largo del tiempo",
23008
+ chartSubtitleDay: "Gasto diario en dólares estadounidenses",
23009
+ chartSubtitleWeek: "Gasto semanal en dólares estadounidenses",
23010
+ chartSubtitleMonth: "Gasto mensual en dólares estadounidenses",
23011
+ chartAria: "Gasto a lo largo del tiempo. Usa las flechas izquierda y derecha para leer cada barra.",
23012
+ chartNoData: "No hay gasto en este período.",
23013
+ chartTableCaption: "Gasto por período",
23014
+ colPeriod: "Período",
23015
+ colCost: "Costo",
23016
+ byModelTitle: "Por modelo",
23017
+ byModelSubtitle: "Parte de tu gasto por modelo",
23018
+ byServiceTitle: "Por servicio",
23019
+ byServiceSubtitle: "De dónde proviene tu gasto",
23020
+ otherRow: "Otros",
23021
+ unknownModel: "Modelo desconocido",
23022
+ unknownService: "Otro servicio",
23023
+ breakdownEmpty: "No hay nada que desglosar en este período.",
23024
+ sectionError: "No se pudo cargar esta sección.",
23025
+ activityTitle: "Actividad reciente",
23026
+ activitySubtitle: "Tus solicitudes de IA más recientes, primero las más nuevas. Abre una para ver cada paso.",
23027
+ activityEmpty: "No hay solicitudes en este período.",
23028
+ colWhen: "Cuándo",
23029
+ colService: "Servicio",
23030
+ colSession: "Sesión",
23031
+ colLatency: "Latencia",
23032
+ colDetails: "Detalles",
23033
+ showSteps: "Mostrar pasos de {when}",
23034
+ hideSteps: "Ocultar pasos de {when}",
23035
+ stepsLoading: "Cargando pasos…",
23036
+ stepsEmpty: "No se registraron pasos para esta solicitud.",
23037
+ stepsError: "No se pudieron cargar los pasos de esta solicitud.",
23038
+ colStep: "Paso",
23039
+ colModel: "Modelo",
23040
+ colInput: "Entrada",
23041
+ colOutput: "Salida",
23042
+ colTotal: "Total",
23043
+ paginationSummary: "Mostrando {from}–{to} de {total}",
23044
+ previous: "Anterior",
23045
+ next: "Siguiente",
23046
+ emptyTitle: "Sin uso de IA en este período",
23047
+ emptyBody: "Los chats, la memoria y otras solicitudes de IA aparecen aquí cuando ocurren. Prueba un rango más amplio.",
23048
+ emptyAction90: "Mostrar los últimos 90 días",
23049
+ emptyActionAll: "Mostrar todo",
23050
+ errorForbiddenTitle: "El uso no está disponible",
23051
+ errorForbiddenBody: "No pudimos cargar el uso de esta cuenta.",
23052
+ errorUnavailableTitle: "El uso no está disponible temporalmente",
23053
+ errorUnavailableBody: "Inténtalo de nuevo en unos minutos.",
23054
+ errorUnauthorizedTitle: "Tu sesión ha expirado",
23055
+ errorUnauthorizedBody: "Vuelve a iniciar sesión para ver tu uso.",
23056
+ errorUnknownTitle: "Algo salió mal",
23057
+ errorUnknownBody: "No pudimos cargar tu uso.",
23058
+ tryAgain: "Intentar de nuevo",
23059
+ scopeUser: "Uso de {username}"
23060
+ };
22792
23061
  var es = {
22793
23062
  accessTabAddAccess: accessTabAddAccess$1,
22794
23063
  accessTabLabels: accessTabLabels$1,
@@ -23073,7 +23342,8 @@ var es = {
23073
23342
  analyticsChartCard: analyticsChartCard$1,
23074
23343
  analyticsCostTabs: analyticsCostTabs$1,
23075
23344
  analyticsLlmUsage: analyticsLlmUsage$1,
23076
- analyticsTraces: analyticsTraces$1
23345
+ analyticsTraces: analyticsTraces$1,
23346
+ profileLlmUsage: profileLlmUsage$1
23077
23347
  };
23078
23348
 
23079
23349
  var accessTabAddAccess = {
@@ -26904,7 +27174,13 @@ var profileAccount = {
26904
27174
  tabBenchmarks: "基准测试",
26905
27175
  descBenchmarks: "构建包含测试输入的基准测试套件,以评估智能体。",
26906
27176
  tabMemory: "记忆",
26907
- descMemory: "管理用户的全局记忆和智能体记忆。"
27177
+ descMemory: "管理用户的全局记忆和智能体记忆。",
27178
+ groupWorkspace: "工作区",
27179
+ groupAiData: "AI 与数据",
27180
+ groupSystem: "系统",
27181
+ ariaSettingsNav: "组织设置",
27182
+ ariaSettingsNavMobile: "组织设置(移动端)",
27183
+ groupFinance: "财务"
26908
27184
  };
26909
27185
  var profileAddCreditsModal = {
26910
27186
  title: "添加积分",
@@ -27100,7 +27376,6 @@ var profileIndex = {
27100
27376
  langSpanish: "西班牙语",
27101
27377
  langFrench: "法语",
27102
27378
  checkboxDisplayMentorAI: "显示助手侧边栏",
27103
- checkboxDisplayLeaderboard: "显示排行榜",
27104
27379
  labelFacebook: "Facebook",
27105
27380
  placeholderFacebook: "Facebook",
27106
27381
  labelLinkedIn: "LinkedIn",
@@ -27121,7 +27396,16 @@ var profileIndex = {
27121
27396
  descChatHistoryPreview: "与 AI 代理的对话。",
27122
27397
  ariaAddEducation: "添加教育经历",
27123
27398
  ariaAddExperience: "添加工作经历",
27124
- ariaAddResume: "添加简历"
27399
+ ariaAddResume: "添加简历",
27400
+ tabLlmUsage: "用量",
27401
+ descLlmUsage: "查看你使用了多少 AI:各对话中的花费、令牌数和请求数。",
27402
+ groupProfile: "个人资料",
27403
+ groupAiData: "AI 与数据",
27404
+ groupAccount: "账户",
27405
+ groupRecords: "记录",
27406
+ descLlmUsagePreview: "各对话中的花费、令牌数和请求数。",
27407
+ sectionFeatures: "功能",
27408
+ tooltipDisplayMentorAI: "让 AI 助手面板始终显示在当前页面旁边,无需离开页面即可提问。"
27125
27409
  };
27126
27410
  var profileInviteUserContent = {
27127
27411
  inviteUsersTitle: "邀请用户",
@@ -29980,6 +30264,81 @@ var analyticsTraces = {
29980
30264
  mentorScopeTitle: "代理范围仅缩小追踪列表。",
29981
30265
  mentorScopeBody: "行级观测记录无法按单个代理筛选 — 打开一条追踪查看它自己的调用。"
29982
30266
  };
30267
+ var profileLlmUsage = {
30268
+ rangeLabel: "日期范围",
30269
+ rangeToday: "今天",
30270
+ range7d: "7 天",
30271
+ range30d: "30 天",
30272
+ range90d: "90 天",
30273
+ rangeAllTime: "全部",
30274
+ periodToday: "今天",
30275
+ period7d: "最近 7 天",
30276
+ period30d: "最近 30 天",
30277
+ period90d: "最近 90 天",
30278
+ periodAllTime: "全部时间",
30279
+ scopeSelf: "仅显示你自己的活动",
30280
+ refresh: "刷新用量",
30281
+ kpiSpend: "花费",
30282
+ kpiTokens: "令牌",
30283
+ kpiRequests: "请求",
30284
+ kpiAvgCost: "每次请求平均花费",
30285
+ kpiTokensSub: "每次请求 {value}",
30286
+ kpiRequestsSub: "AI 调用",
30287
+ kpiAvgCostSub: "花费除以请求数",
30288
+ chartTitle: "花费趋势",
30289
+ chartSubtitleDay: "每日花费(美元)",
30290
+ chartSubtitleWeek: "每周花费(美元)",
30291
+ chartSubtitleMonth: "每月花费(美元)",
30292
+ chartAria: "花费趋势。使用左右方向键逐个读取柱形。",
30293
+ chartNoData: "此期间没有花费。",
30294
+ chartTableCaption: "各期间花费",
30295
+ colPeriod: "期间",
30296
+ colCost: "花费",
30297
+ byModelTitle: "按模型",
30298
+ byModelSubtitle: "各模型占你花费的比例",
30299
+ byServiceTitle: "按服务",
30300
+ byServiceSubtitle: "你的花费来自哪里",
30301
+ otherRow: "其他",
30302
+ unknownModel: "未知模型",
30303
+ unknownService: "其他服务",
30304
+ breakdownEmpty: "此期间没有可细分的数据。",
30305
+ sectionError: "无法加载此部分。",
30306
+ activityTitle: "最近活动",
30307
+ activitySubtitle: "你最近的 AI 请求,最新的在前。展开可查看每个步骤。",
30308
+ activityEmpty: "此期间没有请求。",
30309
+ colWhen: "时间",
30310
+ colService: "服务",
30311
+ colSession: "会话",
30312
+ colLatency: "延迟",
30313
+ colDetails: "详情",
30314
+ showSteps: "显示 {when} 的步骤",
30315
+ hideSteps: "隐藏 {when} 的步骤",
30316
+ stepsLoading: "正在加载步骤…",
30317
+ stepsEmpty: "此请求没有记录任何步骤。",
30318
+ stepsError: "无法加载此请求的步骤。",
30319
+ colStep: "步骤",
30320
+ colModel: "模型",
30321
+ colInput: "输入",
30322
+ colOutput: "输出",
30323
+ colTotal: "合计",
30324
+ paginationSummary: "第 {from}–{to} 条,共 {total} 条",
30325
+ previous: "上一页",
30326
+ next: "下一页",
30327
+ emptyTitle: "此期间没有 AI 用量",
30328
+ emptyBody: "发生聊天、记忆和其他 AI 请求后,相关记录会显示在这里。请尝试更长的时间范围。",
30329
+ emptyAction90: "显示最近 90 天",
30330
+ emptyActionAll: "显示全部",
30331
+ errorForbiddenTitle: "无法查看用量",
30332
+ errorForbiddenBody: "无法加载此账户的用量。",
30333
+ errorUnavailableTitle: "用量暂时不可用",
30334
+ errorUnavailableBody: "请几分钟后再试。",
30335
+ errorUnauthorizedTitle: "你的会话已过期",
30336
+ errorUnauthorizedBody: "请重新登录以查看你的用量。",
30337
+ errorUnknownTitle: "出现问题",
30338
+ errorUnknownBody: "无法加载你的用量。",
30339
+ tryAgain: "重试",
30340
+ scopeUser: "{username} 的用量"
30341
+ };
29983
30342
  var zh = {
29984
30343
  accessTabAddAccess: accessTabAddAccess,
29985
30344
  accessTabLabels: accessTabLabels,
@@ -30264,7 +30623,8 @@ var zh = {
30264
30623
  analyticsChartCard: analyticsChartCard,
30265
30624
  analyticsCostTabs: analyticsCostTabs,
30266
30625
  analyticsLlmUsage: analyticsLlmUsage,
30267
- analyticsTraces: analyticsTraces
30626
+ analyticsTraces: analyticsTraces,
30627
+ profileLlmUsage: profileLlmUsage
30268
30628
  };
30269
30629
 
30270
30630
  /**
@@ -78709,7 +79069,7 @@ const createLucideIcon = (iconName, iconNode) => {
78709
79069
  */
78710
79070
 
78711
79071
 
78712
- const __iconNode$2r = [
79072
+ const __iconNode$2t = [
78713
79073
  [
78714
79074
  "path",
78715
79075
  {
@@ -78718,7 +79078,7 @@ const __iconNode$2r = [
78718
79078
  }
78719
79079
  ]
78720
79080
  ];
78721
- const Activity = createLucideIcon("activity", __iconNode$2r);
79081
+ const Activity = createLucideIcon("activity", __iconNode$2t);
78722
79082
 
78723
79083
  /**
78724
79084
  * @license lucide-react v0.528.0 - ISC
@@ -78728,12 +79088,12 @@ const Activity = createLucideIcon("activity", __iconNode$2r);
78728
79088
  */
78729
79089
 
78730
79090
 
78731
- const __iconNode$2q = [
79091
+ const __iconNode$2s = [
78732
79092
  ["path", { d: "M17 12H7", key: "16if0g" }],
78733
79093
  ["path", { d: "M19 18H5", key: "18s9l3" }],
78734
79094
  ["path", { d: "M21 6H3", key: "1jwq7v" }]
78735
79095
  ];
78736
- const AlignCenter = createLucideIcon("align-center", __iconNode$2q);
79096
+ const AlignCenter = createLucideIcon("align-center", __iconNode$2s);
78737
79097
 
78738
79098
  /**
78739
79099
  * @license lucide-react v0.528.0 - ISC
@@ -78743,12 +79103,12 @@ const AlignCenter = createLucideIcon("align-center", __iconNode$2q);
78743
79103
  */
78744
79104
 
78745
79105
 
78746
- const __iconNode$2p = [
79106
+ const __iconNode$2r = [
78747
79107
  ["path", { d: "M15 12H3", key: "6jk70r" }],
78748
79108
  ["path", { d: "M17 18H3", key: "1amg6g" }],
78749
79109
  ["path", { d: "M21 6H3", key: "1jwq7v" }]
78750
79110
  ];
78751
- const AlignLeft = createLucideIcon("align-left", __iconNode$2p);
79111
+ const AlignLeft = createLucideIcon("align-left", __iconNode$2r);
78752
79112
 
78753
79113
  /**
78754
79114
  * @license lucide-react v0.528.0 - ISC
@@ -78758,12 +79118,12 @@ const AlignLeft = createLucideIcon("align-left", __iconNode$2p);
78758
79118
  */
78759
79119
 
78760
79120
 
78761
- const __iconNode$2o = [
79121
+ const __iconNode$2q = [
78762
79122
  ["path", { d: "M21 12H9", key: "dn1m92" }],
78763
79123
  ["path", { d: "M21 18H7", key: "1ygte8" }],
78764
79124
  ["path", { d: "M21 6H3", key: "1jwq7v" }]
78765
79125
  ];
78766
- const AlignRight = createLucideIcon("align-right", __iconNode$2o);
79126
+ const AlignRight = createLucideIcon("align-right", __iconNode$2q);
78767
79127
 
78768
79128
  /**
78769
79129
  * @license lucide-react v0.528.0 - ISC
@@ -78773,12 +79133,12 @@ const AlignRight = createLucideIcon("align-right", __iconNode$2o);
78773
79133
  */
78774
79134
 
78775
79135
 
78776
- const __iconNode$2n = [
79136
+ const __iconNode$2p = [
78777
79137
  ["rect", { width: "20", height: "5", x: "2", y: "3", rx: "1", key: "1wp1u1" }],
78778
79138
  ["path", { d: "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8", key: "1s80jp" }],
78779
79139
  ["path", { d: "M10 12h4", key: "a56b0p" }]
78780
79140
  ];
78781
- const Archive = createLucideIcon("archive", __iconNode$2n);
79141
+ const Archive = createLucideIcon("archive", __iconNode$2p);
78782
79142
 
78783
79143
  /**
78784
79144
  * @license lucide-react v0.528.0 - ISC
@@ -78788,11 +79148,11 @@ const Archive = createLucideIcon("archive", __iconNode$2n);
78788
79148
  */
78789
79149
 
78790
79150
 
78791
- const __iconNode$2m = [
79151
+ const __iconNode$2o = [
78792
79152
  ["path", { d: "M12 5v14", key: "s699le" }],
78793
79153
  ["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
78794
79154
  ];
78795
- const ArrowDown = createLucideIcon("arrow-down", __iconNode$2m);
79155
+ const ArrowDown = createLucideIcon("arrow-down", __iconNode$2o);
78796
79156
 
78797
79157
  /**
78798
79158
  * @license lucide-react v0.528.0 - ISC
@@ -78802,11 +79162,11 @@ const ArrowDown = createLucideIcon("arrow-down", __iconNode$2m);
78802
79162
  */
78803
79163
 
78804
79164
 
78805
- const __iconNode$2l = [
79165
+ const __iconNode$2n = [
78806
79166
  ["path", { d: "m12 19-7-7 7-7", key: "1l729n" }],
78807
79167
  ["path", { d: "M19 12H5", key: "x3x0zl" }]
78808
79168
  ];
78809
- const ArrowLeft = createLucideIcon("arrow-left", __iconNode$2l);
79169
+ const ArrowLeft = createLucideIcon("arrow-left", __iconNode$2n);
78810
79170
 
78811
79171
  /**
78812
79172
  * @license lucide-react v0.528.0 - ISC
@@ -78816,11 +79176,11 @@ const ArrowLeft = createLucideIcon("arrow-left", __iconNode$2l);
78816
79176
  */
78817
79177
 
78818
79178
 
78819
- const __iconNode$2k = [
79179
+ const __iconNode$2m = [
78820
79180
  ["path", { d: "M5 12h14", key: "1ays0h" }],
78821
79181
  ["path", { d: "m12 5 7 7-7 7", key: "xquz4c" }]
78822
79182
  ];
78823
- const ArrowRight = createLucideIcon("arrow-right", __iconNode$2k);
79183
+ const ArrowRight = createLucideIcon("arrow-right", __iconNode$2m);
78824
79184
 
78825
79185
  /**
78826
79186
  * @license lucide-react v0.528.0 - ISC
@@ -78830,11 +79190,11 @@ const ArrowRight = createLucideIcon("arrow-right", __iconNode$2k);
78830
79190
  */
78831
79191
 
78832
79192
 
78833
- const __iconNode$2j = [
79193
+ const __iconNode$2l = [
78834
79194
  ["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
78835
79195
  ["path", { d: "M12 19V5", key: "x0mq9r" }]
78836
79196
  ];
78837
- const ArrowUp = createLucideIcon("arrow-up", __iconNode$2j);
79197
+ const ArrowUp = createLucideIcon("arrow-up", __iconNode$2l);
78838
79198
 
78839
79199
  /**
78840
79200
  * @license lucide-react v0.528.0 - ISC
@@ -78844,7 +79204,7 @@ const ArrowUp = createLucideIcon("arrow-up", __iconNode$2j);
78844
79204
  */
78845
79205
 
78846
79206
 
78847
- const __iconNode$2i = [
79207
+ const __iconNode$2k = [
78848
79208
  [
78849
79209
  "path",
78850
79210
  {
@@ -78854,7 +79214,7 @@ const __iconNode$2i = [
78854
79214
  ],
78855
79215
  ["circle", { cx: "12", cy: "8", r: "6", key: "1vp47v" }]
78856
79216
  ];
78857
- const Award = createLucideIcon("award", __iconNode$2i);
79217
+ const Award = createLucideIcon("award", __iconNode$2k);
78858
79218
 
78859
79219
  /**
78860
79220
  * @license lucide-react v0.528.0 - ISC
@@ -78864,11 +79224,11 @@ const Award = createLucideIcon("award", __iconNode$2i);
78864
79224
  */
78865
79225
 
78866
79226
 
78867
- const __iconNode$2h = [
79227
+ const __iconNode$2j = [
78868
79228
  ["path", { d: "M4.929 4.929 19.07 19.071", key: "196cmz" }],
78869
79229
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]
78870
79230
  ];
78871
- const Ban = createLucideIcon("ban", __iconNode$2h);
79231
+ const Ban = createLucideIcon("ban", __iconNode$2j);
78872
79232
 
78873
79233
  /**
78874
79234
  * @license lucide-react v0.528.0 - ISC
@@ -78878,12 +79238,12 @@ const Ban = createLucideIcon("ban", __iconNode$2h);
78878
79238
  */
78879
79239
 
78880
79240
 
78881
- const __iconNode$2g = [
79241
+ const __iconNode$2i = [
78882
79242
  ["rect", { width: "20", height: "12", x: "2", y: "6", rx: "2", key: "9lu3g6" }],
78883
79243
  ["circle", { cx: "12", cy: "12", r: "2", key: "1c9p78" }],
78884
79244
  ["path", { d: "M6 12h.01M18 12h.01", key: "113zkx" }]
78885
79245
  ];
78886
- const Banknote = createLucideIcon("banknote", __iconNode$2g);
79246
+ const Banknote = createLucideIcon("banknote", __iconNode$2i);
78887
79247
 
78888
79248
  /**
78889
79249
  * @license lucide-react v0.528.0 - ISC
@@ -78893,7 +79253,7 @@ const Banknote = createLucideIcon("banknote", __iconNode$2g);
78893
79253
  */
78894
79254
 
78895
79255
 
78896
- const __iconNode$2f = [
79256
+ const __iconNode$2h = [
78897
79257
  ["path", { d: "M10.268 21a2 2 0 0 0 3.464 0", key: "vwvbt9" }],
78898
79258
  ["path", { d: "M22 8c0-2.3-.8-4.3-2-6", key: "5bb3ad" }],
78899
79259
  [
@@ -78905,7 +79265,7 @@ const __iconNode$2f = [
78905
79265
  ],
78906
79266
  ["path", { d: "M4 2C2.8 3.7 2 5.7 2 8", key: "tap9e0" }]
78907
79267
  ];
78908
- const BellRing = createLucideIcon("bell-ring", __iconNode$2f);
79268
+ const BellRing = createLucideIcon("bell-ring", __iconNode$2h);
78909
79269
 
78910
79270
  /**
78911
79271
  * @license lucide-react v0.528.0 - ISC
@@ -78915,7 +79275,7 @@ const BellRing = createLucideIcon("bell-ring", __iconNode$2f);
78915
79275
  */
78916
79276
 
78917
79277
 
78918
- const __iconNode$2e = [
79278
+ const __iconNode$2g = [
78919
79279
  ["path", { d: "M10.268 21a2 2 0 0 0 3.464 0", key: "vwvbt9" }],
78920
79280
  [
78921
79281
  "path",
@@ -78925,7 +79285,7 @@ const __iconNode$2e = [
78925
79285
  }
78926
79286
  ]
78927
79287
  ];
78928
- const Bell = createLucideIcon("bell", __iconNode$2e);
79288
+ const Bell = createLucideIcon("bell", __iconNode$2g);
78929
79289
 
78930
79290
  /**
78931
79291
  * @license lucide-react v0.528.0 - ISC
@@ -78935,13 +79295,13 @@ const Bell = createLucideIcon("bell", __iconNode$2e);
78935
79295
  */
78936
79296
 
78937
79297
 
78938
- const __iconNode$2d = [
79298
+ const __iconNode$2f = [
78939
79299
  [
78940
79300
  "path",
78941
79301
  { d: "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8", key: "mg9rjx" }
78942
79302
  ]
78943
79303
  ];
78944
- const Bold$1 = createLucideIcon("bold", __iconNode$2d);
79304
+ const Bold$1 = createLucideIcon("bold", __iconNode$2f);
78945
79305
 
78946
79306
  /**
78947
79307
  * @license lucide-react v0.528.0 - ISC
@@ -78951,7 +79311,7 @@ const Bold$1 = createLucideIcon("bold", __iconNode$2d);
78951
79311
  */
78952
79312
 
78953
79313
 
78954
- const __iconNode$2c = [
79314
+ const __iconNode$2e = [
78955
79315
  ["path", { d: "M12 7v14", key: "1akyts" }],
78956
79316
  [
78957
79317
  "path",
@@ -78961,7 +79321,7 @@ const __iconNode$2c = [
78961
79321
  }
78962
79322
  ]
78963
79323
  ];
78964
- const BookOpen = createLucideIcon("book-open", __iconNode$2c);
79324
+ const BookOpen = createLucideIcon("book-open", __iconNode$2e);
78965
79325
 
78966
79326
  /**
78967
79327
  * @license lucide-react v0.528.0 - ISC
@@ -78971,7 +79331,7 @@ const BookOpen = createLucideIcon("book-open", __iconNode$2c);
78971
79331
  */
78972
79332
 
78973
79333
 
78974
- const __iconNode$2b = [
79334
+ const __iconNode$2d = [
78975
79335
  ["path", { d: "M12 8V4H8", key: "hb8ula" }],
78976
79336
  ["rect", { width: "16", height: "12", x: "4", y: "8", rx: "2", key: "enze0r" }],
78977
79337
  ["path", { d: "M2 14h2", key: "vft8re" }],
@@ -78979,7 +79339,7 @@ const __iconNode$2b = [
78979
79339
  ["path", { d: "M15 13v2", key: "1xurst" }],
78980
79340
  ["path", { d: "M9 13v2", key: "rq6x2g" }]
78981
79341
  ];
78982
- const Bot = createLucideIcon("bot", __iconNode$2b);
79342
+ const Bot = createLucideIcon("bot", __iconNode$2d);
78983
79343
 
78984
79344
  /**
78985
79345
  * @license lucide-react v0.528.0 - ISC
@@ -78989,11 +79349,11 @@ const Bot = createLucideIcon("bot", __iconNode$2b);
78989
79349
  */
78990
79350
 
78991
79351
 
78992
- const __iconNode$2a = [
79352
+ const __iconNode$2c = [
78993
79353
  ["path", { d: "M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16", key: "jecpp" }],
78994
79354
  ["rect", { width: "20", height: "14", x: "2", y: "6", rx: "2", key: "i6l2r4" }]
78995
79355
  ];
78996
- const Briefcase = createLucideIcon("briefcase", __iconNode$2a);
79356
+ const Briefcase = createLucideIcon("briefcase", __iconNode$2c);
78997
79357
 
78998
79358
  /**
78999
79359
  * @license lucide-react v0.528.0 - ISC
@@ -79003,7 +79363,7 @@ const Briefcase = createLucideIcon("briefcase", __iconNode$2a);
79003
79363
  */
79004
79364
 
79005
79365
 
79006
- const __iconNode$29 = [
79366
+ const __iconNode$2b = [
79007
79367
  ["path", { d: "M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z", key: "1b4qmf" }],
79008
79368
  ["path", { d: "M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2", key: "i71pzd" }],
79009
79369
  ["path", { d: "M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2", key: "10jefs" }],
@@ -79012,7 +79372,7 @@ const __iconNode$29 = [
79012
79372
  ["path", { d: "M10 14h4", key: "kelpxr" }],
79013
79373
  ["path", { d: "M10 18h4", key: "1ulq68" }]
79014
79374
  ];
79015
- const Building2 = createLucideIcon("building-2", __iconNode$29);
79375
+ const Building2 = createLucideIcon("building-2", __iconNode$2b);
79016
79376
 
79017
79377
  /**
79018
79378
  * @license lucide-react v0.528.0 - ISC
@@ -79022,13 +79382,13 @@ const Building2 = createLucideIcon("building-2", __iconNode$29);
79022
79382
  */
79023
79383
 
79024
79384
 
79025
- const __iconNode$28 = [
79385
+ const __iconNode$2a = [
79026
79386
  ["path", { d: "M8 2v4", key: "1cmpym" }],
79027
79387
  ["path", { d: "M16 2v4", key: "4m81vk" }],
79028
79388
  ["rect", { width: "18", height: "18", x: "3", y: "4", rx: "2", key: "1hopcy" }],
79029
79389
  ["path", { d: "M3 10h18", key: "8toen8" }]
79030
79390
  ];
79031
- const Calendar$1 = createLucideIcon("calendar", __iconNode$28);
79391
+ const Calendar$1 = createLucideIcon("calendar", __iconNode$2a);
79032
79392
 
79033
79393
  /**
79034
79394
  * @license lucide-react v0.528.0 - ISC
@@ -79038,11 +79398,31 @@ const Calendar$1 = createLucideIcon("calendar", __iconNode$28);
79038
79398
  */
79039
79399
 
79040
79400
 
79041
- const __iconNode$27 = [
79401
+ const __iconNode$29 = [
79402
+ [
79403
+ "path",
79404
+ {
79405
+ d: "M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z",
79406
+ key: "1tc9qg"
79407
+ }
79408
+ ],
79409
+ ["circle", { cx: "12", cy: "13", r: "3", key: "1vg3eu" }]
79410
+ ];
79411
+ const Camera = createLucideIcon("camera", __iconNode$29);
79412
+
79413
+ /**
79414
+ * @license lucide-react v0.528.0 - ISC
79415
+ *
79416
+ * This source code is licensed under the ISC license.
79417
+ * See the LICENSE file in the root directory of this source tree.
79418
+ */
79419
+
79420
+
79421
+ const __iconNode$28 = [
79042
79422
  ["path", { d: "M18 6 7 17l-5-5", key: "116fxf" }],
79043
79423
  ["path", { d: "m22 10-7.5 7.5L13 16", key: "ke71qq" }]
79044
79424
  ];
79045
- const CheckCheck = createLucideIcon("check-check", __iconNode$27);
79425
+ const CheckCheck = createLucideIcon("check-check", __iconNode$28);
79046
79426
 
79047
79427
  /**
79048
79428
  * @license lucide-react v0.528.0 - ISC
@@ -79052,8 +79432,8 @@ const CheckCheck = createLucideIcon("check-check", __iconNode$27);
79052
79432
  */
79053
79433
 
79054
79434
 
79055
- const __iconNode$26 = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
79056
- const Check = createLucideIcon("check", __iconNode$26);
79435
+ const __iconNode$27 = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
79436
+ const Check = createLucideIcon("check", __iconNode$27);
79057
79437
 
79058
79438
  /**
79059
79439
  * @license lucide-react v0.528.0 - ISC
@@ -79063,8 +79443,8 @@ const Check = createLucideIcon("check", __iconNode$26);
79063
79443
  */
79064
79444
 
79065
79445
 
79066
- const __iconNode$25 = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
79067
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$25);
79446
+ const __iconNode$26 = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
79447
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$26);
79068
79448
 
79069
79449
  /**
79070
79450
  * @license lucide-react v0.528.0 - ISC
@@ -79074,11 +79454,11 @@ const ChevronDown = createLucideIcon("chevron-down", __iconNode$25);
79074
79454
  */
79075
79455
 
79076
79456
 
79077
- const __iconNode$24 = [
79457
+ const __iconNode$25 = [
79078
79458
  ["path", { d: "m17 18-6-6 6-6", key: "1yerx2" }],
79079
79459
  ["path", { d: "M7 6v12", key: "1p53r6" }]
79080
79460
  ];
79081
- const ChevronFirst = createLucideIcon("chevron-first", __iconNode$24);
79461
+ const ChevronFirst = createLucideIcon("chevron-first", __iconNode$25);
79082
79462
 
79083
79463
  /**
79084
79464
  * @license lucide-react v0.528.0 - ISC
@@ -79088,11 +79468,11 @@ const ChevronFirst = createLucideIcon("chevron-first", __iconNode$24);
79088
79468
  */
79089
79469
 
79090
79470
 
79091
- const __iconNode$23 = [
79471
+ const __iconNode$24 = [
79092
79472
  ["path", { d: "m7 18 6-6-6-6", key: "lwmzdw" }],
79093
79473
  ["path", { d: "M17 6v12", key: "1o0aio" }]
79094
79474
  ];
79095
- const ChevronLast = createLucideIcon("chevron-last", __iconNode$23);
79475
+ const ChevronLast = createLucideIcon("chevron-last", __iconNode$24);
79096
79476
 
79097
79477
  /**
79098
79478
  * @license lucide-react v0.528.0 - ISC
@@ -79102,8 +79482,8 @@ const ChevronLast = createLucideIcon("chevron-last", __iconNode$23);
79102
79482
  */
79103
79483
 
79104
79484
 
79105
- const __iconNode$22 = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
79106
- const ChevronLeft = createLucideIcon("chevron-left", __iconNode$22);
79485
+ const __iconNode$23 = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
79486
+ const ChevronLeft = createLucideIcon("chevron-left", __iconNode$23);
79107
79487
 
79108
79488
  /**
79109
79489
  * @license lucide-react v0.528.0 - ISC
@@ -79113,8 +79493,8 @@ const ChevronLeft = createLucideIcon("chevron-left", __iconNode$22);
79113
79493
  */
79114
79494
 
79115
79495
 
79116
- const __iconNode$21 = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
79117
- const ChevronRight = createLucideIcon("chevron-right", __iconNode$21);
79496
+ const __iconNode$22 = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
79497
+ const ChevronRight = createLucideIcon("chevron-right", __iconNode$22);
79118
79498
 
79119
79499
  /**
79120
79500
  * @license lucide-react v0.528.0 - ISC
@@ -79124,8 +79504,8 @@ const ChevronRight = createLucideIcon("chevron-right", __iconNode$21);
79124
79504
  */
79125
79505
 
79126
79506
 
79127
- const __iconNode$20 = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
79128
- const ChevronUp = createLucideIcon("chevron-up", __iconNode$20);
79507
+ const __iconNode$21 = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
79508
+ const ChevronUp = createLucideIcon("chevron-up", __iconNode$21);
79129
79509
 
79130
79510
  /**
79131
79511
  * @license lucide-react v0.528.0 - ISC
@@ -79135,11 +79515,11 @@ const ChevronUp = createLucideIcon("chevron-up", __iconNode$20);
79135
79515
  */
79136
79516
 
79137
79517
 
79138
- const __iconNode$1$ = [
79518
+ const __iconNode$20 = [
79139
79519
  ["path", { d: "m11 17-5-5 5-5", key: "13zhaf" }],
79140
79520
  ["path", { d: "m18 17-5-5 5-5", key: "h8a8et" }]
79141
79521
  ];
79142
- const ChevronsLeft = createLucideIcon("chevrons-left", __iconNode$1$);
79522
+ const ChevronsLeft = createLucideIcon("chevrons-left", __iconNode$20);
79143
79523
 
79144
79524
  /**
79145
79525
  * @license lucide-react v0.528.0 - ISC
@@ -79149,11 +79529,11 @@ const ChevronsLeft = createLucideIcon("chevrons-left", __iconNode$1$);
79149
79529
  */
79150
79530
 
79151
79531
 
79152
- const __iconNode$1_ = [
79532
+ const __iconNode$1$ = [
79153
79533
  ["path", { d: "m6 17 5-5-5-5", key: "xnjwq" }],
79154
79534
  ["path", { d: "m13 17 5-5-5-5", key: "17xmmf" }]
79155
79535
  ];
79156
- const ChevronsRight = createLucideIcon("chevrons-right", __iconNode$1_);
79536
+ const ChevronsRight = createLucideIcon("chevrons-right", __iconNode$1$);
79157
79537
 
79158
79538
  /**
79159
79539
  * @license lucide-react v0.528.0 - ISC
@@ -79163,11 +79543,11 @@ const ChevronsRight = createLucideIcon("chevrons-right", __iconNode$1_);
79163
79543
  */
79164
79544
 
79165
79545
 
79166
- const __iconNode$1Z = [
79546
+ const __iconNode$1_ = [
79167
79547
  ["path", { d: "m7 15 5 5 5-5", key: "1hf1tw" }],
79168
79548
  ["path", { d: "m7 9 5-5 5 5", key: "sgt6xg" }]
79169
79549
  ];
79170
- const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$1Z);
79550
+ const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$1_);
79171
79551
 
79172
79552
  /**
79173
79553
  * @license lucide-react v0.528.0 - ISC
@@ -79177,12 +79557,12 @@ const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$1Z);
79177
79557
  */
79178
79558
 
79179
79559
 
79180
- const __iconNode$1Y = [
79560
+ const __iconNode$1Z = [
79181
79561
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
79182
79562
  ["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
79183
79563
  ["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
79184
79564
  ];
79185
- const CircleAlert = createLucideIcon("circle-alert", __iconNode$1Y);
79565
+ const CircleAlert = createLucideIcon("circle-alert", __iconNode$1Z);
79186
79566
 
79187
79567
  /**
79188
79568
  * @license lucide-react v0.528.0 - ISC
@@ -79192,11 +79572,11 @@ const CircleAlert = createLucideIcon("circle-alert", __iconNode$1Y);
79192
79572
  */
79193
79573
 
79194
79574
 
79195
- const __iconNode$1X = [
79575
+ const __iconNode$1Y = [
79196
79576
  ["path", { d: "M21.801 10A10 10 0 1 1 17 3.335", key: "yps3ct" }],
79197
79577
  ["path", { d: "m9 11 3 3L22 4", key: "1pflzl" }]
79198
79578
  ];
79199
- const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$1X);
79579
+ const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$1Y);
79200
79580
 
79201
79581
  /**
79202
79582
  * @license lucide-react v0.528.0 - ISC
@@ -79206,11 +79586,11 @@ const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$1X);
79206
79586
  */
79207
79587
 
79208
79588
 
79209
- const __iconNode$1W = [
79589
+ const __iconNode$1X = [
79210
79590
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
79211
79591
  ["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
79212
79592
  ];
79213
- const CircleCheck = createLucideIcon("circle-check", __iconNode$1W);
79593
+ const CircleCheck = createLucideIcon("circle-check", __iconNode$1X);
79214
79594
 
79215
79595
  /**
79216
79596
  * @license lucide-react v0.528.0 - ISC
@@ -79220,11 +79600,11 @@ const CircleCheck = createLucideIcon("circle-check", __iconNode$1W);
79220
79600
  */
79221
79601
 
79222
79602
 
79223
- const __iconNode$1V = [
79603
+ const __iconNode$1W = [
79224
79604
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
79225
79605
  ["path", { d: "M8 12h8", key: "1wcyev" }]
79226
79606
  ];
79227
- const CircleMinus$1 = createLucideIcon("circle-minus", __iconNode$1V);
79607
+ const CircleMinus$1 = createLucideIcon("circle-minus", __iconNode$1W);
79228
79608
 
79229
79609
  /**
79230
79610
  * @license lucide-react v0.528.0 - ISC
@@ -79234,11 +79614,11 @@ const CircleMinus$1 = createLucideIcon("circle-minus", __iconNode$1V);
79234
79614
  */
79235
79615
 
79236
79616
 
79237
- const __iconNode$1U = [
79617
+ const __iconNode$1V = [
79238
79618
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
79239
79619
  ["rect", { x: "9", y: "9", width: "6", height: "6", rx: "1", key: "1ssd4o" }]
79240
79620
  ];
79241
- const CircleStop = createLucideIcon("circle-stop", __iconNode$1U);
79621
+ const CircleStop = createLucideIcon("circle-stop", __iconNode$1V);
79242
79622
 
79243
79623
  /**
79244
79624
  * @license lucide-react v0.528.0 - ISC
@@ -79248,12 +79628,12 @@ const CircleStop = createLucideIcon("circle-stop", __iconNode$1U);
79248
79628
  */
79249
79629
 
79250
79630
 
79251
- const __iconNode$1T = [
79631
+ const __iconNode$1U = [
79252
79632
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
79253
79633
  ["path", { d: "m15 9-6 6", key: "1uzhvr" }],
79254
79634
  ["path", { d: "m9 9 6 6", key: "z0biqf" }]
79255
79635
  ];
79256
- const CircleX = createLucideIcon("circle-x", __iconNode$1T);
79636
+ const CircleX = createLucideIcon("circle-x", __iconNode$1U);
79257
79637
 
79258
79638
  /**
79259
79639
  * @license lucide-react v0.528.0 - ISC
@@ -79263,8 +79643,8 @@ const CircleX = createLucideIcon("circle-x", __iconNode$1T);
79263
79643
  */
79264
79644
 
79265
79645
 
79266
- const __iconNode$1S = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
79267
- const Circle = createLucideIcon("circle", __iconNode$1S);
79646
+ const __iconNode$1T = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
79647
+ const Circle = createLucideIcon("circle", __iconNode$1T);
79268
79648
 
79269
79649
  /**
79270
79650
  * @license lucide-react v0.528.0 - ISC
@@ -79274,7 +79654,7 @@ const Circle = createLucideIcon("circle", __iconNode$1S);
79274
79654
  */
79275
79655
 
79276
79656
 
79277
- const __iconNode$1R = [
79657
+ const __iconNode$1S = [
79278
79658
  ["rect", { width: "8", height: "4", x: "8", y: "2", rx: "1", ry: "1", key: "tgr4d6" }],
79279
79659
  [
79280
79660
  "path",
@@ -79288,7 +79668,7 @@ const __iconNode$1R = [
79288
79668
  ["path", { d: "M8 11h.01", key: "1dfujw" }],
79289
79669
  ["path", { d: "M8 16h.01", key: "18s6g9" }]
79290
79670
  ];
79291
- const ClipboardList = createLucideIcon("clipboard-list", __iconNode$1R);
79671
+ const ClipboardList = createLucideIcon("clipboard-list", __iconNode$1S);
79292
79672
 
79293
79673
  /**
79294
79674
  * @license lucide-react v0.528.0 - ISC
@@ -79298,11 +79678,11 @@ const ClipboardList = createLucideIcon("clipboard-list", __iconNode$1R);
79298
79678
  */
79299
79679
 
79300
79680
 
79301
- const __iconNode$1Q = [
79681
+ const __iconNode$1R = [
79302
79682
  ["path", { d: "M12 6v6l4 2", key: "mmk7yg" }],
79303
79683
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]
79304
79684
  ];
79305
- const Clock = createLucideIcon("clock", __iconNode$1Q);
79685
+ const Clock = createLucideIcon("clock", __iconNode$1R);
79306
79686
 
79307
79687
  /**
79308
79688
  * @license lucide-react v0.528.0 - ISC
@@ -79312,12 +79692,12 @@ const Clock = createLucideIcon("clock", __iconNode$1Q);
79312
79692
  */
79313
79693
 
79314
79694
 
79315
- const __iconNode$1P = [
79695
+ const __iconNode$1Q = [
79316
79696
  ["path", { d: "m18 16 4-4-4-4", key: "1inbqp" }],
79317
79697
  ["path", { d: "m6 8-4 4 4 4", key: "15zrgr" }],
79318
79698
  ["path", { d: "m14.5 4-5 16", key: "e7oirm" }]
79319
79699
  ];
79320
- const CodeXml = createLucideIcon("code-xml", __iconNode$1P);
79700
+ const CodeXml = createLucideIcon("code-xml", __iconNode$1Q);
79321
79701
 
79322
79702
  /**
79323
79703
  * @license lucide-react v0.528.0 - ISC
@@ -79327,11 +79707,11 @@ const CodeXml = createLucideIcon("code-xml", __iconNode$1P);
79327
79707
  */
79328
79708
 
79329
79709
 
79330
- const __iconNode$1O = [
79710
+ const __iconNode$1P = [
79331
79711
  ["path", { d: "m16 18 6-6-6-6", key: "eg8j8" }],
79332
79712
  ["path", { d: "m8 6-6 6 6 6", key: "ppft3o" }]
79333
79713
  ];
79334
- const Code$1 = createLucideIcon("code", __iconNode$1O);
79714
+ const Code$1 = createLucideIcon("code", __iconNode$1P);
79335
79715
 
79336
79716
  /**
79337
79717
  * @license lucide-react v0.528.0 - ISC
@@ -79341,11 +79721,11 @@ const Code$1 = createLucideIcon("code", __iconNode$1O);
79341
79721
  */
79342
79722
 
79343
79723
 
79344
- const __iconNode$1N = [
79724
+ const __iconNode$1O = [
79345
79725
  ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
79346
79726
  ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
79347
79727
  ];
79348
- const Copy = createLucideIcon("copy", __iconNode$1N);
79728
+ const Copy = createLucideIcon("copy", __iconNode$1O);
79349
79729
 
79350
79730
  /**
79351
79731
  * @license lucide-react v0.528.0 - ISC
@@ -79355,11 +79735,11 @@ const Copy = createLucideIcon("copy", __iconNode$1N);
79355
79735
  */
79356
79736
 
79357
79737
 
79358
- const __iconNode$1M = [
79738
+ const __iconNode$1N = [
79359
79739
  ["rect", { width: "20", height: "14", x: "2", y: "5", rx: "2", key: "ynyp8z" }],
79360
79740
  ["line", { x1: "2", x2: "22", y1: "10", y2: "10", key: "1b3vmo" }]
79361
79741
  ];
79362
- const CreditCard = createLucideIcon("credit-card", __iconNode$1M);
79742
+ const CreditCard = createLucideIcon("credit-card", __iconNode$1N);
79363
79743
 
79364
79744
  /**
79365
79745
  * @license lucide-react v0.528.0 - ISC
@@ -79369,12 +79749,12 @@ const CreditCard = createLucideIcon("credit-card", __iconNode$1M);
79369
79749
  */
79370
79750
 
79371
79751
 
79372
- const __iconNode$1L = [
79752
+ const __iconNode$1M = [
79373
79753
  ["ellipse", { cx: "12", cy: "5", rx: "9", ry: "3", key: "msslwz" }],
79374
79754
  ["path", { d: "M3 5V19A9 3 0 0 0 21 19V5", key: "1wlel7" }],
79375
79755
  ["path", { d: "M3 12A9 3 0 0 0 21 12", key: "mv7ke4" }]
79376
79756
  ];
79377
- const Database = createLucideIcon("database", __iconNode$1L);
79757
+ const Database = createLucideIcon("database", __iconNode$1M);
79378
79758
 
79379
79759
  /**
79380
79760
  * @license lucide-react v0.528.0 - ISC
@@ -79384,11 +79764,11 @@ const Database = createLucideIcon("database", __iconNode$1L);
79384
79764
  */
79385
79765
 
79386
79766
 
79387
- const __iconNode$1K = [
79767
+ const __iconNode$1L = [
79388
79768
  ["line", { x1: "12", x2: "12", y1: "2", y2: "22", key: "7eqyqh" }],
79389
79769
  ["path", { d: "M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6", key: "1b0p4s" }]
79390
79770
  ];
79391
- const DollarSign = createLucideIcon("dollar-sign", __iconNode$1K);
79771
+ const DollarSign = createLucideIcon("dollar-sign", __iconNode$1L);
79392
79772
 
79393
79773
  /**
79394
79774
  * @license lucide-react v0.528.0 - ISC
@@ -79398,7 +79778,7 @@ const DollarSign = createLucideIcon("dollar-sign", __iconNode$1K);
79398
79778
  */
79399
79779
 
79400
79780
 
79401
- const __iconNode$1J = [
79781
+ const __iconNode$1K = [
79402
79782
  ["path", { d: "M11 20H2", key: "nlcfvz" }],
79403
79783
  [
79404
79784
  "path",
@@ -79411,7 +79791,7 @@ const __iconNode$1J = [
79411
79791
  ["path", { d: "M14 12h.01", key: "1jfl7z" }],
79412
79792
  ["path", { d: "M22 20h-3", key: "vhrsz" }]
79413
79793
  ];
79414
- const DoorOpen = createLucideIcon("door-open", __iconNode$1J);
79794
+ const DoorOpen = createLucideIcon("door-open", __iconNode$1K);
79415
79795
 
79416
79796
  /**
79417
79797
  * @license lucide-react v0.528.0 - ISC
@@ -79421,12 +79801,12 @@ const DoorOpen = createLucideIcon("door-open", __iconNode$1J);
79421
79801
  */
79422
79802
 
79423
79803
 
79424
- const __iconNode$1I = [
79804
+ const __iconNode$1J = [
79425
79805
  ["path", { d: "M12 15V3", key: "m9g1x1" }],
79426
79806
  ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
79427
79807
  ["path", { d: "m7 10 5 5 5-5", key: "brsn70" }]
79428
79808
  ];
79429
- const Download = createLucideIcon("download", __iconNode$1I);
79809
+ const Download = createLucideIcon("download", __iconNode$1J);
79430
79810
 
79431
79811
  /**
79432
79812
  * @license lucide-react v0.528.0 - ISC
@@ -79436,12 +79816,12 @@ const Download = createLucideIcon("download", __iconNode$1I);
79436
79816
  */
79437
79817
 
79438
79818
 
79439
- const __iconNode$1H = [
79819
+ const __iconNode$1I = [
79440
79820
  ["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }],
79441
79821
  ["circle", { cx: "12", cy: "5", r: "1", key: "gxeob9" }],
79442
79822
  ["circle", { cx: "12", cy: "19", r: "1", key: "lyex9k" }]
79443
79823
  ];
79444
- const EllipsisVertical = createLucideIcon("ellipsis-vertical", __iconNode$1H);
79824
+ const EllipsisVertical = createLucideIcon("ellipsis-vertical", __iconNode$1I);
79445
79825
 
79446
79826
  /**
79447
79827
  * @license lucide-react v0.528.0 - ISC
@@ -79451,12 +79831,12 @@ const EllipsisVertical = createLucideIcon("ellipsis-vertical", __iconNode$1H);
79451
79831
  */
79452
79832
 
79453
79833
 
79454
- const __iconNode$1G = [
79834
+ const __iconNode$1H = [
79455
79835
  ["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }],
79456
79836
  ["circle", { cx: "19", cy: "12", r: "1", key: "1wjl8i" }],
79457
79837
  ["circle", { cx: "5", cy: "12", r: "1", key: "1pcz8c" }]
79458
79838
  ];
79459
- const Ellipsis = createLucideIcon("ellipsis", __iconNode$1G);
79839
+ const Ellipsis = createLucideIcon("ellipsis", __iconNode$1H);
79460
79840
 
79461
79841
  /**
79462
79842
  * @license lucide-react v0.528.0 - ISC
@@ -79466,12 +79846,12 @@ const Ellipsis = createLucideIcon("ellipsis", __iconNode$1G);
79466
79846
  */
79467
79847
 
79468
79848
 
79469
- const __iconNode$1F = [
79849
+ const __iconNode$1G = [
79470
79850
  ["path", { d: "M15 3h6v6", key: "1q9fwt" }],
79471
79851
  ["path", { d: "M10 14 21 3", key: "gplh6r" }],
79472
79852
  ["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6", key: "a6xqqp" }]
79473
79853
  ];
79474
- const ExternalLink = createLucideIcon("external-link", __iconNode$1F);
79854
+ const ExternalLink = createLucideIcon("external-link", __iconNode$1G);
79475
79855
 
79476
79856
  /**
79477
79857
  * @license lucide-react v0.528.0 - ISC
@@ -79481,7 +79861,7 @@ const ExternalLink = createLucideIcon("external-link", __iconNode$1F);
79481
79861
  */
79482
79862
 
79483
79863
 
79484
- const __iconNode$1E = [
79864
+ const __iconNode$1F = [
79485
79865
  [
79486
79866
  "path",
79487
79867
  {
@@ -79499,7 +79879,7 @@ const __iconNode$1E = [
79499
79879
  ],
79500
79880
  ["path", { d: "m2 2 20 20", key: "1ooewy" }]
79501
79881
  ];
79502
- const EyeOff = createLucideIcon("eye-off", __iconNode$1E);
79882
+ const EyeOff = createLucideIcon("eye-off", __iconNode$1F);
79503
79883
 
79504
79884
  /**
79505
79885
  * @license lucide-react v0.528.0 - ISC
@@ -79509,7 +79889,7 @@ const EyeOff = createLucideIcon("eye-off", __iconNode$1E);
79509
79889
  */
79510
79890
 
79511
79891
 
79512
- const __iconNode$1D = [
79892
+ const __iconNode$1E = [
79513
79893
  [
79514
79894
  "path",
79515
79895
  {
@@ -79519,7 +79899,7 @@ const __iconNode$1D = [
79519
79899
  ],
79520
79900
  ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
79521
79901
  ];
79522
- const Eye = createLucideIcon("eye", __iconNode$1D);
79902
+ const Eye = createLucideIcon("eye", __iconNode$1E);
79523
79903
 
79524
79904
  /**
79525
79905
  * @license lucide-react v0.528.0 - ISC
@@ -79529,7 +79909,7 @@ const Eye = createLucideIcon("eye", __iconNode$1D);
79529
79909
  */
79530
79910
 
79531
79911
 
79532
- const __iconNode$1C = [
79912
+ const __iconNode$1D = [
79533
79913
  ["path", { d: "M10 12v-1", key: "v7bkov" }],
79534
79914
  ["path", { d: "M10 18v-2", key: "1cjy8d" }],
79535
79915
  ["path", { d: "M10 7V6", key: "dljcrl" }],
@@ -79540,7 +79920,7 @@ const __iconNode$1C = [
79540
79920
  ],
79541
79921
  ["circle", { cx: "10", cy: "20", r: "2", key: "1xzdoj" }]
79542
79922
  ];
79543
- const FileArchive = createLucideIcon("file-archive", __iconNode$1C);
79923
+ const FileArchive = createLucideIcon("file-archive", __iconNode$1D);
79544
79924
 
79545
79925
  /**
79546
79926
  * @license lucide-react v0.528.0 - ISC
@@ -79550,7 +79930,7 @@ const FileArchive = createLucideIcon("file-archive", __iconNode$1C);
79550
79930
  */
79551
79931
 
79552
79932
 
79553
- const __iconNode$1B = [
79933
+ const __iconNode$1C = [
79554
79934
  ["path", { d: "M17.5 22h.5a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3", key: "rslqgf" }],
79555
79935
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
79556
79936
  [
@@ -79561,7 +79941,7 @@ const __iconNode$1B = [
79561
79941
  }
79562
79942
  ]
79563
79943
  ];
79564
- const FileAudio = createLucideIcon("file-audio", __iconNode$1B);
79944
+ const FileAudio = createLucideIcon("file-audio", __iconNode$1C);
79565
79945
 
79566
79946
  /**
79567
79947
  * @license lucide-react v0.528.0 - ISC
@@ -79571,13 +79951,13 @@ const FileAudio = createLucideIcon("file-audio", __iconNode$1B);
79571
79951
  */
79572
79952
 
79573
79953
 
79574
- const __iconNode$1A = [
79954
+ const __iconNode$1B = [
79575
79955
  ["path", { d: "M10 12.5 8 15l2 2.5", key: "1tg20x" }],
79576
79956
  ["path", { d: "m14 12.5 2 2.5-2 2.5", key: "yinavb" }],
79577
79957
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
79578
79958
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z", key: "1mlx9k" }]
79579
79959
  ];
79580
- const FileCode = createLucideIcon("file-code", __iconNode$1A);
79960
+ const FileCode = createLucideIcon("file-code", __iconNode$1B);
79581
79961
 
79582
79962
  /**
79583
79963
  * @license lucide-react v0.528.0 - ISC
@@ -79587,13 +79967,13 @@ const FileCode = createLucideIcon("file-code", __iconNode$1A);
79587
79967
  */
79588
79968
 
79589
79969
 
79590
- const __iconNode$1z = [
79970
+ const __iconNode$1A = [
79591
79971
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
79592
79972
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
79593
79973
  ["path", { d: "M12 18v-6", key: "17g6i2" }],
79594
79974
  ["path", { d: "m9 15 3 3 3-3", key: "1npd3o" }]
79595
79975
  ];
79596
- const FileDown = createLucideIcon("file-down", __iconNode$1z);
79976
+ const FileDown = createLucideIcon("file-down", __iconNode$1A);
79597
79977
 
79598
79978
  /**
79599
79979
  * @license lucide-react v0.528.0 - ISC
@@ -79603,13 +79983,13 @@ const FileDown = createLucideIcon("file-down", __iconNode$1z);
79603
79983
  */
79604
79984
 
79605
79985
 
79606
- const __iconNode$1y = [
79986
+ const __iconNode$1z = [
79607
79987
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
79608
79988
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
79609
79989
  ["circle", { cx: "10", cy: "12", r: "2", key: "737tya" }],
79610
79990
  ["path", { d: "m20 17-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22", key: "wt3hpn" }]
79611
79991
  ];
79612
- const FileImage = createLucideIcon("file-image", __iconNode$1y);
79992
+ const FileImage = createLucideIcon("file-image", __iconNode$1z);
79613
79993
 
79614
79994
  /**
79615
79995
  * @license lucide-react v0.528.0 - ISC
@@ -79619,7 +79999,7 @@ const FileImage = createLucideIcon("file-image", __iconNode$1y);
79619
79999
  */
79620
80000
 
79621
80001
 
79622
- const __iconNode$1x = [
80002
+ const __iconNode$1y = [
79623
80003
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
79624
80004
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z", key: "1mlx9k" }],
79625
80005
  [
@@ -79630,7 +80010,7 @@ const __iconNode$1x = [
79630
80010
  }
79631
80011
  ]
79632
80012
  ];
79633
- const FilePlay = createLucideIcon("file-play", __iconNode$1x);
80013
+ const FilePlay = createLucideIcon("file-play", __iconNode$1y);
79634
80014
 
79635
80015
  /**
79636
80016
  * @license lucide-react v0.528.0 - ISC
@@ -79640,7 +80020,7 @@ const FilePlay = createLucideIcon("file-play", __iconNode$1x);
79640
80020
  */
79641
80021
 
79642
80022
 
79643
- const __iconNode$1w = [
80023
+ const __iconNode$1x = [
79644
80024
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
79645
80025
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
79646
80026
  ["path", { d: "M8 13h2", key: "yr2amv" }],
@@ -79648,7 +80028,7 @@ const __iconNode$1w = [
79648
80028
  ["path", { d: "M8 17h2", key: "2yhykz" }],
79649
80029
  ["path", { d: "M14 17h2", key: "10kma7" }]
79650
80030
  ];
79651
- const FileSpreadsheet = createLucideIcon("file-spreadsheet", __iconNode$1w);
80031
+ const FileSpreadsheet = createLucideIcon("file-spreadsheet", __iconNode$1x);
79652
80032
 
79653
80033
  /**
79654
80034
  * @license lucide-react v0.528.0 - ISC
@@ -79658,14 +80038,14 @@ const FileSpreadsheet = createLucideIcon("file-spreadsheet", __iconNode$1w);
79658
80038
  */
79659
80039
 
79660
80040
 
79661
- const __iconNode$1v = [
80041
+ const __iconNode$1w = [
79662
80042
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
79663
80043
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
79664
80044
  ["path", { d: "M10 9H8", key: "b1mrlr" }],
79665
80045
  ["path", { d: "M16 13H8", key: "t4e002" }],
79666
80046
  ["path", { d: "M16 17H8", key: "z1uh3a" }]
79667
80047
  ];
79668
- const FileText = createLucideIcon("file-text", __iconNode$1v);
80048
+ const FileText = createLucideIcon("file-text", __iconNode$1w);
79669
80049
 
79670
80050
  /**
79671
80051
  * @license lucide-react v0.528.0 - ISC
@@ -79675,11 +80055,11 @@ const FileText = createLucideIcon("file-text", __iconNode$1v);
79675
80055
  */
79676
80056
 
79677
80057
 
79678
- const __iconNode$1u = [
80058
+ const __iconNode$1v = [
79679
80059
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
79680
80060
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }]
79681
80061
  ];
79682
- const File$1 = createLucideIcon("file", __iconNode$1u);
80062
+ const File$1 = createLucideIcon("file", __iconNode$1v);
79683
80063
 
79684
80064
  /**
79685
80065
  * @license lucide-react v0.528.0 - ISC
@@ -79689,7 +80069,7 @@ const File$1 = createLucideIcon("file", __iconNode$1u);
79689
80069
  */
79690
80070
 
79691
80071
 
79692
- const __iconNode$1t = [
80072
+ const __iconNode$1u = [
79693
80073
  [
79694
80074
  "path",
79695
80075
  {
@@ -79707,7 +80087,21 @@ const __iconNode$1t = [
79707
80087
  ["path", { d: "M3 5a2 2 0 0 0 2 2h3", key: "f2jnh7" }],
79708
80088
  ["path", { d: "M3 3v13a2 2 0 0 0 2 2h3", key: "k8epm1" }]
79709
80089
  ];
79710
- const FolderTree = createLucideIcon("folder-tree", __iconNode$1t);
80090
+ const FolderTree = createLucideIcon("folder-tree", __iconNode$1u);
80091
+
80092
+ /**
80093
+ * @license lucide-react v0.528.0 - ISC
80094
+ *
80095
+ * This source code is licensed under the ISC license.
80096
+ * See the LICENSE file in the root directory of this source tree.
80097
+ */
80098
+
80099
+
80100
+ const __iconNode$1t = [
80101
+ ["path", { d: "m12 14 4-4", key: "9kzdfg" }],
80102
+ ["path", { d: "M3.34 19a10 10 0 1 1 17.32 0", key: "19p75a" }]
80103
+ ];
80104
+ const Gauge = createLucideIcon("gauge", __iconNode$1t);
79711
80105
 
79712
80106
  /**
79713
80107
  * @license lucide-react v0.528.0 - ISC
@@ -95299,8 +95693,8 @@ function EducationDialog({ open, onOpenChange, org, username, education, onCompl
95299
95693
  }, org: org, username: username })] }));
95300
95694
  }
95301
95695
 
95302
- const Card = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("rounded-lg border bg-card text-card-foreground shadow-sm", className), ...props })));
95303
- Card.displayName = "Card";
95696
+ const Card$1 = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("rounded-lg border bg-card text-card-foreground shadow-sm", className), ...props })));
95697
+ Card$1.displayName = "Card";
95304
95698
  const CardHeader = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })));
95305
95699
  CardHeader.displayName = "CardHeader";
95306
95700
  const CardTitle = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("text-2xl font-semibold leading-none tracking-tight", className), ...props })));
@@ -95313,7 +95707,7 @@ const CardFooter = React.forwardRef(({ className, ...props }, ref) => (jsx("div"
95313
95707
  CardFooter.displayName = "CardFooter";
95314
95708
 
95315
95709
  function ProfileEmptyState({ icon: Icon, message }) {
95316
- 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(Icon, { className: "h-10 w-10 mx-auto text-gray-300 mb-3", "aria-hidden": "true" }), jsx("p", { className: "text-sm text-gray-400", children: message })] }) }));
95710
+ return (jsx(Card$1, { className: "shadow-sm border border-dashed", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-8 text-center", children: [jsx(Icon, { className: "h-10 w-10 mx-auto text-gray-300 mb-3", "aria-hidden": "true" }), jsx("p", { className: "text-sm text-gray-400", children: message })] }) }));
95317
95711
  }
95318
95712
 
95319
95713
  const formatEducationDuration = (education, present) => {
@@ -117736,15 +118130,15 @@ function SubscriptionDetail({ subscription: initialSubscription, platformKey, on
117736
118130
  if (isLoadingDetail) {
117737
118131
  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" }), t('purchasesPurchasesTab.back')] }), jsx(Skeleton, { className: "h-6 w-48" })] }), jsx(Skeleton, { className: "h-64 w-full" })] }));
117738
118132
  }
117739
- 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" }), t('purchasesPurchasesTab.back')] }), jsxs("div", { children: [jsx("h4", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: subscription.item_name || subscription.item_id }), jsx("span", { className: "text-xs text-gray-400 capitalize", children: subscription.item_type })] })] }), 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: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.labelStatus') }), jsx(Badge, { className: statusBadgeStyle$1(subscription.status), children: subscription.status })] }), jsxs("div", { className: "flex items-center justify-between border-t pt-3", children: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.labelPlan') }), jsxs("div", { className: "text-right", children: [jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: (_b = subscription.price) === null || _b === void 0 ? void 0 : _b.name }), jsxs("span", { className: "text-sm text-gray-500 ml-2", children: [formatCurrency((_c = subscription.price) === null || _c === void 0 ? void 0 : _c.amount, (_d = subscription.price) === null || _d === void 0 ? void 0 : _d.currency), formatInterval((_e = subscription.price) === null || _e === void 0 ? void 0 : _e.interval)] })] })] }), jsxs("div", { className: "flex items-center justify-between border-t pt-3", children: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.labelType') }), jsx(Badge, { variant: "secondary", className: "capitalize", children: subscription.item_type })] }), subscription.current_period_end && (jsxs("div", { className: "flex items-center justify-between border-t pt-3", children: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: subscription.cancel_at_period_end
118133
+ 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" }), t('purchasesPurchasesTab.back')] }), jsxs("div", { children: [jsx("h4", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: subscription.item_name || subscription.item_id }), jsx("span", { className: "text-xs text-gray-400 capitalize", children: subscription.item_type })] })] }), jsx(Card$1, { 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: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.labelStatus') }), jsx(Badge, { className: statusBadgeStyle$1(subscription.status), children: subscription.status })] }), jsxs("div", { className: "flex items-center justify-between border-t pt-3", children: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.labelPlan') }), jsxs("div", { className: "text-right", children: [jsx("span", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: (_b = subscription.price) === null || _b === void 0 ? void 0 : _b.name }), jsxs("span", { className: "text-sm text-gray-500 ml-2", children: [formatCurrency((_c = subscription.price) === null || _c === void 0 ? void 0 : _c.amount, (_d = subscription.price) === null || _d === void 0 ? void 0 : _d.currency), formatInterval((_e = subscription.price) === null || _e === void 0 ? void 0 : _e.interval)] })] })] }), jsxs("div", { className: "flex items-center justify-between border-t pt-3", children: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.labelType') }), jsx(Badge, { variant: "secondary", className: "capitalize", children: subscription.item_type })] }), subscription.current_period_end && (jsxs("div", { className: "flex items-center justify-between border-t pt-3", children: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: subscription.cancel_at_period_end
117740
118134
  ? t('purchasesPurchasesTab.labelAccessUntil')
117741
- : t('purchasesPurchasesTab.labelRenewsOn') }), jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1.5", children: [jsx(Calendar$1, { className: "h-3.5 w-3.5" }), new Date(subscription.current_period_end).toLocaleDateString()] })] })), subscription.created_at && (jsxs("div", { className: "flex items-center justify-between border-t pt-3", children: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.labelSubscribedSince') }), jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1.5", children: [jsx(Clock, { className: "h-3.5 w-3.5" }), new Date(subscription.created_at).toLocaleDateString()] })] })), subscription.is_grandfathered && (jsxs("div", { className: "flex items-center justify-between border-t pt-3", children: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.labelLegacyAccess') }), jsxs(Badge, { className: "bg-amber-100 text-amber-700 border-amber-200 text-xs", children: [jsx(Shield, { className: "h-3 w-3 mr-1" }), t('purchasesPurchasesTab.badgeGrandfathered')] })] })), subscription.cancel_at_period_end && (jsxs("div", { className: "flex items-center gap-2 border-t pt-3 text-yellow-600", children: [jsx(TriangleAlert, { className: "h-4 w-4 flex-shrink-0" }), jsx("span", { className: "text-sm", children: t('purchasesPurchasesTab.warningWillNotRenew') })] }))] }) }), canCancel && !cancelResult && (jsx(Card, { className: "shadow-sm border border-blue-100", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-5 space-y-3", children: [jsx("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.cancelSectionHeading') }), jsx("p", { className: "text-xs text-gray-500", children: t('purchasesPurchasesTab.cancelSectionDescription') }), jsxs("div", { className: "flex gap-2 items-end", children: [jsxs("div", { className: "flex-1", children: [jsxs("label", { className: "text-xs text-gray-500 mb-1 block", children: [t('purchasesPurchasesTab.cancelConfirmLabelPrefix'), ' ', jsx("span", { className: "font-mono font-bold", children: "cancel" }), ' ', t('purchasesPurchasesTab.cancelConfirmLabelSuffix')] }), jsx(Input, { value: confirmText, onChange: (e) => setConfirmText(e.target.value), placeholder: t('purchasesPurchasesTab.cancelConfirmPlaceholder') })] }), jsxs(Button$1, { onClick: handleCancel, disabled: confirmText !== 'cancel' || isCanceling, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white cursor-pointer", children: [isCanceling ? (jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" })) : (jsx(CircleX, { className: "h-4 w-4 mr-2" })), t('purchasesPurchasesTab.cancelButton')] })] })] }) })), (cancelResult === null || cancelResult === void 0 ? void 0 : cancelResult.canceled) && (jsx(Card, { className: "shadow-sm border border-green-200", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-5 text-center", children: [jsx(CircleX, { className: "h-8 w-8 text-gray-400 mx-auto mb-2" }), jsx("h4", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 mb-1", children: t('purchasesPurchasesTab.canceledHeading') }), jsx("p", { className: "text-xs text-gray-500", children: t('purchasesPurchasesTab.canceledDescription') }), jsx(Button$1, { variant: "outline", size: "icon", onClick: onBack, "aria-label": t('purchasesPurchasesTab.backToPurchases'), className: "mt-3 h-8 w-8 cursor-pointer rounded-full border-0 bg-gray-100 text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:hover:text-white", children: jsx(ArrowLeft, { className: "h-4 w-4" }) })] }) })), (cancelResult === null || cancelResult === void 0 ? void 0 : cancelResult.portalUrl) && (jsx(Card, { className: "shadow-sm border border-blue-200", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-5 text-center", children: [jsx(ExternalLink, { className: "h-8 w-8 text-blue-400 mx-auto mb-2" }), jsx("h4", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 mb-1", children: t('purchasesPurchasesTab.stripePortalHeading') }), jsx("p", { className: "text-xs text-gray-500 mb-3", children: t('purchasesPurchasesTab.stripePortalDescription') }), jsxs(Button$1, { onClick: () => window.open(cancelResult.portalUrl, '_blank'), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white cursor-pointer", children: [jsx(ExternalLink, { className: "h-4 w-4 mr-2" }), t('purchasesPurchasesTab.openStripePortal')] })] }) }))] }));
118135
+ : t('purchasesPurchasesTab.labelRenewsOn') }), jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1.5", children: [jsx(Calendar$1, { className: "h-3.5 w-3.5" }), new Date(subscription.current_period_end).toLocaleDateString()] })] })), subscription.created_at && (jsxs("div", { className: "flex items-center justify-between border-t pt-3", children: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.labelSubscribedSince') }), jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1.5", children: [jsx(Clock, { className: "h-3.5 w-3.5" }), new Date(subscription.created_at).toLocaleDateString()] })] })), subscription.is_grandfathered && (jsxs("div", { className: "flex items-center justify-between border-t pt-3", children: [jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.labelLegacyAccess') }), jsxs(Badge, { className: "bg-amber-100 text-amber-700 border-amber-200 text-xs", children: [jsx(Shield, { className: "h-3 w-3 mr-1" }), t('purchasesPurchasesTab.badgeGrandfathered')] })] })), subscription.cancel_at_period_end && (jsxs("div", { className: "flex items-center gap-2 border-t pt-3 text-yellow-600", children: [jsx(TriangleAlert, { className: "h-4 w-4 flex-shrink-0" }), jsx("span", { className: "text-sm", children: t('purchasesPurchasesTab.warningWillNotRenew') })] }))] }) }), canCancel && !cancelResult && (jsx(Card$1, { className: "shadow-sm border border-blue-100", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-5 space-y-3", children: [jsx("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: t('purchasesPurchasesTab.cancelSectionHeading') }), jsx("p", { className: "text-xs text-gray-500", children: t('purchasesPurchasesTab.cancelSectionDescription') }), jsxs("div", { className: "flex gap-2 items-end", children: [jsxs("div", { className: "flex-1", children: [jsxs("label", { className: "text-xs text-gray-500 mb-1 block", children: [t('purchasesPurchasesTab.cancelConfirmLabelPrefix'), ' ', jsx("span", { className: "font-mono font-bold", children: "cancel" }), ' ', t('purchasesPurchasesTab.cancelConfirmLabelSuffix')] }), jsx(Input, { value: confirmText, onChange: (e) => setConfirmText(e.target.value), placeholder: t('purchasesPurchasesTab.cancelConfirmPlaceholder') })] }), jsxs(Button$1, { onClick: handleCancel, disabled: confirmText !== 'cancel' || isCanceling, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white cursor-pointer", children: [isCanceling ? (jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" })) : (jsx(CircleX, { className: "h-4 w-4 mr-2" })), t('purchasesPurchasesTab.cancelButton')] })] })] }) })), (cancelResult === null || cancelResult === void 0 ? void 0 : cancelResult.canceled) && (jsx(Card$1, { className: "shadow-sm border border-green-200", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-5 text-center", children: [jsx(CircleX, { className: "h-8 w-8 text-gray-400 mx-auto mb-2" }), jsx("h4", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 mb-1", children: t('purchasesPurchasesTab.canceledHeading') }), jsx("p", { className: "text-xs text-gray-500", children: t('purchasesPurchasesTab.canceledDescription') }), jsx(Button$1, { variant: "outline", size: "icon", onClick: onBack, "aria-label": t('purchasesPurchasesTab.backToPurchases'), className: "mt-3 h-8 w-8 cursor-pointer rounded-full border-0 bg-gray-100 text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:hover:text-white", children: jsx(ArrowLeft, { className: "h-4 w-4" }) })] }) })), (cancelResult === null || cancelResult === void 0 ? void 0 : cancelResult.portalUrl) && (jsx(Card$1, { className: "shadow-sm border border-blue-200", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-5 text-center", children: [jsx(ExternalLink, { className: "h-8 w-8 text-blue-400 mx-auto mb-2" }), jsx("h4", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 mb-1", children: t('purchasesPurchasesTab.stripePortalHeading') }), jsx("p", { className: "text-xs text-gray-500 mb-3", children: t('purchasesPurchasesTab.stripePortalDescription') }), jsxs(Button$1, { onClick: () => window.open(cancelResult.portalUrl, '_blank'), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white cursor-pointer", children: [jsx(ExternalLink, { className: "h-4 w-4 mr-2" }), t('purchasesPurchasesTab.openStripePortal')] })] }) }))] }));
117742
118136
  }
117743
118137
  // ── Subscription Card (List Item) ──
117744
118138
  function SubscriptionCard({ sub, onClick }) {
117745
118139
  var _a, _b, _c, _d, _e, _f, _g;
117746
118140
  const t = useT();
117747
- return (jsx(Card, { className: "shadow-sm border hover:border-blue-200 transition-colors cursor-pointer", style: { borderColor: 'oklch(.922 0 0)' }, onClick: onClick, children: jsx(CardContent, { className: "p-4", children: jsxs("div", { className: "flex items-start justify-between", children: [jsxs("div", { className: "flex-1 min-w-0", children: [jsxs("div", { className: "flex items-center gap-2 mb-1", children: [jsx("h4", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 truncate", children: sub.item_name || sub.item_id }), jsx(Badge, { variant: "secondary", className: "text-xs capitalize flex-shrink-0", children: sub.item_type })] }), jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-600", children: [jsx(CreditCard, { className: "h-3.5 w-3.5 text-gray-400" }), jsxs("span", { children: [(_a = sub.price) === null || _a === void 0 ? void 0 : _a.name, " \u2014", ' ', jsxs("span", { className: "font-semibold", children: [formatCurrency((_b = sub.price) === null || _b === void 0 ? void 0 : _b.amount, (_c = sub.price) === null || _c === void 0 ? void 0 : _c.currency), ((_d = sub.price) === null || _d === void 0 ? void 0 : _d.interval) === 'month'
118141
+ return (jsx(Card$1, { className: "shadow-sm border hover:border-blue-200 transition-colors cursor-pointer", style: { borderColor: 'oklch(.922 0 0)' }, onClick: onClick, children: jsx(CardContent, { className: "p-4", children: jsxs("div", { className: "flex items-start justify-between", children: [jsxs("div", { className: "flex-1 min-w-0", children: [jsxs("div", { className: "flex items-center gap-2 mb-1", children: [jsx("h4", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 truncate", children: sub.item_name || sub.item_id }), jsx(Badge, { variant: "secondary", className: "text-xs capitalize flex-shrink-0", children: sub.item_type })] }), jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-600", children: [jsx(CreditCard, { className: "h-3.5 w-3.5 text-gray-400" }), jsxs("span", { children: [(_a = sub.price) === null || _a === void 0 ? void 0 : _a.name, " \u2014", ' ', jsxs("span", { className: "font-semibold", children: [formatCurrency((_b = sub.price) === null || _b === void 0 ? void 0 : _b.amount, (_c = sub.price) === null || _c === void 0 ? void 0 : _c.currency), ((_d = sub.price) === null || _d === void 0 ? void 0 : _d.interval) === 'month'
117748
118142
  ? t('purchasesPurchasesTab.intervalMonth')
117749
118143
  : ((_e = sub.price) === null || _e === void 0 ? void 0 : _e.interval) === 'year'
117750
118144
  ? t('purchasesPurchasesTab.intervalYear')
@@ -117781,7 +118175,7 @@ function PurchasesTab({ org, username }) {
117781
118175
  refetch();
117782
118176
  } }));
117783
118177
  }
117784
- return (jsxs("div", { className: "space-y-4", 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) => setSearchQuery(e.target.value), placeholder: t('purchasesPurchasesTab.searchPlaceholder'), className: "pl-9" }), isFetching && !isLoading && (jsx(LoaderCircle, { className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 animate-spin text-gray-400" }))] }), jsxs("div", { className: "flex flex-col sm:flex-row gap-2", children: [jsxs(Select$1, { value: statusFilter, onValueChange: setStatusFilter, children: [jsx(SelectTrigger, { className: "w-full sm:w-[160px]", children: jsx(SelectValue, { placeholder: t('purchasesPurchasesTab.filterStatusPlaceholder') }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('purchasesPurchasesTab.filterAllStatuses') }), jsx(SelectItem, { value: "active", children: t('purchasesPurchasesTab.filterActive') }), jsx(SelectItem, { value: "trialing", children: t('purchasesPurchasesTab.filterTrialing') }), jsx(SelectItem, { value: "canceled", children: t('purchasesPurchasesTab.filterCanceled') }), jsx(SelectItem, { value: "past_due", children: t('purchasesPurchasesTab.filterPastDue') })] })] }), jsxs(Select$1, { value: typeFilter, onValueChange: setTypeFilter, children: [jsx(SelectTrigger, { className: "w-full sm:w-[160px]", children: jsx(SelectValue, { placeholder: t('purchasesPurchasesTab.filterTypePlaceholder') }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('purchasesPurchasesTab.filterAllTypes') }), jsx(SelectItem, { value: "mentor", children: t('purchasesPurchasesTab.filterAgent') }), jsx(SelectItem, { value: "course", children: t('purchasesPurchasesTab.filterCourse') }), jsx(SelectItem, { value: "program", children: t('purchasesPurchasesTab.filterProgram') }), jsx(SelectItem, { value: "pathway", children: t('purchasesPurchasesTab.filterPathway') })] })] }), data && (jsx("span", { className: "text-xs text-gray-400 self-center ml-auto", children: t('purchasesPurchasesTab.purchaseCount', { count: data.count }) }))] }), isLoading ? (jsx("div", { className: "space-y-2", children: [1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-24 w-full" }, i))) })) : (data === null || data === void 0 ? void 0 : data.results) && data.results.length > 0 ? (jsxs(Fragment$1, { children: [jsx("div", { className: "space-y-2", children: data.results.map((sub) => (jsx(SubscriptionCard, { sub: sub, onClick: () => setSelectedSubscription(sub) }, sub.unique_id))) }), (data.previous_page !== null || data.next_page !== null) && (jsxs("div", { className: "flex items-center justify-between pt-2", children: [jsx("span", { className: "text-xs text-gray-400", children: t('purchasesPurchasesTab.paginationTotal', { count: data.count }) }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button$1, { variant: "outline", size: "sm", disabled: data.previous_page === null, onClick: () => data.previous_page !== null && setPage(data.previous_page), className: "h-7 text-xs cursor-pointer", children: t('purchasesPurchasesTab.previousPage') }), jsx("span", { className: "text-xs text-gray-500", children: t('purchasesPurchasesTab.pageIndicator', { page }) }), jsx(Button$1, { variant: "outline", size: "sm", disabled: data.next_page === null, onClick: () => data.next_page !== null && setPage(data.next_page), className: "h-7 text-xs cursor-pointer", children: t('purchasesPurchasesTab.nextPage') })] })] }))] })) : (jsx(Card, { className: "shadow-sm border border-dashed", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-8 text-center", children: [jsx(ShoppingBag, { className: "h-10 w-10 mx-auto text-gray-300 mb-3" }), jsx("p", { className: "text-sm text-gray-400", children: debouncedSearch.trim()
118178
+ return (jsxs("div", { className: "space-y-4", 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) => setSearchQuery(e.target.value), placeholder: t('purchasesPurchasesTab.searchPlaceholder'), className: "pl-9" }), isFetching && !isLoading && (jsx(LoaderCircle, { className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 animate-spin text-gray-400" }))] }), jsxs("div", { className: "flex flex-col sm:flex-row gap-2", children: [jsxs(Select$1, { value: statusFilter, onValueChange: setStatusFilter, children: [jsx(SelectTrigger, { className: "w-full sm:w-[160px]", children: jsx(SelectValue, { placeholder: t('purchasesPurchasesTab.filterStatusPlaceholder') }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('purchasesPurchasesTab.filterAllStatuses') }), jsx(SelectItem, { value: "active", children: t('purchasesPurchasesTab.filterActive') }), jsx(SelectItem, { value: "trialing", children: t('purchasesPurchasesTab.filterTrialing') }), jsx(SelectItem, { value: "canceled", children: t('purchasesPurchasesTab.filterCanceled') }), jsx(SelectItem, { value: "past_due", children: t('purchasesPurchasesTab.filterPastDue') })] })] }), jsxs(Select$1, { value: typeFilter, onValueChange: setTypeFilter, children: [jsx(SelectTrigger, { className: "w-full sm:w-[160px]", children: jsx(SelectValue, { placeholder: t('purchasesPurchasesTab.filterTypePlaceholder') }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('purchasesPurchasesTab.filterAllTypes') }), jsx(SelectItem, { value: "mentor", children: t('purchasesPurchasesTab.filterAgent') }), jsx(SelectItem, { value: "course", children: t('purchasesPurchasesTab.filterCourse') }), jsx(SelectItem, { value: "program", children: t('purchasesPurchasesTab.filterProgram') }), jsx(SelectItem, { value: "pathway", children: t('purchasesPurchasesTab.filterPathway') })] })] }), data && (jsx("span", { className: "text-xs text-gray-400 self-center ml-auto", children: t('purchasesPurchasesTab.purchaseCount', { count: data.count }) }))] }), isLoading ? (jsx("div", { className: "space-y-2", children: [1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-24 w-full" }, i))) })) : (data === null || data === void 0 ? void 0 : data.results) && data.results.length > 0 ? (jsxs(Fragment$1, { children: [jsx("div", { className: "space-y-2", children: data.results.map((sub) => (jsx(SubscriptionCard, { sub: sub, onClick: () => setSelectedSubscription(sub) }, sub.unique_id))) }), (data.previous_page !== null || data.next_page !== null) && (jsxs("div", { className: "flex items-center justify-between pt-2", children: [jsx("span", { className: "text-xs text-gray-400", children: t('purchasesPurchasesTab.paginationTotal', { count: data.count }) }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button$1, { variant: "outline", size: "sm", disabled: data.previous_page === null, onClick: () => data.previous_page !== null && setPage(data.previous_page), className: "h-7 text-xs cursor-pointer", children: t('purchasesPurchasesTab.previousPage') }), jsx("span", { className: "text-xs text-gray-500", children: t('purchasesPurchasesTab.pageIndicator', { page }) }), jsx(Button$1, { variant: "outline", size: "sm", disabled: data.next_page === null, onClick: () => data.next_page !== null && setPage(data.next_page), className: "h-7 text-xs cursor-pointer", children: t('purchasesPurchasesTab.nextPage') })] })] }))] })) : (jsx(Card$1, { className: "shadow-sm border border-dashed", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-8 text-center", children: [jsx(ShoppingBag, { className: "h-10 w-10 mx-auto text-gray-300 mb-3" }), jsx("p", { className: "text-sm text-gray-400", children: debouncedSearch.trim()
117785
118179
  ? t('purchasesPurchasesTab.emptySearchResult')
117786
118180
  : t('purchasesPurchasesTab.emptyNoPurchases') })] }) }))] }));
117787
118181
  }
@@ -128694,7 +129088,7 @@ function formatLocale(locale) {
128694
129088
  "q": formatQuarter,
128695
129089
  "Q": formatUnixTimestamp,
128696
129090
  "s": formatUnixTimestampSeconds,
128697
- "S": formatSeconds,
129091
+ "S": formatSeconds$1,
128698
129092
  "u": formatWeekdayNumberMonday,
128699
129093
  "U": formatWeekNumberSunday,
128700
129094
  "V": formatWeekNumberISO,
@@ -129160,7 +129554,7 @@ function formatMinutes(d, p) {
129160
129554
  return pad(d.getMinutes(), p, 2);
129161
129555
  }
129162
129556
 
129163
- function formatSeconds(d, p) {
129557
+ function formatSeconds$1(d, p) {
129164
129558
  return pad(d.getSeconds(), p, 2);
129165
129559
  }
129166
129560
 
@@ -145566,7 +145960,7 @@ function useGradebookData(type, org, username, page, search) {
145566
145960
  page,
145567
145961
  page_size: PAGE_SIZE$a,
145568
145962
  platform_key: org,
145569
- ...(trimmed ? { search: trimmed } : {}),
145963
+ ...(trimmed ? { course_name: trimmed } : {}),
145570
145964
  },
145571
145965
  }, { skip: type !== 'courses', refetchOnMountOrArgChange: true });
145572
145966
  const programsQ = useGetUserEnrolledProgramsQuery([{ username, platformKey: org }], { skip: type !== 'programs' });
@@ -145717,7 +146111,7 @@ function GradebookCard({ row, icon: Icon, onClick, }) {
145717
146111
  var _a;
145718
146112
  const t = useT();
145719
146113
  const clickable = !!onClick;
145720
- return (jsx(Card, { className: cn('shadow-sm border transition-colors', clickable && 'hover:border-blue-200 cursor-pointer'), style: { borderColor: 'oklch(.922 0 0)' }, onClick: onClick, role: clickable ? 'button' : undefined, tabIndex: clickable ? 0 : undefined, onKeyDown: clickable
146114
+ return (jsx(Card$1, { className: cn('shadow-sm border transition-colors', clickable && 'hover:border-blue-200 cursor-pointer'), style: { borderColor: 'oklch(.922 0 0)' }, onClick: onClick, role: clickable ? 'button' : undefined, tabIndex: clickable ? 0 : undefined, onKeyDown: clickable
145721
146115
  ? (e) => {
145722
146116
  if (e.key === 'Enter' || e.key === ' ') {
145723
146117
  e.preventDefault();
@@ -186638,6 +187032,625 @@ function ChatHistoryTab({ org, username }) {
186638
187032
  : t('chatHistoryChatHistoryTab.conversation') }) }), jsx("div", { className: "mx-auto max-w-full overflow-x-hidden", children: selectedSession && (jsx(ConversationPreview, { org: org, username: username, session: selectedSession, agent: resolveAgent(selectedSession) })) })] }) })] }), jsx(TabsContent, { value: "exports", className: "mt-0 min-h-0 flex-1 overflow-y-auto data-[state=inactive]:hidden", children: jsx(ReportHistory, { org: org, username: username, onDownload: downloadFromUrl }) })] }));
186639
187033
  }
186640
187034
 
187035
+ /**
187036
+ * The info icon that sits on every analytics card and, on hover or keyboard
187037
+ * focus, explains what the card measures. The description doubles as the
187038
+ * accessible name so screen readers get it without needing the hover.
187039
+ *
187040
+ * Uses the tooltip primitives directly rather than the shared `TooltipContent`
187041
+ * because analytics wants a light popover, while `TooltipContent` is the dark
187042
+ * `bg-primary` style the rest of the app relies on.
187043
+ */
187044
+ function CardInfoIcon({ title, description, className }) {
187045
+ return (jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("button", { type: "button", "aria-label": description, className: cn('shrink-0 cursor-help rounded p-1 text-[#898989] transition-colors hover:bg-gray-100 hover:text-[#38A1E5] focus-visible:ring-2 focus-visible:ring-[#38A1E5] focus-visible:outline-none', className), children: jsx(Info$3, { className: "h-4 w-4", "aria-hidden": "true" }) }) }), jsx(Portal$3, { children: jsxs(Content2$4, { "data-slot": "tooltip-content", side: "top", align: "center", sideOffset: 6, collisionPadding: 12, className: "animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 z-50 max-w-[260px] rounded-lg border border-[oklch(0.922_0_0)] bg-white p-3 shadow-lg", children: [title && (jsx("div", { "data-slot": "tooltip-title", className: "mb-1 text-sm font-semibold text-[#484848]", children: title })), jsx("p", { "data-slot": "tooltip-description", className: "text-sm leading-relaxed text-[#646464]", children: description })] }) })] }));
187046
+ }
187047
+
187048
+ /**
187049
+ * Chart color system for the analytics surface.
187050
+ *
187051
+ * Single-series charts keep the app's established `#38A1E5`. Multi-series
187052
+ * charts (spend stacked by service, spend by model) use a categorical palette
187053
+ * validated for color-vision-deficiency separation on a white surface
187054
+ * (worst adjacent-pair CVD ΔE 9.1, worst normal-vision ΔE 19.6 — OKLab ×100):
187055
+ * hues are assigned in this fixed order, per entity, never cycled or reshuffled
187056
+ * when a filter changes the series count.
187057
+ *
187058
+ * Three of the light-surface slots sit below 3:1 contrast against white, so
187059
+ * every chart that uses them must carry visible direct labels or a table view
187060
+ * (all of ours do — ranked rows and legends carry the values as text).
187061
+ */
187062
+ const CHART_SERIES_COLORS = [
187063
+ '#2a78d6', // blue
187064
+ '#eb6834', // orange
187065
+ '#1baf7a', // aqua
187066
+ '#eda100', // yellow
187067
+ '#e87ba4', // magenta
187068
+ '#008300', // green
187069
+ ];
187070
+ /** The app's single-series chart color, unchanged. */
187071
+ const CHART_SINGLE_SERIES_COLOR = '#38A1E5';
187072
+ /**
187073
+ * Ordinal blue ramp for ordered measures (latency p50→p99). One hue,
187074
+ * light→dark — never a rainbow for an ordered scale. The lightest step clears
187075
+ * 2:1 against white.
187076
+ */
187077
+ const CHART_ORDINAL_RAMP = [
187078
+ '#86b6ef', // p50
187079
+ '#5598e7', // p75
187080
+ '#2a78d6', // p90
187081
+ '#1c5cab', // p95
187082
+ '#104281', // p99
187083
+ ];
187084
+ /**
187085
+ * Color follows the entity: a service keeps its hue whether or not the other
187086
+ * services are on screen. Services beyond this list fold into slots in first-
187087
+ * seen order via {@link colorForSeries} rather than inventing new hues.
187088
+ */
187089
+ const SERVICE_COLOR_ORDER = [
187090
+ 'chat',
187091
+ 'embeddings',
187092
+ 'memory',
187093
+ 'grading',
187094
+ 'moderation',
187095
+ 'call',
187096
+ ];
187097
+ /**
187098
+ * Stable color for a named series. Known services get their fixed slot; an
187099
+ * unknown name hashes into the palette deterministically so the same name is
187100
+ * the same color on every render and every chart.
187101
+ */
187102
+ function colorForSeries(name) {
187103
+ const fixed = SERVICE_COLOR_ORDER.indexOf(name);
187104
+ if (fixed >= 0)
187105
+ return CHART_SERIES_COLORS[fixed % CHART_SERIES_COLORS.length];
187106
+ let hash = 0;
187107
+ for (let i = 0; i < name.length; i++) {
187108
+ hash = (hash * 31 + name.charCodeAt(i)) >>> 0;
187109
+ }
187110
+ return CHART_SERIES_COLORS[hash % CHART_SERIES_COLORS.length];
187111
+ }
187112
+ /** Stable color for the Nth series of an ordered breakdown (e.g. top models). */
187113
+ function colorForRank(index) {
187114
+ return CHART_SERIES_COLORS[index % CHART_SERIES_COLORS.length];
187115
+ }
187116
+
187117
+ const LLM_USAGE_RANGES = ['today', '7d', '30d', '90d', 'all_time'];
187118
+ const DEFAULT_LLM_USAGE_RANGE = '30d';
187119
+ /** Buckets that keep the time axis readable for the chosen span. */
187120
+ function granularityForRange(range) {
187121
+ if (range === '90d')
187122
+ return 'week';
187123
+ if (range === 'all_time')
187124
+ return 'month';
187125
+ return 'day';
187126
+ }
187127
+ /** The next wider range, offered from the empty state. */
187128
+ function widerRange(range) {
187129
+ if (range === 'all_time')
187130
+ return null;
187131
+ if (range === '90d')
187132
+ return 'all_time';
187133
+ return '90d';
187134
+ }
187135
+ const DAY_MS = 86400000;
187136
+ const DAYS_IN_RANGE = { today: 1, '7d': 7, '30d': 30 };
187137
+ /**
187138
+ * Spend buckets for the chart. Daily ranges get every day of the window, with
187139
+ * zero where the backend sent no bucket (it omits empty days), so the axis is
187140
+ * continuous. Weekly and monthly ranges use the buckets as returned.
187141
+ */
187142
+ function buildSpendSeries(points, range, now = new Date()) {
187143
+ var _a;
187144
+ const days = DAYS_IN_RANGE[range];
187145
+ if (!days || granularityForRange(range) !== 'day')
187146
+ return points;
187147
+ const byDate = new Map(points.map((point) => [point.date, point.totalCost]));
187148
+ const series = [];
187149
+ for (let offset = days - 1; offset >= 0; offset--) {
187150
+ const date = new Date(now.getTime() - offset * DAY_MS).toISOString().slice(0, 10);
187151
+ series.push({ date, totalCost: (_a = byDate.get(date)) !== null && _a !== void 0 ? _a : 0 });
187152
+ }
187153
+ return series;
187154
+ }
187155
+ /** Axis ceiling and ticks on a 1-2-5 step, so labels land on clean numbers. */
187156
+ function niceScale(max, tickCount = 4) {
187157
+ if (!Number.isFinite(max) || max <= 0)
187158
+ return { max: 1, ticks: [0, 0.25, 0.5, 0.75, 1] };
187159
+ const rough = max / tickCount;
187160
+ const magnitude = 10 ** Math.floor(Math.log10(rough));
187161
+ const residual = rough / magnitude;
187162
+ const step = (residual <= 1 ? 1 : residual <= 2 ? 2 : residual <= 5 ? 5 : 10) * magnitude;
187163
+ const top = Math.ceil(max / step - 1e-9) * step;
187164
+ const ticks = [];
187165
+ for (let value = 0; value <= top + step / 2; value += step) {
187166
+ ticks.push(Number(value.toPrecision(12)));
187167
+ }
187168
+ return { max: ticks[ticks.length - 1], ticks };
187169
+ }
187170
+ const usd = (fractionDigits) => new Intl.NumberFormat('en-US', {
187171
+ style: 'currency',
187172
+ currency: 'USD',
187173
+ minimumFractionDigits: fractionDigits,
187174
+ maximumFractionDigits: fractionDigits,
187175
+ });
187176
+ /**
187177
+ * Dollars with enough precision to be meaningful: small values keep four
187178
+ * decimals. `precise` keeps four decimals for anything under a dollar — for
187179
+ * per-request figures (a trace, a step, the average), where $0.0147 and
187180
+ * $0.0102 must not both read as $0.01.
187181
+ */
187182
+ function formatCost$1(value, { precise = false } = {}) {
187183
+ if (value === null || value === undefined || !Number.isFinite(value))
187184
+ return '—';
187185
+ if (value === 0)
187186
+ return usd(2).format(0);
187187
+ const abs = Math.abs(value);
187188
+ if (abs < 0.0001)
187189
+ return `<${usd(4).format(0.0001)}`;
187190
+ if (abs < (precise ? 1 : 0.01))
187191
+ return usd(4).format(value);
187192
+ return usd(2).format(value);
187193
+ }
187194
+ /** Axis labels: whole dollars on big steps, cents (or finer) on small ones; zero is `$0`. */
187195
+ function formatAxisCost(value, step) {
187196
+ if (value === 0)
187197
+ return usd(0).format(0);
187198
+ const decimals = step >= 1 ? 0 : Math.min(4, Math.max(2, Math.ceil(-Math.log10(step))));
187199
+ return usd(decimals).format(value);
187200
+ }
187201
+ function formatCompact(value) {
187202
+ if (value === null || value === undefined || !Number.isFinite(value))
187203
+ return '—';
187204
+ return new Intl.NumberFormat('en-US', { notation: 'compact', maximumFractionDigits: 1 }).format(value);
187205
+ }
187206
+ function formatInteger(value) {
187207
+ if (value === null || value === undefined || !Number.isFinite(value))
187208
+ return '—';
187209
+ return Math.round(value).toLocaleString('en-US');
187210
+ }
187211
+ /** Trace and observation latency arrive in seconds. */
187212
+ function formatSeconds(value) {
187213
+ if (value === null || value === undefined || !Number.isFinite(value))
187214
+ return '—';
187215
+ return `${value < 10 ? value.toFixed(2) : value.toFixed(1)}s`;
187216
+ }
187217
+ /** `YYYY-MM-DD` bucket keys are UTC calendar dates. */
187218
+ function formatBucket(date, granularity) {
187219
+ const parsed = new Date(`${date.slice(0, 10)}T00:00:00Z`);
187220
+ if (Number.isNaN(parsed.getTime()))
187221
+ return date;
187222
+ return parsed.toLocaleDateString('en-US', granularity === 'month'
187223
+ ? { month: 'short', year: 'numeric', timeZone: 'UTC' }
187224
+ : { month: 'short', day: 'numeric', timeZone: 'UTC' });
187225
+ }
187226
+ function formatWhen(iso) {
187227
+ if (!iso)
187228
+ return '—';
187229
+ const date = new Date(iso);
187230
+ if (Number.isNaN(date.getTime()))
187231
+ return '—';
187232
+ return date.toLocaleString('en-US', {
187233
+ month: 'short',
187234
+ day: 'numeric',
187235
+ hour: '2-digit',
187236
+ minute: '2-digit',
187237
+ });
187238
+ }
187239
+ /** `0feb37e6-d125-…-7c9ee0a252e7` → `0feb…52e7`; the full id stays in a title. */
187240
+ function shortId(id) {
187241
+ if (!id)
187242
+ return '—';
187243
+ return id.length > 12 ? `${id.slice(0, 4)}…${id.slice(-4)}` : id;
187244
+ }
187245
+ /**
187246
+ * Keeps the biggest rows and folds the rest into one "Other" row, so a long
187247
+ * tail never floods the card.
187248
+ */
187249
+ function foldTail(rows, keep, otherLabel) {
187250
+ if (rows.length <= keep + 1)
187251
+ return rows;
187252
+ const head = rows.slice(0, keep);
187253
+ const tail = rows.slice(keep);
187254
+ return [
187255
+ ...head,
187256
+ {
187257
+ key: '__other__',
187258
+ label: otherLabel,
187259
+ totalCost: tail.reduce((sum, row) => sum + row.totalCost, 0),
187260
+ count: tail.reduce((sum, row) => sum + row.count, 0),
187261
+ isOther: true,
187262
+ },
187263
+ ];
187264
+ }
187265
+ /** Share of a total as a whole percent, keeping tiny non-zero shares visible. */
187266
+ function sharePercent(value, total) {
187267
+ if (!total || value <= 0)
187268
+ return 0;
187269
+ const pct = (value / total) * 100;
187270
+ return pct < 1 ? Math.round(pct * 10) / 10 : Math.round(pct);
187271
+ }
187272
+
187273
+ /** Single series, so the palette's lead hue; it clears 3:1 on white. */
187274
+ const BAR_COLOR = CHART_SERIES_COLORS[0];
187275
+ const PLOT_HEIGHT = 176;
187276
+ const MAX_X_LABELS = 5;
187277
+ /**
187278
+ * Spend per bucket as columns: ≤24px wide, 4px rounded tops, square at the
187279
+ * baseline, a hairline grid on clean ticks. Hover or arrow keys read one
187280
+ * column into the readout above the plot; the same numbers are in a
187281
+ * visually-hidden table for screen readers.
187282
+ */
187283
+ function SpendChart({ points, granularity, }) {
187284
+ const t = useT();
187285
+ const [active, setActive] = useState(null);
187286
+ const { max, ticks } = useMemo(() => niceScale(Math.max(0, ...points.map((point) => point.totalCost))), [points]);
187287
+ const step = ticks.length > 1 ? ticks[1] - ticks[0] : max;
187288
+ const labelIndexes = useMemo(() => {
187289
+ if (points.length <= MAX_X_LABELS)
187290
+ return new Set(points.map((_, index) => index));
187291
+ const every = (points.length - 1) / (MAX_X_LABELS - 1);
187292
+ return new Set(Array.from({ length: MAX_X_LABELS }, (_, i) => Math.round(i * every)));
187293
+ }, [points]);
187294
+ const onKeyDown = (event) => {
187295
+ if (!points.length)
187296
+ return;
187297
+ const last = points.length - 1;
187298
+ const current = active !== null && active !== void 0 ? active : last;
187299
+ let next = null;
187300
+ if (event.key === 'ArrowRight')
187301
+ next = Math.min(last, active === null ? last : current + 1);
187302
+ if (event.key === 'ArrowLeft')
187303
+ next = Math.max(0, active === null ? last : current - 1);
187304
+ if (event.key === 'Home')
187305
+ next = 0;
187306
+ if (event.key === 'End')
187307
+ next = last;
187308
+ if (next === null)
187309
+ return;
187310
+ event.preventDefault();
187311
+ setActive(next);
187312
+ };
187313
+ const activePoint = active !== null ? points[active] : null;
187314
+ return (jsxs("div", { className: "flex flex-col gap-2", children: [jsx("p", { className: "h-5 text-sm text-gray-600 dark:text-gray-300", "aria-live": "polite", children: activePoint && (jsxs(Fragment$1, { children: [jsx("span", { className: "font-semibold tabular-nums text-gray-900 dark:text-gray-100", children: formatCost$1(activePoint.totalCost) }), ' ', jsxs("span", { className: "text-gray-500 dark:text-gray-400", children: ["\u00B7 ", formatBucket(activePoint.date, granularity)] })] })) }), jsxs("div", { className: "flex gap-2", children: [jsx("div", { className: "relative w-12 flex-shrink-0 text-right text-[11px] tabular-nums text-gray-500 dark:text-gray-400", style: { height: PLOT_HEIGHT }, "aria-hidden": "true", children: ticks.map((tick) => (jsx("span", { className: "absolute right-0 -translate-y-1/2 leading-none", style: { top: `${(1 - tick / max) * 100}%` }, children: formatAxisCost(tick, step) }, tick))) }), jsxs("div", { className: "min-w-0 flex-1", children: [jsxs("div", { role: "group", tabIndex: 0, "aria-label": t('profileLlmUsage.chartAria'), onKeyDown: onKeyDown, onBlur: () => setActive(null), onMouseLeave: () => setActive(null), className: "relative rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500", style: { height: PLOT_HEIGHT }, children: [ticks.map((tick) => (jsx("div", { className: tick === 0
187315
+ ? 'absolute inset-x-0 border-t border-gray-300 dark:border-gray-600'
187316
+ : 'absolute inset-x-0 border-t border-gray-100 dark:border-gray-800', style: { top: `${(1 - tick / max) * 100}%` }, "aria-hidden": "true" }, tick))), jsx("div", { className: "absolute inset-0 flex items-end gap-[2px]", "aria-hidden": "true", children: points.map((point, index) => {
187317
+ const height = max > 0 ? (point.totalCost / max) * 100 : 0;
187318
+ const isActive = index === active;
187319
+ return (jsx("div", {
187320
+ // The whole column slot is the hover target, not just the bar.
187321
+ className: "flex h-full min-w-0 flex-1 items-end justify-center", onMouseEnter: () => setActive(index), children: jsx("div", { className: "w-full max-w-[24px] rounded-t-[4px] transition-opacity", style: {
187322
+ height: point.totalCost > 0 ? `max(${height}%, 2px)` : 0,
187323
+ background: BAR_COLOR,
187324
+ opacity: active === null || isActive ? 1 : 0.45,
187325
+ } }) }, point.date));
187326
+ }) })] }), jsx("div", { className: "relative mt-2 h-4 text-[11px] text-gray-500 dark:text-gray-400", "aria-hidden": "true", children: points.map((point, index) => labelIndexes.has(index) ? (jsx("span", { className: "absolute whitespace-nowrap", style: index === 0
187327
+ ? { left: 0 }
187328
+ : index === points.length - 1
187329
+ ? { right: 0 }
187330
+ : {
187331
+ left: `${((index + 0.5) / points.length) * 100}%`,
187332
+ transform: 'translateX(-50%)',
187333
+ }, children: formatBucket(point.date, granularity) }, point.date)) : null) })] })] }), jsxs("table", { className: "sr-only", children: [jsx("caption", { children: t('profileLlmUsage.chartTableCaption') }), jsx("thead", { children: jsxs("tr", { children: [jsx("th", { scope: "col", children: t('profileLlmUsage.colPeriod') }), jsx("th", { scope: "col", children: t('profileLlmUsage.colCost') })] }) }), jsx("tbody", { children: points.map((point) => (jsxs("tr", { children: [jsx("td", { children: formatBucket(point.date, granularity) }), jsx("td", { children: formatCost$1(point.totalCost) })] }, point.date))) })] })] }));
187334
+ }
187335
+
187336
+ const RANGE_LABEL_KEYS = {
187337
+ today: 'rangeToday',
187338
+ '7d': 'range7d',
187339
+ '30d': 'range30d',
187340
+ '90d': 'range90d',
187341
+ all_time: 'rangeAllTime',
187342
+ };
187343
+ const PERIOD_LABEL_KEYS = {
187344
+ today: 'periodToday',
187345
+ '7d': 'period7d',
187346
+ '30d': 'period30d',
187347
+ '90d': 'period90d',
187348
+ all_time: 'periodAllTime',
187349
+ };
187350
+ const CHART_SUBTITLE_KEYS = {
187351
+ day: 'chartSubtitleDay',
187352
+ week: 'chartSubtitleWeek',
187353
+ month: 'chartSubtitleMonth',
187354
+ };
187355
+ const BREAKDOWN_ROWS = 5;
187356
+ const MODEL_BAR_COLOR = CHART_SERIES_COLORS[0];
187357
+ const CARD = 'rounded-xl border border-gray-200 bg-white dark:border-gray-800 dark:bg-gray-950';
187358
+ function Card({ title, subtitle, aside, children, className, bodyClassName, }) {
187359
+ return (jsxs("section", { className: cn(CARD, className), "aria-label": title, children: [jsxs("div", { className: "flex items-start justify-between gap-4 px-5 pt-5", children: [jsxs("div", { className: "min-w-0", children: [jsx("h4", { className: "text-[15px] font-semibold text-gray-900 dark:text-gray-100", children: title }), subtitle && (jsx("p", { className: "mt-0.5 text-[13px] text-gray-500 dark:text-gray-400", children: subtitle }))] }), aside] }), jsx("div", { className: cn('px-5 pb-5 pt-4', bodyClassName), children: children })] }));
187360
+ }
187361
+ function RangeControl({ value, onChange, }) {
187362
+ const t = useT();
187363
+ const groupRef = useRef(null);
187364
+ const onKeyDown = (event, index) => {
187365
+ var _a, _b;
187366
+ const last = LLM_USAGE_RANGES.length - 1;
187367
+ let next = null;
187368
+ if (event.key === 'ArrowRight' || event.key === 'ArrowDown')
187369
+ next = index === last ? 0 : index + 1;
187370
+ if (event.key === 'ArrowLeft' || event.key === 'ArrowUp')
187371
+ next = index === 0 ? last : index - 1;
187372
+ if (next === null)
187373
+ return;
187374
+ event.preventDefault();
187375
+ onChange(LLM_USAGE_RANGES[next]);
187376
+ (_b = (_a = groupRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll('[role="radio"]')[next]) === null || _b === void 0 ? void 0 : _b.focus();
187377
+ };
187378
+ return (jsx("div", { ref: groupRef, role: "radiogroup", "aria-label": t('profileLlmUsage.rangeLabel'), className: "inline-flex max-w-full gap-0.5 overflow-x-auto rounded-lg bg-gray-100 p-[3px] dark:bg-gray-800", children: LLM_USAGE_RANGES.map((range, index) => {
187379
+ const checked = range === value;
187380
+ return (jsx("button", { type: "button", role: "radio", "aria-checked": checked, tabIndex: checked ? 0 : -1, onClick: () => onChange(range), onKeyDown: (event) => onKeyDown(event, index), className: cn('h-8 whitespace-nowrap rounded-md px-3 text-[13px] transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500', checked
187381
+ ? 'bg-white font-semibold text-gray-900 shadow-sm ring-1 ring-gray-200 dark:bg-gray-950 dark:text-gray-100 dark:ring-gray-700'
187382
+ : 'font-medium text-gray-600 hover:text-gray-900 dark:text-gray-300'), children: t(`profileLlmUsage.${RANGE_LABEL_KEYS[range]}`) }, range));
187383
+ }) }));
187384
+ }
187385
+ function StatTile({ label, value, sub, loading, }) {
187386
+ return (jsxs("div", { className: cn(CARD, 'flex flex-col gap-2 p-4'), children: [jsx("p", { className: "text-[13px] font-medium text-gray-500 dark:text-gray-400", children: label }), loading ? (jsxs(Fragment$1, { children: [jsx(Skeleton, { className: "h-7 w-24" }), jsx(Skeleton, { className: "h-4 w-20" })] })) : (jsxs(Fragment$1, { children: [jsx("p", { className: "text-[26px] font-semibold leading-tight tracking-tight text-gray-900 dark:text-gray-100", children: value }), jsx("p", { className: "min-h-[1rem] text-xs text-gray-500 tabular-nums dark:text-gray-400", children: sub })] }))] }));
187387
+ }
187388
+ function StateMessage({ icon, tone = 'neutral', title, body, action, }) {
187389
+ return (jsxs("div", { className: cn(CARD, 'flex flex-col items-center gap-3 px-6 py-14 text-center'), role: tone === 'error' ? 'alert' : undefined, children: [jsx("div", { className: cn('flex h-12 w-12 items-center justify-center rounded-xl', tone === 'error'
187390
+ ? 'bg-red-50 text-red-700 dark:bg-red-950 dark:text-red-300'
187391
+ : 'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400'), "aria-hidden": "true", children: icon }), jsx("h4", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: title }), jsx("p", { className: "max-w-sm text-sm leading-relaxed text-gray-500 dark:text-gray-400", children: body }), action] }));
187392
+ }
187393
+ function RankedBars$1({ rows, total, colorFor, }) {
187394
+ return (jsx("ul", { className: "flex flex-col gap-3", children: rows.map((row) => {
187395
+ const share = sharePercent(row.totalCost, total);
187396
+ return (jsxs("li", { className: "flex flex-col gap-1.5", children: [jsxs("div", { className: "flex items-baseline justify-between gap-3 text-[13px]", children: [jsxs("span", { className: "flex min-w-0 items-center gap-2 font-medium text-gray-900 dark:text-gray-100", children: [jsx("span", { className: "h-2 w-2 flex-shrink-0 rounded-[2px]", style: { background: colorFor(row) }, "aria-hidden": "true" }), jsx("span", { className: "truncate", title: row.label, children: row.label })] }), jsxs("span", { className: "whitespace-nowrap tabular-nums text-gray-700 dark:text-gray-300", children: [formatCost$1(row.totalCost), jsxs("span", { className: "text-gray-500 dark:text-gray-400", children: [" \u00B7 ", share, "%"] })] })] }), jsx("div", { className: "h-1.5 overflow-hidden rounded-full bg-gray-100 dark:bg-gray-800", "aria-hidden": "true", children: jsx("div", { className: "h-full rounded-full", style: { width: `${Math.min(100, share)}%`, background: colorFor(row) } }) })] }, row.key));
187397
+ }) }));
187398
+ }
187399
+ function BreakdownSkeleton() {
187400
+ return (jsx("div", { className: "flex flex-col gap-4", children: [0, 1, 2, 3].map((i) => (jsxs("div", { className: "flex flex-col gap-2", children: [jsx(Skeleton, { className: "h-4 w-3/4" }), jsx(Skeleton, { className: "h-1.5 w-full" })] }, i))) }));
187401
+ }
187402
+ function SectionError() {
187403
+ const t = useT();
187404
+ return (jsxs("p", { className: "flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400", children: [jsx(CircleAlert, { className: "h-4 w-4 text-red-600", "aria-hidden": "true" }), t('profileLlmUsage.sectionError')] }));
187405
+ }
187406
+ const observationTokens = (o) => {
187407
+ var _a, _b, _c, _d, _e, _f;
187408
+ return ({
187409
+ input: (_b = (_a = o.usage) === null || _a === void 0 ? void 0 : _a.input) !== null && _b !== void 0 ? _b : o.promptTokens,
187410
+ output: (_d = (_c = o.usage) === null || _c === void 0 ? void 0 : _c.output) !== null && _d !== void 0 ? _d : o.completionTokens,
187411
+ total: (_f = (_e = o.usage) === null || _e === void 0 ? void 0 : _e.total) !== null && _f !== void 0 ? _f : o.totalTokens,
187412
+ });
187413
+ };
187414
+ const observationCost = (o) => { var _a, _b, _c; return (_b = (_a = o.calculatedTotalCost) !== null && _a !== void 0 ? _a : o.totalCost) !== null && _b !== void 0 ? _b : (_c = o.costDetails) === null || _c === void 0 ? void 0 : _c.total; };
187415
+ function TraceSteps({ steps, isLoading, error, }) {
187416
+ const t = useT();
187417
+ if (isLoading) {
187418
+ return (jsx("p", { className: "px-4 py-3 text-sm text-gray-500 dark:text-gray-400", children: t('profileLlmUsage.stepsLoading') }));
187419
+ }
187420
+ if (error) {
187421
+ return (jsx("p", { className: "px-4 py-3 text-sm text-gray-500 dark:text-gray-400", children: t('profileLlmUsage.stepsError') }));
187422
+ }
187423
+ if (!steps.length) {
187424
+ return (jsx("p", { className: "px-4 py-3 text-sm text-gray-500 dark:text-gray-400", children: t('profileLlmUsage.stepsEmpty') }));
187425
+ }
187426
+ const cell = 'px-3 py-2 text-right tabular-nums';
187427
+ return (jsx("div", { className: "overflow-x-auto", children: jsxs("table", { className: "w-full text-[12.5px]", children: [jsx("thead", { children: jsxs("tr", { className: "text-left text-gray-500 dark:text-gray-400", children: [jsx("th", { scope: "col", className: "px-4 py-2 font-medium", children: t('profileLlmUsage.colStep') }), jsx("th", { scope: "col", className: "px-3 py-2 font-medium", children: t('profileLlmUsage.colModel') }), jsx("th", { scope: "col", className: cn(cell, 'font-medium'), children: t('profileLlmUsage.colInput') }), jsx("th", { scope: "col", className: cn(cell, 'font-medium'), children: t('profileLlmUsage.colOutput') }), jsx("th", { scope: "col", className: cn(cell, 'font-medium'), children: t('profileLlmUsage.colTotal') }), jsx("th", { scope: "col", className: cn(cell, 'font-medium'), children: t('profileLlmUsage.colLatency') }), jsx("th", { scope: "col", className: "px-4 py-2 text-right font-medium", children: t('profileLlmUsage.colCost') })] }) }), jsx("tbody", { children: steps.map((step) => {
187428
+ const tokens = observationTokens(step);
187429
+ return (jsxs("tr", { className: "border-t border-gray-100 text-gray-700 dark:border-gray-800 dark:text-gray-300", children: [jsx("td", { className: "px-4 py-2 font-medium text-gray-900 dark:text-gray-100", children: step.name || step.type || '—' }), jsx("td", { className: "px-3 py-2", children: step.providedModelName || step.model || '—' }), jsx("td", { className: cell, children: formatInteger(tokens.input) }), jsx("td", { className: cell, children: formatInteger(tokens.output) }), jsx("td", { className: cell, children: formatInteger(tokens.total) }), jsx("td", { className: cell, children: formatSeconds(step.latency) }), jsx("td", { className: "px-4 py-2 text-right font-semibold tabular-nums text-gray-900 dark:text-gray-100", children: formatCost$1(observationCost(step), { precise: true }) })] }, step.id));
187430
+ }) })] }) }));
187431
+ }
187432
+ /**
187433
+ * The profile "Usage" tab: AI spend, tokens and requests for the profile on
187434
+ * screen. Every request names that user, so an admin viewing someone else
187435
+ * sees their rows rather than the whole platform's.
187436
+ */
187437
+ function LlmUsageTab({ org, username, isOwnProfile = true }) {
187438
+ var _a;
187439
+ const t = useT();
187440
+ const [range, setRange] = useState(DEFAULT_LLM_USAGE_RANGE);
187441
+ const [page, setPage] = useState(1);
187442
+ const [openTraceId, setOpenTraceId] = useState(null);
187443
+ const granularity = granularityForRange(range);
187444
+ const scope = { platformKey: org, username, date_filter: range };
187445
+ const summary = useUserLlmUsageSummary(scope);
187446
+ const spend = useUserLlmSpendOverTime({ ...scope, granularity });
187447
+ const byModel = useUserLlmCostByModel({ ...scope, limit: 20 });
187448
+ const byService = useUserLlmCostByService(scope);
187449
+ const activity = useUserLlmRecentActivity({
187450
+ ...scope,
187451
+ page,
187452
+ limit: USER_LLM_RECENT_ACTIVITY_PAGE_SIZE,
187453
+ });
187454
+ const steps = useUserLlmTraceObservations({ ...scope, traceId: openTraceId });
187455
+ const changeRange = (next) => {
187456
+ setRange(next);
187457
+ setPage(1);
187458
+ setOpenTraceId(null);
187459
+ };
187460
+ const refreshAll = () => {
187461
+ summary.refetch();
187462
+ spend.refetch();
187463
+ byModel.refetch();
187464
+ byService.refetch();
187465
+ activity.refetch();
187466
+ if (openTraceId)
187467
+ steps.refetch();
187468
+ };
187469
+ const series = useMemo(() => buildSpendSeries(spend.points, range), [spend.points, range]);
187470
+ const modelRows = useMemo(() => foldTail(byModel.models.map((row, index) => ({
187471
+ key: row.model || `unknown-${index}`,
187472
+ label: row.model || t('profileLlmUsage.unknownModel'),
187473
+ totalCost: row.totalCost,
187474
+ count: row.count,
187475
+ })), BREAKDOWN_ROWS, t('profileLlmUsage.otherRow')), [byModel.models, t]);
187476
+ const serviceRows = useMemo(() => foldTail(byService.services.map((row, index) => ({
187477
+ key: row.service || `unknown-${index}`,
187478
+ label: row.service || t('profileLlmUsage.unknownService'),
187479
+ totalCost: row.totalCost,
187480
+ count: row.count,
187481
+ })), BREAKDOWN_ROWS, t('profileLlmUsage.otherRow')), [byService.services, t]);
187482
+ const modelTotal = modelRows.reduce((sum, row) => sum + row.totalCost, 0);
187483
+ const serviceTotal = serviceRows.reduce((sum, row) => sum + row.totalCost, 0);
187484
+ const totals = summary.summary;
187485
+ const periodLabel = t(`profileLlmUsage.${PERIOD_LABEL_KEYS[range]}`);
187486
+ const next = widerRange(range);
187487
+ const errorCopy = (error) => {
187488
+ if (error.kind === 'unavailable') {
187489
+ return {
187490
+ title: t('profileLlmUsage.errorUnavailableTitle'),
187491
+ body: t('profileLlmUsage.errorUnavailableBody'),
187492
+ };
187493
+ }
187494
+ if (error.kind === 'unauthorized') {
187495
+ return {
187496
+ title: t('profileLlmUsage.errorUnauthorizedTitle'),
187497
+ body: t('profileLlmUsage.errorUnauthorizedBody'),
187498
+ };
187499
+ }
187500
+ if (error.kind === 'forbidden' || error.kind === 'not_found') {
187501
+ return {
187502
+ title: t('profileLlmUsage.errorForbiddenTitle'),
187503
+ body: t('profileLlmUsage.errorForbiddenBody'),
187504
+ };
187505
+ }
187506
+ return {
187507
+ title: t('profileLlmUsage.errorUnknownTitle'),
187508
+ body: t('profileLlmUsage.errorUnknownBody'),
187509
+ };
187510
+ };
187511
+ const meta = activity.meta;
187512
+ const pageSize = (meta === null || meta === void 0 ? void 0 : meta.limit) || USER_LLM_RECENT_ACTIVITY_PAGE_SIZE;
187513
+ const from = meta && meta.totalItems > 0 ? (meta.page - 1) * pageSize + 1 : 0;
187514
+ const to = meta ? Math.min(meta.page * pageSize, meta.totalItems) : 0;
187515
+ const totalPages = (_a = meta === null || meta === void 0 ? void 0 : meta.totalPages) !== null && _a !== void 0 ? _a : 1;
187516
+ let body;
187517
+ if (summary.error) {
187518
+ const copy = errorCopy(summary.error);
187519
+ body = (jsx(StateMessage, { tone: "error", icon: jsx(CircleAlert, { className: "h-6 w-6" }), title: copy.title, body: copy.body, action: summary.error.kind !== 'unauthorized' && (jsx(Button$1, { onClick: refreshAll, className: "mt-1 bg-blue-600 text-white hover:bg-blue-700", children: t('profileLlmUsage.tryAgain') })) }));
187520
+ }
187521
+ else if (summary.isEmpty) {
187522
+ body = (jsx(StateMessage, { icon: jsx(Inbox, { className: "h-6 w-6" }), title: t('profileLlmUsage.emptyTitle'), body: t('profileLlmUsage.emptyBody'), action: next && (jsx(Button$1, { variant: "outline", onClick: () => changeRange(next), className: "mt-1", children: next === 'all_time'
187523
+ ? t('profileLlmUsage.emptyActionAll')
187524
+ : t('profileLlmUsage.emptyAction90') })) }));
187525
+ }
187526
+ else {
187527
+ const loadingTotals = summary.isLoading || summary.isIdle;
187528
+ body = (jsxs(Fragment$1, { children: [jsxs("div", { className: "grid grid-cols-2 gap-3 xl:grid-cols-4", children: [jsx(StatTile, { label: t('profileLlmUsage.kpiSpend'), value: formatCost$1(totals === null || totals === void 0 ? void 0 : totals.totalCost), sub: periodLabel, loading: loadingTotals }), jsx(StatTile, { label: t('profileLlmUsage.kpiTokens'), value: formatCompact(totals === null || totals === void 0 ? void 0 : totals.totalTokens), sub: totals && totals.count > 0
187529
+ ? t('profileLlmUsage.kpiTokensSub', {
187530
+ value: formatCompact(totals.totalTokens / totals.count),
187531
+ })
187532
+ : undefined, loading: loadingTotals }), jsx(StatTile, { label: t('profileLlmUsage.kpiRequests'), value: formatInteger(totals === null || totals === void 0 ? void 0 : totals.count), sub: t('profileLlmUsage.kpiRequestsSub'), loading: loadingTotals }), jsx(StatTile, { label: t('profileLlmUsage.kpiAvgCost'), value: totals && totals.count > 0
187533
+ ? formatCost$1(totals.totalCost / totals.count, { precise: true })
187534
+ : '—', sub: t('profileLlmUsage.kpiAvgCostSub'), loading: loadingTotals })] }), jsx(Card, { title: t('profileLlmUsage.chartTitle'), subtitle: t(`profileLlmUsage.${CHART_SUBTITLE_KEYS[granularity]}`), aside: totals && (jsx("span", { className: "text-[15px] font-semibold tabular-nums text-gray-900 dark:text-gray-100", children: formatCost$1(totals.totalCost) })), bodyClassName: "pt-2", children: spend.isLoading || spend.isIdle ? (jsx(Skeleton, { className: "h-[220px] w-full" })) : spend.error ? (jsx(SectionError, {})) : series.length === 0 ? (jsx("p", { className: "py-10 text-center text-sm text-gray-500 dark:text-gray-400", children: t('profileLlmUsage.chartNoData') })) : (jsx(SpendChart, { points: series, granularity: granularity })) }), jsxs("div", { className: "grid grid-cols-1 gap-3 md:grid-cols-2", children: [jsx(Card, { title: t('profileLlmUsage.byModelTitle'), subtitle: t('profileLlmUsage.byModelSubtitle'), children: byModel.isLoading || byModel.isIdle ? (jsx(BreakdownSkeleton, {})) : byModel.error ? (jsx(SectionError, {})) : modelRows.length === 0 ? (jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: t('profileLlmUsage.breakdownEmpty') })) : (jsx(RankedBars$1, { rows: modelRows, total: modelTotal, colorFor: () => MODEL_BAR_COLOR })) }), jsx(Card, { title: t('profileLlmUsage.byServiceTitle'), subtitle: t('profileLlmUsage.byServiceSubtitle'), children: byService.isLoading || byService.isIdle ? (jsx(BreakdownSkeleton, {})) : byService.error ? (jsx(SectionError, {})) : serviceRows.length === 0 ? (jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: t('profileLlmUsage.breakdownEmpty') })) : (jsx(RankedBars$1, { rows: serviceRows, total: serviceTotal,
187535
+ // Colour follows the service, so "chat" is the same hue everywhere.
187536
+ colorFor: (row) => (row.isOther ? '#9ca3af' : colorForSeries(row.key)) })) })] }), jsxs("section", { className: cn(CARD, 'overflow-hidden'), "aria-labelledby": "llm-activity-heading", children: [jsxs("div", { className: "border-b border-gray-200 px-5 py-4 dark:border-gray-800", children: [jsx("h4", { id: "llm-activity-heading", className: "text-[15px] font-semibold text-gray-900 dark:text-gray-100", children: t('profileLlmUsage.activityTitle') }), jsx("p", { className: "mt-0.5 text-[13px] text-gray-500 dark:text-gray-400", children: t('profileLlmUsage.activitySubtitle') })] }), activity.isLoading || activity.isIdle ? (jsx("div", { className: "flex flex-col gap-3 p-5", children: [0, 1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-8 w-full" }, i))) })) : activity.error ? (jsx("div", { className: "p-5", children: jsx(SectionError, {}) })) : activity.isEmpty || activity.rows.length === 0 ? (jsx("p", { className: "p-5 text-sm text-gray-500 dark:text-gray-400", children: t('profileLlmUsage.activityEmpty') })) : (jsxs(Fragment$1, { children: [jsx("div", { className: "overflow-x-auto", children: jsxs("table", { className: "w-full text-[13px]", children: [jsx("thead", { children: jsxs("tr", { className: "bg-gray-50 text-left text-gray-500 dark:bg-gray-900 dark:text-gray-400", children: [jsx("th", { scope: "col", className: "px-5 py-2.5 font-medium", children: t('profileLlmUsage.colWhen') }), jsx("th", { scope: "col", className: "px-3 py-2.5 font-medium", children: t('profileLlmUsage.colService') }), jsx("th", { scope: "col", className: "hidden px-3 py-2.5 font-medium md:table-cell", children: t('profileLlmUsage.colSession') }), jsx("th", { scope: "col", className: "px-3 py-2.5 text-right font-medium", children: t('profileLlmUsage.colLatency') }), jsx("th", { scope: "col", className: "px-3 py-2.5 text-right font-medium", children: t('profileLlmUsage.colCost') }), jsx("th", { scope: "col", className: "w-12 py-2.5 pl-2 pr-5", children: jsx("span", { className: "sr-only", children: t('profileLlmUsage.colDetails') }) })] }) }), jsx("tbody", { children: activity.rows.map((trace) => {
187537
+ const open = trace.id === openTraceId;
187538
+ const when = formatWhen(trace.timestamp);
187539
+ const service = trace.name || t('profileLlmUsage.unknownService');
187540
+ const stepsId = `llm-trace-${trace.id}-steps`;
187541
+ return (jsxs(Fragment$2, { children: [jsxs("tr", { className: cn('border-t border-gray-200 dark:border-gray-800', open && 'bg-gray-50 dark:bg-gray-900'), children: [jsx("td", { className: "whitespace-nowrap px-5 py-3 text-gray-900 dark:text-gray-100", children: when }), jsx("td", { className: "px-3 py-3", children: jsxs("span", { className: "inline-flex items-center gap-2 text-gray-700 dark:text-gray-300", children: [jsx("span", { className: "h-2 w-2 flex-shrink-0 rounded-[2px]", style: { background: colorForSeries(trace.name || '') }, "aria-hidden": "true" }), jsx("span", { className: "max-w-[16rem] truncate", title: service, children: service })] }) }), jsx("td", { className: "hidden px-3 py-3 font-mono text-xs text-gray-500 dark:text-gray-400 md:table-cell", title: trace.sessionId, children: shortId(trace.sessionId) }), jsx("td", { className: "px-3 py-3 text-right tabular-nums text-gray-700 dark:text-gray-300", children: formatSeconds(trace.latency) }), jsx("td", { className: "px-3 py-3 text-right font-semibold tabular-nums text-gray-900 dark:text-gray-100", children: formatCost$1(trace.totalCost, { precise: true }) }), jsx("td", { className: "py-2 pl-2 pr-5", children: jsx("button", { type: "button", "aria-expanded": open, "aria-controls": open ? stepsId : undefined, "aria-label": open
187542
+ ? t('profileLlmUsage.hideSteps', { when })
187543
+ : t('profileLlmUsage.showSteps', { when }), onClick: () => setOpenTraceId(open ? null : trace.id), className: cn('flex h-8 w-8 items-center justify-center rounded-md transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500', open
187544
+ ? 'bg-gray-200 text-gray-900 dark:bg-gray-700 dark:text-gray-100'
187545
+ : 'text-gray-500 hover:bg-gray-100 hover:text-gray-900 dark:hover:bg-gray-800'), children: open ? (jsx(ChevronDown, { className: "h-4 w-4", "aria-hidden": "true" })) : (jsx(ChevronRight, { className: "h-4 w-4", "aria-hidden": "true" })) }) })] }), open && (jsx("tr", { className: "bg-gray-50 dark:bg-gray-900", children: jsx("td", { colSpan: 6, className: "px-5 pb-4", children: jsx("div", { id: stepsId, className: "overflow-hidden rounded-lg border border-gray-200 bg-white dark:border-gray-800 dark:bg-gray-950", children: jsx(TraceSteps, { steps: steps.rows, isLoading: steps.isLoading, error: steps.error }) }) }) }))] }, trace.id));
187546
+ }) })] }) }), meta && (jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-t border-gray-200 px-5 py-3 dark:border-gray-800", children: [jsx("p", { className: "text-[13px] tabular-nums text-gray-500 dark:text-gray-400", children: t('profileLlmUsage.paginationSummary', {
187547
+ from: formatInteger(from),
187548
+ to: formatInteger(to),
187549
+ total: formatInteger(meta.totalItems),
187550
+ }) }), jsxs("div", { className: "flex gap-2", children: [jsxs(Button$1, { variant: "outline", size: "sm", className: "h-8 gap-1", disabled: page <= 1 || activity.isFetching, onClick: () => {
187551
+ setOpenTraceId(null);
187552
+ setPage((current) => Math.max(1, current - 1));
187553
+ }, children: [jsx(ChevronLeft, { className: "h-4 w-4", "aria-hidden": "true" }), t('profileLlmUsage.previous')] }), jsxs(Button$1, { variant: "outline", size: "sm", className: "h-8 gap-1", disabled: page >= totalPages || activity.isFetching, onClick: () => {
187554
+ setOpenTraceId(null);
187555
+ setPage((current) => current + 1);
187556
+ }, children: [t('profileLlmUsage.next'), jsx(ChevronRight, { className: "h-4 w-4", "aria-hidden": "true" })] })] })] }))] }))] })] }));
187557
+ }
187558
+ const isRefreshing = summary.isFetching ||
187559
+ spend.isFetching ||
187560
+ byModel.isFetching ||
187561
+ byService.isFetching ||
187562
+ activity.isFetching;
187563
+ return (jsxs("div", { className: "flex flex-col gap-5", "data-testid": "llm-usage-tab", children: [jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [jsx(RangeControl, { value: range, onChange: changeRange }), jsxs("div", { className: "flex items-center gap-3", children: [jsxs("span", { className: "inline-flex items-center gap-1.5 text-[13px] text-gray-500 dark:text-gray-400", children: [jsx(Lock, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), isOwnProfile
187564
+ ? t('profileLlmUsage.scopeSelf')
187565
+ : t('profileLlmUsage.scopeUser', { username })] }), jsx(Button$1, { variant: "outline", size: "icon", className: "h-9 w-9", onClick: refreshAll, disabled: isRefreshing, "aria-label": t('profileLlmUsage.refresh'), title: t('profileLlmUsage.refresh'), children: jsx(RefreshCw, { className: cn('h-4 w-4', isRefreshing && 'animate-spin'), "aria-hidden": "true" }) })] })] }), body] }));
187566
+ }
187567
+
187568
+ const tabId = (id, mobile) => (mobile ? `${id}-tab-mobile` : `${id}-tab`);
187569
+ /** Arrow/Home/End handling for the tab variant, with automatic activation. */
187570
+ function useTabKeyboard(items, onSelect, mobile) {
187571
+ const containerRef = useRef(null);
187572
+ const onKeyDown = (event, index) => {
187573
+ var _a, _b;
187574
+ const last = items.length - 1;
187575
+ let next = null;
187576
+ if (event.key === 'ArrowDown' || event.key === 'ArrowRight')
187577
+ next = index === last ? 0 : index + 1;
187578
+ if (event.key === 'ArrowUp' || event.key === 'ArrowLeft')
187579
+ next = index === 0 ? last : index - 1;
187580
+ if (event.key === 'Home')
187581
+ next = 0;
187582
+ if (event.key === 'End')
187583
+ next = last;
187584
+ if (next === null)
187585
+ return;
187586
+ event.preventDefault();
187587
+ const target = items[next];
187588
+ onSelect(target.id);
187589
+ (_b = (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(`[id="${tabId(target.id, mobile)}"]`)) === null || _b === void 0 ? void 0 : _b.focus();
187590
+ };
187591
+ return { containerRef, onKeyDown };
187592
+ }
187593
+ /** Grouped vertical navigation for the desktop sidebar. */
187594
+ function SettingsSidebarNav({ groups, activeId, onSelect, variant, ariaLabel, }) {
187595
+ const visibleGroups = groups.filter((group) => group.items.length > 0);
187596
+ const flat = visibleGroups.flatMap((group) => group.items);
187597
+ const isTabs = variant === 'tabs';
187598
+ const { containerRef, onKeyDown } = useTabKeyboard(flat, onSelect, false);
187599
+ const renderItem = (item) => {
187600
+ const active = item.id === activeId;
187601
+ const Icon = item.icon;
187602
+ return (jsxs("button", { type: "button", onClick: () => onSelect(item.id), ...(isTabs
187603
+ ? {
187604
+ role: 'tab',
187605
+ id: tabId(item.id, false),
187606
+ 'aria-selected': active,
187607
+ 'aria-controls': `${item.id}-tabpanel`,
187608
+ tabIndex: active ? 0 : -1,
187609
+ onKeyDown: (event) => onKeyDown(event, flat.indexOf(item)),
187610
+ }
187611
+ : { 'aria-current': active ? 'page' : undefined }), className: cn('group flex h-9 w-full items-center gap-2.5 rounded-lg px-2.5 text-left text-sm transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-1', active
187612
+ ? 'bg-white font-semibold text-gray-900 shadow-sm ring-1 ring-gray-200 dark:bg-gray-800 dark:text-gray-100 dark:ring-gray-700'
187613
+ : 'font-medium text-gray-700 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-gray-100'), children: [jsx(Icon, { className: cn('h-4 w-4 flex-shrink-0', active
187614
+ ? 'text-blue-600 dark:text-blue-400'
187615
+ : 'text-gray-500 group-hover:text-gray-700 dark:text-gray-400'), "aria-hidden": true }), jsx("span", { className: "truncate", children: item.label })] }, item.id));
187616
+ };
187617
+ return (jsx("nav", { className: "min-h-0 flex-1 overflow-y-auto px-3 py-4", "aria-label": ariaLabel, children: jsx("div", { ref: containerRef, className: "flex flex-col gap-4", ...(isTabs ? { role: 'tablist', 'aria-orientation': 'vertical' } : {}), children: visibleGroups.map((group) => (jsxs("div", { className: "flex flex-col gap-0.5", ...(isTabs
187618
+ ? {}
187619
+ : { role: 'group', 'aria-labelledby': `settings-nav-group-${group.id}` }), children: [jsx("div", { id: `settings-nav-group-${group.id}`, className: "px-2.5 pb-1 text-[11px] font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400", "aria-hidden": isTabs ? true : undefined, children: group.label }), group.items.map(renderItem)] }, group.id))) }) }));
187620
+ }
187621
+ /** Horizontally scrolling pills for small screens. */
187622
+ function SettingsMobileNav({ groups, activeId, onSelect, variant, ariaLabel, }) {
187623
+ const flat = groups.flatMap((group) => group.items);
187624
+ const isTabs = variant === 'tabs';
187625
+ const { containerRef, onKeyDown } = useTabKeyboard(flat, onSelect, true);
187626
+ return (jsx("nav", { className: "border-b border-gray-200 dark:border-gray-800 lg:hidden", "aria-label": ariaLabel, children: jsx("div", { ref: containerRef, className: "flex gap-2 overflow-x-auto px-4 py-2.5 [scrollbar-width:none] sm:px-6", ...(isTabs ? { role: 'tablist', 'aria-orientation': 'horizontal' } : {}), children: flat.map((item, index) => {
187627
+ const active = item.id === activeId;
187628
+ const Icon = item.icon;
187629
+ return (jsxs("button", { type: "button", onClick: () => onSelect(item.id), ...(isTabs
187630
+ ? {
187631
+ role: 'tab',
187632
+ id: tabId(item.id, true),
187633
+ 'aria-selected': active,
187634
+ 'aria-controls': `${item.id}-tabpanel`,
187635
+ tabIndex: active ? 0 : -1,
187636
+ onKeyDown: (event) => onKeyDown(event, index),
187637
+ }
187638
+ : { 'aria-current': active ? 'page' : undefined }), className: cn('flex h-9 flex-shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full px-3.5 text-sm transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-1', active
187639
+ ? 'bg-blue-600 font-semibold text-white dark:bg-blue-500 dark:text-white'
187640
+ : 'border border-gray-200 bg-white font-medium text-gray-700 hover:bg-gray-50 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300'), children: [jsx(Icon, { className: "h-3.5 w-3.5", "aria-hidden": true }), jsx("span", { children: item.label })] }, item.id));
187641
+ }) }) }));
187642
+ }
187643
+ /** Small uppercase chip under the identity card (role, platform key). */
187644
+ function SettingsChip({ children, tone = 'neutral', icon: Icon, }) {
187645
+ return (jsxs("span", { className: cn('inline-flex items-center gap-1 rounded-md px-2 py-0.5 text-xs font-semibold', tone === 'accent'
187646
+ ? 'bg-blue-50 text-blue-700 dark:bg-blue-950 dark:text-blue-300'
187647
+ : 'bg-gray-100 text-gray-600 tracking-wide dark:bg-gray-800 dark:text-gray-300'), children: [Icon && jsx(Icon, { className: "h-3 w-3", "aria-hidden": true }), children] }));
187648
+ }
187649
+ function SettingsShell({ sidebarHeader, sidebarNav, mobileHeader, mobileNav, title, description, panelProps, footer, overlays, children, }) {
187650
+ const { className: panelClassName, ...restPanelProps } = panelProps !== null && panelProps !== void 0 ? panelProps : {};
187651
+ return (jsxs("div", { className: "flex h-full min-h-0 flex-col bg-white dark:bg-gray-950 lg:flex-row", children: [jsx("div", { className: "border-b border-gray-200 py-3 pl-4 pr-14 dark:border-gray-800 sm:pl-6 lg:hidden", children: mobileHeader }), mobileNav, jsxs("aside", { className: "hidden h-full w-[280px] flex-shrink-0 flex-col overflow-hidden border-r border-gray-200 bg-gray-50 dark:border-gray-800 dark:bg-gray-900 lg:flex", children: [jsx("div", { className: "flex-shrink-0 border-b border-gray-200 px-5 pb-4 pt-6 dark:border-gray-800", children: sidebarHeader }), sidebarNav] }), jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden", children: [jsxs("div", { className: "hidden flex-shrink-0 border-b border-gray-200 py-5 pl-8 pr-16 dark:border-gray-800 lg:block", children: [jsx("h3", { className: "text-xl font-semibold tracking-tight text-gray-900 dark:text-gray-100", children: title }), description && (jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: description }))] }), jsxs("div", { className: cn('min-h-0 flex-1 overflow-y-auto overflow-x-hidden px-4 py-5 sm:px-6 lg:px-8 lg:py-6', panelClassName), ...restPanelProps, children: [jsxs("div", { className: "mb-5 lg:hidden", children: [jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100", children: title }), description && (jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: description }))] }), children] }), footer && (jsx("div", { className: "flex-shrink-0 border-t border-gray-200 bg-white px-4 py-3 dark:border-gray-800 dark:bg-gray-950 sm:px-6 lg:px-8 lg:py-4", children: footer }))] }), overlays] }));
187652
+ }
187653
+
186641
187654
  const COWORK_ENABLED_KEY = 'ibl_cowork_enabled';
186642
187655
  /**
186643
187656
  * Whether Cowork is enabled, read from localStorage. This is a user preference
@@ -186658,9 +187671,6 @@ function setCoworkEnabled(enabled) {
186658
187671
  localStorage.setItem(COWORK_ENABLED_KEY, String(enabled));
186659
187672
  }
186660
187673
 
186661
- const renderLucideIcon = (Icon) => function RenderedIcon(props) {
186662
- return jsx(Icon, { ...props });
186663
- };
186664
187674
  const TAB_DESC_KEYS = {
186665
187675
  basic: 'descBasic',
186666
187676
  social: 'descSocial',
@@ -186671,6 +187681,7 @@ const TAB_DESC_KEYS = {
186671
187681
  memory: 'descMemory',
186672
187682
  privacy: 'descPrivacy',
186673
187683
  chatHistory: 'descChatHistory',
187684
+ llmUsage: 'descLlmUsage',
186674
187685
  security: 'descSecurity',
186675
187686
  advanced: 'descAdvanced',
186676
187687
  };
@@ -186685,9 +187696,13 @@ const TAB_DESC_PREVIEW_KEYS = {
186685
187696
  memory: 'descMemoryPreview',
186686
187697
  privacy: 'descPrivacyPreview',
186687
187698
  chatHistory: 'descChatHistoryPreview',
187699
+ llmUsage: 'descLlmUsagePreview',
186688
187700
  };
186689
- function Profile({ tenant, username, tenants, onClose, customization = {}, isAdmin = false, targetTab = 'basic', onAccountDeleted, enableMemoryTab = false, localLLMProps, currentSPA = '', }) {
186690
- var _a, _b, _c, _d, _e, _f, _g, _h;
187701
+ const LABEL_CLASS = 'text-sm font-medium text-gray-700 dark:text-gray-300';
187702
+ const FIELD_CLASS = 'h-10 w-full bg-white border-gray-300 text-sm text-gray-900 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-900 dark:border-gray-700 dark:text-gray-100';
187703
+ const PRIMARY_BUTTON_CLASS = 'bg-blue-600 text-white hover:bg-blue-700 focus-visible:ring-blue-500 disabled:bg-blue-600/60';
187704
+ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdmin = false, targetTab = 'basic', onAccountDeleted, enableMemoryTab = false, showLlmUsageTab = true, localLLMProps, currentSPA = '', }) {
187705
+ var _a, _b, _c, _d, _e, _f;
186691
187706
  const t = useT();
186692
187707
  const { data: memsearchStatus, isError: isMemsearchStatusError } = useGetMemsearchStatusQuery({ org: tenant, userId: username }, { skip: !enableMemoryTab });
186693
187708
  // Show memory tab if enabled for this platform AND memsearch is enabled (or status API is unavailable)
@@ -186706,34 +187721,46 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
186706
187721
  const rbacPermissions = useSelector(selectRbacPermissions);
186707
187722
  const { currentTenant: viewerTenant } = useCurrentTenant();
186708
187723
  const isChatHistoryVisible = !isReadOnly || canViewOtherUsersChatHistory(rbacPermissions, viewerTenant);
186709
- const baseTabs = [
186710
- { id: 'basic', label: t('profileIndex.tabBasic'), renderIcon: renderLucideIcon(User) },
186711
- { id: 'social', label: t('profileIndex.tabSocial'), renderIcon: renderLucideIcon(Globe) },
187724
+ // Usage is always read for the profile on screen, so it works while
187725
+ // previewing someone else too — the backend decides whether this viewer may
187726
+ // see their rows, and answers 403 when they may not. A pure watcher (the
187727
+ // `/watchedgroups/#list` permission without tenant admin) is kept out of
187728
+ // cost reporting entirely, the same way the analytics tabs exclude them.
187729
+ const isLlmUsageVisible = showLlmUsageTab && !isPureWatcher(rbacPermissions, viewerTenant);
187730
+ // Add Advanced tab only when in Tauri app (Local Models is provided and available)
187731
+ const isAdvancedAvailable = (localLLMProps === null || localLLMProps === void 0 ? void 0 : localLLMProps.isAvailable) === true;
187732
+ const TABS = [
187733
+ { id: 'basic', label: t('profileIndex.tabBasic'), icon: User, group: 'profile' },
187734
+ { id: 'social', label: t('profileIndex.tabSocial'), icon: Globe, group: 'profile' },
186712
187735
  ...(isGradebookEnabled
186713
187736
  ? [
186714
187737
  {
186715
187738
  id: 'gradebook',
186716
187739
  label: t('profileIndex.tabGradebook'),
186717
- renderIcon: renderLucideIcon(GraduationCap),
187740
+ icon: GraduationCap,
187741
+ group: 'records',
186718
187742
  },
186719
187743
  ]
186720
187744
  : []),
186721
187745
  {
186722
187746
  id: 'education',
186723
187747
  label: t('profileIndex.tabEducation'),
186724
- renderIcon: renderLucideIcon(BookOpen),
187748
+ icon: BookOpen,
187749
+ group: 'records',
186725
187750
  },
186726
187751
  {
186727
187752
  id: 'experience',
186728
187753
  label: t('profileIndex.tabExperience'),
186729
- renderIcon: renderLucideIcon(Briefcase),
187754
+ icon: Briefcase,
187755
+ group: 'records',
186730
187756
  },
186731
187757
  ...(isPurchasesEnabled
186732
187758
  ? [
186733
187759
  {
186734
187760
  id: 'purchases',
186735
187761
  label: t('profileIndex.tabPurchases'),
186736
- renderIcon: renderLucideIcon(ShoppingBag),
187762
+ icon: ShoppingBag,
187763
+ group: 'records',
186737
187764
  },
186738
187765
  ]
186739
187766
  : []),
@@ -186742,20 +187769,23 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
186742
187769
  {
186743
187770
  id: 'memory',
186744
187771
  label: t('profileIndex.tabMemory'),
186745
- renderIcon: renderLucideIcon(Archive),
187772
+ icon: Archive,
187773
+ group: 'aiData',
186746
187774
  },
186747
187775
  ]
186748
187776
  : []),
186749
187777
  // id stays as 'privacy' so callers passing `targetTab='privacy'` and
186750
187778
  // any test selectors targeting #panel-privacy keep working. The
186751
187779
  // user-visible `label` is "Privacy"; the chat-privacy feature itself
186752
- // is still called "Private Mode" within the tab's content.
187780
+ // is still called "Private Mode" within the tab's content. It sits with
187781
+ // the account controls, just above Security.
186753
187782
  ...(isChatPrivacyEnabled
186754
187783
  ? [
186755
187784
  {
186756
187785
  id: 'privacy',
186757
187786
  label: t('profileIndex.tabPrivacy'),
186758
- renderIcon: renderLucideIcon(Lock),
187787
+ icon: Lock,
187788
+ group: 'account',
186759
187789
  },
186760
187790
  ]
186761
187791
  : []),
@@ -186764,7 +187794,18 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
186764
187794
  {
186765
187795
  id: 'chatHistory',
186766
187796
  label: t('profileIndex.tabChatHistory'),
186767
- renderIcon: renderLucideIcon(History),
187797
+ icon: History,
187798
+ group: 'aiData',
187799
+ },
187800
+ ]
187801
+ : []),
187802
+ ...(isLlmUsageVisible
187803
+ ? [
187804
+ {
187805
+ id: 'llmUsage',
187806
+ label: t('profileIndex.tabLlmUsage'),
187807
+ icon: Gauge,
187808
+ group: 'aiData',
186768
187809
  },
186769
187810
  ]
186770
187811
  : []),
@@ -186773,24 +187814,33 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
186773
187814
  {
186774
187815
  id: 'security',
186775
187816
  label: t('profileIndex.tabSecurity'),
186776
- renderIcon: renderLucideIcon(Shield),
187817
+ icon: Shield,
187818
+ group: 'account',
187819
+ },
187820
+ ]
187821
+ : []),
187822
+ ...(isAdvancedAvailable
187823
+ ? [
187824
+ {
187825
+ id: 'advanced',
187826
+ label: t('profileIndex.tabAdvanced'),
187827
+ icon: Settings,
187828
+ group: 'account',
186777
187829
  },
186778
187830
  ]
186779
187831
  : []),
186780
187832
  ];
186781
- // Add Advanced tab only when in Tauri app (Local Models is provided and available)
186782
- const isAdvancedAvailable = (localLLMProps === null || localLLMProps === void 0 ? void 0 : localLLMProps.isAvailable) === true;
186783
- const TABS = isAdvancedAvailable
186784
- ? [
186785
- ...baseTabs,
186786
- {
186787
- id: 'advanced',
186788
- label: t('profileIndex.tabAdvanced'),
186789
- renderIcon: renderLucideIcon(Settings),
186790
- },
186791
- ]
186792
- : baseTabs;
186793
- const RoleIcon = renderLucideIcon(User);
187833
+ const GROUP_LABELS = {
187834
+ profile: t('profileIndex.groupProfile'),
187835
+ records: t('profileIndex.groupRecords'),
187836
+ aiData: t('profileIndex.groupAiData'),
187837
+ account: t('profileIndex.groupAccount'),
187838
+ };
187839
+ const navGroups = Object.keys(GROUP_LABELS).map((group) => ({
187840
+ id: group,
187841
+ label: GROUP_LABELS[group],
187842
+ items: TABS.filter((tab) => tab.group === group),
187843
+ }));
186794
187844
  const [activeTab, setActiveTab] = useState(targetTab);
186795
187845
  const [isHovering, setIsHovering] = useState(false);
186796
187846
  const fileInputRef = useRef(null);
@@ -186812,8 +187862,7 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
186812
187862
  };
186813
187863
  // The picture itself, with no editing affordance around it. The wrapper
186814
187864
  // below decides whether it is clickable.
186815
- const profileAvatar = (jsxs(Avatar, { className: "h-20 w-20", children: [((_b = userMetadataEdx === null || userMetadataEdx === void 0 ? void 0 : userMetadataEdx.profile_image) === null || _b === void 0 ? void 0 : _b.has_image) ? (jsx(AvatarImage, { src: (_c = userMetadataEdx === null || userMetadataEdx === void 0 ? void 0 : userMetadataEdx.profile_image) === null || _c === void 0 ? void 0 : _c.image_url_full, alt: t('profileIndex.altProfilePicture'), className: "rounded-full object-cover w-full h-full group-hover:opacity-80 transition-opacity" })) : customization.useGravatarPicFallback ? (jsx(Gravatar, { className: "w-full h-full rounded-full object-cover group-hover:opacity-80 transition-opacity", email: userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email, size: 80, alt: t('profileIndex.altProfilePictureGravatar') })) : (jsx(Fragment$1, {})), jsx(AvatarFallback, { className: cn('bg-blue-800 text-white text-xl rounded-full', customization.useGravatarPicFallback &&
186816
- !((_d = userMetadataEdx === null || userMetadataEdx === void 0 ? void 0 : userMetadataEdx.profile_image) === null || _d === void 0 ? void 0 : _d.image_url_full)
187865
+ const profileAvatar = (jsxs(Avatar, { className: "h-14 w-14", children: [((_b = userMetadataEdx === null || userMetadataEdx === void 0 ? void 0 : userMetadataEdx.profile_image) === null || _b === void 0 ? void 0 : _b.has_image) ? (jsx(AvatarImage, { src: (_c = userMetadataEdx === null || userMetadataEdx === void 0 ? void 0 : userMetadataEdx.profile_image) === null || _c === void 0 ? void 0 : _c.image_url_full, alt: t('profileIndex.altProfilePicture'), className: "rounded-full object-cover w-full h-full group-hover:opacity-80 transition-opacity" })) : customization.useGravatarPicFallback ? (jsx(Gravatar, { className: "w-full h-full rounded-full object-cover group-hover:opacity-80 transition-opacity", email: userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email, size: 56, alt: t('profileIndex.altProfilePictureGravatar') })) : (jsx(Fragment$1, {})), jsx(AvatarFallback, { className: cn('bg-blue-800 text-white text-lg font-semibold rounded-full', customization.useGravatarPicFallback && !((_d = userMetadataEdx === null || userMetadataEdx === void 0 ? void 0 : userMetadataEdx.profile_image) === null || _d === void 0 ? void 0 : _d.image_url_full)
186817
187866
  ? 'hidden'
186818
187867
  : ''), children: getInitials((userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.name) || (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.username) || (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email) || '') })] }));
186819
187868
  const handleFileUpload = (event) => {
@@ -186858,115 +187907,122 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
186858
187907
  // Rendered inline on the sub-tabs row (education/experience/resume), pushed to
186859
187908
  // the far right. `headerAdd` already encodes which sub-tab is active, so this
186860
187909
  // only appears on the sub-tabs that support adding/uploading.
186861
- 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" }) }));
187910
+ const headerAddButton = headerAdd && (jsxs(Button$1, { size: "sm", onClick: headerAdd.onClick, className: cn('h-9 flex-shrink-0 gap-1.5 px-3', PRIMARY_BUTTON_CLASS), "aria-label": headerAdd.ariaLabel, children: [headerAdd.upload ? (jsx(Upload, { className: "h-4 w-4", "aria-hidden": "true" })) : (jsx(Plus, { className: "h-4 w-4", "aria-hidden": "true" })), jsx("span", { className: "hidden sm:inline", children: headerAdd.ariaLabel })] }));
186862
187911
  const tabDescription = (id) => {
186863
187912
  const key = (isReadOnly && TAB_DESC_PREVIEW_KEYS[id]) || TAB_DESC_KEYS[id];
186864
187913
  return key ? t(`profileIndex.${key}`) : '';
186865
187914
  };
186866
- return (jsxs("div", { className: "flex flex-col lg:flex-row h-full", children: [jsx("div", { className: "lg:hidden", children: jsx("div", { className: "px-6 py-4 border-b border-gray-200", children: jsx("h2", { className: "text-lg font-semibold text-gray-900", children: t('profileIndex.profileHeading') }) }) }), jsxs("div", { className: "hidden lg:flex bg-white border-r border-gray-200 dark:border-gray-700 flex-col overflow-hidden", style: {
186867
- width: '320px',
186868
- height: '100%',
186869
- }, children: [jsxs("div", { className: "flex flex-col items-center justify-center py-6 px-6 border-b border-gray-200 dark:border-gray-700 flex-shrink-0", children: [isUserMetadataEdxLoading || isUploadingProfileImage ? (jsx(Skeleton, { className: "h-20 w-20 mb-6 rounded-full", "aria-label": t('profileIndex.ariaLoadingProfileImage') })) : isReadOnly ? (
186870
- // Someone else's profile: show the picture, offer no way to replace it.
186871
- jsx("div", { className: "relative w-20 h-20 mb-4 rounded-full", children: profileAvatar })) : (jsxs("button", { type: "button", className: "relative w-20 h-20 mb-4 cursor-pointer group rounded-full focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2", onMouseEnter: () => setIsHovering(true), onMouseLeave: () => setIsHovering(false), onClick: handleAvatarClick, "aria-label": t('profileIndex.ariaUploadProfilePicture'), children: [profileAvatar, isHovering && (jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-blue-800 rounded-full border-4 border-white/20", "aria-hidden": "true", children: jsx("span", { className: "text-white text-xs font-medium text-center px-2", children: t('profileIndex.uploadOverlay') }) })), jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", onChange: handleFileUpload, className: "hidden", "aria-label": t('profileIndex.ariaChooseProfilePicture'), tabIndex: -1 })] })), jsx("h2", { className: "text-base font-semibold text-gray-900 dark:text-gray-100 text-center mb-3 break-all px-2", title: userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email, children: userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email }), jsxs("div", { className: "flex justify-center space-x-3", children: [jsxs("div", { className: "bg-blue-100 text-blue-700 px-2 py-1 rounded font-medium flex items-center text-sm", children: [jsx(RoleIcon, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), jsx("span", { children: isAdmin ? t('profileIndex.roleAdmin') : t('profileIndex.roleUser') })] }), customization.showPlatformName && (jsx("div", { className: "bg-gray-100 text-gray-600 px-4 py-2 rounded text-xs font-medium", children: tenant.toUpperCase() }))] })] }), jsx("nav", { className: "flex-1 overflow-y-auto", style: { minHeight: 0 }, "aria-label": t('profileIndex.ariaProfileTabs'), children: jsx("div", { className: "p-4", children: jsx("div", { className: "flex flex-col space-y-1.5", role: "tablist", "aria-orientation": "vertical", children: TABS.map((tab) => (jsxs("button", { role: "tab", "aria-selected": activeTab === tab.id, "aria-controls": `${tab.id}-tabpanel`, id: `${tab.id}-tab`, onClick: () => setActiveTab(tab.id), className: `w-full justify-start px-4 py-2.5 text-left rounded-lg transition-all flex items-center text-base ${activeTab === tab.id
186872
- ? 'bg-blue-50 text-blue-700 font-medium'
186873
- : '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
186874
- ? 'bg-blue-50 text-blue-600 font-medium'
186875
- : '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: {
186876
- overflowY: 'auto',
186877
- overflowX: 'hidden',
186878
- }, 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) => {
186879
- formEvent.preventDefault();
186880
- formEvent.stopPropagation();
186881
- if (isReadOnly)
186882
- return;
186883
- basicForm.handleSubmit();
186884
- }, className: "space-y-6", children: [jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "fullName", className: "text-gray-500 dark:text-gray-400 text-base", children: t('profileIndex.labelFullName') }), basicForm.Field({
186885
- name: 'fullName',
186886
- validators: {
186887
- onChange: basicValidators.fullName,
186888
- onSubmit: basicValidators.fullName,
186889
- },
186890
- children: (field) => {
186891
- var _a;
186892
- return (jsxs(Fragment$1, { children: [jsx(Input, { id: "fullName", className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-base py-3", value: field.state.value, onChange: (e) => field.handleChange(e.target.value), disabled: basicForm.state.isSubmitting || isUserMetadataLoading || isReadOnly }), ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) > 0 && (jsx("p", { className: "text-red-500 text-sm mt-1", role: "alert", children: field.state.meta.errors }))] }));
186893
- },
186894
- })] }), jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "email", className: "text-gray-500 dark:text-gray-400 text-base", children: t('profileIndex.labelEmail') }), basicForm.Field({
186895
- name: 'email',
186896
- children: (field) => (jsx(Input, { id: "email", type: "email", className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-base py-3", value: field.state.value, onChange: (e) => field.handleChange(e.target.value), disabled: basicForm.state.isSubmitting || isUserMetadataLoading || isReadOnly })),
186897
- })] }), customization.showUsernameField && (jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "username", className: "text-gray-500 dark:text-gray-400 text-base", children: t('profileIndex.labelUsername') }), basicForm.Field({
186898
- name: 'username',
186899
- children: (field) => (jsx(Input, { id: "username", className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-base py-3", value: field.state.value, onChange: (e) => field.handleChange(e.target.value), disabled: basicForm.state.isSubmitting || isUserMetadataLoading || isReadOnly })),
186900
- })] })), jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "title", className: "text-gray-500 dark:text-gray-400 text-base", children: t('profileIndex.labelTitle') }), basicForm.Field({
186901
- name: 'title',
186902
- children: (field) => (jsx(Input, { id: "title", className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-base py-3", value: field.state.value, onChange: (e) => field.handleChange(e.target.value), disabled: basicForm.state.isSubmitting || isUserMetadataLoading || isReadOnly })),
186903
- })] }), jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "about", className: "text-gray-500 dark:text-gray-400 text-base", children: t('profileIndex.labelAbout') }), basicForm.Field({
186904
- name: 'about',
186905
- children: (field) => (jsx(Textarea, { id: "about", placeholder: t('profileIndex.placeholderAbout'), className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-base resize-none", rows: 4, value: field.state.value, onChange: (e) => field.handleChange(e.target.value), disabled: basicForm.state.isSubmitting || isUserMetadataLoading || isReadOnly })),
186906
- })] }), jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "language", className: "text-gray-500 dark:text-gray-400 text-base", children: t('profileIndex.labelLanguage') }), basicForm.Field({
186907
- name: 'language',
186908
- children: (field) => (jsxs(Select$1, { defaultValue: field.state.value, onValueChange: (value) => field.handleChange(value), disabled: basicForm.state.isSubmitting || isUserMetadataLoading || isReadOnly, children: [jsx(SelectTrigger, { className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-base py-3 text-sm", "aria-label": t('profileIndex.selectLanguagePlaceholder'), children: jsx(SelectValue, { placeholder: t('profileIndex.selectLanguagePlaceholder') }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "en", children: t('profileIndex.langEnglish') }), jsx(SelectItem, { value: "es", children: t('profileIndex.langSpanish') }), jsx(SelectItem, { value: "fr", children: t('profileIndex.langFrench') })] })] })),
186909
- })] }), (customization.showLeaderboardDisplayCheckbox ||
186910
- customization.showMentorAIDisplayCheckbox) && (jsxs("div", { className: "grid grid-cols-2 gap-6 pt-4", children: [customization.showMentorAIDisplayCheckbox && (jsx("div", { className: "space-y-2", children: jsxs("div", { className: "flex items-center space-x-2", children: [basicForm.Field({
186911
- name: 'displayMentor',
186912
- children: (field) => (jsx(Switch, { className: "data-[state=checked]:bg-blue-600", onCheckedChange: (checked) => field.handleChange(checked), checked: field.state.value, disabled: basicForm.state.isSubmitting ||
186913
- isUserMetadataLoading ||
186914
- isReadOnly, id: "display-mentor" })),
186915
- }), jsx("label", { htmlFor: "display-mentor", className: "text-sm leading-none font-medium text-gray-700 peer-disabled:cursor-not-allowed peer-disabled:opacity-70", children: t('profileIndex.checkboxDisplayMentorAI') })] }) })), customization.showLeaderboardDisplayCheckbox && (jsx("div", { className: "space-y-2", children: jsxs("div", { className: "flex items-center space-x-2", children: [basicForm.Field({
186916
- name: 'displayLeaderBoard',
186917
- children: (field) => (jsx(Switch, { className: "data-[state=checked]:bg-blue-600", onCheckedChange: (checked) => field.handleChange(checked), checked: field.state.value, disabled: basicForm.state.isSubmitting ||
186918
- isUserMetadataLoading ||
186919
- isReadOnly, id: "display-leaderboard" })),
186920
- }), jsx("label", { htmlFor: "display-leaderboard", className: "text-sm leading-none font-medium text-gray-700 peer-disabled:cursor-not-allowed peer-disabled:opacity-70", children: t('profileIndex.checkboxDisplayLeaderboard') })] }) }))] }))] }) })), activeTab === 'social' && (jsx("div", { className: "space-y-6", children: jsxs("form", { className: "space-y-6", onSubmit: (formEvent) => {
186921
- formEvent.preventDefault();
186922
- formEvent.stopPropagation();
186923
- if (isReadOnly)
186924
- return;
186925
- socialForm.handleSubmit();
186926
- }, children: [jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "facebook", className: "text-gray-500 dark:text-gray-400 text-base", children: t('profileIndex.labelFacebook') }), socialForm.Field({
186927
- name: 'facebook',
186928
- validators: {
186929
- onChange: socialValidators.facebook,
186930
- },
186931
- children: (field) => {
186932
- var _a;
186933
- 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-[#1877F2] text-white rounded w-8 h-8 flex items-center justify-center", children: jsx("span", { className: "font-bold text-sm", children: "f" }) }) }), jsx(Input, { id: "facebook", 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.placeholderFacebook'), value: field.state.value, onChange: (e) => handleSocialLinkChange(e.target.value, field.handleChange, FACEBOOK_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 })] }));
186934
- },
186935
- })] }), jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "linkedin", className: "text-gray-500 dark:text-gray-400 text-base", children: t('profileIndex.labelLinkedIn') }), socialForm.Field({
186936
- name: 'linkedIn',
186937
- validators: {
186938
- onChange: socialValidators.linkedIn,
186939
- },
186940
- children: (field) => {
186941
- var _a;
186942
- 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-[#0A66C2] text-white rounded w-8 h-8 flex items-center justify-center", children: jsx("span", { className: "font-bold text-xs", children: "in" }) }) }), jsx(Input, { id: "linkedin", 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.placeholderLinkedIn'), value: field.state.value, onChange: (e) => handleSocialLinkChange(e.target.value, field.handleChange, LINKEDIN_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 })] }));
186943
- },
186944
- })] }), jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "x", className: "text-gray-500 dark:text-gray-400 text-base", children: t('profileIndex.labelX') }), socialForm.Field({
186945
- name: 'x',
186946
- validators: {
186947
- onChange: socialValidators.x,
186948
- },
186949
- children: (field) => {
186950
- var _a;
186951
- 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 })] }));
186952
- },
186953
- })] })] }) })), 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 }), isChatHistoryVisible && activeTab === 'chatHistory' && (jsx(ChatHistoryTab, { 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 && (jsx("div", { className: "space-y-6", children: 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 }) }))] }), !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: () => {
186954
- if (activeTab === 'basic') {
186955
- basicForm.handleSubmit();
186956
- }
186957
- else if (activeTab === 'social') {
186958
- socialForm.handleSubmit();
186959
- }
186960
- }, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", disabled: (activeTab === 'basic' &&
186961
- (basicForm.state.isSubmitting || isUserMetadataLoading)) ||
186962
- (activeTab === 'social' && socialForm.state.isSubmitting), children: (activeTab === 'basic' && basicForm.state.isSubmitting) ||
186963
- (activeTab === 'social' && socialForm.state.isSubmitting)
186964
- ? t('profileIndex.buttonSaving')
186965
- : t('profileIndex.buttonSaveChanges') })] }) }))] }), jsx(EducationDialog, { open: isEducationDialogOpen, onOpenChange: setIsEducationDialogOpen, education: undefined, org: tenant, username: username, onComplete: () => {
186966
- // The education tab will handle refetching
186967
- } }), jsx(ExperienceDialog, { open: isExperienceDialogOpen, onOpenChange: setIsExperienceDialogOpen, experience: undefined, org: tenant, username: username, onComplete: () => {
186968
- // The experience tab will handle refetching
186969
- } }), jsx(ToastProvider, {})] }));
187915
+ const email = (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email) || '';
187916
+ const displayName = (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.name) || (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.username) || email;
187917
+ const roleChip = (jsx(SettingsChip, { tone: "accent", icon: User, children: isAdmin ? t('profileIndex.roleAdmin') : t('profileIndex.roleUser') }));
187918
+ const platformChip = customization.showPlatformName ? (jsx(SettingsChip, { children: tenant.toUpperCase() })) : null;
187919
+ const avatarBlock = isUserMetadataEdxLoading || isUploadingProfileImage ? (jsx(Skeleton, { className: "h-14 w-14 flex-shrink-0 rounded-full", "aria-label": t('profileIndex.ariaLoadingProfileImage') })) : isReadOnly ? (
187920
+ // Someone else's profile: show the picture, offer no way to replace it.
187921
+ jsx("div", { className: "relative h-14 w-14 flex-shrink-0 rounded-full", children: profileAvatar })) : (jsxs("button", { type: "button", className: "group relative h-14 w-14 flex-shrink-0 cursor-pointer rounded-full focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2", onMouseEnter: () => setIsHovering(true), onMouseLeave: () => setIsHovering(false), onClick: handleAvatarClick, "aria-label": t('profileIndex.ariaUploadProfilePicture'), children: [profileAvatar, isHovering && (jsx("div", { className: "absolute inset-0 flex items-center justify-center rounded-full bg-blue-900/80", "aria-hidden": "true", children: jsx("span", { className: "px-1 text-center text-[11px] font-semibold text-white", children: t('profileIndex.uploadOverlay') }) })), jsx("span", { className: "absolute -bottom-0.5 -right-0.5 flex h-6 w-6 items-center justify-center rounded-full border border-gray-200 bg-white text-gray-700 shadow-sm dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200", "aria-hidden": "true", children: jsx(Camera, { className: "h-3 w-3" }) }), jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", onChange: handleFileUpload, className: "hidden", "aria-label": t('profileIndex.ariaChooseProfilePicture'), tabIndex: -1 })] }));
187922
+ const sidebarHeader = (jsxs("div", { className: "flex flex-col gap-3", children: [jsxs("div", { className: "flex items-center gap-3", children: [avatarBlock, jsxs("div", { className: "min-w-0 space-y-1", children: [jsx("h2", { className: "truncate text-[15px] font-semibold text-gray-900 dark:text-gray-100", title: displayName, children: displayName }), jsxs("div", { className: "flex flex-wrap gap-1.5", children: [roleChip, platformChip] })] })] }), email && email !== displayName && (jsx("p", { className: "break-all text-[13px] leading-snug text-gray-500 dark:text-gray-400", title: email, children: email }))] }));
187923
+ // Name only: the email already sits in the sidebar card, which small
187924
+ // screens hide, and the dialog title covers the rest.
187925
+ const mobileHeader = (jsx("p", { className: "truncate text-[15px] font-semibold text-gray-900 dark:text-gray-100", children: (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.name) || (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.username) || t('profileIndex.profileHeading') }));
187926
+ const isBusyBasic = basicForm.state.isSubmitting || isUserMetadataLoading || isReadOnly;
187927
+ const footer = !isReadOnly && ['basic', 'social'].includes(activeTab) ? (jsxs("div", { className: "flex justify-end gap-3", children: [jsx(Button$1, { onClick: onClose, variant: "outline", className: "h-10 px-4", children: t('profileIndex.buttonCancel') }), jsx(Button$1, { onClick: () => {
187928
+ if (activeTab === 'basic') {
187929
+ basicForm.handleSubmit();
187930
+ }
187931
+ else if (activeTab === 'social') {
187932
+ socialForm.handleSubmit();
187933
+ }
187934
+ }, className: cn('h-10 px-5', PRIMARY_BUTTON_CLASS), disabled: (activeTab === 'basic' && (basicForm.state.isSubmitting || isUserMetadataLoading)) ||
187935
+ (activeTab === 'social' && socialForm.state.isSubmitting), children: (activeTab === 'basic' && basicForm.state.isSubmitting) ||
187936
+ (activeTab === 'social' && socialForm.state.isSubmitting)
187937
+ ? t('profileIndex.buttonSaving')
187938
+ : t('profileIndex.buttonSaveChanges') })] })) : null;
187939
+ const socialField = ({ id, name, label, placeholder, prefix, badge, validator, }) => (jsxs("div", { className: "space-y-1.5", children: [jsx("label", { htmlFor: id, className: LABEL_CLASS, children: label }), socialForm.Field({
187940
+ name,
187941
+ validators: {
187942
+ onChange: validator,
187943
+ },
187944
+ children: (field) => {
187945
+ var _a;
187946
+ return (jsxs(Fragment$1, { children: [jsxs("div", { className: "relative mb-0", children: [jsx("div", { className: "pointer-events-none absolute inset-y-0 left-2 flex items-center", "aria-hidden": "true", children: jsx("div", { className: cn('flex h-7 w-7 items-center justify-center rounded-md text-white', badge.className), children: jsx("span", { className: cn('font-bold', badge.textClassName), children: badge.text }) }) }), jsx(Input, { id: id, className: cn(FIELD_CLASS, 'pl-12'), placeholder: placeholder, value: field.state.value, onChange: (e) => handleSocialLinkChange(e.target.value, field.handleChange, prefix), disabled: socialForm.state.isSubmitting || isReadOnly })] }), jsx("p", { className: "text-sm text-red-600 dark:text-red-400", role: ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) ? 'alert' : undefined, "aria-live": "polite", children: field.state.meta.errors })] }));
187947
+ },
187948
+ })] }));
187949
+ return (jsxs(SettingsShell, { sidebarHeader: sidebarHeader, sidebarNav: jsx(SettingsSidebarNav, { groups: navGroups, activeId: activeTab, onSelect: setActiveTab, variant: "tabs", ariaLabel: t('profileIndex.ariaProfileTabs') }), mobileHeader: mobileHeader, mobileNav: jsx(SettingsMobileNav, { groups: navGroups, activeId: activeTab, onSelect: setActiveTab, variant: "tabs", ariaLabel: t('profileIndex.ariaProfileTabsMobile') }),
187950
+ // Render the tab's label rather than the id — every label is already
187951
+ // cased correctly.
187952
+ title: (_f = (_e = TABS.find((tab) => tab.id === activeTab)) === null || _e === void 0 ? void 0 : _e.label) !== null && _f !== void 0 ? _f : activeTab, description: tabDescription(activeTab), panelProps: {
187953
+ role: 'tabpanel',
187954
+ id: `${activeTab}-tabpanel`,
187955
+ 'aria-labelledby': `${activeTab}-tab`,
187956
+ tabIndex: 0,
187957
+ }, footer: footer, overlays: jsxs(Fragment$1, { children: [jsx(EducationDialog, { open: isEducationDialogOpen, onOpenChange: setIsEducationDialogOpen, education: undefined, org: tenant, username: username, onComplete: () => {
187958
+ // The education tab will handle refetching
187959
+ } }), jsx(ExperienceDialog, { open: isExperienceDialogOpen, onOpenChange: setIsExperienceDialogOpen, experience: undefined, org: tenant, username: username, onComplete: () => {
187960
+ // The experience tab will handle refetching
187961
+ } }), jsx(ToastProvider, {})] }), children: [activeTab === 'basic' && (jsxs("form", { onSubmit: (formEvent) => {
187962
+ formEvent.preventDefault();
187963
+ formEvent.stopPropagation();
187964
+ if (isReadOnly)
187965
+ return;
187966
+ basicForm.handleSubmit();
187967
+ }, className: "max-w-3xl space-y-8", children: [jsxs("div", { className: "grid grid-cols-1 gap-x-5 gap-y-5 md:grid-cols-2", children: [jsxs("div", { className: "space-y-1.5", children: [jsx("label", { htmlFor: "fullName", className: LABEL_CLASS, children: t('profileIndex.labelFullName') }), basicForm.Field({
187968
+ name: 'fullName',
187969
+ validators: {
187970
+ onChange: basicValidators.fullName,
187971
+ onSubmit: basicValidators.fullName,
187972
+ },
187973
+ children: (field) => {
187974
+ var _a;
187975
+ return (jsxs(Fragment$1, { children: [jsx(Input, { id: "fullName", className: FIELD_CLASS, value: field.state.value, onChange: (e) => field.handleChange(e.target.value), disabled: isBusyBasic }), ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) > 0 && (jsx("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", role: "alert", children: field.state.meta.errors }))] }));
187976
+ },
187977
+ })] }), jsxs("div", { className: "space-y-1.5", children: [jsx("label", { htmlFor: "email", className: LABEL_CLASS, children: t('profileIndex.labelEmail') }), basicForm.Field({
187978
+ name: 'email',
187979
+ children: (field) => (jsx(Input, { id: "email", type: "email", className: FIELD_CLASS, value: field.state.value, onChange: (e) => field.handleChange(e.target.value), disabled: isBusyBasic })),
187980
+ })] }), customization.showUsernameField && (jsxs("div", { className: "space-y-1.5", children: [jsx("label", { htmlFor: "username", className: LABEL_CLASS, children: t('profileIndex.labelUsername') }), basicForm.Field({
187981
+ name: 'username',
187982
+ children: (field) => (jsx(Input, { id: "username", className: FIELD_CLASS, value: field.state.value, onChange: (e) => field.handleChange(e.target.value), disabled: isBusyBasic })),
187983
+ })] })), jsxs("div", { className: "space-y-1.5", children: [jsx("label", { htmlFor: "title", className: LABEL_CLASS, children: t('profileIndex.labelTitle') }), basicForm.Field({
187984
+ name: 'title',
187985
+ children: (field) => (jsx(Input, { id: "title", className: FIELD_CLASS, value: field.state.value, onChange: (e) => field.handleChange(e.target.value), disabled: isBusyBasic })),
187986
+ })] }), jsxs("div", { className: "space-y-1.5", children: [jsx("label", { htmlFor: "language", className: LABEL_CLASS, children: t('profileIndex.labelLanguage') }), basicForm.Field({
187987
+ name: 'language',
187988
+ children: (field) => (jsxs(Select$1, { defaultValue: field.state.value, onValueChange: (value) => field.handleChange(value), disabled: isBusyBasic, children: [jsx(SelectTrigger, { id: "language", className: FIELD_CLASS, "aria-label": t('profileIndex.selectLanguagePlaceholder'), children: jsx(SelectValue, { placeholder: t('profileIndex.selectLanguagePlaceholder') }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "en", children: t('profileIndex.langEnglish') }), jsx(SelectItem, { value: "es", children: t('profileIndex.langSpanish') }), jsx(SelectItem, { value: "fr", children: t('profileIndex.langFrench') })] })] })),
187989
+ })] }), jsxs("div", { className: "space-y-1.5 md:col-span-2", children: [jsx("label", { htmlFor: "about", className: LABEL_CLASS, children: t('profileIndex.labelAbout') }), basicForm.Field({
187990
+ name: 'about',
187991
+ children: (field) => (jsx(Textarea, { id: "about", placeholder: t('profileIndex.placeholderAbout'), className: cn(FIELD_CLASS, 'h-auto resize-none py-2.5 leading-relaxed'), rows: 4, value: field.state.value, onChange: (e) => field.handleChange(e.target.value), disabled: isBusyBasic })),
187992
+ })] })] }), customization.showMentorAIDisplayCheckbox && (jsxs("section", { className: "space-y-2.5", "aria-labelledby": "profile-features-heading", children: [jsx("h4", { id: "profile-features-heading", className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: t('profileIndex.sectionFeatures') }), jsx("div", { className: "divide-y divide-gray-200 rounded-xl border border-gray-200 dark:divide-gray-800 dark:border-gray-800", children: jsxs("div", { className: "flex items-center justify-between gap-4 px-4 py-3.5", children: [jsxs("div", { className: "flex min-w-0 items-center gap-1", children: [jsx("label", { htmlFor: "display-mentor", className: "text-sm font-medium text-gray-700 peer-disabled:cursor-not-allowed peer-disabled:opacity-70 dark:text-gray-300", children: t('profileIndex.checkboxDisplayMentorAI') }), jsx(CardInfoIcon, { description: t('profileIndex.tooltipDisplayMentorAI') })] }), basicForm.Field({
187993
+ name: 'displayMentor',
187994
+ children: (field) => (jsx(Switch, { className: "data-[state=checked]:bg-blue-600", onCheckedChange: (checked) => field.handleChange(checked), checked: field.state.value, disabled: isBusyBasic, id: "display-mentor" })),
187995
+ })] }) })] }))] })), activeTab === 'social' && (jsxs("form", { className: "max-w-2xl space-y-5", onSubmit: (formEvent) => {
187996
+ formEvent.preventDefault();
187997
+ formEvent.stopPropagation();
187998
+ if (isReadOnly)
187999
+ return;
188000
+ socialForm.handleSubmit();
188001
+ }, children: [socialField({
188002
+ id: 'facebook',
188003
+ name: 'facebook',
188004
+ label: t('profileIndex.labelFacebook'),
188005
+ placeholder: t('profileIndex.placeholderFacebook'),
188006
+ prefix: FACEBOOK_URL_PREFIX,
188007
+ badge: { className: 'bg-[#1877F2]', text: 'f', textClassName: 'text-sm' },
188008
+ validator: socialValidators.facebook,
188009
+ }), socialField({
188010
+ id: 'linkedin',
188011
+ name: 'linkedIn',
188012
+ label: t('profileIndex.labelLinkedIn'),
188013
+ placeholder: t('profileIndex.placeholderLinkedIn'),
188014
+ prefix: LINKEDIN_URL_PREFIX,
188015
+ badge: { className: 'bg-[#0A66C2]', text: 'in', textClassName: 'text-xs' },
188016
+ validator: socialValidators.linkedIn,
188017
+ }), socialField({
188018
+ id: 'x',
188019
+ name: 'x',
188020
+ label: t('profileIndex.labelX'),
188021
+ placeholder: t('profileIndex.placeholderX'),
188022
+ prefix: X_URL_PREFIX,
188023
+ badge: { className: 'bg-black', text: 'X', textClassName: 'text-sm' },
188024
+ validator: socialValidators.x,
188025
+ })] })), 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 }), isChatHistoryVisible && activeTab === 'chatHistory' && (jsx(ChatHistoryTab, { org: tenant, username: username })), isLlmUsageVisible && activeTab === 'llmUsage' && (jsx(LlmUsageTab, { org: tenant, username: username, isOwnProfile: !isReadOnly })), !isReadOnly && activeTab === 'security' && (jsx(Security, { app: currentSPA || '', email: (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email) || '', platformKey: tenant, onAccountDeleted: onAccountDeleted })), activeTab === 'advanced' && localLLMProps && (jsx("div", { className: "space-y-6", children: 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 }) }))] }));
186970
188026
  }
186971
188027
 
186972
188028
  function CSVEditor({ csvData, onSave, onCancel }) {
@@ -188428,7 +189484,7 @@ function RetrievedDocumentsButton({ sessionId = '', documents, className, label,
188428
189484
  // Safe inside clickable transcript rows: the row must not react.
188429
189485
  event.stopPropagation();
188430
189486
  setIsOpen(true);
188431
- }, "data-testid": "retrieved-documents-button", children: [jsx(FileText, { className: "h-4 w-4 text-blue-600" }), jsx("span", { children: label !== null && label !== void 0 ? label : t('retrievedDocumentsButton.title') })] }), jsx(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: jsxs(DialogContent, { className: "flex max-h-[80vh] flex-col gap-0 p-0 sm:max-w-[425px] md:max-w-[600px]", children: [jsx(DialogHeader, { className: "border-b px-4 py-2", children: jsxs(DialogTitle, { className: "flex items-center gap-2 text-base font-medium text-[#646464]", children: [jsx(FileText, { className: "h-5 w-5 text-blue-600" }), t('retrievedDocumentsButton.title')] }) }), jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", "data-testid": "retrieved-documents-scroll", children: jsx(DocumentSidebar, { isModal: true, sessionId: sessionId, documents: documents }) })] }) })] }));
189487
+ }, "data-testid": "retrieved-documents-button", children: [jsx(FileText, { className: "h-4 w-4 text-blue-600" }), jsx("span", { children: label !== null && label !== void 0 ? label : t('retrievedDocumentsButton.title') })] }), jsx(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: jsxs(DialogContent, { className: "flex max-h-[80vh] flex-col gap-0 p-0 sm:max-w-[425px] md:max-w-[600px]", children: [jsx(DialogHeader, { className: "border-b border-gray-200 px-4 py-2", children: jsxs(DialogTitle, { className: "flex items-center gap-2 text-base font-medium text-[#646464]", children: [jsx(FileText, { className: "h-5 w-5 text-blue-600" }), t('retrievedDocumentsButton.title')] }) }), jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", "data-testid": "retrieved-documents-scroll", children: jsx(DocumentSidebar, { isModal: true, sessionId: sessionId, documents: documents }) })] }) })] }));
188432
189488
  }
188433
189489
 
188434
189490
  var COLLAPSIBLE_NAME = "Collapsible";
@@ -194376,19 +195432,6 @@ function AddCreditsModal({ isOpen, onClose, tenant }) {
194376
195432
  return (jsx(Dialog, { open: isOpen, onOpenChange: handleClose, children: jsxs(DialogContent, { className: "max-w-md", children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { children: t('profileAddCreditsModal.title') }), jsx(DialogDescription, { children: t('profileAddCreditsModal.description') })] }), jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [jsxs("div", { className: "space-y-2", children: [jsx(Label$2, { htmlFor: "credit-amount", className: "text-sm font-medium", children: t('profileAddCreditsModal.amountLabel') }), jsxs("div", { className: "relative", children: [jsx(DollarSign, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-400" }), jsx(Input, { id: "credit-amount", type: "number", min: "0.01", step: "0.01", placeholder: "50.00", value: amount, onChange: (e) => setAmount(e.target.value), className: "pl-9" })] }), jsx("p", { className: "text-xs text-slate-500 dark:text-slate-400", children: t('profileAddCreditsModal.amountHint') })] }), jsxs("div", { className: "flex items-start gap-2 p-3 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-100 dark:border-blue-800", children: [jsx(CircleAlert, { className: "h-4 w-4 text-blue-500 mt-0.5 flex-shrink-0" }), jsx("p", { className: "text-xs text-blue-700 dark:text-blue-300", children: t('profileAddCreditsModal.paymentMethodNotice') })] }), jsxs(DialogFooter, { className: "gap-2 sm:gap-0", children: [jsx(Button$1, { type: "button", variant: "outline", onClick: handleClose, children: t('profileAddCreditsModal.cancel') }), jsx(Button$1, { type: "submit", disabled: isLoading, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", children: isLoading ? (jsxs(Fragment$1, { children: [jsx(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), t('profileAddCreditsModal.processing')] })) : (t('profileAddCreditsModal.addCredits')) })] })] })] }) }));
194377
195433
  }
194378
195434
 
194379
- /**
194380
- * The info icon that sits on every analytics card and, on hover or keyboard
194381
- * focus, explains what the card measures. The description doubles as the
194382
- * accessible name so screen readers get it without needing the hover.
194383
- *
194384
- * Uses the tooltip primitives directly rather than the shared `TooltipContent`
194385
- * because analytics wants a light popover, while `TooltipContent` is the dark
194386
- * `bg-primary` style the rest of the app relies on.
194387
- */
194388
- function CardInfoIcon({ title, description, className }) {
194389
- return (jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("button", { type: "button", "aria-label": description, className: cn('shrink-0 cursor-help rounded p-1 text-[#898989] transition-colors hover:bg-gray-100 hover:text-[#38A1E5] focus-visible:ring-2 focus-visible:ring-[#38A1E5] focus-visible:outline-none', className), children: jsx(Info$3, { className: "h-4 w-4", "aria-hidden": "true" }) }) }), jsx(Portal$3, { children: jsxs(Content2$4, { "data-slot": "tooltip-content", side: "top", align: "center", sideOffset: 6, collisionPadding: 12, className: "animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 z-50 max-w-[260px] rounded-lg border border-[oklch(0.922_0_0)] bg-white p-3 shadow-lg", children: [title && (jsx("div", { "data-slot": "tooltip-title", className: "mb-1 text-sm font-semibold text-[#484848]", children: title })), jsx("p", { "data-slot": "tooltip-description", className: "text-sm leading-relaxed text-[#646464]", children: description })] }) })] }));
194390
- }
194391
-
194392
195435
  /**
194393
195436
  * Shared utilities for tab label systems.
194394
195437
  *
@@ -197609,11 +198652,11 @@ function StripeConnect({ platformKey }) {
197609
198652
  }
197610
198653
  };
197611
198654
  if (isLoading) {
197612
- return (jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx(CardContent, { className: "p-6", children: jsxs("div", { className: "flex items-center gap-4", children: [jsx(Skeleton, { className: "h-12 w-12 rounded-full" }), jsxs("div", { className: "flex-1 space-y-2", children: [jsx(Skeleton, { className: "h-5 w-48" }), jsx(Skeleton, { className: "h-4 w-72" })] }), jsx(Skeleton, { className: "h-9 w-32" })] }) }) }));
198655
+ return (jsx(Card$1, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx(CardContent, { className: "p-6", children: jsxs("div", { className: "flex items-center gap-4", children: [jsx(Skeleton, { className: "h-12 w-12 rounded-full" }), jsxs("div", { className: "flex-1 space-y-2", children: [jsx(Skeleton, { className: "h-5 w-48" }), jsx(Skeleton, { className: "h-4 w-72" })] }), jsx(Skeleton, { className: "h-9 w-32" })] }) }) }));
197613
198656
  }
197614
198657
  const isReady = status === null || status === void 0 ? void 0 : status.is_ready_for_payments;
197615
198658
  const hasAccount = status === null || status === void 0 ? void 0 : status.has_account;
197616
- return (jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx(CardContent, { className: "p-6", children: jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center gap-4", children: [jsxs("div", { className: "flex-1 min-w-0", children: [jsxs("div", { className: "flex items-center gap-2 mb-1", children: [jsx("h4", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: t('monetizationStripeConnect.stripeConfiguration') }), isReady ? (jsx(Badge, { className: "bg-blue-100 text-blue-700 border-blue-200", children: t('monetizationStripeConnect.badgeConfigured') })) : hasAccount ? (jsx(Badge, { className: "bg-yellow-100 text-yellow-700 border-yellow-200", children: t('monetizationStripeConnect.badgeIncomplete') })) : (jsx(Badge, { variant: "secondary", children: t('monetizationStripeConnect.badgeNotConfigured') }))] }), isReady ? (jsxs("p", { className: "text-sm text-gray-500", children: [t('monetizationStripeConnect.stripeConnectedReady'), (status === null || status === void 0 ? void 0 : status.charges_enabled) && ' ' + t('monetizationStripeConnect.chargesEnabled'), (status === null || status === void 0 ? void 0 : status.payouts_enabled) && ' ' + t('monetizationStripeConnect.payoutsEnabled')] })) : hasAccount ? (jsx("p", { className: "text-sm text-gray-500", children: t('monetizationStripeConnect.onboardingIncomplete') })) : (jsx("p", { className: "text-sm text-gray-500", children: t('monetizationStripeConnect.connectStripePrompt') }))] }), jsx("div", { className: "flex gap-2 flex-shrink-0", children: isError ? null : isReady ? (jsxs(Button$1, { onClick: handleOpenDashboard, disabled: isRedirecting, variant: "outline", className: "cursor-pointer", children: [isRedirecting ? (jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" })) : (jsx(ExternalLink, { className: "h-4 w-4 mr-2" })), t('monetizationStripeConnect.stripeDashboardButton')] })) : (jsxs(Button$1, { onClick: handleStartOnboarding, disabled: isStartingOnboarding || isRedirecting, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white cursor-pointer", children: [isStartingOnboarding || isRedirecting ? (jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" })) : (jsx(Link$1, { className: "h-4 w-4 mr-2" })), isStartingOnboarding || isRedirecting
198659
+ return (jsx(Card$1, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx(CardContent, { className: "p-6", children: jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center gap-4", children: [jsxs("div", { className: "flex-1 min-w-0", children: [jsxs("div", { className: "flex items-center gap-2 mb-1", children: [jsx("h4", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: t('monetizationStripeConnect.stripeConfiguration') }), isReady ? (jsx(Badge, { className: "bg-blue-100 text-blue-700 border-blue-200", children: t('monetizationStripeConnect.badgeConfigured') })) : hasAccount ? (jsx(Badge, { className: "bg-yellow-100 text-yellow-700 border-yellow-200", children: t('monetizationStripeConnect.badgeIncomplete') })) : (jsx(Badge, { variant: "secondary", children: t('monetizationStripeConnect.badgeNotConfigured') }))] }), isReady ? (jsxs("p", { className: "text-sm text-gray-500", children: [t('monetizationStripeConnect.stripeConnectedReady'), (status === null || status === void 0 ? void 0 : status.charges_enabled) && ' ' + t('monetizationStripeConnect.chargesEnabled'), (status === null || status === void 0 ? void 0 : status.payouts_enabled) && ' ' + t('monetizationStripeConnect.payoutsEnabled')] })) : hasAccount ? (jsx("p", { className: "text-sm text-gray-500", children: t('monetizationStripeConnect.onboardingIncomplete') })) : (jsx("p", { className: "text-sm text-gray-500", children: t('monetizationStripeConnect.connectStripePrompt') }))] }), jsx("div", { className: "flex gap-2 flex-shrink-0", children: isError ? null : isReady ? (jsxs(Button$1, { onClick: handleOpenDashboard, disabled: isRedirecting, variant: "outline", className: "cursor-pointer", children: [isRedirecting ? (jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" })) : (jsx(ExternalLink, { className: "h-4 w-4 mr-2" })), t('monetizationStripeConnect.stripeDashboardButton')] })) : (jsxs(Button$1, { onClick: handleStartOnboarding, disabled: isStartingOnboarding || isRedirecting, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white cursor-pointer", children: [isStartingOnboarding || isRedirecting ? (jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" })) : (jsx(Link$1, { className: "h-4 w-4 mr-2" })), isStartingOnboarding || isRedirecting
197617
198660
  ? t('monetizationStripeConnect.redirecting')
197618
198661
  : hasAccount
197619
198662
  ? t('monetizationStripeConnect.completeSetup')
@@ -197766,12 +198809,12 @@ function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
197766
198809
  page_size: PAGE_SIZE$6,
197767
198810
  ...(statusFilter !== 'all' && { is_enabled: statusFilter === 'active' }),
197768
198811
  }, { refetchOnMountOrArgChange: true });
197769
- 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: t('monetizationPaywalledItemsList.configureItemForSale') }), 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: t('monetizationPaywalledItemsList.addCustomItemTitle'), 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: t('monetizationPaywalledItemsList.configuredItems') }), jsxs(Select$1, { value: statusFilter, onValueChange: (v) => {
198812
+ return (jsxs("div", { className: "space-y-4", children: [jsx(Card$1, { 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: t('monetizationPaywalledItemsList.configureItemForSale') }), 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: t('monetizationPaywalledItemsList.addCustomItemTitle'), 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: t('monetizationPaywalledItemsList.configuredItems') }), jsxs(Select$1, { value: statusFilter, onValueChange: (v) => {
197770
198813
  setStatusFilter(v);
197771
198814
  setPage(1);
197772
198815
  }, children: [jsx(SelectTrigger, { className: "w-[130px] h-8 text-xs", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('monetizationPaywalledItemsList.filterAll') }), jsx(SelectItem, { value: "active", children: t('monetizationPaywalledItemsList.filterActive') }), jsx(SelectItem, { value: "disabled", children: t('monetizationPaywalledItemsList.filterDisabled') })] })] })] }), 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) => {
197773
198816
  var _a;
197774
- 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 &&
198817
+ return (jsx(Card$1, { 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 &&
197775
198818
  (() => {
197776
198819
  const activeCount = pw.prices.filter((p) => p.is_active).length;
197777
198820
  return activeCount > 0 ? (jsx("span", { className: "text-xs text-gray-400", children: activeCount !== 1
@@ -197827,7 +198870,7 @@ function PriceForm({ form, onChange, onSave, onCancel, isSaving, isEdit, }) {
197827
198870
  const handleRemoveFeature = (index) => {
197828
198871
  onChange({ ...form, features: form.features.filter((_, i) => i !== index) });
197829
198872
  };
197830
- return (jsx(Card, { className: "shadow-sm border border-blue-200 bg-blue-50/30", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4 space-y-3", children: [jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: [jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.nameLabel') }), jsx(Input, { value: form.name, onChange: (e) => onChange({ ...form, name: e.target.value }), placeholder: t('monetizationPriceManagement.namePlaceholder'), className: "mt-1" })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.amountLabel') }), jsx(Input, { type: "number", min: 0, step: "0.01", value: form.amount, onChange: (e) => onChange({ ...form, amount: e.target.value }), placeholder: t('monetizationPriceManagement.amountPlaceholder'), className: "mt-1" })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.intervalLabel') }), jsxs(Select$1, { value: form.interval, onValueChange: (v) => onChange({ ...form, interval: v }), children: [jsx(SelectTrigger, { className: "mt-1", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "month", children: t('monetizationPriceManagement.intervalMonthly') }), jsx(SelectItem, { value: "year", children: t('monetizationPriceManagement.intervalYearly') }), jsx(SelectItem, { value: "one_time", children: t('monetizationPriceManagement.intervalOneTime') })] })] })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.currencyLabel') }), jsx(Input, { value: form.currency, disabled: true, className: "mt-1 bg-gray-50 text-gray-500 cursor-not-allowed" })] })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.descriptionLabel') }), jsx(Input, { value: form.description, onChange: (e) => onChange({ ...form, description: e.target.value }), placeholder: t('monetizationPriceManagement.descriptionPlaceholder'), className: "mt-1" })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.featuresLabel') }), form.features.length > 0 && (jsx("div", { className: "flex flex-wrap gap-1.5 mt-1.5 mb-1.5", children: form.features.map((feature, i) => (jsxs(Badge, { variant: "secondary", className: "text-xs font-normal pl-2 pr-1 py-0.5 flex items-center gap-1", children: [feature, jsx("button", { type: "button", onClick: () => handleRemoveFeature(i), className: "hover:bg-gray-300 rounded-full p-0.5 transition-colors cursor-pointer", children: jsx(X$1, { className: "h-2.5 w-2.5" }) })] }, i))) })), jsxs("div", { className: "flex gap-1.5 mt-1", children: [jsx(Input, { value: featureInput, onChange: (e) => setFeatureInput(e.target.value), onKeyDown: (e) => {
198873
+ return (jsx(Card$1, { className: "shadow-sm border border-blue-200 bg-blue-50/30", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4 space-y-3", children: [jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: [jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.nameLabel') }), jsx(Input, { value: form.name, onChange: (e) => onChange({ ...form, name: e.target.value }), placeholder: t('monetizationPriceManagement.namePlaceholder'), className: "mt-1" })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.amountLabel') }), jsx(Input, { type: "number", min: 0, step: "0.01", value: form.amount, onChange: (e) => onChange({ ...form, amount: e.target.value }), placeholder: t('monetizationPriceManagement.amountPlaceholder'), className: "mt-1" })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.intervalLabel') }), jsxs(Select$1, { value: form.interval, onValueChange: (v) => onChange({ ...form, interval: v }), children: [jsx(SelectTrigger, { className: "mt-1", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "month", children: t('monetizationPriceManagement.intervalMonthly') }), jsx(SelectItem, { value: "year", children: t('monetizationPriceManagement.intervalYearly') }), jsx(SelectItem, { value: "one_time", children: t('monetizationPriceManagement.intervalOneTime') })] })] })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.currencyLabel') }), jsx(Input, { value: form.currency, disabled: true, className: "mt-1 bg-gray-50 text-gray-500 cursor-not-allowed" })] })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.descriptionLabel') }), jsx(Input, { value: form.description, onChange: (e) => onChange({ ...form, description: e.target.value }), placeholder: t('monetizationPriceManagement.descriptionPlaceholder'), className: "mt-1" })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-xs text-gray-500", children: t('monetizationPriceManagement.featuresLabel') }), form.features.length > 0 && (jsx("div", { className: "flex flex-wrap gap-1.5 mt-1.5 mb-1.5", children: form.features.map((feature, i) => (jsxs(Badge, { variant: "secondary", className: "text-xs font-normal pl-2 pr-1 py-0.5 flex items-center gap-1", children: [feature, jsx("button", { type: "button", onClick: () => handleRemoveFeature(i), className: "hover:bg-gray-300 rounded-full p-0.5 transition-colors cursor-pointer", children: jsx(X$1, { className: "h-2.5 w-2.5" }) })] }, i))) })), jsxs("div", { className: "flex gap-1.5 mt-1", children: [jsx(Input, { value: featureInput, onChange: (e) => setFeatureInput(e.target.value), onKeyDown: (e) => {
197831
198874
  if (e.key === 'Enter') {
197832
198875
  e.preventDefault();
197833
198876
  handleAddFeature();
@@ -197944,7 +198987,7 @@ function PriceManagement({ platformKey, itemType, itemId }) {
197944
198987
  return editingPriceId === price.id ? (jsx(PriceForm, { form: formData, onChange: setFormData, onSave: handleUpdate, onCancel: () => {
197945
198988
  setEditingPriceId(null);
197946
198989
  setFormData(EMPTY_FORM);
197947
- }, isSaving: isUpdating, isEdit: true }, price.id)) : (jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx(CardContent, { className: "p-4", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx(Tag, { className: "h-4 w-4 text-gray-400" }), jsxs("div", { children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: price.name }), jsxs("span", { className: "text-sm font-semibold text-blue-600", children: ["$", price.amount, " ", formatInterval$1(price.interval)] }), !price.is_active && (jsx(Badge, { variant: "secondary", className: "text-xs", children: t('monetizationPriceManagement.inactiveBadge') }))] }), price.description && (jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: price.description })), ((_a = price.features) === null || _a === void 0 ? void 0 : _a.length) > 0 && (jsx("div", { className: "flex flex-wrap gap-1 mt-1", children: price.features.map((f, i) => (jsx(Badge, { variant: "outline", className: "text-xs font-normal", children: f }, i))) }))] })] }), jsxs("div", { className: "flex gap-1 flex-shrink-0", children: [jsx(Button$1, { onClick: () => handleStartEdit(price), variant: "ghost", size: "sm", className: "h-8 w-8 p-0 cursor-pointer", children: jsx(Pencil, { className: "h-3 w-3" }) }), jsx(Button$1, { onClick: () => handleDelete(price.id), variant: "ghost", size: "sm", disabled: deletingId === price.id, className: "h-8 w-8 p-0 text-red-500 hover:text-red-700 cursor-pointer", children: deletingId === price.id ? (jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" })) : (jsx(Trash2, { className: "h-3 w-3" })) })] })] }) }) }, price.id));
198990
+ }, isSaving: isUpdating, isEdit: true }, price.id)) : (jsx(Card$1, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx(CardContent, { className: "p-4", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx(Tag, { className: "h-4 w-4 text-gray-400" }), jsxs("div", { children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: price.name }), jsxs("span", { className: "text-sm font-semibold text-blue-600", children: ["$", price.amount, " ", formatInterval$1(price.interval)] }), !price.is_active && (jsx(Badge, { variant: "secondary", className: "text-xs", children: t('monetizationPriceManagement.inactiveBadge') }))] }), price.description && (jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: price.description })), ((_a = price.features) === null || _a === void 0 ? void 0 : _a.length) > 0 && (jsx("div", { className: "flex flex-wrap gap-1 mt-1", children: price.features.map((f, i) => (jsx(Badge, { variant: "outline", className: "text-xs font-normal", children: f }, i))) }))] })] }), jsxs("div", { className: "flex gap-1 flex-shrink-0", children: [jsx(Button$1, { onClick: () => handleStartEdit(price), variant: "ghost", size: "sm", className: "h-8 w-8 p-0 cursor-pointer", children: jsx(Pencil, { className: "h-3 w-3" }) }), jsx(Button$1, { onClick: () => handleDelete(price.id), variant: "ghost", size: "sm", disabled: deletingId === price.id, className: "h-8 w-8 p-0 text-red-500 hover:text-red-700 cursor-pointer", children: deletingId === price.id ? (jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" })) : (jsx(Trash2, { className: "h-3 w-3" })) })] })] }) }) }, price.id));
197948
198991
  }) })) : (jsx("p", { className: "text-xs text-gray-400 text-center py-4", children: t('monetizationPriceManagement.emptyState') }))] }));
197949
198992
  }
197950
198993
 
@@ -198114,13 +199157,13 @@ function PaywallDetail({ platformKey, authURL, itemType, itemId, itemName, isCus
198114
199157
  const currentIndex = wizardSteps.findIndex((s) => s.key === currentStep);
198115
199158
  if (targetIndex < currentIndex)
198116
199159
  setCurrentStep(step);
198117
- } }), 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: t('monetizationPaywallDetail.stepItemDetails') }), jsxs("div", { className: "space-y-3", children: [jsxs("div", { children: [jsx(Label$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelItemType') }), jsx(Input, { value: customItemType, onChange: (e) => setCustomItemType(e.target.value), placeholder: t('monetizationPaywallDetail.placeholderItemType'), className: "mt-1", disabled: itemCreated }), customItemType && (jsx("p", { className: "text-xs text-gray-400 mt-1", children: t('monetizationPaywallDetail.slugPreview', { slug: slugify(customItemType) }) }))] }), jsxs("div", { children: [jsx(Label$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelItemName') }), jsx(Input, { value: customItemName, onChange: (e) => setCustomItemName(e.target.value), placeholder: t('monetizationPaywallDetail.placeholderItemName'), className: "mt-1", disabled: itemCreated }), customItemName && (jsx("p", { className: "text-xs text-gray-400 mt-1", children: t('monetizationPaywallDetail.idPreview', { id: slugify(customItemName) }) }))] }), jsxs("div", { children: [jsx(Label$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelDescription') }), jsx(Textarea, { value: customDescription, onChange: (e) => setCustomDescription(e.target.value), placeholder: t('monetizationPaywallDetail.placeholderDescription'), className: "mt-1", rows: 3 })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelProductUrl') }), jsx(Input, { type: "url", value: customProductUrl, onChange: (e) => setCustomProductUrl(e.target.value), placeholder: t('monetizationPaywallDetail.placeholderProductUrl'), className: "mt-1", disabled: itemCreated }), jsx("p", { className: "text-xs text-gray-400 mt-1", children: t('monetizationPaywallDetail.hintProductUrl') })] })] }), 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" })), t('monetizationPaywallDetail.createAndContinue')] }) })] }) })), 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$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelPaywallEnabled') }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: t('monetizationPaywallDetail.hintPaywallEnabled') })] }), 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$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelAllowFreeTier') }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: t('monetizationPaywallDetail.hintAllowFreeTier') })] }), 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$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelTrialPeriod') }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: t('monetizationPaywallDetail.hintTrialPeriod') })] }), 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$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelExistingUsers') }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: t('monetizationPaywallDetail.hintExistingUsers') })] }), 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: t('monetizationPaywallDetail.grandfatheringFreeForever') }), jsx(SelectItem, { value: "require_subscription", children: t('monetizationPaywallDetail.grandfatheringRequireSubscription') })] })] })] })] }), 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" })), t('monetizationPaywallDetail.saveConfiguration')] }) })] }) })), currentStep === 'pricing' && (jsx(PriceManagement, { platformKey: platformKey, itemType: resolvedItemType, itemId: resolvedItemId }))] }));
199160
+ } }), currentStep === 'custom-item' && isCustom && (jsx(Card$1, { 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: t('monetizationPaywallDetail.stepItemDetails') }), jsxs("div", { className: "space-y-3", children: [jsxs("div", { children: [jsx(Label$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelItemType') }), jsx(Input, { value: customItemType, onChange: (e) => setCustomItemType(e.target.value), placeholder: t('monetizationPaywallDetail.placeholderItemType'), className: "mt-1", disabled: itemCreated }), customItemType && (jsx("p", { className: "text-xs text-gray-400 mt-1", children: t('monetizationPaywallDetail.slugPreview', { slug: slugify(customItemType) }) }))] }), jsxs("div", { children: [jsx(Label$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelItemName') }), jsx(Input, { value: customItemName, onChange: (e) => setCustomItemName(e.target.value), placeholder: t('monetizationPaywallDetail.placeholderItemName'), className: "mt-1", disabled: itemCreated }), customItemName && (jsx("p", { className: "text-xs text-gray-400 mt-1", children: t('monetizationPaywallDetail.idPreview', { id: slugify(customItemName) }) }))] }), jsxs("div", { children: [jsx(Label$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelDescription') }), jsx(Textarea, { value: customDescription, onChange: (e) => setCustomDescription(e.target.value), placeholder: t('monetizationPaywallDetail.placeholderDescription'), className: "mt-1", rows: 3 })] }), jsxs("div", { children: [jsx(Label$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelProductUrl') }), jsx(Input, { type: "url", value: customProductUrl, onChange: (e) => setCustomProductUrl(e.target.value), placeholder: t('monetizationPaywallDetail.placeholderProductUrl'), className: "mt-1", disabled: itemCreated }), jsx("p", { className: "text-xs text-gray-400 mt-1", children: t('monetizationPaywallDetail.hintProductUrl') })] })] }), 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" })), t('monetizationPaywallDetail.createAndContinue')] }) })] }) })), currentStep === 'paywall' && (jsx(Card$1, { 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$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelPaywallEnabled') }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: t('monetizationPaywallDetail.hintPaywallEnabled') })] }), 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$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelAllowFreeTier') }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: t('monetizationPaywallDetail.hintAllowFreeTier') })] }), 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$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelTrialPeriod') }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: t('monetizationPaywallDetail.hintTrialPeriod') })] }), 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$2, { className: "text-sm font-medium", children: t('monetizationPaywallDetail.labelExistingUsers') }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: t('monetizationPaywallDetail.hintExistingUsers') })] }), 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: t('monetizationPaywallDetail.grandfatheringFreeForever') }), jsx(SelectItem, { value: "require_subscription", children: t('monetizationPaywallDetail.grandfatheringRequireSubscription') })] })] })] })] }), 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" })), t('monetizationPaywallDetail.saveConfiguration')] }) })] }) })), currentStep === 'pricing' && (jsx(PriceManagement, { platformKey: platformKey, itemType: resolvedItemType, itemId: resolvedItemId }))] }));
198118
199161
  }
198119
199162
 
198120
199163
  function PaywallConfig({ platformKey, authURL, disabled }) {
198121
199164
  const [selectedItem, setSelectedItem] = useState(null);
198122
199165
  if (disabled) {
198123
- 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." })] }) }));
199166
+ return (jsx(Card$1, { 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." })] }) }));
198124
199167
  }
198125
199168
  if (selectedItem) {
198126
199169
  return (jsx(PaywallDetail, { platformKey: platformKey, authURL: authURL, itemType: selectedItem.type, itemId: selectedItem.id, itemName: selectedItem.name, isCustom: selectedItem.isCustom, onBack: () => setSelectedItem(null) }));
@@ -229415,75 +230458,6 @@ function ChatPrivacyToggle({ org, userId, mentor, className }) {
229415
230458
  className: "text-white font-semibold bg-gradient-to-r from-blue-600 to-blue-400 hover:from-blue-700 hover:to-blue-500 [text-shadow:0_1px_2px_rgba(0,0,0,0.35)] [&_svg]:[filter:drop-shadow(0_1px_1px_rgba(0,0,0,0.4))]", children: isDisablingChatHistory ? (jsxs(Fragment$1, { children: [jsx(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), t('chatPrivacyChatPrivacyToggle.enabling')] })) : (t('chatPrivacyChatPrivacyToggle.enablePrivateMode')) })] })] }) })] }));
229416
230459
  }
229417
230460
 
229418
- /**
229419
- * Chart color system for the analytics surface.
229420
- *
229421
- * Single-series charts keep the app's established `#38A1E5`. Multi-series
229422
- * charts (spend stacked by service, spend by model) use a categorical palette
229423
- * validated for color-vision-deficiency separation on a white surface
229424
- * (worst adjacent-pair CVD ΔE 9.1, worst normal-vision ΔE 19.6 — OKLab ×100):
229425
- * hues are assigned in this fixed order, per entity, never cycled or reshuffled
229426
- * when a filter changes the series count.
229427
- *
229428
- * Three of the light-surface slots sit below 3:1 contrast against white, so
229429
- * every chart that uses them must carry visible direct labels or a table view
229430
- * (all of ours do — ranked rows and legends carry the values as text).
229431
- */
229432
- const CHART_SERIES_COLORS = [
229433
- '#2a78d6', // blue
229434
- '#eb6834', // orange
229435
- '#1baf7a', // aqua
229436
- '#eda100', // yellow
229437
- '#e87ba4', // magenta
229438
- '#008300', // green
229439
- ];
229440
- /** The app's single-series chart color, unchanged. */
229441
- const CHART_SINGLE_SERIES_COLOR = '#38A1E5';
229442
- /**
229443
- * Ordinal blue ramp for ordered measures (latency p50→p99). One hue,
229444
- * light→dark — never a rainbow for an ordered scale. The lightest step clears
229445
- * 2:1 against white.
229446
- */
229447
- const CHART_ORDINAL_RAMP = [
229448
- '#86b6ef', // p50
229449
- '#5598e7', // p75
229450
- '#2a78d6', // p90
229451
- '#1c5cab', // p95
229452
- '#104281', // p99
229453
- ];
229454
- /**
229455
- * Color follows the entity: a service keeps its hue whether or not the other
229456
- * services are on screen. Services beyond this list fold into slots in first-
229457
- * seen order via {@link colorForSeries} rather than inventing new hues.
229458
- */
229459
- const SERVICE_COLOR_ORDER = [
229460
- 'chat',
229461
- 'embeddings',
229462
- 'memory',
229463
- 'grading',
229464
- 'moderation',
229465
- 'call',
229466
- ];
229467
- /**
229468
- * Stable color for a named series. Known services get their fixed slot; an
229469
- * unknown name hashes into the palette deterministically so the same name is
229470
- * the same color on every render and every chart.
229471
- */
229472
- function colorForSeries(name) {
229473
- const fixed = SERVICE_COLOR_ORDER.indexOf(name);
229474
- if (fixed >= 0)
229475
- return CHART_SERIES_COLORS[fixed % CHART_SERIES_COLORS.length];
229476
- let hash = 0;
229477
- for (let i = 0; i < name.length; i++) {
229478
- hash = (hash * 31 + name.charCodeAt(i)) >>> 0;
229479
- }
229480
- return CHART_SERIES_COLORS[hash % CHART_SERIES_COLORS.length];
229481
- }
229482
- /** Stable color for the Nth series of an ordered breakdown (e.g. top models). */
229483
- function colorForRank(index) {
229484
- return CHART_SERIES_COLORS[index % CHART_SERIES_COLORS.length];
229485
- }
229486
-
229487
230461
  /**
229488
230462
  * The small trend line at the foot of a stat card. Decorative reinforcement of
229489
230463
  * the delta — it has no axes and is hidden from assistive tech; the number and
@@ -229524,9 +230498,9 @@ function StatCard({ title, value, percentage, loading = false, showDollarSign =
229524
230498
  }
229525
230499
  const hasTrend = !!trend && trend.length > 1;
229526
230500
  if (loading) {
229527
- return (jsx(Card, { className: "h-full w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "flex h-full flex-col p-4", "aria-label": t('analyticsStatCard.ariaLabelLoading', { title }), children: [jsxs("div", { className: "mb-2.5 flex items-start justify-between gap-2", children: [jsx(Skeleton, { className: "h-4 w-24" }), jsx(Skeleton, { className: "h-5 w-5 rounded" })] }), jsx(Skeleton, { className: "mb-2.5 h-8 w-20" }), jsx(Skeleton, { className: "h-4 w-32" }), jsx("div", { className: "mt-auto pt-2.5", children: jsx(Skeleton, { className: "w-full", style: { height: SPARKLINE_HEIGHT } }) })] }) }));
230501
+ return (jsx(Card$1, { className: "h-full w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "flex h-full flex-col p-4", "aria-label": t('analyticsStatCard.ariaLabelLoading', { title }), children: [jsxs("div", { className: "mb-2.5 flex items-start justify-between gap-2", children: [jsx(Skeleton, { className: "h-4 w-24" }), jsx(Skeleton, { className: "h-5 w-5 rounded" })] }), jsx(Skeleton, { className: "mb-2.5 h-8 w-20" }), jsx(Skeleton, { className: "h-4 w-32" }), jsx("div", { className: "mt-auto pt-2.5", children: jsx(Skeleton, { className: "w-full", style: { height: SPARKLINE_HEIGHT } }) })] }) }));
229528
230502
  }
229529
- return (jsx(Card, { className: "h-full w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "flex h-full flex-col p-4", "aria-label": t('analyticsStatCard.ariaLabel', { title }), children: [jsxs("div", { className: "mb-2.5 flex items-start justify-between gap-2", children: [jsxs("h3", { className: "flex min-w-0 items-center gap-1.5 text-sm font-medium text-[#898989]", children: [icon && (jsx("span", { className: "shrink-0 text-gray-400 [&>svg]:h-4 [&>svg]:w-4", "aria-hidden": "true", children: icon })), jsx("span", { className: "truncate", children: title })] }), description && (jsx(CardInfoIcon, { title: title, description: description, className: "-mt-1" }))] }), jsxs("div", { className: "flex items-baseline gap-2", children: [jsx("p", { className: "text-[28px] font-semibold leading-none tracking-[-0.01em] text-[#484848] tabular-nums", "aria-label": t('analyticsStatCard.ariaLabelValue', { title }), children: showDollarSign ? `$${value}` : value }), subValue && (jsx("span", { className: "truncate text-[13px] text-[#898989] tabular-nums", children: subValue }))] }), jsx("p", { className: "mt-2.5 flex h-5 items-center gap-1.5 whitespace-nowrap text-[13px]", children: delta }), jsx("div", { className: "mt-auto pt-2.5", style: { minHeight: SPARKLINE_HEIGHT + 10 }, children: hasTrend && (jsx(TrendSparkline, { points: trend, color: trendColor, height: SPARKLINE_HEIGHT })) })] }) }));
230503
+ return (jsx(Card$1, { className: "h-full w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "flex h-full flex-col p-4", "aria-label": t('analyticsStatCard.ariaLabel', { title }), children: [jsxs("div", { className: "mb-2.5 flex items-start justify-between gap-2", children: [jsxs("h3", { className: "flex min-w-0 items-center gap-1.5 text-sm font-medium text-[#898989]", children: [icon && (jsx("span", { className: "shrink-0 text-gray-400 [&>svg]:h-4 [&>svg]:w-4", "aria-hidden": "true", children: icon })), jsx("span", { className: "truncate", children: title })] }), description && (jsx(CardInfoIcon, { title: title, description: description, className: "-mt-1" }))] }), jsxs("div", { className: "flex items-baseline gap-2", children: [jsx("p", { className: "text-[28px] font-semibold leading-none tracking-[-0.01em] text-[#484848] tabular-nums", "aria-label": t('analyticsStatCard.ariaLabelValue', { title }), children: showDollarSign ? `$${value}` : value }), subValue && (jsx("span", { className: "truncate text-[13px] text-[#898989] tabular-nums", children: subValue }))] }), jsx("p", { className: "mt-2.5 flex h-5 items-center gap-1.5 whitespace-nowrap text-[13px]", children: delta }), jsx("div", { className: "mt-auto pt-2.5", style: { minHeight: SPARKLINE_HEIGHT + 10 }, children: hasTrend && (jsx(TrendSparkline, { points: trend, color: trendColor, height: SPARKLINE_HEIGHT })) })] }) }));
229530
230504
  }
229531
230505
 
229532
230506
  const THEMES = { light: '', dark: '.dark' };
@@ -229817,7 +230791,7 @@ function ChartRangeControl() {
229817
230791
  }), jsx("button", { type: "button", "aria-label": t('analyticsChartCard.clearOverride'), onClick: resync, className: "ml-0.5 inline-flex cursor-pointer rounded-sm opacity-70 hover:opacity-100", children: jsx(X$1, { className: "h-3 w-3", "aria-hidden": "true" }) })] })), jsxs(Popover, { children: [jsx(PopoverTrigger, { asChild: true, children: jsx("button", { type: "button", "aria-label": t('analyticsChartCard.adjustRange'), className: "inline-flex h-[26px] w-[26px] cursor-pointer items-center justify-center rounded-md border border-[oklch(0.922_0_0)] bg-white text-gray-500 transition-colors hover:bg-gray-50 hover:text-gray-700", children: jsx(Calendar$1, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) }) }), jsxs(PopoverContent, { className: "z-[60] w-auto p-3", align: "end", children: [jsx("p", { className: "mb-2 text-xs text-[#898989]", children: t('analyticsChartCard.adjustRangeHint') }), jsx(TimeFilter, {})] })] })] }));
229818
230792
  }
229819
230793
  function ChartCardWrapper({ title, label, children, filters, setOutsideFilters, overflowAuto, height, description, source, headerRight, }) {
229820
- return (jsx(ChartFiltersProvider, { initialFilters: filters, setOutsideFilters: setOutsideFilters, children: jsx(Card, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", children: jsxs(CardContent, { className: "p-4", "aria-label": `${title} chart card`, children: [jsx("div", { className: "mb-4", children: jsxs("div", { className: "flex items-start justify-between gap-3", children: [jsxs("div", { className: "min-w-0", children: [jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [jsx("h3", { className: "truncate text-base font-semibold text-gray-700", children: title }), description && jsx(CardInfoIcon, { title: title, description: description })] }), description && (jsx("p", { className: "mt-1 text-[13px] leading-relaxed text-[#898989]", children: description }))] }), jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [headerRight, jsx(ChartRangeControl, {})] })] }) }), jsx("div", { className: "w-full", style: { height: height || '350px' }, children: jsx(ChartContainer, { title: title, config: {
230794
+ return (jsx(ChartFiltersProvider, { initialFilters: filters, setOutsideFilters: setOutsideFilters, children: jsx(Card$1, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", children: jsxs(CardContent, { className: "p-4", "aria-label": `${title} chart card`, children: [jsx("div", { className: "mb-4", children: jsxs("div", { className: "flex items-start justify-between gap-3", children: [jsxs("div", { className: "min-w-0", children: [jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [jsx("h3", { className: "truncate text-base font-semibold text-gray-700", children: title }), description && jsx(CardInfoIcon, { title: title, description: description })] }), description && (jsx("p", { className: "mt-1 text-[13px] leading-relaxed text-[#898989]", children: description }))] }), jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [headerRight, jsx(ChartRangeControl, {})] })] }) }), jsx("div", { className: "w-full", style: { height: height || '350px' }, children: jsx(ChartContainer, { title: title, config: {
229821
230795
  value: {
229822
230796
  label,
229823
230797
  color: '#38A1E5', // Reverted to original color
@@ -231446,6 +232420,154 @@ const useFinancial = ({ tenantKey, mentorId, userId, }) => {
231446
232420
  };
231447
232421
  };
231448
232422
 
232423
+ /**
232424
+ * One place that decides how a user is shown.
232425
+ *
232426
+ * Backend payloads name their user in a dozen ways — `email` / `lti_email` /
232427
+ * `user_email`, `username` / `student` / `lti_username`, `name` /
232428
+ * `full_name` / `user_full_name`, or a nested `user` object — and most of
232429
+ * them can be empty, `null`, or a placeholder like "None". Every surface used
232430
+ * to pick through those on its own. `resolveUserIdentity()` takes whatever
232431
+ * the payload is and returns what to show, what to open a profile on, and
232432
+ * the avatar initial, so the rule lives here and can be tweaked once.
232433
+ *
232434
+ * Default rule: a real full name first (see {@link hasDistinctName}), else
232435
+ * email → username → the anonymous label.
232436
+ */
232437
+ const DEFAULT_USER_IDENTITY_ORDER = ['email', 'name', 'username'];
232438
+ /** Order used when the payload carries a real name (see {@link hasDistinctName}). */
232439
+ const NAME_FIRST_ORDER = ['name', 'email', 'username'];
232440
+ /**
232441
+ * Lower-case letters and digits of any script, accents and punctuation dropped,
232442
+ * so "Conrad Mugabe" / "conrad.mugabe" and "José" / "jose" compare equal.
232443
+ */
232444
+ const identityKey = (value) => (value !== null && value !== void 0 ? value : '')
232445
+ .normalize('NFKD')
232446
+ .replace(/[^\p{L}\p{N}]/gu, '')
232447
+ .toLowerCase();
232448
+ /**
232449
+ * Whether `name` is a real name rather than a restatement of the username.
232450
+ *
232451
+ * Many payloads fill the name field with the username ("conradmugabe" →
232452
+ * "Conrad Mugabe", "fayyaz_4_ibleducation_com"), which tells an admin nothing
232453
+ * the email does not. A name that matches none of the usernames on the record
232454
+ * is the most recognisable thing on it — including for LTI learners, whose
232455
+ * minted `<opaque-id>@edx-lti-1p3.com` address and username identify nobody.
232456
+ */
232457
+ function hasDistinctName(name, ...usernames) {
232458
+ const key = identityKey(name);
232459
+ if (!key)
232460
+ return false;
232461
+ return usernames.every((username) => key !== identityKey(username));
232462
+ }
232463
+ const DEFAULT_ANONYMOUS_LABEL = 'Anonymous';
232464
+ /** Values backends emit instead of "nothing". Compared case-insensitively. */
232465
+ const PLACEHOLDERS = new Set([
232466
+ '',
232467
+ 'none',
232468
+ 'null',
232469
+ 'undefined',
232470
+ 'n/a',
232471
+ 'na',
232472
+ '-',
232473
+ 'anonymous',
232474
+ 'anonymoususer',
232475
+ ]);
232476
+ /**
232477
+ * `local@domain.tld` with no whitespace, checked with a single pass rather than
232478
+ * a backtracking pattern (CodeQL flags `[^@]+@[^@]+\.[^@]+` as polynomial on
232479
+ * adversarial input).
232480
+ */
232481
+ const isEmailLike = (value) => {
232482
+ const text = value.trim();
232483
+ if (!text || /\s/.test(text))
232484
+ return false;
232485
+ const at = text.indexOf('@');
232486
+ if (at <= 0 || at !== text.lastIndexOf('@') || at === text.length - 1)
232487
+ return false;
232488
+ const domain = text.slice(at + 1);
232489
+ const dot = domain.indexOf('.');
232490
+ // A dot somewhere inside the domain, with something after the last one.
232491
+ return dot > 0 && !domain.endsWith('.');
232492
+ };
232493
+ /** Trimmed string, or undefined for blanks, non-strings and placeholders. */
232494
+ const clean = (value) => {
232495
+ if (typeof value !== 'string')
232496
+ return undefined;
232497
+ const trimmed = value.trim();
232498
+ return PLACEHOLDERS.has(trimmed.toLowerCase()) ? undefined : trimmed;
232499
+ };
232500
+ const firstOf = (...candidates) => {
232501
+ for (const candidate of candidates) {
232502
+ const value = clean(candidate);
232503
+ if (value)
232504
+ return value;
232505
+ }
232506
+ return undefined;
232507
+ };
232508
+ const nested = (source) => source.user && typeof source.user === 'object' ? source.user : undefined;
232509
+ /**
232510
+ * Resolve how a user should be displayed from any payload that names one.
232511
+ *
232512
+ * - `email`: `lti_email`, `email`, `user_email`, the nested `user`'s email —
232513
+ * or a username field that turns out to hold an email address.
232514
+ * - `username`: `lti_username`, `username`, `student`, `user_username`, the
232515
+ * nested `user`'s username, or a bare string/number `user` value.
232516
+ * - `name`: `user_full_name`, `full_name`, `name`, `first_name last_name`, or
232517
+ * the nested `user`'s name.
232518
+ * - `profileUsername`: the first *platform* username (never an LTI claim).
232519
+ *
232520
+ * A string source is treated as an email when it looks like one, else as a
232521
+ * username. Placeholder strings ("None", "-", "anonymous"…) count as absent.
232522
+ *
232523
+ * The default order flips to name → email → username when the record carries a
232524
+ * real name (see {@link hasDistinctName}): "Joseph Oti" is more use to an admin
232525
+ * than his address, while a name that merely repeats the username is not, so
232526
+ * those records keep showing the email. An explicit `order` is always obeyed.
232527
+ */
232528
+ function resolveUserIdentity(source, options = {}) {
232529
+ var _a, _b;
232530
+ const anonymousLabel = options.anonymousLabel || DEFAULT_ANONYMOUS_LABEL;
232531
+ const order = ((_a = options.order) === null || _a === void 0 ? void 0 : _a.length) ? options.order : DEFAULT_USER_IDENTITY_ORDER;
232532
+ const record = source && typeof source === 'object' ? source : { user: source !== null && source !== void 0 ? source : null };
232533
+ const inner = nested(record);
232534
+ // A bare `user` value is an id or username; numeric ids are still shown.
232535
+ const bareUser = typeof record.user === 'number' && Number.isFinite(record.user)
232536
+ ? String(record.user)
232537
+ : typeof record.user === 'string'
232538
+ ? clean(record.user)
232539
+ : undefined;
232540
+ let email = firstOf(record.lti_email, record.email, record.user_email, inner === null || inner === void 0 ? void 0 : inner.lti_email, inner === null || inner === void 0 ? void 0 : inner.email, inner === null || inner === void 0 ? void 0 : inner.user_email);
232541
+ const platformUsername = firstOf(record.username, record.student, record.user_username, inner === null || inner === void 0 ? void 0 : inner.username, inner === null || inner === void 0 ? void 0 : inner.student, inner === null || inner === void 0 ? void 0 : inner.user_username, bareUser && !isEmailLike(bareUser) ? bareUser : undefined);
232542
+ let username = firstOf(record.lti_username, inner === null || inner === void 0 ? void 0 : inner.lti_username, platformUsername);
232543
+ const composed = [clean(record.first_name), clean(record.last_name)].filter(Boolean).join(' ');
232544
+ const name = firstOf(record.user_full_name, record.full_name, record.name, composed, inner === null || inner === void 0 ? void 0 : inner.user_full_name, inner === null || inner === void 0 ? void 0 : inner.full_name, inner === null || inner === void 0 ? void 0 : inner.name);
232545
+ // A bare string that looks like an email is an email, and so is a
232546
+ // "username" field that actually carries one.
232547
+ if (!email && bareUser && isEmailLike(bareUser))
232548
+ email = bareUser;
232549
+ if (!email && username && isEmailLike(username)) {
232550
+ email = username;
232551
+ username = undefined;
232552
+ }
232553
+ const facts = { email, username, name };
232554
+ // Every username on the record counts: the platform one a profile opens on
232555
+ // and the LTI claim that would be displayed.
232556
+ const labelOrder = !((_b = options.order) === null || _b === void 0 ? void 0 : _b.length) && hasDistinctName(name, platformUsername, username)
232557
+ ? NAME_FIRST_ORDER
232558
+ : order;
232559
+ const label = labelOrder.map((field) => facts[field]).find(Boolean);
232560
+ return {
232561
+ label: label !== null && label !== void 0 ? label : anonymousLabel,
232562
+ email,
232563
+ username,
232564
+ name,
232565
+ profileUsername: platformUsername,
232566
+ initial: (label !== null && label !== void 0 ? label : anonymousLabel).charAt(0).toUpperCase() || 'A',
232567
+ isAnonymous: !label,
232568
+ };
232569
+ }
232570
+
231449
232571
  const TONES = {
231450
232572
  amber: {
231451
232573
  container: 'border-amber-200 bg-amber-50 text-amber-800',
@@ -231492,7 +232614,7 @@ function AnalyticsLlmUsageStats({ tenantKey, mentorId, filters, }) {
231492
232614
  const t = useT();
231493
232615
  const { kpis, trends, isLoadingKpis, isKpisUnavailable, isForbidden, refetchKpis, spendOverTime, isLoadingSpendOverTime, isSpendOverTimeUnavailable, spendOverTimeFilters, setSpendOverTimeFilters, spendByModel, isLoadingSpendByModel, isSpendByModelUnavailable, spendByModelFilters, setSpendByModelFilters, latencyByModel, isLoadingLatencyByModel, isLatencyByModelUnavailable, latencyFilters, setLatencyFilters, } = useLlmUsage({ tenantKey, mentorId, filters });
231494
232616
  if (isForbidden) {
231495
- return (jsx(Card, { className: "rounded-lg border border-gray-100 bg-white shadow-sm", children: jsx(CardContent, { className: "p-8 text-center", children: jsx("p", { className: "text-gray-500", children: t('analyticsLlmUsage.noPermission') }) }) }));
232617
+ return (jsx(Card$1, { className: "rounded-lg border border-gray-100 bg-white shadow-sm", children: jsx(CardContent, { className: "p-8 text-center", children: jsx("p", { className: "text-gray-500", children: t('analyticsLlmUsage.noPermission') }) }) }));
231496
232618
  }
231497
232619
  const maxModelCost = Math.max(...spendByModel.map((row) => row.totalCost), 0);
231498
232620
  const maxLatency = Math.max(...latencyByModel.map((row) => row.p95), 0);
@@ -231732,7 +232854,7 @@ function TraceDetail({ tenantKey, currentSPA, trace, observations, isLoadingObse
231732
232854
  [t('analyticsTraces.detailEnvironment'), trace.environment || '—'],
231733
232855
  [t('analyticsTraces.detailStarted'), formatTime(trace.timestamp)],
231734
232856
  ];
231735
- return (jsx(Card, { className: "rounded-lg border border-gray-100 bg-white shadow-sm", children: jsxs(CardContent, { className: "p-4", children: [jsxs("div", { className: "mb-4 flex items-start justify-between gap-3", children: [jsxs("div", { className: "min-w-0", children: [jsx("div", { className: "flex items-center gap-2", children: jsx("h3", { className: "text-base font-semibold text-gray-700", children: trace.name || t('analyticsTraces.detailTitle') }) }), jsx("div", { className: "mt-1 truncate font-mono text-xs text-[#898989]", title: trace.id, children: trace.id })] }), jsx(Button$1, { variant: "outline", size: "sm", className: "h-8 w-8 shrink-0 p-0", "aria-label": t('analyticsTraces.closeDetail'), onClick: onClose, children: jsx(X$1, { className: "h-4 w-4", "aria-hidden": "true" }) })] }), jsxs("div", { className: "flex gap-4 rounded-lg border border-[oklch(0.922_0_0)] bg-gray-50 px-4 py-3.5", children: [jsxs("div", { className: "flex-1", children: [jsx("div", { className: "mb-1 text-xs text-[#898989]", children: t('analyticsTraces.detailLatency') }), jsx("div", { className: "text-xl font-semibold text-[#484848] tabular-nums", children: trace.latency !== undefined ? `${Number(trace.latency).toFixed(2)}s` : '—' })] }), jsxs("div", { className: "flex-1", children: [jsx("div", { className: "mb-1 text-xs text-[#898989]", children: t('analyticsTraces.detailCost') }), jsx("div", { className: "text-xl font-semibold text-[#484848] tabular-nums", children: formatCost(totalCost) })] }), jsxs("div", { className: "flex-1", children: [jsx("div", { className: "mb-1 text-xs text-[#898989]", children: t('analyticsTraces.detailObservations') }), jsx("div", { className: "text-xl font-semibold text-[#484848] tabular-nums", children: observations.length || '—' })] })] }), jsx("dl", { className: "mt-4 grid grid-cols-2 gap-x-4 gap-y-3 border-b border-[oklch(0.922_0_0)] pb-4 lg:grid-cols-4", children: meta.map(([label, value]) => (jsxs("div", { className: "min-w-0", children: [jsx("dt", { className: "mb-0.5 text-[11px] uppercase tracking-wide text-[#898989]", children: label }), jsx("dd", { className: "truncate text-[13px] font-medium text-[#484848]", children: value })] }, label))) }), jsxs("div", { className: "mb-1 mt-4 flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700", children: t('analyticsTraces.observationsHeading') }), jsxs("div", { className: "flex gap-0 text-[11px] uppercase tracking-wide text-[#898989]", children: [jsx("span", { className: "w-[52px] text-right", children: t('analyticsTraces.colTime') }), jsx("span", { className: "w-[58px] text-right", children: t('analyticsTraces.colTokens') }), jsx("span", { className: "w-[64px] text-right", children: t('analyticsTraces.colCost') })] })] }), isLoadingObservations ? (jsx("div", { className: "h-[80px]", children: jsx(ChartLoading, {}) })) : observations.length === 0 ? (jsx("div", { className: "h-[80px]", children: jsx(EmptyStats, { title: t('analyticsTraces.noObservations') }) })) : (jsx("div", { children: observations.map((observation) => (jsx(ObservationRow, { observation: observation, traceStart: traceStart, traceDuration: traceDuration }, observation.id))) })), trace.sessionId && onOpenTranscript && (jsx("div", { className: "mt-4", children: jsx(Button$1, { variant: "outline", size: "sm", className: "h-9 gap-1.5 border-blue-100 bg-blue-50 px-3 text-blue-700 hover:bg-blue-100", onClick: () => onOpenTranscript(String(trace.sessionId)), children: t('analyticsTraces.openTranscript') }) }))] }) }));
232857
+ return (jsx(Card$1, { className: "rounded-lg border border-gray-100 bg-white shadow-sm", children: jsxs(CardContent, { className: "p-4", children: [jsxs("div", { className: "mb-4 flex items-start justify-between gap-3", children: [jsxs("div", { className: "min-w-0", children: [jsx("div", { className: "flex items-center gap-2", children: jsx("h3", { className: "text-base font-semibold text-gray-700", children: trace.name || t('analyticsTraces.detailTitle') }) }), jsx("div", { className: "mt-1 truncate font-mono text-xs text-[#898989]", title: trace.id, children: trace.id })] }), jsx(Button$1, { variant: "outline", size: "sm", className: "h-8 w-8 shrink-0 p-0", "aria-label": t('analyticsTraces.closeDetail'), onClick: onClose, children: jsx(X$1, { className: "h-4 w-4", "aria-hidden": "true" }) })] }), jsxs("div", { className: "flex gap-4 rounded-lg border border-[oklch(0.922_0_0)] bg-gray-50 px-4 py-3.5", children: [jsxs("div", { className: "flex-1", children: [jsx("div", { className: "mb-1 text-xs text-[#898989]", children: t('analyticsTraces.detailLatency') }), jsx("div", { className: "text-xl font-semibold text-[#484848] tabular-nums", children: trace.latency !== undefined ? `${Number(trace.latency).toFixed(2)}s` : '—' })] }), jsxs("div", { className: "flex-1", children: [jsx("div", { className: "mb-1 text-xs text-[#898989]", children: t('analyticsTraces.detailCost') }), jsx("div", { className: "text-xl font-semibold text-[#484848] tabular-nums", children: formatCost(totalCost) })] }), jsxs("div", { className: "flex-1", children: [jsx("div", { className: "mb-1 text-xs text-[#898989]", children: t('analyticsTraces.detailObservations') }), jsx("div", { className: "text-xl font-semibold text-[#484848] tabular-nums", children: observations.length || '—' })] })] }), jsx("dl", { className: "mt-4 grid grid-cols-2 gap-x-4 gap-y-3 border-b border-[oklch(0.922_0_0)] pb-4 lg:grid-cols-4", children: meta.map(([label, value]) => (jsxs("div", { className: "min-w-0", children: [jsx("dt", { className: "mb-0.5 text-[11px] uppercase tracking-wide text-[#898989]", children: label }), jsx("dd", { className: "truncate text-[13px] font-medium text-[#484848]", children: value })] }, label))) }), jsxs("div", { className: "mb-1 mt-4 flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700", children: t('analyticsTraces.observationsHeading') }), jsxs("div", { className: "flex gap-0 text-[11px] uppercase tracking-wide text-[#898989]", children: [jsx("span", { className: "w-[52px] text-right", children: t('analyticsTraces.colTime') }), jsx("span", { className: "w-[58px] text-right", children: t('analyticsTraces.colTokens') }), jsx("span", { className: "w-[64px] text-right", children: t('analyticsTraces.colCost') })] })] }), isLoadingObservations ? (jsx("div", { className: "h-[80px]", children: jsx(ChartLoading, {}) })) : observations.length === 0 ? (jsx("div", { className: "h-[80px]", children: jsx(EmptyStats, { title: t('analyticsTraces.noObservations') }) })) : (jsx("div", { children: observations.map((observation) => (jsx(ObservationRow, { observation: observation, traceStart: traceStart, traceDuration: traceDuration }, observation.id))) })), trace.sessionId && onOpenTranscript && (jsx("div", { className: "mt-4", children: jsx(Button$1, { variant: "outline", size: "sm", className: "h-9 gap-1.5 border-blue-100 bg-blue-50 px-3 text-blue-700 hover:bg-blue-100", onClick: () => onOpenTranscript(String(trace.sessionId)), children: t('analyticsTraces.openTranscript') }) }))] }) }));
231736
232858
  }
231737
232859
  /**
231738
232860
  * The drill-down Langfuse makes possible: trace list → one trace → its
@@ -231749,7 +232871,7 @@ function AnalyticsTraces({ tenantKey, currentSPA, mentorId, filters, onOpenTrans
231749
232871
  initialUsername,
231750
232872
  });
231751
232873
  if (isForbidden) {
231752
- return (jsx(Card, { className: "rounded-lg border border-gray-100 bg-white shadow-sm", children: jsx(CardContent, { className: "p-8 text-center", children: jsx("p", { className: "text-gray-500", children: t('analyticsLlmUsage.noPermission') }) }) }));
232874
+ return (jsx(Card$1, { className: "rounded-lg border border-gray-100 bg-white shadow-sm", children: jsx(CardContent, { className: "p-8 text-center", children: jsx("p", { className: "text-gray-500", children: t('analyticsLlmUsage.noPermission') }) }) }));
231753
232875
  }
231754
232876
  const totalPages = (_a = meta === null || meta === void 0 ? void 0 : meta.totalPages) !== null && _a !== void 0 ? _a : 1;
231755
232877
  return (jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "rounded-lg border border-[oklch(0.922_0_0)] bg-white p-3", children: jsxs("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-center", children: [jsx("div", { className: "min-w-[180px]", children: jsxs(Select$1, { value: traceName || ALL_SERVICES, onValueChange: (value) => setFilter.traceName(value === ALL_SERVICES ? '' : value), children: [jsx(SelectTrigger, { className: "h-9 w-full bg-white font-normal", children: jsx(SelectValue, { placeholder: t('analyticsTraces.filterService') }) }), jsxs(SelectContent, { className: "z-[60]", children: [jsx(SelectItem, { value: ALL_SERVICES, children: t('analyticsTraces.allServices') }), TRACE_NAMES.map((name) => (jsx(SelectItem, { value: name, children: name }, name)))] })] }) }), jsx("div", { className: "min-w-[200px] flex-1", children: jsx(UserFilterSelect, { tenantKey: tenantKey, value: username, showSelfOption: false, onChange: (nextUsername) => {
@@ -231803,6 +232925,10 @@ const costTick = (value) => {
231803
232925
  function SpendTab({ tenantKey, currentSPA, mentorId: currentMentorId, userId, onOpenUserTraces, }) {
231804
232926
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
231805
232927
  const t = useT();
232928
+ // The label a cost row shows for its user, by the shared identity rule.
232929
+ const identify = React__default.useCallback((row) => resolveUserIdentity(row, {
232930
+ anonymousLabel: t('analyticsAnalyticsFinancialStats.anonymous'),
232931
+ }), [t]);
231806
232932
  const { weeklyCostData, isLoadingWeeklyCostData, isErrorWeeklyCostData, monthlyCostData, isLoadingMonthlyCostData, isErrorMonthlyCostData, totalCostData, isLoadingTotalCostData, isErrorTotalCostData, detailedCostPerDayData, isLoadingDetailedCostPerDayData, detailedCostPerDayFilters, setDetailedCostPerDayFilters, detailedCostPerProviderData, isLoadingDetailedCostPerProviderData, detailedCostPerProviderFilters, setDetailedCostPerProviderFilters, detailedCostPerUserData, isLoadingDetailedCostPerUserData, detailedCostPerUserFilters, setDetailedCostPerUserFilters, costPerUserPage, setCostPerUserPage, costPerUserLimit, providerColors, detailedLLMCostData, isLoadingDetailedLLMCostData, detailedLLMCostFilters, setDetailedLLMCostFilters, } = useFinancial({ tenantKey, mentorId: currentMentorId, userId });
231807
232933
  // Pagination handlers
231808
232934
  const handleFirstPage = () => {
@@ -231897,7 +233023,7 @@ function SpendTab({ tenantKey, currentSPA, mentorId: currentMentorId, userId, on
231897
233023
  shown: (_p = (_o = detailedLLMCostData === null || detailedLLMCostData === void 0 ? void 0 : detailedLLMCostData.rows) === null || _o === void 0 ? void 0 : _o.length) !== null && _p !== void 0 ? _p : 0,
231898
233024
  }) })) : (jsx(EmptyStats, {})) })] }), jsx("div", { className: "grid grid-cols-1 gap-6", children: jsx(ChartCardWrapper, { title: t('analyticsAnalyticsFinancialStats.costPerUserTitle'), source: "clickhouse", label: t('analyticsAnalyticsFinancialStats.costPerUserLabel'), filters: detailedCostPerUserFilters, setOutsideFilters: setDetailedCostPerUserFilters, overflowAuto: true, height: "450px", description: t('analyticsAnalyticsFinancialStats.costPerUserDescription'), children: jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "rounded-md", style: { borderColor: 'oklch(.922 0 0)', borderWidth: '1px' }, children: jsxs(Table, { children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "h-[48px]", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableHead, { className: "w-[250px]", children: t('analyticsAnalyticsFinancialStats.tableHeaderUserEmail') }), jsx(TableHead, { className: "w-[120px]", children: t('analyticsAnalyticsFinancialStats.tableHeaderTotalCost') }), hasSessions && (jsx(TableHead, { children: t('analyticsAnalyticsFinancialStats.tableHeaderSessions') })), hasLastActive && (jsx(TableHead, { className: "text-right", children: t('analyticsAnalyticsFinancialStats.tableHeaderLastActive') })), onOpenUserTraces && jsx(TableHead, { className: "w-[90px]" })] }) }), jsx(TableBody, { children: (_q = detailedCostPerUserData === null || detailedCostPerUserData === void 0 ? void 0 : detailedCostPerUserData.rows) === null || _q === void 0 ? void 0 : _q.map((user, index) => {
231899
233025
  var _a;
231900
- return (jsxs(TableRow, { className: cn(index % 2 === 0 ? 'bg-gray-50' : '', 'h-[48px]'), style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableCell, { className: "font-medium", children: jsx("div", { className: "flex items-center", children: (user === null || user === void 0 ? void 0 : user.email) || (user === null || user === void 0 ? void 0 : user.username) ? (jsx(UserProfileLink, { tenantKey: tenantKey, currentSPA: currentSPA, username: user.username, display: String(user.email || user.username) })) : (t('analyticsAnalyticsFinancialStats.anonymous')) }) }), jsxs(TableCell, { className: "font-medium", children: ["$", Number(user.total_cost || 0).toFixed(2)] }), hasSessions && jsx(TableCell, { children: (_a = user.sessions) !== null && _a !== void 0 ? _a : '\u2014' }), hasLastActive && (jsx(TableCell, { className: "text-right", children: user.last_active ? formatRelativeTime$2(user.last_active) : '-' })), onOpenUserTraces && (jsx(TableCell, { className: "text-right", children: (user === null || user === void 0 ? void 0 : user.username) || (user === null || user === void 0 ? void 0 : user.email) ? (jsx("button", { type: "button", className: "cursor-pointer text-sm font-semibold text-blue-600 hover:text-blue-700 hover:underline", onClick: () => onOpenUserTraces(String(user.username || user.email)), children: t('analyticsAnalyticsFinancialStats.viewTraces') })) : null }))] }, index));
233026
+ return (jsxs(TableRow, { className: cn(index % 2 === 0 ? 'bg-gray-50' : '', 'h-[48px]'), style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableCell, { className: "font-medium", children: jsx("div", { className: "flex items-center", children: jsx(UserProfileLink, { tenantKey: tenantKey, currentSPA: currentSPA, username: user.username, display: identify(user).label }) }) }), jsxs(TableCell, { className: "font-medium", children: ["$", Number(user.total_cost || 0).toFixed(2)] }), hasSessions && jsx(TableCell, { children: (_a = user.sessions) !== null && _a !== void 0 ? _a : '\u2014' }), hasLastActive && (jsx(TableCell, { className: "text-right", children: user.last_active ? formatRelativeTime$2(user.last_active) : '-' })), onOpenUserTraces && (jsx(TableCell, { className: "text-right", children: (user === null || user === void 0 ? void 0 : user.username) || (user === null || user === void 0 ? void 0 : user.user_email) || (user === null || user === void 0 ? void 0 : user.email) ? (jsx("button", { type: "button", className: "cursor-pointer text-sm font-semibold text-blue-600 hover:text-blue-700 hover:underline", onClick: () => onOpenUserTraces(String(user.username || user.user_email || user.email)), children: t('analyticsAnalyticsFinancialStats.viewTraces') })) : null }))] }, index));
231901
233027
  }) })] }) }), isLoadingDetailedCostPerUserData && (jsx("div", { className: "h-[60px]", children: jsx(ChartLoading, {}) })), !isLoadingDetailedCostPerUserData &&
231902
233028
  (!((_r = detailedCostPerUserData === null || detailedCostPerUserData === void 0 ? void 0 : detailedCostPerUserData.rows) === null || _r === void 0 ? void 0 : _r.length) ||
231903
233029
  ((_s = detailedCostPerUserData === null || detailedCostPerUserData === void 0 ? void 0 : detailedCostPerUserData.rows) === null || _s === void 0 ? void 0 : _s.length) === 0) && (jsx("div", { className: "h-[60px]", children: jsx(EmptyStats, {}) })), detailedCostPerUserData && detailedCostPerUserData.total_pages > 1 && (jsxs("div", { className: "flex items-center justify-between py-3", children: [jsx("div", { className: "text-sm text-gray-700", children: t('analyticsAnalyticsFinancialStats.paginationShowing', {
@@ -232388,7 +233514,7 @@ function SectionHeading({ icon, children }) {
232388
233514
  return (jsxs("h4", { className: "mb-2 flex items-center gap-1.5 text-xs font-semibold tracking-wide text-gray-700 uppercase", children: [icon, children] }));
232389
233515
  }
232390
233516
  const MODEL_KEYS = new Set(['llm_model', 'llm_provider']);
232391
- function MetadataSection({ metadata, renderModel, }) {
233517
+ function MetadataSection({ metadata, renderModel, tenantKey, mentorId, }) {
232392
233518
  var _a, _b;
232393
233519
  const t = useT();
232394
233520
  const labelFor = useFieldLabels();
@@ -232396,7 +233522,9 @@ function MetadataSection({ metadata, renderModel, }) {
232396
233522
  const model = ((_a = metadata.llm_model) !== null && _a !== void 0 ? _a : '').trim() || undefined;
232397
233523
  const provider = ((_b = metadata.llm_provider) !== null && _b !== void 0 ? _b : '').trim() || undefined;
232398
233524
  const hasModel = !!(model || provider);
232399
- return (jsxs("section", { "data-testid": "transcript-turn-metadata", children: [jsx(SectionHeading, { icon: jsx(Info$3, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), children: t('analyticsTranscriptTurnDetails.metadata') }), hasModel && (jsx("div", { "data-testid": "transcript-turn-model", className: "mb-2", children: (renderModel !== null && renderModel !== void 0 ? renderModel : defaultRenderModel)({ model, provider }) })), jsx(DetailRows, { entries: rest, labelFor: labelFor })] }));
233525
+ return (jsxs("section", { "data-testid": "transcript-turn-metadata", children: [jsx(SectionHeading, { icon: jsx(Info$3, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), children: t('analyticsTranscriptTurnDetails.metadata') }), hasModel && (jsx("div", { "data-testid": "transcript-turn-model", className: "mb-2", children: renderModel
233526
+ ? renderModel({ model, provider })
233527
+ : defaultRenderModel({ model, provider, tenantKey, mentorId }) })), jsx(DetailRows, { entries: rest, labelFor: labelFor })] }));
232400
233528
  }
232401
233529
  function RequestContextSection({ requestContext }) {
232402
233530
  const t = useT();
@@ -232411,7 +233539,7 @@ function RequestContextSection({ requestContext }) {
232411
233539
  */
232412
233540
  const defaultRenderDocuments = (documents) => (jsx(RetrievedDocumentsButton, { documents: toRetrievedDocuments(documents) }));
232413
233541
  const defaultRenderToolCalls = (toolCalls) => (jsx(ToolCallIndicator, { toolCalls: toToolCallInfos(toolCalls), showResults: true }));
232414
- const defaultRenderModel = ({ model, provider }) => (jsx(LlmModelBadge, { model: model, provider: provider }));
233542
+ const defaultRenderModel = ({ model, provider, tenantKey, mentorId, }) => jsx(LlmModelBadge, { model: model, provider: provider, tenantKey: tenantKey, mentorId: mentorId });
232415
233543
  const defaultRenderFiles = (files) => (jsx(TranscriptFileCards, { files: files }));
232416
233544
  /**
232417
233545
  * Collapsible "Sources / Tools / Metadata" panel for one AI turn of an admin
@@ -232421,7 +233549,7 @@ const defaultRenderFiles = (files) => (jsx(TranscriptFileCards, { files: files }
232421
233549
  * renders nothing at all when every field is null or empty, so it is safe to
232422
233550
  * drop under every AI bubble.
232423
233551
  */
232424
- function TranscriptTurnDetails({ turn, className, defaultOpen = false, renderDocuments, renderToolCalls, renderModel, renderFiles, }) {
233552
+ function TranscriptTurnDetails({ turn, className, defaultOpen = false, renderDocuments, renderToolCalls, renderModel, renderFiles, tenantKey, mentorId, }) {
232425
233553
  const t = useT();
232426
233554
  const labelFor = useFieldLabels();
232427
233555
  const [open, setOpen] = React__default.useState(defaultOpen);
@@ -232435,7 +233563,7 @@ function TranscriptTurnDetails({ turn, className, defaultOpen = false, renderDoc
232435
233563
  const requestContext = hasEntries(turn === null || turn === void 0 ? void 0 : turn.request_context) ? turn === null || turn === void 0 ? void 0 : turn.request_context : null;
232436
233564
  return (jsx(DetailCtx.Provider, { value: detailContext, children: jsxs(Collapsible, { open: open, onOpenChange: setOpen, className: cn('mt-2', className), "data-testid": "transcript-turn-details", children: [jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [jsx(CollapsibleTrigger, { asChild: true, children: jsxs(Button$1, { type: "button", variant: "outline", size: "sm", className: "flex items-center gap-2 border-gray-200 bg-white text-gray-700 hover:bg-gray-50", "aria-expanded": open, children: [jsx(ChevronDown, { className: cn('h-4 w-4 transition-transform', open && 'rotate-180'), "aria-hidden": "true" }), open
232437
233565
  ? t('analyticsTranscriptTurnDetails.hideDetails')
232438
- : t('analyticsTranscriptTurnDetails.showDetails')] }) }), documents.length > 0 && (jsx("div", { "data-testid": "transcript-turn-sources", className: "contents", children: (renderDocuments !== null && renderDocuments !== void 0 ? renderDocuments : defaultRenderDocuments)(documents) })), jsx(TranscriptRollupBadges, { documentsCount: 0, toolCallsCount: toolCalls.length })] }), jsxs(CollapsibleContent, { className: "mt-2 space-y-5 rounded-lg border border-gray-200 bg-white p-3", children: [toolCalls.length > 0 && (jsx("div", { "data-testid": "transcript-turn-tools", children: (renderToolCalls !== null && renderToolCalls !== void 0 ? renderToolCalls : defaultRenderToolCalls)(toolCalls) })), metadata && jsx(MetadataSection, { metadata: metadata, renderModel: renderModel }), requestContext && jsx(RequestContextSection, { requestContext: requestContext })] })] }) }));
233566
+ : t('analyticsTranscriptTurnDetails.showDetails')] }) }), documents.length > 0 && (jsx("div", { "data-testid": "transcript-turn-sources", className: "contents", children: (renderDocuments !== null && renderDocuments !== void 0 ? renderDocuments : defaultRenderDocuments)(documents) })), jsx(TranscriptRollupBadges, { documentsCount: 0, toolCallsCount: toolCalls.length })] }), jsxs(CollapsibleContent, { className: "mt-2 space-y-5 rounded-lg border border-gray-200 bg-white p-3", children: [toolCalls.length > 0 && (jsx("div", { "data-testid": "transcript-turn-tools", children: (renderToolCalls !== null && renderToolCalls !== void 0 ? renderToolCalls : defaultRenderToolCalls)(toolCalls) })), metadata && (jsx(MetadataSection, { metadata: metadata, renderModel: renderModel, tenantKey: tenantKey, mentorId: mentorId })), requestContext && jsx(RequestContextSection, { requestContext: requestContext })] })] }) }));
232439
233567
  }
232440
233568
  /**
232441
233569
  * "Documents · N" / "Tools · N" chips for a conversation row, from the
@@ -232451,118 +233579,6 @@ function TranscriptRollupBadges({ documentsCount, toolCallsCount, className, })
232451
233579
  return (jsxs("span", { className: cn('inline-flex flex-wrap items-center gap-1.5', className), "data-testid": "transcript-rollup-badges", children: [documents > 0 && (jsxs(Badge, { variant: "outline", className: "gap-1 border-transparent bg-blue-50 font-normal text-blue-700", "data-testid": "transcript-sources-badge", children: [jsx(FileText, { className: "h-3 w-3", "aria-hidden": "true" }), t('analyticsTranscriptTurnDetails.sourcesBadge', { count: documents })] })), tools > 0 && (jsxs(Badge, { variant: "outline", className: "gap-1 border-transparent bg-amber-50 font-normal text-amber-800", "data-testid": "transcript-tools-badge", children: [jsx(Wrench, { className: "h-3 w-3", "aria-hidden": "true" }), t('analyticsTranscriptTurnDetails.toolsBadge', { count: tools })] }))] }));
232452
233580
  }
232453
233581
 
232454
- /**
232455
- * One place that decides how a user is shown.
232456
- *
232457
- * Backend payloads name their user in a dozen ways — `email` / `lti_email` /
232458
- * `user_email`, `username` / `student` / `lti_username`, `name` /
232459
- * `full_name` / `user_full_name`, or a nested `user` object — and most of
232460
- * them can be empty, `null`, or a placeholder like "None". Every surface used
232461
- * to pick through those on its own. `resolveUserIdentity()` takes whatever
232462
- * the payload is and returns what to show, what to open a profile on, and
232463
- * the avatar initial, so the rule lives here and can be tweaked once.
232464
- *
232465
- * Default rule: email → full name → username → the anonymous label.
232466
- */
232467
- const DEFAULT_USER_IDENTITY_ORDER = ['email', 'name', 'username'];
232468
- const DEFAULT_ANONYMOUS_LABEL = 'Anonymous';
232469
- /** Values backends emit instead of "nothing". Compared case-insensitively. */
232470
- const PLACEHOLDERS = new Set([
232471
- '',
232472
- 'none',
232473
- 'null',
232474
- 'undefined',
232475
- 'n/a',
232476
- 'na',
232477
- '-',
232478
- 'anonymous',
232479
- 'anonymoususer',
232480
- ]);
232481
- /**
232482
- * `local@domain.tld` with no whitespace, checked with a single pass rather than
232483
- * a backtracking pattern (CodeQL flags `[^@]+@[^@]+\.[^@]+` as polynomial on
232484
- * adversarial input).
232485
- */
232486
- const isEmailLike = (value) => {
232487
- const text = value.trim();
232488
- if (!text || /\s/.test(text))
232489
- return false;
232490
- const at = text.indexOf('@');
232491
- if (at <= 0 || at !== text.lastIndexOf('@') || at === text.length - 1)
232492
- return false;
232493
- const domain = text.slice(at + 1);
232494
- const dot = domain.indexOf('.');
232495
- // A dot somewhere inside the domain, with something after the last one.
232496
- return dot > 0 && !domain.endsWith('.');
232497
- };
232498
- /** Trimmed string, or undefined for blanks, non-strings and placeholders. */
232499
- const clean = (value) => {
232500
- if (typeof value !== 'string')
232501
- return undefined;
232502
- const trimmed = value.trim();
232503
- return PLACEHOLDERS.has(trimmed.toLowerCase()) ? undefined : trimmed;
232504
- };
232505
- const firstOf = (...candidates) => {
232506
- for (const candidate of candidates) {
232507
- const value = clean(candidate);
232508
- if (value)
232509
- return value;
232510
- }
232511
- return undefined;
232512
- };
232513
- const nested = (source) => source.user && typeof source.user === 'object' ? source.user : undefined;
232514
- /**
232515
- * Resolve how a user should be displayed from any payload that names one.
232516
- *
232517
- * - `email`: `lti_email`, `email`, `user_email`, the nested `user`'s email —
232518
- * or a username field that turns out to hold an email address.
232519
- * - `username`: `lti_username`, `username`, `student`, `user_username`, the
232520
- * nested `user`'s username, or a bare string/number `user` value.
232521
- * - `name`: `user_full_name`, `full_name`, `name`, `first_name last_name`, or
232522
- * the nested `user`'s name.
232523
- * - `profileUsername`: the first *platform* username (never an LTI claim).
232524
- *
232525
- * A string source is treated as an email when it looks like one, else as a
232526
- * username. Placeholder strings ("None", "-", "anonymous"…) count as absent.
232527
- */
232528
- function resolveUserIdentity(source, options = {}) {
232529
- var _a;
232530
- const anonymousLabel = options.anonymousLabel || DEFAULT_ANONYMOUS_LABEL;
232531
- const order = ((_a = options.order) === null || _a === void 0 ? void 0 : _a.length) ? options.order : DEFAULT_USER_IDENTITY_ORDER;
232532
- const record = source && typeof source === 'object' ? source : { user: source !== null && source !== void 0 ? source : null };
232533
- const inner = nested(record);
232534
- // A bare `user` value is an id or username; numeric ids are still shown.
232535
- const bareUser = typeof record.user === 'number' && Number.isFinite(record.user)
232536
- ? String(record.user)
232537
- : typeof record.user === 'string'
232538
- ? clean(record.user)
232539
- : undefined;
232540
- let email = firstOf(record.lti_email, record.email, record.user_email, inner === null || inner === void 0 ? void 0 : inner.lti_email, inner === null || inner === void 0 ? void 0 : inner.email, inner === null || inner === void 0 ? void 0 : inner.user_email);
232541
- const platformUsername = firstOf(record.username, record.student, record.user_username, inner === null || inner === void 0 ? void 0 : inner.username, inner === null || inner === void 0 ? void 0 : inner.student, inner === null || inner === void 0 ? void 0 : inner.user_username, bareUser && !isEmailLike(bareUser) ? bareUser : undefined);
232542
- let username = firstOf(record.lti_username, inner === null || inner === void 0 ? void 0 : inner.lti_username, platformUsername);
232543
- const composed = [clean(record.first_name), clean(record.last_name)].filter(Boolean).join(' ');
232544
- const name = firstOf(record.user_full_name, record.full_name, record.name, composed, inner === null || inner === void 0 ? void 0 : inner.user_full_name, inner === null || inner === void 0 ? void 0 : inner.full_name, inner === null || inner === void 0 ? void 0 : inner.name);
232545
- // A bare string that looks like an email is an email, and so is a
232546
- // "username" field that actually carries one.
232547
- if (!email && bareUser && isEmailLike(bareUser))
232548
- email = bareUser;
232549
- if (!email && username && isEmailLike(username)) {
232550
- email = username;
232551
- username = undefined;
232552
- }
232553
- const facts = { email, username, name };
232554
- const label = order.map((field) => facts[field]).find(Boolean);
232555
- return {
232556
- label: label !== null && label !== void 0 ? label : anonymousLabel,
232557
- email,
232558
- username,
232559
- name,
232560
- profileUsername: platformUsername,
232561
- initial: (label !== null && label !== void 0 ? label : anonymousLabel).charAt(0).toUpperCase() || 'A',
232562
- isAnonymous: !label,
232563
- };
232564
- }
232565
-
232566
233582
  // Utility function to format relative time
232567
233583
  const formatRelativeTime = (dateString, t) => {
232568
233584
  const date = new Date(dateString);
@@ -232608,8 +233624,13 @@ const getMessageContent = (content) => {
232608
233624
  * in the order the caller asks for; "-" when the row names nobody.
232609
233625
  */
232610
233626
  const identifyUser = (source, order) => resolveUserIdentity(source, { order, anonymousLabel: '-' }).label;
232611
- /** The model as the nav bar shows it (logo + display name); hosts may override via `turnDetails.renderModel`. */
232612
- const renderModelBadge = ({ model, provider }) => (jsx(LlmModelBadge, { model: model, provider: provider }));
233627
+ /**
233628
+ * The model as the nav bar shows it (logo + display name); hosts may override
233629
+ * via `turnDetails.renderModel`. The catalogue is read for the tenant and the
233630
+ * agent the conversation ran on — route params only carry those on the mentor
233631
+ * SPA, so analytics passes them explicitly.
233632
+ */
233633
+ const renderModelBadge = ({ model, provider, tenantKey, mentorId, }) => jsx(LlmModelBadge, { model: model, provider: provider, tenantKey: tenantKey, mentorId: mentorId });
232613
233634
  /** Newer deployments name the provider on rows and summaries; older ones only the model. */
232614
233635
  const providerOf = (source) => {
232615
233636
  const value = source === null || source === void 0 ? void 0 : source.llm_provider;
@@ -232645,7 +233666,7 @@ function TranscriptDocumentsButton({ detail, className, }) {
232645
233666
  return (jsx(RetrievedDocumentsButton, { sessionId: sessionId, documents: documents.length > 0 ? documents : undefined, className: className }));
232646
233667
  }
232647
233668
  function AnalyticsTranscriptsStats({ tenantKey, currentSPA, mentorId, selectedMentorId, usergroupIds, turnDetails, }) {
232648
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
233669
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
232649
233670
  const t = useT();
232650
233671
  const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
232651
233672
  const [isModalOpen, setIsModalOpen] = useState(false);
@@ -232653,6 +233674,10 @@ function AnalyticsTranscriptsStats({ tenantKey, currentSPA, mentorId, selectedMe
232653
233674
  const router = useRouter();
232654
233675
  const pathname = usePathname();
232655
233676
  const { transcriptsMessagesData, isLoadingTranscriptsMessagesData, isFetchingTranscriptsMessagesData, filters, setFilters, handleClearFilters, currentPage, handlePageChange, selectedTranscript, setSelectedTranscript, transcriptsMessagesDetailsData, isLoadingTranscriptsMessagesDetailsData, isErrorTranscriptsMessagesDetailsData, transcriptsConversationHeadlineData, isLoadingTranscriptsConversationHeadlineData, } = useTranscripts({ tenantKey, mentorId: currentMentorId, usergroupIds });
233677
+ // The agent the open transcript ran on — the catalogue scope for its model
233678
+ // badge. Hosts that browse across agents (the LMS analytics route) pass no
233679
+ // mentorId, so the transcript's own agent is the only correct scope.
233680
+ const detailMentorId = ((_a = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _a === void 0 ? void 0 : _a.mentor_unique_id) || currentMentorId;
232656
233681
  // Read session_id from URL on mount and select the transcript
232657
233682
  useEffect(() => {
232658
233683
  const sessionIdParam = searchParams === null || searchParams === void 0 ? void 0 : searchParams.get('session_id');
@@ -232765,21 +233790,23 @@ function AnalyticsTranscriptsStats({ tenantKey, currentSPA, mentorId, selectedMe
232765
233790
  ? ((_e = turnDetails === null || turnDetails === void 0 ? void 0 : turnDetails.renderModel) !== null && _e !== void 0 ? _e : renderModelBadge)({
232766
233791
  model: transcriptsMessagesDetailsData.summary.model,
232767
233792
  provider: (_f = providerOf(transcriptsMessagesDetailsData.summary)) !== null && _f !== void 0 ? _f : providerOfTurns(transcriptsMessagesDetailsData.messages),
233793
+ tenantKey,
233794
+ mentorId: detailMentorId,
232768
233795
  })
232769
233796
  : '-'] }), jsx(TranscriptDocumentsButton, { detail: transcriptsMessagesDetailsData, className: "mt-2" })] })] }), jsx("div", { className: "flex-1 overflow-y-auto space-y-4 min-h-0", children: ((_g = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.messages) === null || _g === void 0 ? void 0 : _g.length) > 0 ? ((_h = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.messages) === null || _h === void 0 ? void 0 : _h.map((message, index) => {
232770
233797
  var _a, _b;
232771
- return (jsxs(React__default.Fragment, { children: [((message === null || message === void 0 ? void 0 : message.human) || !!((_a = message === null || message === void 0 ? void 0 : message.human_files) === null || _a === void 0 ? void 0 : _a.length)) && (jsxs("div", { className: `p-3 rounded-lg bg-blue-100 ml-4`, children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleUser') }) }), message.human && (jsx("p", { className: "text-sm", children: getMessageContent(message.human) })), jsx(TranscriptFiles, { files: message.human_files })] }, `${index}-human`)), ((message === null || message === void 0 ? void 0 : message.ai) || !!((_b = message === null || message === void 0 ? void 0 : message.ai_files) === null || _b === void 0 ? void 0 : _b.length)) && (jsxs("div", { className: `p-3 rounded-lg bg-white mr-4`, children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleAgent') }) }), message.ai && jsx(Markdown, { children: getMessageContent(message.ai) }), jsx(TranscriptFiles, { files: message.ai_files }), jsx(TranscriptTurnDetails, { turn: message, ...turnDetails })] }, `${index}-ai`))] }, index));
233798
+ return (jsxs(React__default.Fragment, { children: [((message === null || message === void 0 ? void 0 : message.human) || !!((_a = message === null || message === void 0 ? void 0 : message.human_files) === null || _a === void 0 ? void 0 : _a.length)) && (jsxs("div", { className: `p-3 rounded-lg bg-blue-100 ml-4`, children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleUser') }) }), message.human && (jsx("p", { className: "text-sm", children: getMessageContent(message.human) })), jsx(TranscriptFiles, { files: message.human_files })] }, `${index}-human`)), ((message === null || message === void 0 ? void 0 : message.ai) || !!((_b = message === null || message === void 0 ? void 0 : message.ai_files) === null || _b === void 0 ? void 0 : _b.length)) && (jsxs("div", { className: `p-3 rounded-lg bg-white mr-4`, children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleAgent') }) }), message.ai && jsx(Markdown, { children: getMessageContent(message.ai) }), jsx(TranscriptFiles, { files: message.ai_files }), jsx(TranscriptTurnDetails, { turn: message, tenantKey: tenantKey, mentorId: detailMentorId, ...turnDetails })] }, `${index}-ai`))] }, index));
232772
233799
  })) : (jsx("div", { className: "text-center text-gray-500 py-8", children: jsx("p", { children: t('analyticsAnalyticsTranscriptsStats.noMessages') }) })) })] })) }));
232773
233800
  };
232774
- return (jsxs("div", { className: "space-y-8", children: [jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-6", children: [jsx(StatCard, { title: t('analyticsAnalyticsTranscriptsStats.avgMessagesPerConversation'), value: ((_a = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_messages_per_conversation) === null || _a === void 0 ? void 0 : _a.value) || 0, percentage: ((_b = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_messages_per_conversation) === null || _b === void 0 ? void 0 : _b.percentage_change) ||
232775
- undefined, loading: isLoadingTranscriptsConversationHeadlineData, description: t('analyticsAnalyticsTranscriptsStats.avgMessagesPerConversationDescription') }), jsx(StatCard, { title: t('analyticsAnalyticsTranscriptsStats.avgCostPerConversation'), value: Number(((_c = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_cost_per_conversation) === null || _c === void 0 ? void 0 : _c.value) || 0).toFixed(2), percentage: ((_d = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_cost_per_conversation) === null || _d === void 0 ? void 0 : _d.percentage_change) ||
232776
- undefined, showDollarSign: true, loading: isLoadingTranscriptsConversationHeadlineData, description: t('analyticsAnalyticsTranscriptsStats.avgCostPerConversationDescription') }), jsx(StatCard, { title: t('analyticsAnalyticsTranscriptsStats.avgRating'), value: ((_e = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_rating) === null || _e === void 0 ? void 0 : _e.value) || 0, percentage: ((_f = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_rating) === null || _f === void 0 ? void 0 : _f.percentage_change) || undefined, loading: isLoadingTranscriptsConversationHeadlineData, description: t('analyticsAnalyticsTranscriptsStats.avgRatingDescription') })] }), jsxs("div", { className: "flex h-[calc(100vh-120px)]", children: [jsxs("div", { className: "w-full md:w-2/3 md:pr-6 overflow-y-auto md:border-r border-gray-200 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: [jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex gap-2 mb-4 items-center", children: [jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" }), jsx(Input, { placeholder: t('analyticsAnalyticsTranscriptsStats.placeholderTopics'), value: filters.topicSearch, onChange: (e) => setFilters({ ...filters, topicSearch: e.target.value }), className: "pl-10 w-[200px]" })] }), jsx("div", { className: "w-[200px]", children: jsx(UserFilterSelect, { tenantKey: tenantKey, value: filters.userSearch, onChange: (username) => setFilters({ ...filters, userSearch: username }), showSelfOption: false, className: "bg-transparent" }) }), isFetchingTranscriptsMessagesData && (filters.userSearch || filters.topicSearch) ? (jsx("div", { className: "animate-spin rounded-full h-5 w-5 border-b-2 border-blue-500 ml-2", "aria-hidden": "true" })) : (jsx(Button$1, { variant: "outline", onClick: handleClearFilters, className: "whitespace-nowrap", children: t('analyticsAnalyticsTranscriptsStats.clearAll') }))] }) }), jsxs("div", { className: "bg-gray-50 p-4 rounded-lg mb-6", children: [jsxs("div", { className: "flex flex-wrap gap-x-8 gap-y-2 text-sm text-gray-600", children: [jsxs("div", { "aria-label": t('analyticsAnalyticsTranscriptsStats.ariaTotalConversations'), children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.total_conversations, ' ', t('analyticsAnalyticsTranscriptsStats.conversations')] }), jsx("div", { children: "\u2022" }), jsxs("div", { children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.user_queries, ' ', t('analyticsAnalyticsTranscriptsStats.userQueries')] }), jsx("div", { children: "\u2022" }), jsxs("div", { children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.assistant_responses, ' ', t('analyticsAnalyticsTranscriptsStats.assistantResponses')] })] }), jsx("div", { className: "flex flex-wrap gap-x-8 gap-y-2 text-sm text-gray-600 mt-2", children: jsxs("div", { children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.average_sentiment_score, ' ', t('analyticsAnalyticsTranscriptsStats.averageSentimentScore')] }) })] }), jsx("div", { className: "flex flex-col gap-4", children: isLoadingTranscriptsMessagesData ? (
233801
+ return (jsxs("div", { className: "space-y-8", children: [jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-6", children: [jsx(StatCard, { title: t('analyticsAnalyticsTranscriptsStats.avgMessagesPerConversation'), value: ((_b = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_messages_per_conversation) === null || _b === void 0 ? void 0 : _b.value) || 0, percentage: ((_c = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_messages_per_conversation) === null || _c === void 0 ? void 0 : _c.percentage_change) ||
233802
+ undefined, loading: isLoadingTranscriptsConversationHeadlineData, description: t('analyticsAnalyticsTranscriptsStats.avgMessagesPerConversationDescription') }), jsx(StatCard, { title: t('analyticsAnalyticsTranscriptsStats.avgCostPerConversation'), value: Number(((_d = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_cost_per_conversation) === null || _d === void 0 ? void 0 : _d.value) || 0).toFixed(2), percentage: ((_e = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_cost_per_conversation) === null || _e === void 0 ? void 0 : _e.percentage_change) ||
233803
+ undefined, showDollarSign: true, loading: isLoadingTranscriptsConversationHeadlineData, description: t('analyticsAnalyticsTranscriptsStats.avgCostPerConversationDescription') }), jsx(StatCard, { title: t('analyticsAnalyticsTranscriptsStats.avgRating'), value: ((_f = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_rating) === null || _f === void 0 ? void 0 : _f.value) || 0, percentage: ((_g = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_rating) === null || _g === void 0 ? void 0 : _g.percentage_change) || undefined, loading: isLoadingTranscriptsConversationHeadlineData, description: t('analyticsAnalyticsTranscriptsStats.avgRatingDescription') })] }), jsxs("div", { className: "flex h-[calc(100vh-120px)]", children: [jsxs("div", { className: "w-full md:w-2/3 md:pr-6 overflow-y-auto md:border-r border-gray-200 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: [jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex gap-2 mb-4 items-center", children: [jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" }), jsx(Input, { placeholder: t('analyticsAnalyticsTranscriptsStats.placeholderTopics'), value: filters.topicSearch, onChange: (e) => setFilters({ ...filters, topicSearch: e.target.value }), className: "pl-10 w-[200px]" })] }), jsx("div", { className: "w-[200px]", children: jsx(UserFilterSelect, { tenantKey: tenantKey, value: filters.userSearch, onChange: (username) => setFilters({ ...filters, userSearch: username }), showSelfOption: false, className: "bg-transparent" }) }), isFetchingTranscriptsMessagesData && (filters.userSearch || filters.topicSearch) ? (jsx("div", { className: "animate-spin rounded-full h-5 w-5 border-b-2 border-blue-500 ml-2", "aria-hidden": "true" })) : (jsx(Button$1, { variant: "outline", onClick: handleClearFilters, className: "whitespace-nowrap", children: t('analyticsAnalyticsTranscriptsStats.clearAll') }))] }) }), jsxs("div", { className: "bg-gray-50 p-4 rounded-lg mb-6", children: [jsxs("div", { className: "flex flex-wrap gap-x-8 gap-y-2 text-sm text-gray-600", children: [jsxs("div", { "aria-label": t('analyticsAnalyticsTranscriptsStats.ariaTotalConversations'), children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.total_conversations, ' ', t('analyticsAnalyticsTranscriptsStats.conversations')] }), jsx("div", { children: "\u2022" }), jsxs("div", { children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.user_queries, ' ', t('analyticsAnalyticsTranscriptsStats.userQueries')] }), jsx("div", { children: "\u2022" }), jsxs("div", { children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.assistant_responses, ' ', t('analyticsAnalyticsTranscriptsStats.assistantResponses')] })] }), jsx("div", { className: "flex flex-wrap gap-x-8 gap-y-2 text-sm text-gray-600 mt-2", children: jsxs("div", { children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.average_sentiment_score, ' ', t('analyticsAnalyticsTranscriptsStats.averageSentimentScore')] }) })] }), jsx("div", { className: "flex flex-col gap-4", children: isLoadingTranscriptsMessagesData ? (
232777
233804
  // Loading state
232778
- jsx("div", { className: "space-y-4", children: Array.from({ length: 3 }).map((_, index) => (jsxs(Card, { className: "p-4 animate-pulse", children: [jsx("div", { className: "mb-3", children: jsx("div", { className: "h-4 bg-gray-200 rounded w-3/4" }) }), jsxs("div", { className: "flex flex-wrap gap-2 mb-3", children: [jsx("div", { className: "h-6 bg-gray-200 rounded w-16" }), jsx("div", { className: "h-6 bg-gray-200 rounded w-20" })] }), jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-2 mb-2", children: [jsx("div", { className: "h-4 bg-gray-200 rounded w-24" }), jsx("div", { className: "h-4 bg-gray-200 rounded w-20" })] }), jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-2", children: [jsx("div", { className: "h-4 bg-gray-200 rounded w-20" }), jsx("div", { className: "h-4 bg-gray-200 rounded w-24" })] })] }, index))) })) : (transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.results) && transcriptsMessagesData.results.length > 0 ? (
233805
+ jsx("div", { className: "space-y-4", children: Array.from({ length: 3 }).map((_, index) => (jsxs(Card$1, { className: "p-4 animate-pulse", children: [jsx("div", { className: "mb-3", children: jsx("div", { className: "h-4 bg-gray-200 rounded w-3/4" }) }), jsxs("div", { className: "flex flex-wrap gap-2 mb-3", children: [jsx("div", { className: "h-6 bg-gray-200 rounded w-16" }), jsx("div", { className: "h-6 bg-gray-200 rounded w-20" })] }), jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-2 mb-2", children: [jsx("div", { className: "h-4 bg-gray-200 rounded w-24" }), jsx("div", { className: "h-4 bg-gray-200 rounded w-20" })] }), jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-2", children: [jsx("div", { className: "h-4 bg-gray-200 rounded w-20" }), jsx("div", { className: "h-4 bg-gray-200 rounded w-24" })] })] }, index))) })) : (transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.results) && transcriptsMessagesData.results.length > 0 ? (
232779
233806
  // Results
232780
233807
  transcriptsMessagesData.results.map((transcript) => {
232781
233808
  var _a, _b, _c;
232782
- return (jsxs(Card, { className: cn(`p-4 hover:shadow-md transition-shadow cursor-pointer border ${selectedTranscript === transcript.session
233809
+ return (jsxs(Card$1, { className: cn(`p-4 hover:shadow-md transition-shadow cursor-pointer border ${selectedTranscript === transcript.session
232783
233810
  ? 'border-blue-500 bg-blue-50'
232784
233811
  : 'border-gray-200'}`), onClick: () => handleTranscriptSelect(transcript.session), children: [jsx("div", { className: "mb-3", children: jsx("p", { className: "text-gray-800", children: transcript.first_user_message }) }), jsxs("div", { className: "flex flex-wrap gap-2 mb-3", children: [((_a = transcript === null || transcript === void 0 ? void 0 : transcript.topics) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
232785
233812
  ((_b = transcript.topics) === null || _b === void 0 ? void 0 : _b.map((topic, index) => (jsx("span", { className: "bg-gray-100 text-gray-600 px-3 py-1 rounded-[5px] text-xs", children: topic }, index)))), jsx(TranscriptRollupBadges, { documentsCount: transcript.documents_count, toolCallsCount: transcript.tool_calls_count })] }), jsx("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2 text-sm mb-2", children: jsxs("div", { className: cn('flex items-center gap-1', transcript.sentiment === 'negative'
@@ -232794,6 +233821,8 @@ function AnalyticsTranscriptsStats({ tenantKey, currentSPA, mentorId, selectedMe
232794
233821
  ? ((_c = turnDetails === null || turnDetails === void 0 ? void 0 : turnDetails.renderModel) !== null && _c !== void 0 ? _c : renderModelBadge)({
232795
233822
  model: transcript.model,
232796
233823
  provider: providerOf(transcript),
233824
+ tenantKey,
233825
+ mentorId: (transcript === null || transcript === void 0 ? void 0 : transcript.mentor_unique_id) || currentMentorId,
232797
233826
  })
232798
233827
  : '-'] }) }), jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-2 text-xs text-gray-500", children: [jsxs("div", { children: [transcript.message_count, " ", t('analyticsAnalyticsTranscriptsStats.messages')] }), jsx("div", { children: "\u2022" }), jsxs("div", { children: ["$", Number((transcript === null || transcript === void 0 ? void 0 : transcript.cost) || 0).toFixed(2), ' ', t('analyticsAnalyticsTranscriptsStats.estimatedCost')] }), (transcript === null || transcript === void 0 ? void 0 : transcript.created_at) && (jsxs(Fragment$1, { children: [jsx("div", { children: "\u2022" }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.created'), ' ', formatRelativeTime(transcript.created_at, t)] })] }))] })] }, transcript.session));
232799
233828
  })) : (
@@ -232831,14 +233860,16 @@ function AnalyticsTranscriptsStats({ tenantKey, currentSPA, mentorId, selectedMe
232831
233860
  /* Error or no data state */
232832
233861
  jsx("div", { className: "flex items-center justify-center h-full text-gray-400", children: jsxs("div", { className: "text-center", children: [jsx(X$1, { className: "h-6 w-6 mx-auto mb-2 text-red-400" }), jsx("p", { children: t('analyticsAnalyticsTranscriptsStats.noTranscriptDetails') }), jsx("p", { className: "text-sm mt-1", children: t('analyticsAnalyticsTranscriptsStats.unableToLoadTranscript') })] }) })) : (
232833
233862
  /* Data loaded successfully */
232834
- jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "mb-4", children: jsxs("div", { className: "text-sm text-gray-500 space-y-1", children: [jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelUser'), ' ', jsx(UserProfileLink, { currentSPA: currentSPA, tenantKey: tenantKey, username: (_g = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _g === void 0 ? void 0 : _g.username, display: identifyUser(transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) })] }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelAgent'), ' ', jsx(AgentScopeLink, { uniqueId: (_h = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _h === void 0 ? void 0 : _h.mentor_unique_id, name: (_j = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _j === void 0 ? void 0 : _j.mentor })] }), jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [t('analyticsAnalyticsTranscriptsStats.labelModel'), ' ', ((_k = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _k === void 0 ? void 0 : _k.model)
232835
- ? ((_l = turnDetails === null || turnDetails === void 0 ? void 0 : turnDetails.renderModel) !== null && _l !== void 0 ? _l : renderModelBadge)({
233863
+ jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "mb-4", children: jsxs("div", { className: "text-sm text-gray-500 space-y-1", children: [jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelUser'), ' ', jsx(UserProfileLink, { currentSPA: currentSPA, tenantKey: tenantKey, username: (_h = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _h === void 0 ? void 0 : _h.username, display: identifyUser(transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) })] }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelAgent'), ' ', jsx(AgentScopeLink, { uniqueId: (_j = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _j === void 0 ? void 0 : _j.mentor_unique_id, name: (_k = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _k === void 0 ? void 0 : _k.mentor })] }), jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [t('analyticsAnalyticsTranscriptsStats.labelModel'), ' ', ((_l = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _l === void 0 ? void 0 : _l.model)
233864
+ ? ((_m = turnDetails === null || turnDetails === void 0 ? void 0 : turnDetails.renderModel) !== null && _m !== void 0 ? _m : renderModelBadge)({
232836
233865
  model: transcriptsMessagesDetailsData.summary.model,
232837
- provider: (_m = providerOf(transcriptsMessagesDetailsData.summary)) !== null && _m !== void 0 ? _m : providerOfTurns(transcriptsMessagesDetailsData.messages),
233866
+ provider: (_o = providerOf(transcriptsMessagesDetailsData.summary)) !== null && _o !== void 0 ? _o : providerOfTurns(transcriptsMessagesDetailsData.messages),
233867
+ tenantKey,
233868
+ mentorId: detailMentorId,
232838
233869
  })
232839
- : '-'] }), jsx(TranscriptDocumentsButton, { detail: transcriptsMessagesDetailsData, className: "mt-2" })] }) }), jsx("div", { className: "space-y-4 pb-4", children: ((_o = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.messages) === null || _o === void 0 ? void 0 : _o.length) > 0 ? ((_p = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.messages) === null || _p === void 0 ? void 0 : _p.map((message, index) => {
233870
+ : '-'] }), jsx(TranscriptDocumentsButton, { detail: transcriptsMessagesDetailsData, className: "mt-2" })] }) }), jsx("div", { className: "space-y-4 pb-4", children: ((_p = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.messages) === null || _p === void 0 ? void 0 : _p.length) > 0 ? ((_q = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.messages) === null || _q === void 0 ? void 0 : _q.map((message, index) => {
232840
233871
  var _a, _b;
232841
- return (jsxs(React__default.Fragment, { children: [((message === null || message === void 0 ? void 0 : message.human) || !!((_a = message === null || message === void 0 ? void 0 : message.human_files) === null || _a === void 0 ? void 0 : _a.length)) && (jsxs("div", { className: "p-3 rounded-lg bg-blue-100 ml-4", children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleUser') }) }), message.human && (jsx("p", { className: "text-sm", children: getMessageContent(message.human) })), jsx(TranscriptFiles, { files: message.human_files })] })), ((message === null || message === void 0 ? void 0 : message.ai) || !!((_b = message === null || message === void 0 ? void 0 : message.ai_files) === null || _b === void 0 ? void 0 : _b.length)) && (jsxs("div", { className: "p-3 rounded-lg bg-white mr-4 border", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleAgent') }) }), message.ai && jsx(Markdown, { children: getMessageContent(message.ai) }), jsx(TranscriptFiles, { files: message.ai_files }), jsx(TranscriptTurnDetails, { turn: message, ...turnDetails })] }))] }, index));
233872
+ return (jsxs(React__default.Fragment, { children: [((message === null || message === void 0 ? void 0 : message.human) || !!((_a = message === null || message === void 0 ? void 0 : message.human_files) === null || _a === void 0 ? void 0 : _a.length)) && (jsxs("div", { className: "p-3 rounded-lg bg-blue-100 ml-4", children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleUser') }) }), message.human && (jsx("p", { className: "text-sm", children: getMessageContent(message.human) })), jsx(TranscriptFiles, { files: message.human_files })] })), ((message === null || message === void 0 ? void 0 : message.ai) || !!((_b = message === null || message === void 0 ? void 0 : message.ai_files) === null || _b === void 0 ? void 0 : _b.length)) && (jsxs("div", { className: "p-3 rounded-lg bg-white mr-4 border", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleAgent') }) }), message.ai && jsx(Markdown, { children: getMessageContent(message.ai) }), jsx(TranscriptFiles, { files: message.ai_files }), jsx(TranscriptTurnDetails, { turn: message, tenantKey: tenantKey, mentorId: detailMentorId, ...turnDetails })] }))] }, index));
232842
233873
  })) : (jsx("div", { className: "text-center text-gray-500 py-8", children: jsx("p", { children: t('analyticsAnalyticsTranscriptsStats.noMessages') }) })) })] })) })] }) }))] }));
232843
233874
  }
232844
233875
 
@@ -233667,7 +234698,7 @@ function AnalyticsReports({ tenantKey, selectedMentorId, disabledReports = [], u
233667
234698
  }, [reports, hiddenReports]);
233668
234699
  const content = useMemo(() => {
233669
234700
  if (isLoading) {
233670
- return (jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8 items-stretch", children: Array.from({ length: 12 }).map((_, key) => (jsx(Card, { className: "bg-white border-gray-200 h-full flex flex-col", children: jsx(CardContent, { className: "p-6 flex-1 flex flex-col", children: jsxs("div", { className: "flex-1", children: [jsxs("div", { className: "flex justify-between items-start mb-2", children: [jsx(Skeleton, { className: "h-5 w-32 flex-1 mr-2" }), jsx(Skeleton, { className: "h-8 w-8 flex-shrink-0" })] }), jsx(Skeleton, { className: "h-4 w-full" })] }) }) }, key))) }));
234701
+ return (jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8 items-stretch", children: Array.from({ length: 12 }).map((_, key) => (jsx(Card$1, { className: "bg-white border-gray-200 h-full flex flex-col", children: jsx(CardContent, { className: "p-6 flex-1 flex flex-col", children: jsxs("div", { className: "flex-1", children: [jsxs("div", { className: "flex justify-between items-start mb-2", children: [jsx(Skeleton, { className: "h-5 w-32 flex-1 mr-2" }), jsx(Skeleton, { className: "h-8 w-8 flex-shrink-0" })] }), jsx(Skeleton, { className: "h-4 w-full" })] }) }) }, key))) }));
233671
234702
  }
233672
234703
  if (!filteredReports.length) {
233673
234704
  return (jsx("div", { className: "flex flex-col items-center justify-center space-y-4", children: jsx(EmptyStats, { title: t('analyticsAnalyticsReports.noReportsAvailable') }) }));
@@ -233737,7 +234768,7 @@ function ReportCard({ report, isActive, isDisabled, isCombinableReport, hasCompl
233737
234768
  };
233738
234769
  const dialogOpen = popoverMode !== null;
233739
234770
  const hasDateSelection = Boolean(dateRange === null || dateRange === void 0 ? void 0 : dateRange.from);
233740
- return (jsxs(Fragment$1, { children: [jsx(Card, { "aria-label": `${displayName} report card`, className: "bg-white border-gray-200 h-full flex flex-col", "data-testid": isCombinableReport ? 'combined-recommendation-report-card' : undefined, children: jsx(CardContent, { className: "p-6 flex-1 flex flex-col", children: jsxs("div", { className: "flex-1", children: [jsxs("div", { className: "flex justify-between items-start mb-2", children: [jsx("h3", { className: "text-base font-medium text-gray-700 flex-1 pr-2", children: headerTitle }), jsxs("div", { className: "flex items-center gap-1 flex-shrink-0", children: [hasCompletedReport && (jsxs(Popover, { open: showRegenerateHint, onOpenChange: (next) => {
234771
+ return (jsxs(Fragment$1, { children: [jsx(Card$1, { "aria-label": `${displayName} report card`, className: "bg-white border-gray-200 h-full flex flex-col", "data-testid": isCombinableReport ? 'combined-recommendation-report-card' : undefined, children: jsx(CardContent, { className: "p-6 flex-1 flex flex-col", children: jsxs("div", { className: "flex-1", children: [jsxs("div", { className: "flex justify-between items-start mb-2", children: [jsx("h3", { className: "text-base font-medium text-gray-700 flex-1 pr-2", children: headerTitle }), jsxs("div", { className: "flex items-center gap-1 flex-shrink-0", children: [hasCompletedReport && (jsxs(Popover, { open: showRegenerateHint, onOpenChange: (next) => {
233741
234772
  if (!next)
233742
234773
  onDismissRegenerateHint();
233743
234774
  }, children: [jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx(PopoverTrigger, { asChild: true, children: jsx(Button$1, { variant: "outline", size: "sm", className: cn('h-8 w-8 p-0 bg-transparent hover:bg-[#155dfc] hover:text-white border-[#155dfc] text-[#155dfc]', showRegenerateHint &&
@@ -234091,7 +235122,7 @@ function AnalyticsCourses({ tenantKey, mentorId, selectedMentorId, basePath = ''
234091
235122
  date: formatDateToShortFormat$1(point.date, enrollmentStatsDateFilter.activeFilter === 'today'),
234092
235123
  value: formatSecondsToHours$1(point.value),
234093
235124
  rawSeconds: point.value,
234094
- }))) || [], tooltipLabel: t('analyticsAnalyticsCourses.tooltipTimeSpentLabel'), tooltipValue: (point) => formatSecondsToTime$1(Number(point.rawSeconds) || 0), tooltipAriaLabel: (label) => t('analyticsAnalyticsCourses.tooltipAriaLabel', { label }), yTickFormatter: (value) => `${value}h` })) }) })), jsx("div", { className: "grid grid-cols-1 gap-6", children: jsx(Card, { className: "w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsCourses.coursesTableAriaLabel'), children: [jsxs("div", { className: "flex items-center gap-1 mb-4", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsCourses.coursesHeading') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsCourses.coursesHeading'), description: t('analyticsAnalyticsCourses.coursesTableDescription') })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "relative flex-1 w-full", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { id: "search-course", type: "text", placeholder: t('analyticsAnalyticsCourses.searchPlaceholder'), value: coursesListSearch, onChange: handleSearchInputChange, className: "pl-9 border-gray-300 focus:bg-transparent focus:color-transparent h-11", "aria-label": t('analyticsAnalyticsCourses.searchAriaLabel') })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-8", children: jsx("div", { className: "text-sm text-gray-500", children: t('analyticsAnalyticsCourses.loading') }) })) : ((_c = coursesList === null || coursesList === void 0 ? void 0 : coursesList.courses) === null || _c === void 0 ? void 0 : _c.length) && coursesList.courses.length > 0 ? (jsxs(Fragment$1, { children: [jsx("div", { className: "rounded-md overflow-x-auto", style: { borderColor: 'oklch(.922 0 0)', borderWidth: '1px' }, children: jsxs(Table, { children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "h-[48px]", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsCourses.colCourseName') }), jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsCourses.colCourseId') }), jsx(TableHead, { className: "text-right", children: t('analyticsAnalyticsCourses.colEnrollments') })] }) }), jsx(TableBody, { children: coursesList.courses.map((course, index) => (jsxs(TableRow, { className: `cursor-pointer hover:bg-muted/50 h-[48px] ${index % 2 === 0 ? 'bg-gray-50' : ''}`,
235125
+ }))) || [], tooltipLabel: t('analyticsAnalyticsCourses.tooltipTimeSpentLabel'), tooltipValue: (point) => formatSecondsToTime$1(Number(point.rawSeconds) || 0), tooltipAriaLabel: (label) => t('analyticsAnalyticsCourses.tooltipAriaLabel', { label }), yTickFormatter: (value) => `${value}h` })) }) })), jsx("div", { className: "grid grid-cols-1 gap-6", children: jsx(Card$1, { className: "w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsCourses.coursesTableAriaLabel'), children: [jsxs("div", { className: "flex items-center gap-1 mb-4", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsCourses.coursesHeading') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsCourses.coursesHeading'), description: t('analyticsAnalyticsCourses.coursesTableDescription') })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "relative flex-1 w-full", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { id: "search-course", type: "text", placeholder: t('analyticsAnalyticsCourses.searchPlaceholder'), value: coursesListSearch, onChange: handleSearchInputChange, className: "pl-9 border-gray-300 focus:bg-transparent focus:color-transparent h-11", "aria-label": t('analyticsAnalyticsCourses.searchAriaLabel') })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-8", children: jsx("div", { className: "text-sm text-gray-500", children: t('analyticsAnalyticsCourses.loading') }) })) : ((_c = coursesList === null || coursesList === void 0 ? void 0 : coursesList.courses) === null || _c === void 0 ? void 0 : _c.length) && coursesList.courses.length > 0 ? (jsxs(Fragment$1, { children: [jsx("div", { className: "rounded-md overflow-x-auto", style: { borderColor: 'oklch(.922 0 0)', borderWidth: '1px' }, children: jsxs(Table, { children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "h-[48px]", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsCourses.colCourseName') }), jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsCourses.colCourseId') }), jsx(TableHead, { className: "text-right", children: t('analyticsAnalyticsCourses.colEnrollments') })] }) }), jsx(TableBody, { children: coursesList.courses.map((course, index) => (jsxs(TableRow, { className: `cursor-pointer hover:bg-muted/50 h-[48px] ${index % 2 === 0 ? 'bg-gray-50' : ''}`,
234095
235126
  // Mouse shortcut only; the id cell may hold a link,
234096
235127
  // so the row itself must not be a button —
234097
235128
  // interactive content inside one is invalid, and
@@ -234139,7 +235170,7 @@ function AnalyticsCourseDetail({ tenantKey, currentSPA, mentorId, selectedMentor
234139
235170
  const [selectedEnrollment, setSelectedEnrollment] = useState(null);
234140
235171
  const resolvedCourseName = courseName || (courseInfo === null || courseInfo === void 0 ? void 0 : courseInfo.name);
234141
235172
  const showTitle = showCourseTitle && !!resolvedCourseName;
234142
- return (jsxs("div", { className: "space-y-8", children: [(onBack || showTitle) && (jsxs("div", { className: "mb-4 flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-4", children: [jsx("div", { className: "flex flex-1 justify-start", children: onBack && (jsx(Button$1, { variant: "ghost", size: "icon", onClick: onBack, "aria-label": t('analyticsAnalyticsCourseDetail.goBackAriaLabel'), className: "h-8 w-8 rounded-full bg-gray-100 text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:hover:text-white", children: jsx(ArrowLeft, { className: "h-4 w-4" }) })) }), showTitle && (jsx("h2", { className: "flex-1 text-left text-2xl font-medium text-gray-700 sm:text-center", children: resolvedCourseName })), jsx("div", { className: "hidden flex-1 sm:block" })] })), jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4 mb-6", children: [jsx(StatCard, { loading: isDetailStatsLoading, title: t('analyticsAnalyticsCourseDetail.activeEnrollments'), value: courseDetailStats.active_enrollments, percentage: courseDetailStats.active_enrollments_percentage, description: t('analyticsAnalyticsCourseDetail.activeEnrollmentsDescription') }), jsx(StatCard, { loading: isDetailStatsLoading, title: t('analyticsAnalyticsCourseDetail.completedEnrollments'), value: courseDetailStats.completed_enrollments, percentage: courseDetailStats.completed_enrollments_percentage, description: t('analyticsAnalyticsCourseDetail.completedEnrollmentsDescription') })] }), jsx("div", { className: "grid grid-cols-1 gap-6", children: jsx(Card, { className: "w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsCourseDetail.courseEnrollmentsTableAriaLabel'), children: [jsxs("div", { className: "flex items-center gap-1 mb-4", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsCourseDetail.enrolledUsers') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsCourseDetail.enrolledUsers'), description: t('analyticsAnalyticsCourseDetail.enrolledUsersDescription') })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "relative flex-1 w-full", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { id: "search-enrolled-user", type: "text", placeholder: t('analyticsAnalyticsCourseDetail.searchPlaceholder'), value: courseEnrollmentsSearch, onChange: handleCourseEnrollmentsSearchInputChange, className: "pl-9 border-gray-300 focus:bg-transparent focus:color-transparent h-11", "aria-label": t('analyticsAnalyticsCourseDetail.searchAriaLabel') })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-8", children: jsx("div", { className: "text-sm text-gray-500", children: t('analyticsAnalyticsCourseDetail.loadingLabel') }) })) : ((_a = courseEnrollments === null || courseEnrollments === void 0 ? void 0 : courseEnrollments.enrollments) === null || _a === void 0 ? void 0 : _a.length) &&
235173
+ return (jsxs("div", { className: "space-y-8", children: [(onBack || showTitle) && (jsxs("div", { className: "mb-4 flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-4", children: [jsx("div", { className: "flex flex-1 justify-start", children: onBack && (jsx(Button$1, { variant: "ghost", size: "icon", onClick: onBack, "aria-label": t('analyticsAnalyticsCourseDetail.goBackAriaLabel'), className: "h-8 w-8 rounded-full bg-gray-100 text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:hover:text-white", children: jsx(ArrowLeft, { className: "h-4 w-4" }) })) }), showTitle && (jsx("h2", { className: "flex-1 text-left text-2xl font-medium text-gray-700 sm:text-center", children: resolvedCourseName })), jsx("div", { className: "hidden flex-1 sm:block" })] })), jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4 mb-6", children: [jsx(StatCard, { loading: isDetailStatsLoading, title: t('analyticsAnalyticsCourseDetail.activeEnrollments'), value: courseDetailStats.active_enrollments, percentage: courseDetailStats.active_enrollments_percentage, description: t('analyticsAnalyticsCourseDetail.activeEnrollmentsDescription') }), jsx(StatCard, { loading: isDetailStatsLoading, title: t('analyticsAnalyticsCourseDetail.completedEnrollments'), value: courseDetailStats.completed_enrollments, percentage: courseDetailStats.completed_enrollments_percentage, description: t('analyticsAnalyticsCourseDetail.completedEnrollmentsDescription') })] }), jsx("div", { className: "grid grid-cols-1 gap-6", children: jsx(Card$1, { className: "w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsCourseDetail.courseEnrollmentsTableAriaLabel'), children: [jsxs("div", { className: "flex items-center gap-1 mb-4", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsCourseDetail.enrolledUsers') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsCourseDetail.enrolledUsers'), description: t('analyticsAnalyticsCourseDetail.enrolledUsersDescription') })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "relative flex-1 w-full", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { id: "search-enrolled-user", type: "text", placeholder: t('analyticsAnalyticsCourseDetail.searchPlaceholder'), value: courseEnrollmentsSearch, onChange: handleCourseEnrollmentsSearchInputChange, className: "pl-9 border-gray-300 focus:bg-transparent focus:color-transparent h-11", "aria-label": t('analyticsAnalyticsCourseDetail.searchAriaLabel') })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-8", children: jsx("div", { className: "text-sm text-gray-500", children: t('analyticsAnalyticsCourseDetail.loadingLabel') }) })) : ((_a = courseEnrollments === null || courseEnrollments === void 0 ? void 0 : courseEnrollments.enrollments) === null || _a === void 0 ? void 0 : _a.length) &&
234143
235174
  courseEnrollments.enrollments.length > 0 ? (jsxs(Fragment$1, { children: [jsx("div", { className: "rounded-md overflow-x-auto", style: { borderColor: 'oklch(.922 0 0)', borderWidth: '1px' }, children: jsxs(Table, { children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "h-[48px]", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsCourseDetail.columnName') }), jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsCourseDetail.columnEmail') }), jsx(TableHead, { className: "text-right", children: t('analyticsAnalyticsCourseDetail.columnEnrollmentDate') }), jsx(TableHead, { className: "text-right", children: t('analyticsAnalyticsCourseDetail.columnLastActiveOn') }), jsx(TableHead, { className: "w-[1%] text-right whitespace-nowrap", children: t('analyticsAnalyticsCourseDetail.columnProgress') })] }) }), jsx(TableBody, { children: courseEnrollments.enrollments.map((enrollment, index) => (jsxs(TableRow, { className: `cursor-pointer hover:bg-muted/50 h-[48px] ${index % 2 === 0 ? 'bg-gray-50' : ''}`,
234144
235175
  // Mouse shortcut only; the name and email cells hold profile
234145
235176
  // links, so keyboard and screen-reader users reach the
@@ -234491,7 +235522,7 @@ function AnalyticsPrograms({ tenantKey, mentorId, selectedMentorId, basePath = '
234491
235522
  date: formatDateToShortFormat(point.date, enrollmentStatsDateFilter.activeFilter === 'today'),
234492
235523
  value: formatSecondsToHours(point.value),
234493
235524
  rawSeconds: point.value,
234494
- }))) || [], tooltipLabel: t('analyticsAnalyticsPrograms.timeSpent'), tooltipValue: (point) => formatSecondsToTime(Number(point.rawSeconds) || 0), tooltipAriaLabel: (label) => t('analyticsAnalyticsPrograms.tooltipAriaLabel', { label }), yTickFormatter: (value) => `${value}h` })) }) })), jsx("div", { className: "grid grid-cols-1 gap-6", children: jsx(Card, { className: "w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsPrograms.programsTableAriaLabel'), children: [jsxs("div", { className: "flex items-center gap-1 mb-4", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsPrograms.programs') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsPrograms.programs'), description: t('analyticsAnalyticsPrograms.programsTableDescription') })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "relative flex-1 w-full", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { id: "search-program", type: "text", placeholder: t('analyticsAnalyticsPrograms.searchPlaceholder'), value: programsListSearch, onChange: handleSearchInputChange, className: "pl-9 border-gray-300 focus:bg-transparent focus:color-transparent h-11", "aria-label": t('analyticsAnalyticsPrograms.searchAriaLabel') })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-8", children: jsx("div", { className: "text-sm text-gray-500", children: t('analyticsAnalyticsPrograms.loading') }) })) : ((_c = programsList === null || programsList === void 0 ? void 0 : programsList.programs) === null || _c === void 0 ? void 0 : _c.length) && programsList.programs.length > 0 ? (jsxs(Fragment$1, { children: [jsx("div", { className: "rounded-md overflow-x-auto", style: { borderColor: 'oklch(.922 0 0)', borderWidth: '1px' }, children: jsxs(Table, { children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "h-[48px]", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsPrograms.programName') }), jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsPrograms.programId') }), jsx(TableHead, { className: "text-right", children: t('analyticsAnalyticsPrograms.enrollments') })] }) }), jsx(TableBody, { children: programsList.programs.map((program, index) => (jsxs(TableRow, { className: `cursor-pointer hover:bg-muted/50 h-[48px] ${index % 2 === 0 ? 'bg-gray-50' : ''}`,
235525
+ }))) || [], tooltipLabel: t('analyticsAnalyticsPrograms.timeSpent'), tooltipValue: (point) => formatSecondsToTime(Number(point.rawSeconds) || 0), tooltipAriaLabel: (label) => t('analyticsAnalyticsPrograms.tooltipAriaLabel', { label }), yTickFormatter: (value) => `${value}h` })) }) })), jsx("div", { className: "grid grid-cols-1 gap-6", children: jsx(Card$1, { className: "w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsPrograms.programsTableAriaLabel'), children: [jsxs("div", { className: "flex items-center gap-1 mb-4", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsPrograms.programs') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsPrograms.programs'), description: t('analyticsAnalyticsPrograms.programsTableDescription') })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "relative flex-1 w-full", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { id: "search-program", type: "text", placeholder: t('analyticsAnalyticsPrograms.searchPlaceholder'), value: programsListSearch, onChange: handleSearchInputChange, className: "pl-9 border-gray-300 focus:bg-transparent focus:color-transparent h-11", "aria-label": t('analyticsAnalyticsPrograms.searchAriaLabel') })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-8", children: jsx("div", { className: "text-sm text-gray-500", children: t('analyticsAnalyticsPrograms.loading') }) })) : ((_c = programsList === null || programsList === void 0 ? void 0 : programsList.programs) === null || _c === void 0 ? void 0 : _c.length) && programsList.programs.length > 0 ? (jsxs(Fragment$1, { children: [jsx("div", { className: "rounded-md overflow-x-auto", style: { borderColor: 'oklch(.922 0 0)', borderWidth: '1px' }, children: jsxs(Table, { children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "h-[48px]", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsPrograms.programName') }), jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsPrograms.programId') }), jsx(TableHead, { className: "text-right", children: t('analyticsAnalyticsPrograms.enrollments') })] }) }), jsx(TableBody, { children: programsList.programs.map((program, index) => (jsxs(TableRow, { className: `cursor-pointer hover:bg-muted/50 h-[48px] ${index % 2 === 0 ? 'bg-gray-50' : ''}`,
234495
235526
  // Mouse shortcut only; the id cell may hold a link,
234496
235527
  // so the row itself must not be a button —
234497
235528
  // interactive content inside one is invalid, and
@@ -234538,7 +235569,7 @@ function AnalyticsProgramDetail({ tenantKey, currentSPA, mentorId, selectedMento
234538
235569
  });
234539
235570
  const [selectedEnrollment, setSelectedEnrollment] = useState(null);
234540
235571
  const resolvedProgramName = programName || (programInfo === null || programInfo === void 0 ? void 0 : programInfo.name);
234541
- return (jsxs("div", { className: "space-y-8", children: [(onBack || resolvedProgramName) && (jsxs("div", { className: "mb-4 flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-4", children: [jsx("div", { className: "flex flex-1 justify-start", children: onBack && (jsx(Button$1, { variant: "ghost", size: "icon", onClick: onBack, "aria-label": t('analyticsAnalyticsProgramDetail.backAriaLabel'), className: "h-8 w-8 rounded-full bg-gray-100 text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:hover:text-white", children: jsx(ArrowLeft, { className: "h-4 w-4" }) })) }), resolvedProgramName && (jsx("h2", { className: "flex-1 truncate text-left text-2xl font-medium text-gray-700 sm:text-center", children: resolvedProgramName })), jsx("div", { className: "hidden flex-1 sm:block" })] })), jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-4 mb-6", children: [jsx(StatCard, { loading: isDetailStatsLoading, title: t('analyticsAnalyticsProgramDetail.statTotalEnrollments'), value: programDetailStats.enrollments, percentage: programDetailStats.enrollments_percentage, description: t('analyticsAnalyticsProgramDetail.statTotalEnrollmentsDescription') }), jsx(StatCard, { loading: isDetailStatsLoading, title: t('analyticsAnalyticsProgramDetail.statActiveEnrollments'), value: programDetailStats.active_enrollments, percentage: programDetailStats.active_enrollments_percentage, description: t('analyticsAnalyticsProgramDetail.statActiveEnrollmentsDescription') }), jsx(StatCard, { loading: isDetailStatsLoading, title: t('analyticsAnalyticsProgramDetail.statCompletedEnrollments'), value: programDetailStats.completed_enrollments, percentage: programDetailStats.completed_enrollments_percentage, description: t('analyticsAnalyticsProgramDetail.statCompletedEnrollmentsDescription') })] }), jsx("div", { className: "grid grid-cols-1 gap-6", children: jsx(Card, { className: "w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsProgramDetail.tableAriaLabel'), children: [jsxs("div", { className: "flex items-center gap-1 mb-4", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsProgramDetail.enrolledUsersHeading') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsProgramDetail.enrolledUsersHeading'), description: t('analyticsAnalyticsProgramDetail.enrolledUsersDescription') })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "relative flex-1 w-full", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { id: "search-enrolled-user", type: "text", placeholder: t('analyticsAnalyticsProgramDetail.searchPlaceholder'), value: programEnrollmentsSearch, onChange: handleProgramEnrollmentsSearchInputChange, className: "pl-9 border-gray-300 focus:bg-transparent focus:color-transparent h-11", "aria-label": t('analyticsAnalyticsProgramDetail.searchAriaLabel') })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-8", children: jsx("div", { className: "text-sm text-gray-500", children: t('analyticsAnalyticsProgramDetail.loadingLabel') }) })) : ((_a = programEnrollments === null || programEnrollments === void 0 ? void 0 : programEnrollments.enrollments) === null || _a === void 0 ? void 0 : _a.length) &&
235572
+ return (jsxs("div", { className: "space-y-8", children: [(onBack || resolvedProgramName) && (jsxs("div", { className: "mb-4 flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-4", children: [jsx("div", { className: "flex flex-1 justify-start", children: onBack && (jsx(Button$1, { variant: "ghost", size: "icon", onClick: onBack, "aria-label": t('analyticsAnalyticsProgramDetail.backAriaLabel'), className: "h-8 w-8 rounded-full bg-gray-100 text-gray-700 hover:bg-gray-200 hover:text-gray-900 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:hover:text-white", children: jsx(ArrowLeft, { className: "h-4 w-4" }) })) }), resolvedProgramName && (jsx("h2", { className: "flex-1 truncate text-left text-2xl font-medium text-gray-700 sm:text-center", children: resolvedProgramName })), jsx("div", { className: "hidden flex-1 sm:block" })] })), jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-4 mb-6", children: [jsx(StatCard, { loading: isDetailStatsLoading, title: t('analyticsAnalyticsProgramDetail.statTotalEnrollments'), value: programDetailStats.enrollments, percentage: programDetailStats.enrollments_percentage, description: t('analyticsAnalyticsProgramDetail.statTotalEnrollmentsDescription') }), jsx(StatCard, { loading: isDetailStatsLoading, title: t('analyticsAnalyticsProgramDetail.statActiveEnrollments'), value: programDetailStats.active_enrollments, percentage: programDetailStats.active_enrollments_percentage, description: t('analyticsAnalyticsProgramDetail.statActiveEnrollmentsDescription') }), jsx(StatCard, { loading: isDetailStatsLoading, title: t('analyticsAnalyticsProgramDetail.statCompletedEnrollments'), value: programDetailStats.completed_enrollments, percentage: programDetailStats.completed_enrollments_percentage, description: t('analyticsAnalyticsProgramDetail.statCompletedEnrollmentsDescription') })] }), jsx("div", { className: "grid grid-cols-1 gap-6", children: jsx(Card$1, { className: "w-full bg-white shadow-xs", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsProgramDetail.tableAriaLabel'), children: [jsxs("div", { className: "flex items-center gap-1 mb-4", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsProgramDetail.enrolledUsersHeading') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsProgramDetail.enrolledUsersHeading'), description: t('analyticsAnalyticsProgramDetail.enrolledUsersDescription') })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "relative flex-1 w-full", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { id: "search-enrolled-user", type: "text", placeholder: t('analyticsAnalyticsProgramDetail.searchPlaceholder'), value: programEnrollmentsSearch, onChange: handleProgramEnrollmentsSearchInputChange, className: "pl-9 border-gray-300 focus:bg-transparent focus:color-transparent h-11", "aria-label": t('analyticsAnalyticsProgramDetail.searchAriaLabel') })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-8", children: jsx("div", { className: "text-sm text-gray-500", children: t('analyticsAnalyticsProgramDetail.loadingLabel') }) })) : ((_a = programEnrollments === null || programEnrollments === void 0 ? void 0 : programEnrollments.enrollments) === null || _a === void 0 ? void 0 : _a.length) &&
234542
235573
  programEnrollments.enrollments.length > 0 ? (jsxs(Fragment$1, { children: [jsx("div", { className: "rounded-md overflow-x-auto", style: { borderColor: 'oklch(.922 0 0)', borderWidth: '1px' }, children: jsxs(Table, { children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "h-[48px]", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsProgramDetail.colName') }), jsx(TableHead, { className: "text-left", children: t('analyticsAnalyticsProgramDetail.colEmail') }), jsx(TableHead, { className: "text-right", children: t('analyticsAnalyticsProgramDetail.colEnrollmentDate') }), jsx(TableHead, { className: "text-right", children: t('analyticsAnalyticsProgramDetail.colLastActiveOn') }), jsx(TableHead, { className: "w-[1%] text-right whitespace-nowrap", children: t('analyticsAnalyticsProgramDetail.colProgress') })] }) }), jsx(TableBody, { children: programEnrollments.enrollments.map((enrollment, index) => (jsxs(TableRow, { className: `cursor-pointer hover:bg-muted/50 h-[48px] ${index % 2 === 0 ? 'bg-gray-50' : ''}`,
234543
235574
  // Mouse shortcut only; the name and email cells hold profile
234544
235575
  // links, so keyboard and screen-reader users reach the
@@ -234749,7 +235780,7 @@ function AnalyticsMonetizationStats({ tenantKey }) {
234749
235780
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
234750
235781
  const t = useT();
234751
235782
  const { revenueData, isLoadingRevenue, paywallsData, isLoadingPaywalls, subscribersData, isLoadingSubscribers, paywallTypeFilter, setPaywallTypeFilter, subscriberStatusFilter, setSubscriberStatusFilter, paywallPage, setPaywallPage, subscriberPage, setSubscriberPage, statusDistribution, itemTypeDistribution, statusColors, itemTypeColors, } = useMonetization({ tenantKey });
234752
- return (jsxs("div", { className: "space-y-8", children: [jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6", children: [jsx(StatCard, { loading: isLoadingRevenue, title: t('analyticsAnalyticsMonetizationStats.totalRevenue'), value: Number((revenueData === null || revenueData === void 0 ? void 0 : revenueData.sales_volume) || 0).toLocaleString(), showDollarSign: true, description: t('analyticsAnalyticsMonetizationStats.totalRevenueDescription') }), jsx(StatCard, { loading: isLoadingRevenue, title: t('analyticsAnalyticsMonetizationStats.totalSales'), value: (_a = revenueData === null || revenueData === void 0 ? void 0 : revenueData.sales_count) !== null && _a !== void 0 ? _a : 0, description: t('analyticsAnalyticsMonetizationStats.totalSalesDescription') }), jsx(StatCard, { loading: isLoadingPaywalls, title: t('analyticsAnalyticsMonetizationStats.activePaywalls'), value: (_b = paywallsData === null || paywallsData === void 0 ? void 0 : paywallsData.count) !== null && _b !== void 0 ? _b : 0, description: t('analyticsAnalyticsMonetizationStats.activePaywallsDescription') }), jsx(StatCard, { loading: isLoadingSubscribers, title: t('analyticsAnalyticsMonetizationStats.totalSubscribers'), value: (_c = subscribersData === null || subscribersData === void 0 ? void 0 : subscribersData.count) !== null && _c !== void 0 ? _c : 0, description: t('analyticsAnalyticsMonetizationStats.totalSubscribersDescription') })] }), jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-5", children: [jsx(Card, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsMonetizationStats.subscriptionStatusChartCardAriaLabel'), children: [jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex items-center gap-1", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsMonetizationStats.subscribersByStatus') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsMonetizationStats.subscribersByStatus'), description: t('analyticsAnalyticsMonetizationStats.subscribersByStatusDescription') })] }) }), jsx("div", { className: "w-full", style: { height: '350px' }, children: jsx(ChartContainer, { title: t('analyticsAnalyticsMonetizationStats.subscribersByStatus'), config: {
235783
+ return (jsxs("div", { className: "space-y-8", children: [jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6", children: [jsx(StatCard, { loading: isLoadingRevenue, title: t('analyticsAnalyticsMonetizationStats.totalRevenue'), value: Number((revenueData === null || revenueData === void 0 ? void 0 : revenueData.sales_volume) || 0).toLocaleString(), showDollarSign: true, description: t('analyticsAnalyticsMonetizationStats.totalRevenueDescription') }), jsx(StatCard, { loading: isLoadingRevenue, title: t('analyticsAnalyticsMonetizationStats.totalSales'), value: (_a = revenueData === null || revenueData === void 0 ? void 0 : revenueData.sales_count) !== null && _a !== void 0 ? _a : 0, description: t('analyticsAnalyticsMonetizationStats.totalSalesDescription') }), jsx(StatCard, { loading: isLoadingPaywalls, title: t('analyticsAnalyticsMonetizationStats.activePaywalls'), value: (_b = paywallsData === null || paywallsData === void 0 ? void 0 : paywallsData.count) !== null && _b !== void 0 ? _b : 0, description: t('analyticsAnalyticsMonetizationStats.activePaywallsDescription') }), jsx(StatCard, { loading: isLoadingSubscribers, title: t('analyticsAnalyticsMonetizationStats.totalSubscribers'), value: (_c = subscribersData === null || subscribersData === void 0 ? void 0 : subscribersData.count) !== null && _c !== void 0 ? _c : 0, description: t('analyticsAnalyticsMonetizationStats.totalSubscribersDescription') })] }), jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-5", children: [jsx(Card$1, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsMonetizationStats.subscriptionStatusChartCardAriaLabel'), children: [jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex items-center gap-1", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsMonetizationStats.subscribersByStatus') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsMonetizationStats.subscribersByStatus'), description: t('analyticsAnalyticsMonetizationStats.subscribersByStatusDescription') })] }) }), jsx("div", { className: "w-full", style: { height: '350px' }, children: jsx(ChartContainer, { title: t('analyticsAnalyticsMonetizationStats.subscribersByStatus'), config: {
234753
235784
  value: {
234754
235785
  label: t('analyticsAnalyticsMonetizationStats.subscribersLabel'),
234755
235786
  color: '#38A1E5',
@@ -234763,7 +235794,7 @@ function AnalyticsMonetizationStats({ tenantKey }) {
234763
235794
  return null;
234764
235795
  const data = (_a = payload[0]) === null || _a === void 0 ? void 0 : _a.payload;
234765
235796
  return (jsxs("div", { className: "bg-background border border-border rounded-md p-3 shadow-lg z-50", style: { borderColor: 'oklch(.922 0 0)' }, role: "tooltip", tabIndex: -1, children: [jsx("div", { className: "font-medium text-foreground mb-2 text-base capitalize", children: data === null || data === void 0 ? void 0 : data.name }), jsx("div", { className: "space-y-2 text-sm", children: jsxs("div", { className: "flex justify-between items-center gap-4", children: [jsx("span", { className: "text-muted-foreground", children: t('analyticsAnalyticsMonetizationStats.subscribersTooltipLabel') }), jsx("span", { className: "font-medium text-foreground", children: data === null || data === void 0 ? void 0 : data.value })] }) })] }));
234766
- }, wrapperStyle: { outline: 'none' } })] })) : (jsx(EmptyStats, {})) }) }) })] }) }), jsx(Card, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsMonetizationStats.paywallItemTypeChartCardAriaLabel'), children: [jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex items-center gap-1", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsMonetizationStats.paywallsByType') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsMonetizationStats.paywallsByType'), description: t('analyticsAnalyticsMonetizationStats.paywallsByTypeDescription') })] }) }), jsx("div", { className: "w-full", style: { height: '350px' }, children: jsx(ChartContainer, { title: t('analyticsAnalyticsMonetizationStats.paywallsByType'), config: {
235797
+ }, wrapperStyle: { outline: 'none' } })] })) : (jsx(EmptyStats, {})) }) }) })] }) }), jsx(Card$1, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsMonetizationStats.paywallItemTypeChartCardAriaLabel'), children: [jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex items-center gap-1", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsMonetizationStats.paywallsByType') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsMonetizationStats.paywallsByType'), description: t('analyticsAnalyticsMonetizationStats.paywallsByTypeDescription') })] }) }), jsx("div", { className: "w-full", style: { height: '350px' }, children: jsx(ChartContainer, { title: t('analyticsAnalyticsMonetizationStats.paywallsByType'), config: {
234767
235798
  value: {
234768
235799
  label: t('analyticsAnalyticsMonetizationStats.paywallsLabel'),
234769
235800
  color: '#38A1E5',
@@ -234777,7 +235808,7 @@ function AnalyticsMonetizationStats({ tenantKey }) {
234777
235808
  return null;
234778
235809
  const data = (_a = payload[0]) === null || _a === void 0 ? void 0 : _a.payload;
234779
235810
  return (jsxs("div", { className: "bg-background border border-border rounded-md p-3 shadow-lg z-50", style: { borderColor: 'oklch(.922 0 0)' }, role: "tooltip", tabIndex: -1, children: [jsx("div", { className: "font-medium text-foreground mb-2 text-base capitalize", children: data === null || data === void 0 ? void 0 : data.name }), jsx("div", { className: "space-y-2 text-sm", children: jsxs("div", { className: "flex justify-between items-center gap-4", children: [jsx("span", { className: "text-muted-foreground", children: t('analyticsAnalyticsMonetizationStats.paywallsTooltipLabel') }), jsx("span", { className: "font-medium text-foreground", children: data === null || data === void 0 ? void 0 : data.value })] }) })] }));
234780
- }, wrapperStyle: { outline: 'none' } })] })) : (jsx(EmptyStats, {})) }) }) })] }) })] }), jsx(Card, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsMonetizationStats.subscribersTableCardAriaLabel'), children: [jsx("div", { className: "mb-4", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { className: "flex items-center gap-1", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsMonetizationStats.subscribersSectionHeading', {
235811
+ }, wrapperStyle: { outline: 'none' } })] })) : (jsx(EmptyStats, {})) }) }) })] }) })] }), jsx(Card$1, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsMonetizationStats.subscribersTableCardAriaLabel'), children: [jsx("div", { className: "mb-4", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { className: "flex items-center gap-1", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsMonetizationStats.subscribersSectionHeading', {
234781
235812
  count: (_d = subscribersData === null || subscribersData === void 0 ? void 0 : subscribersData.count) !== null && _d !== void 0 ? _d : 0,
234782
235813
  }) }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsMonetizationStats.subscribersSectionHeading', {
234783
235814
  count: (_e = subscribersData === null || subscribersData === void 0 ? void 0 : subscribersData.count) !== null && _e !== void 0 ? _e : 0,
@@ -234795,7 +235826,7 @@ function AnalyticsMonetizationStats({ tenantKey }) {
234795
235826
  plural: subscribersData.count !== 1 ? 's' : '',
234796
235827
  }) }), jsxs("div", { className: "flex items-center space-x-2", children: [jsx(Button$1, { variant: "outline", size: "sm", className: "h-8 text-xs", disabled: subscribersData.previous_page === null, onClick: () => subscribersData.previous_page !== null &&
234797
235828
  setSubscriberPage(subscribersData.previous_page), children: t('analyticsAnalyticsMonetizationStats.previous') }), jsx("span", { className: "text-xs text-gray-500", children: t('analyticsAnalyticsMonetizationStats.pageLabel', { page: subscriberPage }) }), jsx(Button$1, { variant: "outline", size: "sm", className: "h-8 text-xs", disabled: subscribersData.next_page === null, onClick: () => subscribersData.next_page !== null &&
234798
- setSubscriberPage(subscribersData.next_page), children: t('analyticsAnalyticsMonetizationStats.next') })] })] }))] }) }), jsx(Card, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsMonetizationStats.paywallsTableCardAriaLabel'), children: [jsx("div", { className: "mb-4", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { className: "flex items-center gap-1", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsMonetizationStats.configuredPaywalls', {
235829
+ setSubscriberPage(subscribersData.next_page), children: t('analyticsAnalyticsMonetizationStats.next') })] })] }))] }) }), jsx(Card$1, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsMonetizationStats.paywallsTableCardAriaLabel'), children: [jsx("div", { className: "mb-4", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { className: "flex items-center gap-1", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsMonetizationStats.configuredPaywalls', {
234799
235830
  count: (_j = paywallsData === null || paywallsData === void 0 ? void 0 : paywallsData.count) !== null && _j !== void 0 ? _j : 0,
234800
235831
  }) }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsMonetizationStats.configuredPaywalls', {
234801
235832
  count: (_k = paywallsData === null || paywallsData === void 0 ? void 0 : paywallsData.count) !== null && _k !== void 0 ? _k : 0,
@@ -235318,7 +236349,7 @@ function AnalyticsPlatformAuditLog({ platformKey, timezone, currentSPA, }) {
235318
236349
  // a permissions answer, not a failure, so it replaces the whole view rather
235319
236350
  // than showing an error next to unusable filters.
235320
236351
  if (isForbidden) {
235321
- return (jsx(Card, { className: "rounded-lg border border-gray-100 bg-white shadow-sm", children: jsxs(CardContent, { className: "p-8 text-center", children: [jsx("p", { className: "font-medium text-gray-700", children: t('analyticsAnalyticsPlatformAuditLog.forbiddenTitle') }), jsx("p", { className: "mt-1 text-sm text-gray-500", children: t('analyticsAnalyticsPlatformAuditLog.forbiddenBody') })] }) }));
236352
+ return (jsx(Card$1, { className: "rounded-lg border border-gray-100 bg-white shadow-sm", children: jsxs(CardContent, { className: "p-8 text-center", children: [jsx("p", { className: "font-medium text-gray-700", children: t('analyticsAnalyticsPlatformAuditLog.forbiddenTitle') }), jsx("p", { className: "mt-1 text-sm text-gray-500", children: t('analyticsAnalyticsPlatformAuditLog.forbiddenBody') })] }) }));
235322
236353
  }
235323
236354
  const results = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
235324
236355
  const hasError = Boolean(error);
@@ -235515,7 +236546,7 @@ function AgentAuditLogView({ tenantKey, mentorId, userId, selectedMentorId, curr
235515
236546
  }, [data === null || data === void 0 ? void 0 : data.results]);
235516
236547
  const is403 = error && 'status' in error && error.status === 403;
235517
236548
  if (is403) {
235518
- return (jsx(Card, { className: "bg-white rounded-lg border border-gray-100 shadow-sm", children: jsx(CardContent, { className: "p-8 text-center", children: jsx("p", { className: "text-gray-500", children: t('analyticsAnalyticsAuditLogStats.noPermission') }) }) }));
236549
+ return (jsx(Card$1, { className: "bg-white rounded-lg border border-gray-100 shadow-sm", children: jsx(CardContent, { className: "p-8 text-center", children: jsx("p", { className: "text-gray-500", children: t('analyticsAnalyticsAuditLogStats.noPermission') }) }) }));
235519
236550
  }
235520
236551
  return (jsxs("div", { className: "space-y-6", children: [jsx("div", { className: "border border-[oklch(0.922_0_0)] rounded-lg p-4 bg-white", children: jsxs("div", { className: "flex flex-col lg:flex-row gap-3", children: [jsx("div", { className: "relative flex-1 min-w-[200px]", children: jsxs(Popover, { open: actorOpen, onOpenChange: setActorOpen, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", role: "combobox", "aria-expanded": actorOpen, "aria-label": t('analyticsAnalyticsAuditLogStats.searchForUser'), className: "w-full justify-between font-normal bg-white h-9", children: [actorFilter || t('analyticsAnalyticsAuditLogStats.searchForUser'), jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), jsx(PopoverContent, { className: "w-full p-0", align: "start", portalled: false, children: jsxs(Command, { children: [jsx(CommandInput, { placeholder: t('analyticsAnalyticsAuditLogStats.searchUserPlaceholder') }), jsxs(CommandList, { children: [jsx(CommandEmpty, { children: t('analyticsAnalyticsAuditLogStats.noUsersFound') }), jsxs(CommandGroup, { children: [jsxs(CommandItem, { value: "", onSelect: () => {
235521
236552
  setActorFilter('');
@@ -235533,7 +236564,10 @@ function AgentAuditLogView({ tenantKey, mentorId, userId, selectedMentorId, curr
235533
236564
  }, numberOfMonths: 2 }) })] }), jsx("div", { className: "min-w-[160px]", children: jsxs(Select$1, { value: actionFilter !== undefined ? String(actionFilter) : 'all', onValueChange: (val) => {
235534
236565
  setActionFilter(val === 'all' ? undefined : Number(val));
235535
236566
  setPage(1);
235536
- }, children: [jsx(SelectTrigger, { className: "w-full font-normal bg-white h-9", children: jsx(SelectValue, { placeholder: t('analyticsAnalyticsAuditLogStats.allActions') }) }), jsx(SelectContent, { children: ACTION_FILTER_OPTIONS.map((opt) => (jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value))) })] }) })] }) }), jsx("div", { className: "overflow-hidden rounded-md border border-[oklch(0.922_0_0)] bg-white", children: jsx("div", { className: "overflow-x-auto", children: jsx("div", { className: "inline-block min-w-full align-middle", children: isLoading ? (jsx("div", { className: "flex items-center justify-center w-full py-10", children: jsx("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-blue-600 border-t-transparent" }) })) : error && !is403 ? (jsx("div", { className: "py-8 text-center text-[#646464]", children: t('analyticsAnalyticsAuditLogStats.loadError') })) : !((_a = data === null || data === void 0 ? void 0 : data.results) === null || _a === void 0 ? void 0 : _a.length) ? (jsx("div", { className: "h-[120px]", children: jsx(EmptyStats, { title: t('analyticsAnalyticsAuditLogStats.noEntries') }) })) : (jsxs(Table, { className: "min-w-full", children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "bg-muted/50 border-b border-[oklch(0.922_0_0)]", children: [jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('analyticsAnalyticsAuditLogStats.colUser') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('analyticsAnalyticsAuditLogStats.colAction') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('analyticsAnalyticsAuditLogStats.colTime') })] }) }), jsx(TableBody, { children: data.results.map((entry) => (jsxs(TableRow, { className: "border-b border-[oklch(0.922_0_0)] last:border-0", children: [jsx(TableCell, { className: "p-3 font-medium whitespace-nowrap text-[#646464]", children: jsx(UserProfileLink, { tenantKey: tenantKey, currentSPA: currentSPA, username: entry.actor_username, display: entry.actor_email || entry.actor_username }) }), jsx(TableCell, { className: "min-w-[250px] p-3 text-[#646464]", children: summarizeChanges(entry) }), jsx(TableCell, { className: "p-3 whitespace-nowrap text-[#646464]", children: formatDistanceToNow(new Date(entry.timestamp), { addSuffix: true }) })] }, entry.id))) })] })) }) }) }), jsx(IblPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isLoading })] }));
236567
+ }, children: [jsx(SelectTrigger, { className: "w-full font-normal bg-white h-9", children: jsx(SelectValue, { placeholder: t('analyticsAnalyticsAuditLogStats.allActions') }) }), jsx(SelectContent, { children: ACTION_FILTER_OPTIONS.map((opt) => (jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value))) })] }) })] }) }), jsx("div", { className: "overflow-hidden rounded-md border border-[oklch(0.922_0_0)] bg-white", children: jsx("div", { className: "overflow-x-auto", children: jsx("div", { className: "inline-block min-w-full align-middle", children: isLoading ? (jsx("div", { className: "flex items-center justify-center w-full py-10", children: jsx("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-blue-600 border-t-transparent" }) })) : error && !is403 ? (jsx("div", { className: "py-8 text-center text-[#646464]", children: t('analyticsAnalyticsAuditLogStats.loadError') })) : !((_a = data === null || data === void 0 ? void 0 : data.results) === null || _a === void 0 ? void 0 : _a.length) ? (jsx("div", { className: "h-[120px]", children: jsx(EmptyStats, { title: t('analyticsAnalyticsAuditLogStats.noEntries') }) })) : (jsxs(Table, { className: "min-w-full", children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "bg-muted/50 border-b border-[oklch(0.922_0_0)]", children: [jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('analyticsAnalyticsAuditLogStats.colUser') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('analyticsAnalyticsAuditLogStats.colAction') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('analyticsAnalyticsAuditLogStats.colTime') })] }) }), jsx(TableBody, { children: data.results.map((entry) => (jsxs(TableRow, { className: "border-b border-[oklch(0.922_0_0)] last:border-0", children: [jsx(TableCell, { className: "p-3 font-medium whitespace-nowrap text-[#646464]", children: jsx(UserProfileLink, { tenantKey: tenantKey, currentSPA: currentSPA, username: entry.actor_username, display: resolveUserIdentity({
236568
+ email: entry.actor_email,
236569
+ username: entry.actor_username,
236570
+ }).label }) }), jsx(TableCell, { className: "min-w-[250px] p-3 text-[#646464]", children: summarizeChanges(entry) }), jsx(TableCell, { className: "p-3 whitespace-nowrap text-[#646464]", children: formatDistanceToNow(new Date(entry.timestamp), { addSuffix: true }) })] }, entry.id))) })] })) }) }) }), jsx(IblPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isLoading })] }));
235537
236571
  }
235538
236572
  function AnalyticsAuditLogStats({ tenantKey, currentSPA, mentorId, userId, selectedMentorId, defaultScope = 'agent', timezone, canViewPlatformAudit, }) {
235539
236573
  const t = useT();
@@ -235580,7 +236614,7 @@ function toRowFromMentorMemory(memory) {
235580
236614
  content: memory.content,
235581
236615
  categoryName: (_b = (_a = memory.category) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : null,
235582
236616
  categorySlug: (_d = (_c = memory.category) === null || _c === void 0 ? void 0 : _c.slug) !== null && _d !== void 0 ? _d : null,
235583
- learner: memory.email || memory.username,
236617
+ learner: resolveUserIdentity(memory).label,
235584
236618
  username: memory.username,
235585
236619
  email: memory.email || null,
235586
236620
  mentorId: (_e = memory.mentor_id) !== null && _e !== void 0 ? _e : null,
@@ -235730,7 +236764,7 @@ const useMemory = ({ tenantKey, userId, mentorId, myMemory = false, }) => {
235730
236764
  let totalMemories = 0;
235731
236765
  const categories = groups.map((group) => {
235732
236766
  group.memories.forEach((memory) => {
235733
- learners.add(memory.email || memory.username);
236767
+ learners.add(resolveUserIdentity(memory).label);
235734
236768
  if (memory.is_auto_generated)
235735
236769
  autoCaptured += 1;
235736
236770
  });
@@ -235839,7 +236873,7 @@ function AnalyticsMemoryStats({ tenantKey, mentorId, userId, selectedMentorId, m
235839
236873
  // themselves are that agent's — see `useMemory`.
235840
236874
  const showCategoryFilter = scope === 'mentor' && categories.length > 0;
235841
236875
  if (isForbidden) {
235842
- return (jsx(Card, { className: "rounded-lg border border-gray-100 bg-white shadow-sm", children: jsx(CardContent, { className: "p-8 text-center", children: jsx("p", { className: "text-gray-500", children: t('analyticsAnalyticsMemoryStats.noPermission') }) }) }));
236876
+ return (jsx(Card$1, { className: "rounded-lg border border-gray-100 bg-white shadow-sm", children: jsx(CardContent, { className: "p-8 text-center", children: jsx("p", { className: "text-gray-500", children: t('analyticsAnalyticsMemoryStats.noPermission') }) }) }));
235843
236877
  }
235844
236878
  return (jsxs("div", { className: "space-y-6", children: [jsx("div", { className: "rounded-lg border border-[oklch(0.922_0_0)] bg-white p-4", children: jsxs("div", { className: "flex flex-col gap-3 lg:flex-row", children: [jsx("div", { className: "min-w-[160px]", children: jsxs(Select$1, { value: scope, onValueChange: (value) => setScope(value), children: [jsx(SelectTrigger, { className: "h-9 w-full bg-white font-normal", "aria-label": t('analyticsAnalyticsMemoryStats.scopeLabel'), children: jsx(SelectValue, {}) }), jsx(SelectContent, { children: availableScopes.map((value) => (jsx(SelectItem, { value: value, children: scopeLabels[value] }, value))) })] }) }), jsx("div", { className: "min-w-[200px] flex-1", children: jsx(UserFilterSelect, { tenantKey: tenantKey, currentUsername: userId, value: learnerFilter, onChange: setLearnerFilter }) }), scope === 'global' && (jsx("form", { className: "min-w-[180px] flex-1", onSubmit: (event) => {
235845
236879
  event.preventDefault();
@@ -240404,7 +241438,7 @@ function AppleRestrictionModal({ isOpen, onClose }) {
240404
241438
 
240405
241439
  function Version({ appName, appVersion, poweredBy, }) {
240406
241440
  const t = useT();
240407
- return (jsx("div", { className: "min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-500 to-blue-200 p-4", children: jsx(Card, { className: "w-full max-w-md shadow-xl rounded-2xl border border-gray-300", children: jsxs(CardContent, { className: "p-6 text-center items-center", children: [jsxs("div", { className: "flex items-center justify-center gap-2 text-gray-700", children: [jsx(Terminal, { className: "w-6 h-6 text-primary" }), jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: t('version.appTitle', { appName }) })] }), jsx(Separator, { className: "my-4" }), jsx("p", { className: "text-sm text-muted-foreground mb-2", children: t('version.currentVersion') }), jsx(Badge, { className: "text-base px-4 py-1 hover:bg-green-700 hover:text-white rounded-full bg-green-100 text-green-700", children: appVersion }), jsx("div", { className: "w-full text-center mt-auto py-4", children: jsx("div", { className: "flex items-end justify-center text-sm text-gray-500", children: jsxs("span", { className: "flex items-end h-6 text-xs", children: [t('version.poweredBy'), poweredBy, t('version.inNewYork')] }) }) })] }) }) }));
241441
+ return (jsx("div", { className: "min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-500 to-blue-200 p-4", children: jsx(Card$1, { className: "w-full max-w-md shadow-xl rounded-2xl border border-gray-300", children: jsxs(CardContent, { className: "p-6 text-center items-center", children: [jsxs("div", { className: "flex items-center justify-center gap-2 text-gray-700", children: [jsx(Terminal, { className: "w-6 h-6 text-primary" }), jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: t('version.appTitle', { appName }) })] }), jsx(Separator, { className: "my-4" }), jsx("p", { className: "text-sm text-muted-foreground mb-2", children: t('version.currentVersion') }), jsx(Badge, { className: "text-base px-4 py-1 hover:bg-green-700 hover:text-white rounded-full bg-green-100 text-green-700", children: appVersion }), jsx("div", { className: "w-full text-center mt-auto py-4", children: jsx("div", { className: "flex items-end justify-center text-sm text-gray-500", children: jsxs("span", { className: "flex items-end h-6 text-xs", children: [t('version.poweredBy'), poweredBy, t('version.inNewYork')] }) }) })] }) }) }));
240408
241442
  }
240409
241443
 
240410
241444
  const iconMap = {
@@ -240989,7 +242023,7 @@ function ProjectsPage({ tenantKey, username, onOpenProject, navigateToMentorInPr
240989
242023
  if (error) {
240990
242024
  return (jsx("div", { className: "flex h-full items-center justify-center", children: jsxs("div", { className: "text-center", children: [jsx(CircleAlert, { className: "mx-auto mb-4 h-12 w-12 text-red-500" }), jsx("p", { className: "text-gray-600", children: t('projectsProjectsPage.failedToLoadProjects') })] }) }));
240991
242025
  }
240992
- return (jsxs("div", { className: "flex h-full overflow-hidden", children: [jsx("div", { className: "scrollbar-hide flex-1 overflow-y-auto", children: jsxs("div", { className: "mx-auto max-w-[920px] px-3 py-6 md:px-6 md:py-8", children: [jsxs("div", { className: "mb-6", children: [jsx("h1", { className: "mb-2 text-2xl font-semibold text-gray-700", children: t('projectsProjectsPage.heading') }), jsx("p", { className: "text-sm text-gray-600", children: t('projectsProjectsPage.subheading') })] }), jsxs("div", { className: "mb-6 flex flex-col gap-4 sm:flex-row", children: [jsxs("div", { className: "relative flex-1", children: [jsx(Search, { className: "absolute top-1/2 left-4 h-5 w-5 -translate-y-1/2 transform text-gray-400" }), jsx(Input, { placeholder: t('projectsProjectsPage.searchPlaceholder'), value: searchValue, onChange: (e) => setSearchValue(e.target.value), className: `w-full rounded-lg border-gray-300 py-3 pl-12 text-base focus:border-blue-500 focus:ring-2 focus:ring-blue-500 ${isSearching ? 'pr-11' : 'pr-4'}` }), isSearching && (jsx(LoaderCircle, { role: "status", "aria-label": t('projectsProjectsPage.searching'), className: "absolute top-1/2 right-4 h-5 w-5 -translate-y-1/2 transform animate-spin text-blue-500" }))] }), jsxs(Button$1, { className: "rounded-lg bg-gradient-to-r from-[#38A1E5] to-[#7284FF] px-6 py-3 whitespace-nowrap text-white hover:from-[#2E8BD1] hover:to-[#5F6FE8]", onClick: () => executeWithTrialCheck(() => setIsCreateModalOpen(true)), children: [jsx(Plus, { className: "mr-2 h-5 w-5" }), t('projectsProjectsPage.newProject')] })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-12", children: jsx(LoaderCircle, { className: "h-8 w-8 animate-spin text-gray-400" }) })) : (jsxs(Fragment$1, { children: [jsx("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2", children: projects.map((project) => (jsx(Card, { className: "cursor-pointer rounded-lg border border-[#D0E0FF] bg-[#F5F8FF] transition-shadow hover:shadow-md", onClick: () => executeWithTrialCheck(() => onOpenProject(project)), children: jsxs(CardContent, { className: "p-6", children: [jsxs("div", { className: "mb-3 flex items-start justify-between gap-2", children: [jsx("h3", { className: "text-base font-semibold text-gray-900", children: project.name }), jsxs(DropdownMenu, { modal: false, children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsx(Button$1, { variant: "ghost", size: "icon", className: "h-7 w-7 flex-shrink-0 text-gray-500 hover:bg-[#c9d8f8]", "aria-label": t('projectsProjectsPage.projectActions'), onClick: (e) => e.stopPropagation(), children: jsx(EllipsisVertical, { className: "h-4 w-4" }) }) }), jsxs(DropdownMenuContent, { align: "end", onClick: (e) => e.stopPropagation(), children: [jsxs(DropdownMenuItem, { onClick: (e) => {
242026
+ return (jsxs("div", { className: "flex h-full overflow-hidden", children: [jsx("div", { className: "scrollbar-hide flex-1 overflow-y-auto", children: jsxs("div", { className: "mx-auto max-w-[920px] px-3 py-6 md:px-6 md:py-8", children: [jsxs("div", { className: "mb-6", children: [jsx("h1", { className: "mb-2 text-2xl font-semibold text-gray-700", children: t('projectsProjectsPage.heading') }), jsx("p", { className: "text-sm text-gray-600", children: t('projectsProjectsPage.subheading') })] }), jsxs("div", { className: "mb-6 flex flex-col gap-4 sm:flex-row", children: [jsxs("div", { className: "relative flex-1", children: [jsx(Search, { className: "absolute top-1/2 left-4 h-5 w-5 -translate-y-1/2 transform text-gray-400" }), jsx(Input, { placeholder: t('projectsProjectsPage.searchPlaceholder'), value: searchValue, onChange: (e) => setSearchValue(e.target.value), className: `w-full rounded-lg border-gray-300 py-3 pl-12 text-base focus:border-blue-500 focus:ring-2 focus:ring-blue-500 ${isSearching ? 'pr-11' : 'pr-4'}` }), isSearching && (jsx(LoaderCircle, { role: "status", "aria-label": t('projectsProjectsPage.searching'), className: "absolute top-1/2 right-4 h-5 w-5 -translate-y-1/2 transform animate-spin text-blue-500" }))] }), jsxs(Button$1, { className: "rounded-lg bg-gradient-to-r from-[#38A1E5] to-[#7284FF] px-6 py-3 whitespace-nowrap text-white hover:from-[#2E8BD1] hover:to-[#5F6FE8]", onClick: () => executeWithTrialCheck(() => setIsCreateModalOpen(true)), children: [jsx(Plus, { className: "mr-2 h-5 w-5" }), t('projectsProjectsPage.newProject')] })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-12", children: jsx(LoaderCircle, { className: "h-8 w-8 animate-spin text-gray-400" }) })) : (jsxs(Fragment$1, { children: [jsx("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2", children: projects.map((project) => (jsx(Card$1, { className: "cursor-pointer rounded-lg border border-[#D0E0FF] bg-[#F5F8FF] transition-shadow hover:shadow-md", onClick: () => executeWithTrialCheck(() => onOpenProject(project)), children: jsxs(CardContent, { className: "p-6", children: [jsxs("div", { className: "mb-3 flex items-start justify-between gap-2", children: [jsx("h3", { className: "text-base font-semibold text-gray-900", children: project.name }), jsxs(DropdownMenu, { modal: false, children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsx(Button$1, { variant: "ghost", size: "icon", className: "h-7 w-7 flex-shrink-0 text-gray-500 hover:bg-[#c9d8f8]", "aria-label": t('projectsProjectsPage.projectActions'), onClick: (e) => e.stopPropagation(), children: jsx(EllipsisVertical, { className: "h-4 w-4" }) }) }), jsxs(DropdownMenuContent, { align: "end", onClick: (e) => e.stopPropagation(), children: [jsxs(DropdownMenuItem, { onClick: (e) => {
240993
242027
  e.stopPropagation();
240994
242028
  executeWithTrialCheck(() => handleRenameProject(String(project.id), project.name));
240995
242029
  }, children: [jsx(Pencil, { className: "mr-2 h-4 w-4" }), t('projectsProjectsPage.rename')] }), jsxs(DropdownMenuItem, { onClick: (e) => {
@@ -243779,7 +244813,7 @@ function useWebsiteCrawlerResource(resource) {
243779
244813
  function WebsiteCrawlModal({ resource }) {
243780
244814
  const t = useT();
243781
244815
  const { form, handleCheckUrlIsValid, crawlerMatchPatterns, setCrawlerMatchPatterns } = useWebsiteCrawlerResource(resource);
243782
- return (jsxs(Card, { className: "mx-auto w-full max-w-2xl", role: "dialog", "aria-labelledby": "crawler-title", "aria-describedby": "crawler-description", children: [jsxs(CardHeader, { children: [jsx(CardTitle, { id: "crawler-title", className: "text-md font-semibold text-gray-600", children: t('resourceModalWebsiteCrawlModal.title') }), jsx("p", { id: "crawler-description", className: "text-muted-foreground text-sm", children: t('resourceModalWebsiteCrawlModal.description') })] }), jsx(CardContent, { children: jsx("form", { className: "space-y-4", onSubmit: (e) => {
244816
+ return (jsxs(Card$1, { className: "mx-auto w-full max-w-2xl", role: "dialog", "aria-labelledby": "crawler-title", "aria-describedby": "crawler-description", children: [jsxs(CardHeader, { children: [jsx(CardTitle, { id: "crawler-title", className: "text-md font-semibold text-gray-600", children: t('resourceModalWebsiteCrawlModal.title') }), jsx("p", { id: "crawler-description", className: "text-muted-foreground text-sm", children: t('resourceModalWebsiteCrawlModal.description') })] }), jsx(CardContent, { children: jsx("form", { className: "space-y-4", onSubmit: (e) => {
243783
244817
  e.preventDefault();
243784
244818
  e.stopPropagation();
243785
244819
  form.handleSubmit();
@@ -247006,7 +248040,7 @@ function PromptCard({ prompt, onEdit, onSelect, title, tenantKey, userIsStudent
247006
248040
  onSelect(prompt.prompt);
247007
248041
  }
247008
248042
  };
247009
- return (jsxs(Fragment$1, { children: [jsx(Card, { className: "overflow-hidden border-0 bg-[#F8F8F8] transition-shadow hover:shadow-md", children: jsxs(CardContent, { className: "h-full p-4", children: [jsxs("div", { className: "mb-5 flex flex-1 items-start gap-2", children: [jsx(MessageSquare, { className: "mt-1 h-4 w-4 flex-shrink-0 text-gray-400" }), jsxs("div", { className: "flex-1", children: [jsx("h3", { className: "text-sm font-medium text-gray-600", children: title }), jsx(Markdown, { className: "mt-1 line-clamp-4 text-sm text-gray-500", children: parsePrompt(prompt.prompt) })] })] }), jsxs("div", { className: "flex flex-wrap justify-start gap-2", children: [!userIsStudent && (jsxs(Button$1, { variant: "outline", size: "sm", className: "flex h-7 items-center border-gray-200 px-3 text-xs font-normal text-gray-600", onClick: handleEdit, disabled: isDeleting, children: [jsx(SquarePen, { className: "mr-1.5 h-3 w-3" }), t('promptGalleryModalPromptCard.edit')] })), jsxs(Button$1, { variant: "outline", size: "sm", className: "flex h-7 items-center border-gray-200 px-3 text-xs font-normal text-gray-600", onClick: () => executeWithTrialCheck(handleRun), disabled: isDeleting, children: [jsx(Play, { className: "mr-1.5 h-3 w-3" }), t('promptGalleryModalPromptCard.run')] }), jsx(Button$1, { variant: "outline", size: "sm", className: "flex h-7 items-center border-gray-200 px-3 text-xs font-normal text-gray-600", onClick: () => copy(prompt.prompt), disabled: isDeleting, children: status === 'success' ? (jsxs(Fragment$1, { children: [jsx(Check, { className: "mr-1.5 h-3 w-3" }), " ", t('promptGalleryModalPromptCard.copied')] })) : (jsxs(Fragment$1, { children: [jsx(Copy, { className: "mr-1.5 h-3 w-3" }), " ", t('promptGalleryModalPromptCard.copy')] })) }), !userIsStudent && (jsxs(Button$1, { variant: "outline", size: "sm", className: "flex h-7 items-center border-gray-200 px-3 text-xs font-normal text-gray-600 hover:text-gray-600", onClick: () => executeWithTrialCheck(handleDelete), disabled: isDeleting, children: [jsx(DeleteIcon, { className: cn('mr-1.5 h-3 w-3', isDeleting && 'animate-spin') }), t('promptGalleryModalPromptCard.delete')] }))] })] }) }), isModalOpen && FreeTrialDialog && (jsx(FreeTrialDialog, { onClose: closeModal, isOpen: isModalOpen }))] }));
248043
+ return (jsxs(Fragment$1, { children: [jsx(Card$1, { className: "overflow-hidden border-0 bg-[#F8F8F8] transition-shadow hover:shadow-md", children: jsxs(CardContent, { className: "h-full p-4", children: [jsxs("div", { className: "mb-5 flex flex-1 items-start gap-2", children: [jsx(MessageSquare, { className: "mt-1 h-4 w-4 flex-shrink-0 text-gray-400" }), jsxs("div", { className: "flex-1", children: [jsx("h3", { className: "text-sm font-medium text-gray-600", children: title }), jsx(Markdown, { className: "mt-1 line-clamp-4 text-sm text-gray-500", children: parsePrompt(prompt.prompt) })] })] }), jsxs("div", { className: "flex flex-wrap justify-start gap-2", children: [!userIsStudent && (jsxs(Button$1, { variant: "outline", size: "sm", className: "flex h-7 items-center border-gray-200 px-3 text-xs font-normal text-gray-600", onClick: handleEdit, disabled: isDeleting, children: [jsx(SquarePen, { className: "mr-1.5 h-3 w-3" }), t('promptGalleryModalPromptCard.edit')] })), jsxs(Button$1, { variant: "outline", size: "sm", className: "flex h-7 items-center border-gray-200 px-3 text-xs font-normal text-gray-600", onClick: () => executeWithTrialCheck(handleRun), disabled: isDeleting, children: [jsx(Play, { className: "mr-1.5 h-3 w-3" }), t('promptGalleryModalPromptCard.run')] }), jsx(Button$1, { variant: "outline", size: "sm", className: "flex h-7 items-center border-gray-200 px-3 text-xs font-normal text-gray-600", onClick: () => copy(prompt.prompt), disabled: isDeleting, children: status === 'success' ? (jsxs(Fragment$1, { children: [jsx(Check, { className: "mr-1.5 h-3 w-3" }), " ", t('promptGalleryModalPromptCard.copied')] })) : (jsxs(Fragment$1, { children: [jsx(Copy, { className: "mr-1.5 h-3 w-3" }), " ", t('promptGalleryModalPromptCard.copy')] })) }), !userIsStudent && (jsxs(Button$1, { variant: "outline", size: "sm", className: "flex h-7 items-center border-gray-200 px-3 text-xs font-normal text-gray-600 hover:text-gray-600", onClick: () => executeWithTrialCheck(handleDelete), disabled: isDeleting, children: [jsx(DeleteIcon, { className: cn('mr-1.5 h-3 w-3', isDeleting && 'animate-spin') }), t('promptGalleryModalPromptCard.delete')] }))] })] }) }), isModalOpen && FreeTrialDialog && (jsx(FreeTrialDialog, { onClose: closeModal, isOpen: isModalOpen }))] }));
247010
248044
  }
247011
248045
 
247012
248046
  function EmptyPrompts() {
@@ -247238,5 +248272,5 @@ var trainOrDeleteModal = /*#__PURE__*/Object.freeze({
247238
248272
  TrainOrDeleteModal: TrainOrDeleteModal
247239
248273
  });
247240
248274
 
247241
- export { ACCESS_COURSE_LABEL, ALL_CATEGORIES, AccessTimeHeatmap, AccessiblePaginate, AddMentorToProjectModal, AddSkillDialog, Admin, AdvancedTab, AgentConfigPrompts, AgentScopeLink, AgentSkills, AlertsTab, AnalyticsAgentPicker, AnalyticsAreaChart, AnalyticsAuditLogStats, AnalyticsBarChart, AnalyticsControlBar, AnalyticsCourseDetail, AnalyticsCourses, AnalyticsFinancialStats, AnalyticsGlobalFiltersProvider, AnalyticsLayout, AnalyticsLlmUsageStats, AnalyticsMemoryStats, AnalyticsMonetizationStats, AnalyticsNotice, AnalyticsOverview, AnalyticsPlatformAuditLog, AnalyticsProgramDetail, AnalyticsPrograms, AnalyticsReportDownload, AnalyticsReports, AnalyticsScopeProvider, AnalyticsSettingsProvider, AnalyticsTopicsStats, AnalyticsTraces, AnalyticsTranscriptsStats, AnalyticsUsersStats, AppleRestrictionModal, ApplyWizard, AuditLogChangesView, AuditLogJsonView, BUY_NOW_LABEL, BillingTab, CATALOGS, CHART_ORDINAL_RAMP, CHART_SERIES_COLORS, CHART_SINGLE_SERIES_COLOR, CREATE_AGENT_LABELS, CUA_DRIVER_REPO_URL, CUA_DRIVER_TAURI_COMMANDS, CUA_DRIVER_TAURI_EVENTS, CardInfoIcon, CategorizedDropdownMenu, ChartCardWrapper, ChartFiltersProvider, ChartLoading, ChartTooltipCard, ChatContext, ChatPrivacyToggle, ChatProvider, CompanyDialog, ConnectorManagementDialog, CopyButtonIcon, CourseAccessGuard, CourseCardSkeleton, CourseContentLoading, CourseOutline, CourseOutlineContext, CourseOutlineDrawer, CreateAgentForm, CreateAgentModal, CreateProjectModal, CreateWorkflowModal, CredentialBox, CredentialMiniBoxSkeleton, CredentialsList, CreditBalance, CustomDateRangePicker, CustomTooltip, DEFAULT_COWORK_REQUIRED_SIZE_GB, DEFAULT_LOCALE, DEFAULT_USER_IDENTITY_ORDER, DefaultEmptyBox, DeleteProjectModal, DeleteWorkflowModal, DiscoverContentCard, DiscoverFacetsFilter, DiscoverFilterDrawer, DocumentSidebar, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ENROLL_NOW_COURSE_STARTING_SOON_LABEL, ENROLL_NOW_LABEL, EditAlertDialog, EducationBox, EducationDialog, EducationTab, EdxIframeContext, EmptyStats, ExperienceBox, ExperienceDialog, ExperienceTab, FacetFilterContext, Footer, GradebookTab, GroupsFilterDropdown, INVITATION_ONLY_LABEL, InstitutionDialog, IntegrationsTab, InviteUserContent, InviteUserDialog, InvitedUsersDialog, LOCAL_LLM_CHANGED_EVENT, LOCAL_MODELS, LlmModelBadge, Loader, LocalLLMTab, LocalModelsContent, LoginButton, MACOS_PERMISSIONS_COMMANDS, MEMORY_PAGE_SIZE, Markdown, MemoryAdminTab, MinimumMentorAlert, MonetizationTab, NotificationDisplay, NotificationDropdown, ONBOARDING_FIELD_TYPES, ONBOARDING_SECTORS, OnboardingField, OnboardingShell, OnboardingWizard, PLATFORM_AUDIT_DEEP_PAGING_THRESHOLD, PLATFORM_AUDIT_PAGE_SIZE, PaywallModal, PlacementExam, PlacementExamsDropdown, PlatformAuditLogDetailSheet, PlatformNavbar, PlatformNavbarSearch, Profile, ProfileTimeChart, ProgressDots, ProjectActionButtons, ProjectFilesModal, ProjectInstructionsModal, ProjectLandingPage, ProjectMentorsList, ProjectsPage, REQUEST_ACCESS_COURSE_STARTING_SOON_LABEL, REQUEST_ACCESS_LABEL, RankedBars, RenameProjectModal, ResumeBox, ResumeTab, RetrievedDocumentsButton, RichTextEditor, SERVICE_COLOR_ORDER, SUPPORTED_LOCALES, SandboxConfig, SearchableMultiSelect, SendNotificationDialog, SignupButton, SkeletonActivityStatBox, SkeletonAddSkillsLoading, SkeletonCreatePathwaySearchList, SkeletonDiscoverFilterBox, SkeletonEducationBox, SkeletonMultiplier, SkeletonPathwayBox, SkeletonProfileInfoCard, SkeletonSkillBox, SkillBox, SkillDetailModal, SkillLeaderboardChart, SkillsBox, SkillsList, SlashSkillPicker, SourceChip, Spinner, StatCard, StepHeader, SummerNoteTextEditor, TAURI_COMMANDS, TAURI_EVENTS, TRACES_PAGE_SIZE, TenantSwitcher, TimeFilter, TimeTrackingProvider, TimedExam, ToolCallIndicator, ToolDialogs, TopBanner, TranscriptFileCards, TranscriptRollupBadges, TranscriptTurnDetails, TrendSparkline, USER_ONBOARDING_FORM_SLUG, USER_ONBOARDING_FORM_VERSION, USER_ONBOARDING_SUBMISSION_SLUG, UpgradePackageModal, UserAvatar, UserOnboardingWizard, UserProfileDialog, UserProfileLink, Version, WebContainersI18nProvider, WorkflowSidebar, addBookmarksTab, areChartFiltersEqual, availablePlacementExams, buildOnboardingAgentPath, buildUserOnboardingFormMetadata, buildUserOnboardingSubmissionMetadata, coerceOnboardingAgent, coerceOnboardingAgents, coerceUserOnboardingForm, colorForRank, colorForSeries, conversationDocuments, emptyUserOnboardingForm, findLastResumeBlock, findOnboardingAgent, findSequentialParent, flattenVerticalBlocks, formatAuditTimestamp, formatCompactNumber, formatFileSize, formatLatencySeconds, formatResult, formatTimeZoneLabel, getCatalog, getFirstAvailableUnit, getFriendlyToolName, getLLMModelDisplayName, getLocalLLMModel, getLocalLLMToolSupport, getNextUnitIframe, getOrg, getParentBlockById, getParentsInfosFromSublessonId, getPreviousUnitIframe, getQueryLabel, getRandomCourseImage, getSectorById, getTenant, getUnitToIframe, getUserId, getUserName, granularityForFilter, hasOnboardingContent, humanizeAuditToken, humanizeFieldName, inBrowserPrint, inIframe, inferProviderKeysFromModel, initialCuaDriverInstallState, initialModelDownloadState, isCoworkEnabled, isEmailLike, isFileReference, isLlmUsageForbidden, isLlmUsageUnavailable, isLocalLLMEnabled, isPlatformNavbarCreditBalanceVisible, isSlashCommandToken, isTauriApp, isValidLocale, isValidTimeZone, llmUsageDateArgs, components as markdownComponents, modelSupportsCowork, onboardingPrimaryButtonClass, onboardingSecondaryButtonClass, readUserOnboardingForm, readUserOnboardingSubmission, readUserOnboardingSubmissions, resolveAuditTimeZone, resolveCreateAgentLabels, resolveUserIdentity, sanitizeCss, setCoworkEnabled, setLocalLLMEnabled, setLocalLLMModel, setLocalLLMToolSupport, smallestCoworkModel, summarizeTranscriptTurns, toFileReference, toRetrievedDocuments, toToolCallInfos, useAnalyticsGlobalFilters, useAnalyticsScope, useAnalyticsSettings, useAuditLog, useCatalogSearch, useChartFilters, useChatPrivacy, useChatState, useCourseDetail, useCourseMetadata, useCourses, useCuaDriver, useDiscover, useEdxIframe, useFinancial, useIframeMessageHandler, useLlmDisplayName, useLlmProviderCatalogue, useLlmTraces, useLlmUsage, useLocalStorage, useMemory, useModelDownload, useMonetization, useOverview, usePlatformAuditLabels, usePlatformAuditLog, useProfileActivityStats, useProfileCredentials, useProfilePathways, useProfilePrograms, useProfileSkills, useProfileTimeSpent, usePrograms, useReports, useScopedMentorDbId, useScopedMentorId, useSelectedLocalModel, useSlashSkillPicker, useSlashSkills, useT, useTauri, useTimeTracking, useTopics, useTranscripts, useUserCourses, useUserMetadata, useUsers, useWebContainersI18n, useWebContainersLocale };
248275
+ export { ACCESS_COURSE_LABEL, ALL_CATEGORIES, AccessTimeHeatmap, AccessiblePaginate, AddMentorToProjectModal, AddSkillDialog, Admin, AdvancedTab, AgentConfigPrompts, AgentScopeLink, AgentSkills, AlertsTab, AnalyticsAgentPicker, AnalyticsAreaChart, AnalyticsAuditLogStats, AnalyticsBarChart, AnalyticsControlBar, AnalyticsCourseDetail, AnalyticsCourses, AnalyticsFinancialStats, AnalyticsGlobalFiltersProvider, AnalyticsLayout, AnalyticsLlmUsageStats, AnalyticsMemoryStats, AnalyticsMonetizationStats, AnalyticsNotice, AnalyticsOverview, AnalyticsPlatformAuditLog, AnalyticsProgramDetail, AnalyticsPrograms, AnalyticsReportDownload, AnalyticsReports, AnalyticsScopeProvider, AnalyticsSettingsProvider, AnalyticsTopicsStats, AnalyticsTraces, AnalyticsTranscriptsStats, AnalyticsUsersStats, AppleRestrictionModal, ApplyWizard, AuditLogChangesView, AuditLogJsonView, BUY_NOW_LABEL, BillingTab, CATALOGS, CHART_ORDINAL_RAMP, CHART_SERIES_COLORS, CHART_SINGLE_SERIES_COLOR, CREATE_AGENT_LABELS, CUA_DRIVER_REPO_URL, CUA_DRIVER_TAURI_COMMANDS, CUA_DRIVER_TAURI_EVENTS, CardInfoIcon, CategorizedDropdownMenu, ChartCardWrapper, ChartFiltersProvider, ChartLoading, ChartTooltipCard, ChatContext, ChatPrivacyToggle, ChatProvider, CompanyDialog, ConnectorManagementDialog, CopyButtonIcon, CourseAccessGuard, CourseCardSkeleton, CourseContentLoading, CourseOutline, CourseOutlineContext, CourseOutlineDrawer, CreateAgentForm, CreateAgentModal, CreateProjectModal, CreateWorkflowModal, CredentialBox, CredentialMiniBoxSkeleton, CredentialsList, CreditBalance, CustomDateRangePicker, CustomTooltip, DEFAULT_COWORK_REQUIRED_SIZE_GB, DEFAULT_LOCALE, DEFAULT_USER_IDENTITY_ORDER, DefaultEmptyBox, DeleteProjectModal, DeleteWorkflowModal, DiscoverContentCard, DiscoverFacetsFilter, DiscoverFilterDrawer, DocumentSidebar, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ENROLL_NOW_COURSE_STARTING_SOON_LABEL, ENROLL_NOW_LABEL, EditAlertDialog, EducationBox, EducationDialog, EducationTab, EdxIframeContext, EmptyStats, ExperienceBox, ExperienceDialog, ExperienceTab, FacetFilterContext, Footer, GradebookTab, GroupsFilterDropdown, INVITATION_ONLY_LABEL, InstitutionDialog, IntegrationsTab, InviteUserContent, InviteUserDialog, InvitedUsersDialog, LOCAL_LLM_CHANGED_EVENT, LOCAL_MODELS, LlmModelBadge, Loader, LocalLLMTab, LocalModelsContent, LoginButton, MACOS_PERMISSIONS_COMMANDS, MEMORY_PAGE_SIZE, Markdown, MemoryAdminTab, MinimumMentorAlert, MonetizationTab, NotificationDisplay, NotificationDropdown, ONBOARDING_FIELD_TYPES, ONBOARDING_SECTORS, OnboardingField, OnboardingShell, OnboardingWizard, PLATFORM_AUDIT_DEEP_PAGING_THRESHOLD, PLATFORM_AUDIT_PAGE_SIZE, PaywallModal, PlacementExam, PlacementExamsDropdown, PlatformAuditLogDetailSheet, PlatformNavbar, PlatformNavbarSearch, Profile, ProfileTimeChart, ProgressDots, ProjectActionButtons, ProjectFilesModal, ProjectInstructionsModal, ProjectLandingPage, ProjectMentorsList, ProjectsPage, REQUEST_ACCESS_COURSE_STARTING_SOON_LABEL, REQUEST_ACCESS_LABEL, RankedBars, RenameProjectModal, ResumeBox, ResumeTab, RetrievedDocumentsButton, RichTextEditor, SERVICE_COLOR_ORDER, SUPPORTED_LOCALES, SandboxConfig, SearchableMultiSelect, SendNotificationDialog, SignupButton, SkeletonActivityStatBox, SkeletonAddSkillsLoading, SkeletonCreatePathwaySearchList, SkeletonDiscoverFilterBox, SkeletonEducationBox, SkeletonMultiplier, SkeletonPathwayBox, SkeletonProfileInfoCard, SkeletonSkillBox, SkillBox, SkillDetailModal, SkillLeaderboardChart, SkillsBox, SkillsList, SlashSkillPicker, SourceChip, Spinner, StatCard, StepHeader, SummerNoteTextEditor, TAURI_COMMANDS, TAURI_EVENTS, TRACES_PAGE_SIZE, TenantSwitcher, TimeFilter, TimeTrackingProvider, TimedExam, ToolCallIndicator, ToolDialogs, TopBanner, TranscriptFileCards, TranscriptRollupBadges, TranscriptTurnDetails, TrendSparkline, USER_ONBOARDING_FORM_SLUG, USER_ONBOARDING_FORM_VERSION, USER_ONBOARDING_SUBMISSION_SLUG, UpgradePackageModal, UserAvatar, UserOnboardingWizard, UserProfileDialog, UserProfileLink, Version, WebContainersI18nProvider, WorkflowSidebar, addBookmarksTab, areChartFiltersEqual, availablePlacementExams, buildOnboardingAgentPath, buildUserOnboardingFormMetadata, buildUserOnboardingSubmissionMetadata, coerceOnboardingAgent, coerceOnboardingAgents, coerceUserOnboardingForm, colorForRank, colorForSeries, conversationDocuments, emptyUserOnboardingForm, findLastResumeBlock, findOnboardingAgent, findSequentialParent, flattenVerticalBlocks, formatAuditTimestamp, formatCompactNumber, formatFileSize, formatLatencySeconds, formatResult, formatTimeZoneLabel, getCatalog, getFirstAvailableUnit, getFriendlyToolName, getLLMModelDisplayName, getLocalLLMModel, getLocalLLMToolSupport, getNextUnitIframe, getOrg, getParentBlockById, getParentsInfosFromSublessonId, getPreviousUnitIframe, getQueryLabel, getRandomCourseImage, getSectorById, getTenant, getUnitToIframe, getUserId, getUserName, granularityForFilter, hasDistinctName, hasOnboardingContent, humanizeAuditToken, humanizeFieldName, inBrowserPrint, inIframe, inferProviderKeysFromModel, initialCuaDriverInstallState, initialModelDownloadState, isCoworkEnabled, isEmailLike, isFileReference, isLlmUsageForbidden, isLlmUsageUnavailable, isLocalLLMEnabled, isPlatformNavbarCreditBalanceVisible, isSlashCommandToken, isTauriApp, isValidLocale, isValidTimeZone, llmUsageDateArgs, components as markdownComponents, modelSupportsCowork, onboardingPrimaryButtonClass, onboardingSecondaryButtonClass, readUserOnboardingForm, readUserOnboardingSubmission, readUserOnboardingSubmissions, resolveAuditTimeZone, resolveCreateAgentLabels, resolveUserIdentity, sanitizeCss, setCoworkEnabled, setLocalLLMEnabled, setLocalLLMModel, setLocalLLMToolSupport, smallestCoworkModel, summarizeTranscriptTurns, toFileReference, toRetrievedDocuments, toToolCallInfos, useAnalyticsGlobalFilters, useAnalyticsScope, useAnalyticsSettings, useAuditLog, useCatalogSearch, useChartFilters, useChatPrivacy, useChatState, useCourseDetail, useCourseMetadata, useCourses, useCuaDriver, useDiscover, useEdxIframe, useFinancial, useIframeMessageHandler, useLlmDisplayName, useLlmProviderCatalogue, useLlmTraces, useLlmUsage, useLocalStorage, useMemory, useModelDownload, useMonetization, useOverview, usePlatformAuditLabels, usePlatformAuditLog, useProfileActivityStats, useProfileCredentials, useProfilePathways, useProfilePrograms, useProfileSkills, useProfileTimeSpent, usePrograms, useReports, useScopedMentorDbId, useScopedMentorId, useSelectedLocalModel, useSlashSkillPicker, useSlashSkills, useT, useTauri, useTimeTracking, useTopics, useTranscripts, useUserCourses, useUserMetadata, useUsers, useWebContainersI18n, useWebContainersLocale };
247242
248276
  //# sourceMappingURL=index.esm.js.map