@iblai/iblai-js 1.3.6 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -7,7 +7,7 @@ import Link$2 from 'next/link';
|
|
|
7
7
|
import * as ReactDOM from 'react-dom';
|
|
8
8
|
import ReactDOM__default from 'react-dom';
|
|
9
9
|
import { z as z$1 } from 'zod';
|
|
10
|
-
import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useCreateGlobalMemoryMutation, useGetMemsearchConfigQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, useUpdateTenantMetadataMutation, LOGO_ENDPOINTS, useDeleteApiKeyMutation, useGetApiKeysQuery, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, 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, useUpdateMemsearchConfigMutation, useGetCustomMentorsQuery, useCreateSessionIdMutation } from '@iblai/data-layer';
|
|
10
|
+
import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useCreateGlobalMemoryMutation, useGetMemsearchConfigQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, useUpdateTenantMetadataMutation, LOGO_ENDPOINTS, useDeleteApiKeyMutation, useGetApiKeysQuery, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, 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, useUpdateMemsearchConfigMutation, useGetCustomMentorsQuery, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useDisablePaywallMutation, useListPaywallsQuery, useGetAiSearchMentorsQuery, useCreateSessionIdMutation } from '@iblai/data-layer';
|
|
11
11
|
import { toast, Toaster as Toaster$1 } from 'sonner';
|
|
12
12
|
import { getInitials, useTenantMetadata, isAlphaNumeric32, checkRbacPermission, WithPermissions, useTenantContext, CHAT_AREA_SIZE, TimeTracker, advancedTabsProperties, defaultSessionIds, chatActions } from '@iblai/web-utils';
|
|
13
13
|
import '@iblai/iblai-api';
|
|
@@ -81631,6 +81631,152 @@ function ResumeTab({ org, username }) {
|
|
|
81631
81631
|
return (jsxs("div", { className: "space-y-1", children: [jsx("div", { className: "flex items-center justify-end", children: jsx("input", { ref: fileInputRef, type: "file", accept: "application/pdf", className: "hidden", onChange: handleFileChange }) }), !isLoading && (isError || !resumeUrl) && (jsxs("div", { className: "flex flex-col items-center justify-center rounded-lg border border-dashed border-gray-300 bg-gray-50 p-8 text-center", children: [jsx("h3", { className: "text-base font-semibold text-gray-700", children: "No resume added yet" }), jsx("p", { className: "mt-1 text-sm text-gray-500", children: "Upload your resume to share with mentors and administrators." }), jsxs(Button$1, { className: "mt-4 bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, children: [jsx(Upload, { className: "h-4 w-4 mr-2" }), " ", isUploading ? 'Uploading...' : 'Upload resume'] })] })), isLoading && (jsx("div", { className: "rounded-xl border border-gray-200 bg-white p-6 shadow-sm", children: jsxs("div", { className: "space-y-4", children: [jsx(Skeleton, { className: "h-6 w-32" }), jsx(Skeleton, { className: "h-64 w-full" })] }) })), !isLoading && resumeUrl && (jsx("div", { className: "rounded-xl border border-gray-200 bg-white p-6 shadow-sm", children: jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 rounded-lg bg-gray-50 px-4 py-3", children: [jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-700", children: [jsxs(Button$1, { variant: "outline", size: "sm", onClick: () => setPageNumber((prev) => Math.max(1, prev - 1)), disabled: pageNumber <= 1, children: [jsx(ChevronLeft, { className: "h-4 w-4 mr-1" }), " Prev"] }), jsxs("span", { children: ["Page ", pageNumber, " of ", numPages || '—'] }), jsxs(Button$1, { variant: "outline", size: "sm", onClick: () => setPageNumber((prev) => Math.min(numPages, prev + 1)), disabled: pageNumber >= numPages, children: ["Next ", jsx(ChevronRight, { className: "h-4 w-4 ml-1" })] })] }), jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-700", children: [jsx(Button$1, { variant: "outline", size: "sm", onClick: () => setScale((current) => Math.max(0.5, Number((current - 0.2).toFixed(1)))), disabled: scale <= 0.5, children: jsx(ZoomOut, { className: "h-4 w-4 mr-1" }) }), jsxs("span", { children: [Math.round(scale * 100), "%"] }), jsx(Button$1, { variant: "outline", size: "sm", onClick: () => setScale((current) => Number((current + 0.2).toFixed(1))), children: jsx(ZoomIn, { className: "h-4 w-4 mr-1" }) })] }), jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-700", children: [jsx(Button$1, { variant: "outline", size: "sm", onClick: () => setRotation((current) => current - 90), children: jsx(RotateCcw, { className: "h-4 w-4 mr-1" }) }), jsx(Button$1, { variant: "outline", size: "sm", onClick: () => setRotation((current) => current + 90), children: jsx(RotateCw, { className: "h-4 w-4 mr-1" }) })] })] }), jsx("div", { className: "flex justify-center", children: jsx("div", { className: "overflow-hidden rounded-lg border border-gray-200 bg-gray-100", children: jsx(Document$1, { file: resumeUrl, onLoadSuccess: handleDocumentLoad, onLoadError: () => toast.error('Unable to load resume preview'), loading: jsx(Skeleton, { className: "h-[480px] w-[360px]" }), children: jsx(Page, { pageNumber: pageNumber, scale: scale, rotate: rotation, width: 720 }) }) }) })] }) }))] }));
|
|
81632
81632
|
}
|
|
81633
81633
|
|
|
81634
|
+
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 })));
|
|
81635
|
+
Card.displayName = "Card";
|
|
81636
|
+
const CardHeader = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })));
|
|
81637
|
+
CardHeader.displayName = "CardHeader";
|
|
81638
|
+
const CardTitle = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("text-2xl font-semibold leading-none tracking-tight", className), ...props })));
|
|
81639
|
+
CardTitle.displayName = "CardTitle";
|
|
81640
|
+
const CardDescription = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("text-sm text-muted-foreground", className), ...props })));
|
|
81641
|
+
CardDescription.displayName = "CardDescription";
|
|
81642
|
+
const CardContent = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("p-6 pt-0", className), ...props })));
|
|
81643
|
+
CardContent.displayName = "CardContent";
|
|
81644
|
+
const CardFooter = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("flex items-center p-6 pt-0", className), ...props })));
|
|
81645
|
+
CardFooter.displayName = "CardFooter";
|
|
81646
|
+
|
|
81647
|
+
const badgeVariants = cva("inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", {
|
|
81648
|
+
variants: {
|
|
81649
|
+
variant: {
|
|
81650
|
+
default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
|
|
81651
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
81652
|
+
destructive: "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
|
|
81653
|
+
outline: "text-foreground",
|
|
81654
|
+
},
|
|
81655
|
+
},
|
|
81656
|
+
defaultVariants: {
|
|
81657
|
+
variant: "default",
|
|
81658
|
+
},
|
|
81659
|
+
});
|
|
81660
|
+
function Badge({ className, variant, ...props }) {
|
|
81661
|
+
return (jsx("div", { className: cn(badgeVariants({ variant }), className), ...props }));
|
|
81662
|
+
}
|
|
81663
|
+
|
|
81664
|
+
function statusBadgeStyle(status) {
|
|
81665
|
+
switch (status) {
|
|
81666
|
+
case 'active':
|
|
81667
|
+
return 'bg-blue-100 text-blue-700 border-blue-200 hover:bg-blue-100';
|
|
81668
|
+
case 'trialing':
|
|
81669
|
+
return 'bg-purple-100 text-purple-700 border-purple-200 hover:bg-purple-100';
|
|
81670
|
+
case 'canceled':
|
|
81671
|
+
return 'bg-gray-100 text-gray-500 border-gray-200 hover:bg-gray-100';
|
|
81672
|
+
case 'past_due':
|
|
81673
|
+
return 'bg-red-100 text-red-700 border-red-200 hover:bg-red-100';
|
|
81674
|
+
default:
|
|
81675
|
+
return 'bg-gray-100 text-gray-500 border-gray-200 hover:bg-gray-100';
|
|
81676
|
+
}
|
|
81677
|
+
}
|
|
81678
|
+
function formatInterval$1(interval) {
|
|
81679
|
+
switch (interval) {
|
|
81680
|
+
case 'month':
|
|
81681
|
+
return '/month';
|
|
81682
|
+
case 'year':
|
|
81683
|
+
return '/year';
|
|
81684
|
+
case 'one_time':
|
|
81685
|
+
return 'one-time';
|
|
81686
|
+
default:
|
|
81687
|
+
return interval;
|
|
81688
|
+
}
|
|
81689
|
+
}
|
|
81690
|
+
function useDebounce$1(value, delay) {
|
|
81691
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
81692
|
+
useEffect(() => {
|
|
81693
|
+
const timer = setTimeout(() => setDebouncedValue(value), delay);
|
|
81694
|
+
return () => clearTimeout(timer);
|
|
81695
|
+
}, [value, delay]);
|
|
81696
|
+
return debouncedValue;
|
|
81697
|
+
}
|
|
81698
|
+
function formatCurrency(amount, currency = 'usd') {
|
|
81699
|
+
return new Intl.NumberFormat('en-US', {
|
|
81700
|
+
style: 'currency',
|
|
81701
|
+
currency: currency.toUpperCase(),
|
|
81702
|
+
}).format(typeof amount === 'string' ? parseFloat(amount) : amount);
|
|
81703
|
+
}
|
|
81704
|
+
// ── Subscription Detail View ──
|
|
81705
|
+
function SubscriptionDetail({ subscription: initialSubscription, platformKey, onBack, }) {
|
|
81706
|
+
var _a, _b, _c, _d, _e;
|
|
81707
|
+
const [confirmText, setConfirmText] = useState('');
|
|
81708
|
+
const [cancelResult, setCancelResult] = useState(null);
|
|
81709
|
+
const { data: fetchedSubscription, isLoading: isLoadingDetail } = useGetItemSubscriptionQuery({
|
|
81710
|
+
platform_key: platformKey,
|
|
81711
|
+
item_type: initialSubscription.item_type,
|
|
81712
|
+
item_id: initialSubscription.item_id,
|
|
81713
|
+
}, { refetchOnMountOrArgChange: true });
|
|
81714
|
+
const subscription = fetchedSubscription !== null && fetchedSubscription !== void 0 ? fetchedSubscription : initialSubscription;
|
|
81715
|
+
const [cancelSubscription, { isLoading: isCanceling }] = useCancelSubscriptionMutation();
|
|
81716
|
+
const isOneTime = ((_a = subscription.price) === null || _a === void 0 ? void 0 : _a.interval) === 'one_time';
|
|
81717
|
+
const isRecurring = !isOneTime;
|
|
81718
|
+
const canCancel = isRecurring &&
|
|
81719
|
+
(subscription.status === 'active' || subscription.status === 'trialing') &&
|
|
81720
|
+
!subscription.cancel_at_period_end;
|
|
81721
|
+
const handleCancel = async () => {
|
|
81722
|
+
try {
|
|
81723
|
+
const result = await cancelSubscription({
|
|
81724
|
+
platform_key: platformKey,
|
|
81725
|
+
item_type: subscription.item_type,
|
|
81726
|
+
item_id: subscription.item_id,
|
|
81727
|
+
...(isRecurring ? { return_url: window.location.href } : {}),
|
|
81728
|
+
}).unwrap();
|
|
81729
|
+
if (result.portal_url) {
|
|
81730
|
+
setCancelResult({ portalUrl: result.portal_url });
|
|
81731
|
+
}
|
|
81732
|
+
else if (result.status === 'canceled') {
|
|
81733
|
+
setCancelResult({ canceled: true });
|
|
81734
|
+
toast.success('Subscription canceled');
|
|
81735
|
+
}
|
|
81736
|
+
}
|
|
81737
|
+
catch (_a) {
|
|
81738
|
+
toast.error('Failed to cancel subscription');
|
|
81739
|
+
}
|
|
81740
|
+
};
|
|
81741
|
+
if (isLoadingDetail) {
|
|
81742
|
+
return (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsxs(Button$1, { variant: "ghost", size: "sm", onClick: onBack, className: "cursor-pointer", children: [jsx(ChevronLeft, { className: "h-4 w-4 mr-1" }), "Back"] }), jsx(Skeleton, { className: "h-6 w-48" })] }), jsx(Skeleton, { className: "h-64 w-full" })] }));
|
|
81743
|
+
}
|
|
81744
|
+
return (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsxs(Button$1, { variant: "ghost", size: "sm", onClick: onBack, className: "cursor-pointer", children: [jsx(ChevronLeft, { className: "h-4 w-4 mr-1" }), "Back"] }), jsxs("div", { children: [jsx("h4", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: 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: "Status" }), jsx(Badge, { className: statusBadgeStyle(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: "Plan" }), 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$1((_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: "Type" }), 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 ? 'Access Until' : 'Renews On' }), 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: "Subscribed Since" }), 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: "Legacy Access" }), jsxs(Badge, { className: "bg-amber-100 text-amber-700 border-amber-200 text-xs", children: [jsx(Shield, { className: "h-3 w-3 mr-1" }), "Grandfathered"] })] })), 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: "This subscription will not renew and expires at the end of the current period." })] }))] }) }), 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: "Cancel Subscription" }), jsx("p", { className: "text-xs text-gray-500", children: "You will be redirected to the Stripe portal to manage cancellation. Your access continues until the end of the billing period." }), 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: ["Type ", jsx("span", { className: "font-mono font-bold", children: "cancel" }), " to confirm"] }), jsx(Input, { value: confirmText, onChange: (e) => setConfirmText(e.target.value), placeholder: "Type 'cancel'" })] }), 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" })), "Cancel"] })] })] }) })), (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: "Subscription Canceled" }), jsx("p", { className: "text-xs text-gray-500", children: "Your access has been revoked." }), jsx(Button$1, { variant: "outline", onClick: onBack, className: "mt-3 cursor-pointer", children: "Back to Purchases" })] }) })), (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: "Stripe Customer Portal" }), jsx("p", { className: "text-xs text-gray-500 mb-3", children: "Complete the cancellation in the Stripe Customer Portal." }), 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" }), "Open Stripe Portal"] })] }) }))] }));
|
|
81745
|
+
}
|
|
81746
|
+
// ── Subscription Card (List Item) ──
|
|
81747
|
+
function SubscriptionCard({ sub, onClick }) {
|
|
81748
|
+
var _a, _b, _c, _d;
|
|
81749
|
+
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), formatInterval$1((_d = sub.price) === null || _d === void 0 ? void 0 : _d.interval)] })] })] }), jsxs("div", { className: "flex flex-wrap items-center gap-3 mt-2 text-xs text-gray-400", children: [sub.current_period_end && (jsxs("span", { className: "flex items-center gap-1", children: [jsx(Calendar$1, { className: "h-3 w-3" }), sub.cancel_at_period_end ? 'Expires' : 'Renews', ":", ' ', new Date(sub.current_period_end).toLocaleDateString()] })), sub.created_at && (jsxs("span", { className: "flex items-center gap-1", children: [jsx(Clock, { className: "h-3 w-3" }), "Since: ", new Date(sub.created_at).toLocaleDateString()] }))] }), sub.cancel_at_period_end && (jsxs("div", { className: "flex items-center gap-1.5 mt-2 text-xs text-yellow-600", children: [jsx(TriangleAlert, { className: "h-3 w-3" }), "Cancels at period end"] }))] }), jsxs("div", { className: "flex flex-col items-end gap-1 flex-shrink-0 ml-3", children: [jsx(Badge, { className: statusBadgeStyle(sub.status), children: sub.status }), sub.is_grandfathered && (jsxs(Badge, { className: "bg-amber-100 text-amber-700 border-amber-200 text-xs", children: [jsx(Shield, { className: "h-3 w-3 mr-1" }), "Legacy"] }))] })] }) }) }));
|
|
81750
|
+
}
|
|
81751
|
+
// ── Main Purchases Tab ──
|
|
81752
|
+
function PurchasesTab({ org, username }) {
|
|
81753
|
+
const [statusFilter, setStatusFilter] = useState('all');
|
|
81754
|
+
const [typeFilter, setTypeFilter] = useState('all');
|
|
81755
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
81756
|
+
const [page, setPage] = useState(1);
|
|
81757
|
+
const [selectedSubscription, setSelectedSubscription] = useState(null);
|
|
81758
|
+
const debouncedSearch = useDebounce$1(searchQuery, 300);
|
|
81759
|
+
// Reset page when filters or search change
|
|
81760
|
+
useEffect(() => {
|
|
81761
|
+
setPage(1);
|
|
81762
|
+
}, [statusFilter, typeFilter, debouncedSearch]);
|
|
81763
|
+
const { data, isLoading, isFetching, refetch } = useGetMySubscriptionsQuery({
|
|
81764
|
+
platform_key: org,
|
|
81765
|
+
page,
|
|
81766
|
+
page_size: 8,
|
|
81767
|
+
...(statusFilter !== 'all' ? { status: statusFilter } : {}),
|
|
81768
|
+
...(typeFilter !== 'all' ? { item_type: typeFilter } : {}),
|
|
81769
|
+
...(debouncedSearch.trim() ? { item_name: debouncedSearch.trim() } : {}),
|
|
81770
|
+
}, { refetchOnMountOrArgChange: true });
|
|
81771
|
+
if (selectedSubscription) {
|
|
81772
|
+
return (jsx(SubscriptionDetail, { subscription: selectedSubscription, platformKey: org, onBack: () => {
|
|
81773
|
+
setSelectedSubscription(null);
|
|
81774
|
+
refetch();
|
|
81775
|
+
} }));
|
|
81776
|
+
}
|
|
81777
|
+
return (jsxs("div", { className: "max-w-2xl 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: "Search purchases...", 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: "Status" }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: "All Statuses" }), jsx(SelectItem, { value: "active", children: "Active" }), jsx(SelectItem, { value: "trialing", children: "Trialing" }), jsx(SelectItem, { value: "canceled", children: "Canceled" }), jsx(SelectItem, { value: "past_due", children: "Past Due" })] })] }), jsxs(Select$1, { value: typeFilter, onValueChange: setTypeFilter, children: [jsx(SelectTrigger, { className: "w-full sm:w-[160px]", children: jsx(SelectValue, { placeholder: "Item Type" }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: "All Types" }), jsx(SelectItem, { value: "mentor", children: "Mentor" }), jsx(SelectItem, { value: "course", children: "Course" }), jsx(SelectItem, { value: "program", children: "Program" }), jsx(SelectItem, { value: "pathway", children: "Pathway" })] })] }), data && (jsxs("span", { className: "text-xs text-gray-400 self-center ml-auto", children: [data.count, " purchase", data.count !== 1 ? 's' : ''] }))] }), 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: [jsxs("span", { className: "text-xs text-gray-400", children: [data.count, " total"] }), 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: "Previous" }), jsxs("span", { className: "text-xs text-gray-500", children: ["Page ", 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: "Next" })] })] }))] })) : (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() ? 'No purchases match your search.' : 'No purchases found.' })] }) }))] }));
|
|
81778
|
+
}
|
|
81779
|
+
|
|
81634
81780
|
function AddMemoryDialog({ open, onOpenChange, org, username }) {
|
|
81635
81781
|
const [content, setContent] = useState('');
|
|
81636
81782
|
const [createMemory, { isLoading }] = useCreateGlobalMemoryMutation();
|
|
@@ -81757,6 +81903,7 @@ function Profile({ tenant, username, onClose, customization = {}, isAdmin = fals
|
|
|
81757
81903
|
{ id: 'education', label: 'Education', renderIcon: renderLucideIcon(BookOpen) },
|
|
81758
81904
|
{ id: 'experience', label: 'Experience', renderIcon: renderLucideIcon(Briefcase) },
|
|
81759
81905
|
{ id: 'resume', label: 'Resume', renderIcon: renderLucideIcon(FileText) },
|
|
81906
|
+
{ id: 'purchases', label: 'Purchases', renderIcon: renderLucideIcon(ShoppingBag) },
|
|
81760
81907
|
...(isMemoryEnabled
|
|
81761
81908
|
? [{ id: 'memory', label: 'Memory', renderIcon: renderLucideIcon(Archive) }]
|
|
81762
81909
|
: []),
|
|
@@ -81817,7 +81964,7 @@ function Profile({ tenant, username, onClose, customization = {}, isAdmin = fals
|
|
|
81817
81964
|
? 'bg-blue-50 text-blue-700 font-medium'
|
|
81818
81965
|
: '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": "Profile tabs mobile", 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
|
|
81819
81966
|
? 'bg-blue-50 text-blue-600 font-medium'
|
|
81820
|
-
: 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(tab.renderIcon, { className: "h-4 w-4", "aria-hidden": "true" }), jsx("span", { className: "hidden sm:inline", children: tab.label }), jsx("span", { className: "sm:hidden", children: tab.label })] }, tab.id))) }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsx("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'basic' && 'Manage your basic account information and preferences.', activeTab === 'social' && 'Connect and manage your social media accounts.', activeTab === 'education' && 'Review and update your academic achievements.', activeTab === 'experience' && 'Keep your professional journey up to date.', activeTab === 'resume' && 'Upload and preview your most recent resume.', activeTab === 'memory' && 'Manage what the AI remembers about you.', activeTab === 'security' && 'Update your security settings and password.', activeTab === 'advanced' && 'Manage your advanced settings.'] })] }), (activeTab === 'education' ||
|
|
81967
|
+
: 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(tab.renderIcon, { className: "h-4 w-4", "aria-hidden": "true" }), jsx("span", { className: "hidden sm:inline", children: tab.label }), jsx("span", { className: "sm:hidden", children: tab.label })] }, tab.id))) }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsx("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'basic' && 'Manage your basic account information and preferences.', activeTab === 'social' && 'Connect and manage your social media accounts.', activeTab === 'education' && 'Review and update your academic achievements.', activeTab === 'experience' && 'Keep your professional journey up to date.', activeTab === 'resume' && 'Upload and preview your most recent resume.', activeTab === 'purchases' && 'View and manage your subscriptions and purchases.', activeTab === 'memory' && 'Manage what the AI remembers about you.', activeTab === 'security' && 'Update your security settings and password.', activeTab === 'advanced' && 'Manage your advanced settings.'] })] }), (activeTab === 'education' ||
|
|
81821
81968
|
activeTab === 'experience' ||
|
|
81822
81969
|
activeTab === 'resume') && (jsx(Button$1, { size: "icon", onClick: activeTab === 'education'
|
|
81823
81970
|
? handleAddEducation
|
|
@@ -81904,7 +82051,7 @@ function Profile({ tenant, username, onClose, customization = {}, isAdmin = fals
|
|
|
81904
82051
|
var _a;
|
|
81905
82052
|
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: "X", value: field.state.value, onChange: (e) => handleSocialLinkChange(e.target.value, field.handleChange, X_URL_PREFIX), disabled: socialForm.state.isSubmitting })] }), 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 })] }));
|
|
81906
82053
|
},
|
|
81907
|
-
})] })] }) })), activeTab === 'education' && jsx(EducationTab, { org: tenant, username: username }), activeTab === 'experience' && jsx(ExperienceTab, { org: tenant, username: username }), activeTab === 'resume' && jsx(ResumeTab, { org: tenant, username: username }), activeTab === 'memory' && jsx(MemoryTab, { org: tenant, username: username }), activeTab === 'security' && (jsx(Security, { email: userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email, onAccountDeleted: onAccountDeleted })), activeTab === 'advanced' && localLLMProps && (jsx(LocalLLMTab, { isAvailable: localLLMProps.isAvailable, state: localLLMProps.state, ollamaStatus: localLLMProps.ollamaStatus, isUsingFoundry: localLLMProps.isUsingFoundry, foundryModels: localLLMProps.foundryModels, selectedFoundryModel: localLLMProps.selectedFoundryModel, foundryStatus: localLLMProps.foundryStatus, onStartDownload: localLLMProps.onStartDownload, onCancelDownload: localLLMProps.onCancelDownload, onInstallOllama: localLLMProps.onInstallOllama, onInstallFoundry: localLLMProps.onInstallFoundry, onCheckStatus: localLLMProps.onCheckStatus, onResetState: localLLMProps.onResetState, onSelectFoundryModel: localLLMProps.onSelectFoundryModel }))] }), ['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: "Cancel" }), jsx(Button$1, { onClick: () => {
|
|
82054
|
+
})] })] }) })), activeTab === 'education' && jsx(EducationTab, { org: tenant, username: username }), activeTab === 'experience' && jsx(ExperienceTab, { org: tenant, username: username }), activeTab === 'resume' && jsx(ResumeTab, { org: tenant, username: username }), activeTab === 'purchases' && jsx(PurchasesTab, { org: tenant, username: username }), activeTab === 'memory' && jsx(MemoryTab, { org: tenant, username: username }), activeTab === 'security' && (jsx(Security, { email: userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email, onAccountDeleted: onAccountDeleted })), activeTab === 'advanced' && localLLMProps && (jsx(LocalLLMTab, { isAvailable: localLLMProps.isAvailable, state: localLLMProps.state, ollamaStatus: localLLMProps.ollamaStatus, isUsingFoundry: localLLMProps.isUsingFoundry, foundryModels: localLLMProps.foundryModels, selectedFoundryModel: localLLMProps.selectedFoundryModel, foundryStatus: localLLMProps.foundryStatus, onStartDownload: localLLMProps.onStartDownload, onCancelDownload: localLLMProps.onCancelDownload, onInstallOllama: localLLMProps.onInstallOllama, onInstallFoundry: localLLMProps.onInstallFoundry, onCheckStatus: localLLMProps.onCheckStatus, onResetState: localLLMProps.onResetState, onSelectFoundryModel: localLLMProps.onSelectFoundryModel }))] }), ['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: "Cancel" }), jsx(Button$1, { onClick: () => {
|
|
81908
82055
|
if (activeTab === 'basic') {
|
|
81909
82056
|
basicForm.handleSubmit();
|
|
81910
82057
|
}
|
|
@@ -83285,23 +83432,6 @@ function InvitedUsersDialog({ tenant, onClose, }) {
|
|
|
83285
83432
|
}, children: jsx(DialogPortal$1, { forceMount: true, children: jsxs(DialogContent$1, { "aria-label": "Invited Users Dialog", className: "max-w-sm rounded-2xl px-6 py-8 pointer-events-auto", "aria-describedby": "invited-users-dialog", children: [jsx(DialogHeader, { className: "relative flex-row justify-between", children: jsx(DialogTitle$1, { className: "text-blue-600 text-xl font-semibold", children: "Invited Users" }) }), jsxs("div", { className: "mt-4 space-y-1", children: [jsx("p", { className: "text-gray-500 text-sm", children: "Showing list of invited users pending confirmation" }), jsx("form", { children: jsx(Input, { value: query, onChange: (event) => setQuery(event.target.value), placeholder: "Search Invited Users", className: "mt-2" }) })] }), jsxs("div", { children: [jsx("h2", { className: "text-md text-gray-600 font-semibold mb-4", children: "Email" }), invitedUsers === null || invitedUsers === void 0 ? void 0 : invitedUsers.results.map((user) => (jsx("div", { className: "border-b-gray-50 pb-2 mb-4 text-sm text-gray-600 dark:text-gray-400", children: user.email }, user.id))), (invitedUsers === null || invitedUsers === void 0 ? void 0 : invitedUsers.results.length) === 0 && (jsx("p", { className: "text-gray", children: "No records found" }))] })] }) }) }));
|
|
83286
83433
|
}
|
|
83287
83434
|
|
|
83288
|
-
const badgeVariants = cva("inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", {
|
|
83289
|
-
variants: {
|
|
83290
|
-
variant: {
|
|
83291
|
-
default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
|
|
83292
|
-
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
83293
|
-
destructive: "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
|
|
83294
|
-
outline: "text-foreground",
|
|
83295
|
-
},
|
|
83296
|
-
},
|
|
83297
|
-
defaultVariants: {
|
|
83298
|
-
variant: "default",
|
|
83299
|
-
},
|
|
83300
|
-
});
|
|
83301
|
-
function Badge({ className, variant, ...props }) {
|
|
83302
|
-
return (jsx("div", { className: cn(badgeVariants({ variant }), className), ...props }));
|
|
83303
|
-
}
|
|
83304
|
-
|
|
83305
83435
|
// ::- Persistent data structure representing an ordered mapping from
|
|
83306
83436
|
// strings to values, with some convenient update methods.
|
|
83307
83437
|
function OrderedMap(content) {
|
|
@@ -113326,19 +113456,6 @@ var ResponsiveContainer = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
113326
113456
|
}, chartContent);
|
|
113327
113457
|
});
|
|
113328
113458
|
|
|
113329
|
-
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 })));
|
|
113330
|
-
Card.displayName = "Card";
|
|
113331
|
-
const CardHeader = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })));
|
|
113332
|
-
CardHeader.displayName = "CardHeader";
|
|
113333
|
-
const CardTitle = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("text-2xl font-semibold leading-none tracking-tight", className), ...props })));
|
|
113334
|
-
CardTitle.displayName = "CardTitle";
|
|
113335
|
-
const CardDescription = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("text-sm text-muted-foreground", className), ...props })));
|
|
113336
|
-
CardDescription.displayName = "CardDescription";
|
|
113337
|
-
const CardContent = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("p-6 pt-0", className), ...props })));
|
|
113338
|
-
CardContent.displayName = "CardContent";
|
|
113339
|
-
const CardFooter = React.forwardRef(({ className, ...props }, ref) => (jsx("div", { ref: ref, className: cn("flex items-center p-6 pt-0", className), ...props })));
|
|
113340
|
-
CardFooter.displayName = "CardFooter";
|
|
113341
|
-
|
|
113342
113459
|
const THEMES = { light: '', dark: '.dark' };
|
|
113343
113460
|
const ChartContext = React.createContext(null);
|
|
113344
113461
|
function useChart() {
|
|
@@ -118637,11 +118754,412 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
|
|
|
118637
118754
|
})()), jsx(StartScreenContent, { platformKey: platformKey, currentSPA: currentSPA }), jsx(ContentViewWrapper, { currentSPA: currentSPA, spas: ['mentor'], children: jsx(ChatAreaWidth, { chatAreaSize: metadata === null || metadata === void 0 ? void 0 : metadata.chat_area_size, isUpdating: isUpdatingTenantMetadata, onUpdate: handleChatAreaSizeUpdate, onError: handleChatAreaSizeError }) }), jsx(AuthSpaCustomizationContent, { platformKey: platformKey, currentSPA: currentSPA }), jsx(AdvancedCssContent, { platformKey: platformKey, currentSPA: currentSPA || '' }), jsx(RecommendationSystemPromptsContent, { platformKey: platformKey, currentSPA: currentSPA }), jsx(StudentMentorCreationContent, { platformKey: platformKey }), jsx(MemsearchConfigContent, { platformKey: platformKey, userId: username }), jsx(PlatformMembershipContent, { platformKey: platformKey, authURL: authURL }), jsx(CustomDomainsContent, { platformKey: platformKey, currentSPA: currentSPA || '', currentPlatformBaseDomain: currentPlatformBaseDomain || '' }), jsx(SmtpContent, { platformKey: platformKey }), (currentSPA === null || currentSPA === void 0 ? void 0 : currentSPA.includes('skills')) && (jsxs(Fragment$1, { children: [jsx(ProviderConfigContent, { platformKey: platformKey, username: username }), jsx(ExternalMappingContent, { platformKey: platformKey, username: username })] }))] }) }));
|
|
118638
118755
|
}
|
|
118639
118756
|
|
|
118757
|
+
function StripeConnect({ platformKey }) {
|
|
118758
|
+
const [isRedirecting, setIsRedirecting] = useState(false);
|
|
118759
|
+
const { data: status, isLoading, refetch, } = useGetStripeConnectStatusQuery({ platform_key: platformKey }, { refetchOnMountOrArgChange: true });
|
|
118760
|
+
const [startOnboarding, { isLoading: isStartingOnboarding }] = useStartStripeConnectOnboardingMutation();
|
|
118761
|
+
const [triggerGetDashboard] = useLazyGetStripeConnectDashboardQuery();
|
|
118762
|
+
const buildMonetizationUrl = () => {
|
|
118763
|
+
const url = new URL(window.location.href);
|
|
118764
|
+
url.searchParams.set('profileTab', 'monetization');
|
|
118765
|
+
return url.toString();
|
|
118766
|
+
};
|
|
118767
|
+
const handleStartOnboarding = async () => {
|
|
118768
|
+
const redirectUrl = buildMonetizationUrl();
|
|
118769
|
+
try {
|
|
118770
|
+
const result = await startOnboarding({
|
|
118771
|
+
platform_key: platformKey,
|
|
118772
|
+
return_url: redirectUrl,
|
|
118773
|
+
refresh_url: redirectUrl,
|
|
118774
|
+
business_type: 'company',
|
|
118775
|
+
}).unwrap();
|
|
118776
|
+
if (result.onboarding_url) {
|
|
118777
|
+
setIsRedirecting(true);
|
|
118778
|
+
toast.info('Redirecting to Stripe...');
|
|
118779
|
+
window.location.href = result.onboarding_url;
|
|
118780
|
+
}
|
|
118781
|
+
}
|
|
118782
|
+
catch (_a) {
|
|
118783
|
+
toast.error('Failed to start Stripe onboarding');
|
|
118784
|
+
}
|
|
118785
|
+
};
|
|
118786
|
+
const handleOpenDashboard = async () => {
|
|
118787
|
+
setIsRedirecting(true);
|
|
118788
|
+
try {
|
|
118789
|
+
const result = await triggerGetDashboard({ platform_key: platformKey }).unwrap();
|
|
118790
|
+
if (result.dashboard_url) {
|
|
118791
|
+
toast.info('Opening Stripe Dashboard...');
|
|
118792
|
+
window.open(result.dashboard_url, '_blank');
|
|
118793
|
+
}
|
|
118794
|
+
}
|
|
118795
|
+
catch (_a) {
|
|
118796
|
+
toast.error('Failed to open Stripe dashboard');
|
|
118797
|
+
}
|
|
118798
|
+
finally {
|
|
118799
|
+
setIsRedirecting(false);
|
|
118800
|
+
}
|
|
118801
|
+
};
|
|
118802
|
+
if (isLoading) {
|
|
118803
|
+
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" })] }) }) }));
|
|
118804
|
+
}
|
|
118805
|
+
const isReady = status === null || status === void 0 ? void 0 : status.is_ready_for_payments;
|
|
118806
|
+
const hasAccount = status === null || status === void 0 ? void 0 : status.has_account;
|
|
118807
|
+
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: "Stripe Connect" }), isReady ? (jsx(Badge, { className: "bg-blue-100 text-blue-700 border-blue-200", children: "Connected" })) : hasAccount ? (jsx(Badge, { className: "bg-yellow-100 text-yellow-700 border-yellow-200", children: "Incomplete" })) : (jsx(Badge, { variant: "secondary", children: "Not Connected" }))] }), isReady ? (jsxs("p", { className: "text-sm text-gray-500", children: ["Stripe is connected and ready to accept payments.", (status === null || status === void 0 ? void 0 : status.charges_enabled) && ' Charges enabled.', (status === null || status === void 0 ? void 0 : status.payouts_enabled) && ' Payouts enabled.'] })) : hasAccount ? (jsx("p", { className: "text-sm text-gray-500", children: "Stripe account created but onboarding is incomplete. Complete setup to start accepting payments." })) : (jsx("p", { className: "text-sm text-gray-500", children: "Connect a Stripe account to enable monetization features." }))] }), jsx("div", { className: "flex gap-2 flex-shrink-0", children: 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" })), "Stripe Dashboard"] })) : (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
|
|
118808
|
+
? 'Redirecting...'
|
|
118809
|
+
: hasAccount
|
|
118810
|
+
? 'Complete Setup'
|
|
118811
|
+
: 'Connect Stripe'] })) })] }) }) }));
|
|
118812
|
+
}
|
|
118813
|
+
|
|
118814
|
+
const EMPTY_FORM = {
|
|
118815
|
+
name: '',
|
|
118816
|
+
amount: '',
|
|
118817
|
+
currency: 'usd',
|
|
118818
|
+
interval: 'month',
|
|
118819
|
+
description: '',
|
|
118820
|
+
features: [],
|
|
118821
|
+
is_active: true,
|
|
118822
|
+
sort_order: 0,
|
|
118823
|
+
};
|
|
118824
|
+
function formatInterval(interval) {
|
|
118825
|
+
switch (interval) {
|
|
118826
|
+
case 'month':
|
|
118827
|
+
return '/mo';
|
|
118828
|
+
case 'year':
|
|
118829
|
+
return '/yr';
|
|
118830
|
+
case 'one_time':
|
|
118831
|
+
return 'one-time';
|
|
118832
|
+
default:
|
|
118833
|
+
return interval;
|
|
118834
|
+
}
|
|
118835
|
+
}
|
|
118836
|
+
// ── Price Form (shared between create & edit) ──
|
|
118837
|
+
function PriceForm({ form, onChange, onSave, onCancel, isSaving, isEdit, }) {
|
|
118838
|
+
const [featureInput, setFeatureInput] = useState('');
|
|
118839
|
+
const handleAddFeature = () => {
|
|
118840
|
+
const trimmed = featureInput.trim();
|
|
118841
|
+
if (trimmed && !form.features.includes(trimmed)) {
|
|
118842
|
+
onChange({ ...form, features: [...form.features, trimmed] });
|
|
118843
|
+
setFeatureInput('');
|
|
118844
|
+
}
|
|
118845
|
+
};
|
|
118846
|
+
const handleRemoveFeature = (index) => {
|
|
118847
|
+
onChange({ ...form, features: form.features.filter((_, i) => i !== index) });
|
|
118848
|
+
};
|
|
118849
|
+
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, { className: "text-xs text-gray-500", children: "Name *" }), jsx(Input, { value: form.name, onChange: (e) => onChange({ ...form, name: e.target.value }), placeholder: "e.g. Monthly Plan", className: "mt-1" })] }), jsxs("div", { children: [jsx(Label, { className: "text-xs text-gray-500", children: "Amount (USD) *" }), jsx(Input, { type: "number", min: 0, step: "0.01", value: form.amount, onChange: (e) => onChange({ ...form, amount: e.target.value }), placeholder: "9.99", className: "mt-1" })] }), jsxs("div", { children: [jsx(Label, { className: "text-xs text-gray-500", children: "Interval" }), 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: "Monthly" }), jsx(SelectItem, { value: "year", children: "Yearly" }), jsx(SelectItem, { value: "one_time", children: "One-Time" })] })] })] }), jsxs("div", { children: [jsx(Label, { className: "text-xs text-gray-500", children: "Currency" }), jsx(Input, { value: form.currency, disabled: true, className: "mt-1 bg-gray-50 text-gray-500 cursor-not-allowed" })] })] }), jsxs("div", { children: [jsx(Label, { className: "text-xs text-gray-500", children: "Description" }), jsx(Input, { value: form.description, onChange: (e) => onChange({ ...form, description: e.target.value }), placeholder: "Optional description", className: "mt-1" })] }), jsxs("div", { children: [jsx(Label, { className: "text-xs text-gray-500", children: "Features" }), 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, { 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) => {
|
|
118850
|
+
if (e.key === 'Enter') {
|
|
118851
|
+
e.preventDefault();
|
|
118852
|
+
handleAddFeature();
|
|
118853
|
+
}
|
|
118854
|
+
}, placeholder: "Add a feature...", className: "flex-1" }), jsx(Button$1, { type: "button", onClick: handleAddFeature, disabled: !featureInput.trim(), variant: "outline", size: "sm", className: "h-9 px-2 cursor-pointer", children: jsx(Plus, { className: "h-3.5 w-3.5" }) })] })] }), jsx("div", { className: "flex items-center justify-between pt-2", children: jsxs("div", { className: "flex gap-2", children: [jsxs(Button$1, { onClick: onSave, disabled: isSaving || !form.name.trim() || !form.amount, size: "sm", className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white cursor-pointer", children: [isSaving ? (jsx(LoaderCircle, { className: "h-3 w-3 mr-1 animate-spin" })) : (jsx(Check, { className: "h-3 w-3 mr-1" })), isEdit ? 'Update' : 'Create'] }), jsxs(Button$1, { onClick: onCancel, variant: "outline", size: "sm", className: "cursor-pointer", children: [jsx(X, { className: "h-3 w-3 mr-1" }), "Cancel"] })] }) })] }) }));
|
|
118855
|
+
}
|
|
118856
|
+
// ── Main Component ──
|
|
118857
|
+
function PriceManagement({ platformKey, itemType, itemId }) {
|
|
118858
|
+
const { data: prices, isLoading, refetch, } = useListPricesQuery({ platform_key: platformKey, item_type: itemType, item_id: itemId }, { refetchOnMountOrArgChange: true });
|
|
118859
|
+
const [createPrice, { isLoading: isCreating }] = useCreatePriceMutation();
|
|
118860
|
+
const [updatePrice, { isLoading: isUpdating }] = useUpdatePriceMutation();
|
|
118861
|
+
const [deletePrice] = useDeletePriceMutation();
|
|
118862
|
+
const [showCreateForm, setShowCreateForm] = useState(false);
|
|
118863
|
+
const [editingPriceId, setEditingPriceId] = useState(null);
|
|
118864
|
+
const [formData, setFormData] = useState(EMPTY_FORM);
|
|
118865
|
+
const [deletingId, setDeletingId] = useState(null);
|
|
118866
|
+
const handleCreate = async () => {
|
|
118867
|
+
try {
|
|
118868
|
+
await createPrice({
|
|
118869
|
+
platform_key: platformKey,
|
|
118870
|
+
item_type: itemType,
|
|
118871
|
+
item_id: itemId,
|
|
118872
|
+
name: formData.name,
|
|
118873
|
+
amount: parseFloat(formData.amount),
|
|
118874
|
+
currency: formData.currency,
|
|
118875
|
+
interval: formData.interval,
|
|
118876
|
+
description: formData.description || undefined,
|
|
118877
|
+
features: formData.features.length > 0 ? formData.features : undefined,
|
|
118878
|
+
is_active: formData.is_active,
|
|
118879
|
+
sort_order: formData.sort_order,
|
|
118880
|
+
}).unwrap();
|
|
118881
|
+
toast.success('Price created');
|
|
118882
|
+
setShowCreateForm(false);
|
|
118883
|
+
setFormData(EMPTY_FORM);
|
|
118884
|
+
refetch();
|
|
118885
|
+
}
|
|
118886
|
+
catch (_a) {
|
|
118887
|
+
toast.error('Failed to create price');
|
|
118888
|
+
}
|
|
118889
|
+
};
|
|
118890
|
+
const handleStartEdit = (price) => {
|
|
118891
|
+
var _a;
|
|
118892
|
+
setEditingPriceId(price.id);
|
|
118893
|
+
setFormData({
|
|
118894
|
+
name: price.name,
|
|
118895
|
+
amount: String(price.amount),
|
|
118896
|
+
currency: price.currency,
|
|
118897
|
+
interval: price.interval,
|
|
118898
|
+
description: price.description || '',
|
|
118899
|
+
features: (_a = price.features) !== null && _a !== void 0 ? _a : [],
|
|
118900
|
+
is_active: price.is_active,
|
|
118901
|
+
sort_order: price.sort_order,
|
|
118902
|
+
});
|
|
118903
|
+
setShowCreateForm(false);
|
|
118904
|
+
};
|
|
118905
|
+
const handleUpdate = async () => {
|
|
118906
|
+
if (!editingPriceId)
|
|
118907
|
+
return;
|
|
118908
|
+
try {
|
|
118909
|
+
await updatePrice({
|
|
118910
|
+
platform_key: platformKey,
|
|
118911
|
+
item_type: itemType,
|
|
118912
|
+
item_id: itemId,
|
|
118913
|
+
price_unique_id: editingPriceId,
|
|
118914
|
+
name: formData.name,
|
|
118915
|
+
amount: parseFloat(formData.amount),
|
|
118916
|
+
currency: formData.currency,
|
|
118917
|
+
interval: formData.interval,
|
|
118918
|
+
description: formData.description || undefined,
|
|
118919
|
+
features: formData.features.length > 0 ? formData.features : undefined,
|
|
118920
|
+
is_active: formData.is_active,
|
|
118921
|
+
sort_order: formData.sort_order,
|
|
118922
|
+
}).unwrap();
|
|
118923
|
+
toast.success('Price updated');
|
|
118924
|
+
setEditingPriceId(null);
|
|
118925
|
+
setFormData(EMPTY_FORM);
|
|
118926
|
+
refetch();
|
|
118927
|
+
}
|
|
118928
|
+
catch (_a) {
|
|
118929
|
+
toast.error('Failed to update price');
|
|
118930
|
+
}
|
|
118931
|
+
};
|
|
118932
|
+
const handleDelete = async (priceId) => {
|
|
118933
|
+
setDeletingId(priceId);
|
|
118934
|
+
try {
|
|
118935
|
+
await deletePrice({
|
|
118936
|
+
platform_key: platformKey,
|
|
118937
|
+
item_type: itemType,
|
|
118938
|
+
item_id: itemId,
|
|
118939
|
+
price_unique_id: priceId,
|
|
118940
|
+
}).unwrap();
|
|
118941
|
+
toast.success('Price deleted');
|
|
118942
|
+
refetch();
|
|
118943
|
+
}
|
|
118944
|
+
catch (_a) {
|
|
118945
|
+
toast.error('Failed to delete price');
|
|
118946
|
+
}
|
|
118947
|
+
finally {
|
|
118948
|
+
setDeletingId(null);
|
|
118949
|
+
}
|
|
118950
|
+
};
|
|
118951
|
+
return (jsxs("div", { className: "space-y-3", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: "Pricing Tiers" }), !showCreateForm && !editingPriceId && (jsxs(Button$1, { onClick: () => {
|
|
118952
|
+
setShowCreateForm(true);
|
|
118953
|
+
setFormData(EMPTY_FORM);
|
|
118954
|
+
setEditingPriceId(null);
|
|
118955
|
+
}, variant: "outline", size: "sm", className: "cursor-pointer", children: [jsx(Plus, { className: "h-3 w-3 mr-1" }), "Add Price"] }))] }), showCreateForm && (jsx(PriceForm, { form: formData, onChange: setFormData, onSave: handleCreate, onCancel: () => {
|
|
118956
|
+
setShowCreateForm(false);
|
|
118957
|
+
setFormData(EMPTY_FORM);
|
|
118958
|
+
}, isSaving: isCreating, isEdit: false })), isLoading ? (jsx("div", { className: "space-y-2", children: [1, 2].map((i) => (jsx(Skeleton, { className: "h-20 w-full" }, i))) })) : prices && prices.length > 0 ? (jsx("div", { className: "space-y-2", children: prices.map((price) => {
|
|
118959
|
+
var _a;
|
|
118960
|
+
return editingPriceId === price.id ? (jsx(PriceForm, { form: formData, onChange: setFormData, onSave: handleUpdate, onCancel: () => {
|
|
118961
|
+
setEditingPriceId(null);
|
|
118962
|
+
setFormData(EMPTY_FORM);
|
|
118963
|
+
}, 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(price.interval)] }), !price.is_active && (jsx(Badge, { variant: "secondary", className: "text-xs", children: "Inactive" }))] }), 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));
|
|
118964
|
+
}) })) : (jsx("p", { className: "text-xs text-gray-400 text-center py-4", children: "No pricing tiers yet. Add one to start accepting payments." }))] }));
|
|
118965
|
+
}
|
|
118966
|
+
|
|
118967
|
+
function useDebounce(value, delay) {
|
|
118968
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
118969
|
+
useEffect(() => {
|
|
118970
|
+
const timer = setTimeout(() => setDebouncedValue(value), delay);
|
|
118971
|
+
return () => clearTimeout(timer);
|
|
118972
|
+
}, [value, delay]);
|
|
118973
|
+
return debouncedValue;
|
|
118974
|
+
}
|
|
118975
|
+
// ── Item Selector ──
|
|
118976
|
+
function ItemSearchDropdown({ platformKey, onSelect, }) {
|
|
118977
|
+
var _a, _b;
|
|
118978
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
118979
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
118980
|
+
const dropdownRef = useRef(null);
|
|
118981
|
+
const debouncedSearch = useDebounce(searchQuery, 300);
|
|
118982
|
+
// Mentor search
|
|
118983
|
+
const { data: mentors, isFetching: isFetchingMentors } = useGetAiSearchMentorsQuery({
|
|
118984
|
+
platform_key: platformKey,
|
|
118985
|
+
query: debouncedSearch || undefined,
|
|
118986
|
+
limit: 6,
|
|
118987
|
+
include_main_public_mentors: false,
|
|
118988
|
+
}, { skip: !platformKey });
|
|
118989
|
+
// Course search
|
|
118990
|
+
const { data: coursesData, isFetching: isFetchingCourses } = useGetPersonnalizedSearchQuery([
|
|
118991
|
+
{
|
|
118992
|
+
username: getUserName(),
|
|
118993
|
+
content: ['courses'],
|
|
118994
|
+
tenant: platformKey,
|
|
118995
|
+
query: debouncedSearch || '',
|
|
118996
|
+
returnItems: false,
|
|
118997
|
+
returnFacet: false,
|
|
118998
|
+
allowSkillSearch: false,
|
|
118999
|
+
limit: 6,
|
|
119000
|
+
},
|
|
119001
|
+
]);
|
|
119002
|
+
const isFetching = isFetchingMentors || isFetchingCourses;
|
|
119003
|
+
// Normalize and merge results
|
|
119004
|
+
const mentorItems = ((_a = mentors === null || mentors === void 0 ? void 0 : mentors.results) !== null && _a !== void 0 ? _a : []).map((m) => {
|
|
119005
|
+
var _a;
|
|
119006
|
+
return ({
|
|
119007
|
+
itemType: 'mentor',
|
|
119008
|
+
id: (_a = m.unique_id) !== null && _a !== void 0 ? _a : '',
|
|
119009
|
+
name: m.name,
|
|
119010
|
+
badge: m.slug,
|
|
119011
|
+
});
|
|
119012
|
+
});
|
|
119013
|
+
const courseItems = ((_b = coursesData === null || coursesData === void 0 ? void 0 : coursesData.results) !== null && _b !== void 0 ? _b : [])
|
|
119014
|
+
.filter((item) => item.type === 'course')
|
|
119015
|
+
.map((item) => {
|
|
119016
|
+
var _a, _b, _c, _d, _e, _f;
|
|
119017
|
+
return ({
|
|
119018
|
+
itemType: 'course',
|
|
119019
|
+
id: (_d = (_b = (_a = item.data) === null || _a === void 0 ? void 0 : _a.course_id) !== null && _b !== void 0 ? _b : (_c = item.data) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : '',
|
|
119020
|
+
name: (_f = (_e = item.data) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : '',
|
|
119021
|
+
});
|
|
119022
|
+
});
|
|
119023
|
+
const items = [...mentorItems, ...courseItems];
|
|
119024
|
+
// Close dropdown on outside click
|
|
119025
|
+
useEffect(() => {
|
|
119026
|
+
const handleClickOutside = (e) => {
|
|
119027
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
119028
|
+
setIsOpen(false);
|
|
119029
|
+
}
|
|
119030
|
+
};
|
|
119031
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
119032
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
119033
|
+
}, []);
|
|
119034
|
+
return (jsxs("div", { ref: dropdownRef, className: "relative flex-1", children: [jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => {
|
|
119035
|
+
setSearchQuery(e.target.value);
|
|
119036
|
+
setIsOpen(true);
|
|
119037
|
+
}, onFocus: () => setIsOpen(true), placeholder: "Search items", className: "pl-9" }), isFetching && (jsx(LoaderCircle, { className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 animate-spin text-gray-400" }))] }), isOpen && (jsx("div", { className: "absolute z-50 mt-1 w-full max-h-60 overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-900", style: { borderColor: 'oklch(.922 0 0)' }, children: items.length > 0 ? (items.map((item) => (jsxs("button", { type: "button", className: "flex w-full items-center gap-3 px-3 py-2 text-left hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors", onClick: () => {
|
|
119038
|
+
onSelect(item.itemType, item.id, item.name);
|
|
119039
|
+
setSearchQuery('');
|
|
119040
|
+
setIsOpen(false);
|
|
119041
|
+
}, children: [jsx("div", { className: "flex-1 min-w-0", children: jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 block truncate", children: item.name }) }), jsx(Badge, { variant: "secondary", className: "text-xs shrink-0 capitalize", children: item.itemType })] }, `${item.itemType}-${item.id}`)))) : isFetching ? (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-400", children: "Searching..." })) : (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-400", children: "No items found" })) }))] }));
|
|
119042
|
+
}
|
|
119043
|
+
function PaywalledItemsList({ platformKey, onSelectItem, }) {
|
|
119044
|
+
const [page, setPage] = useState(1);
|
|
119045
|
+
const [statusFilter, setStatusFilter] = useState('all');
|
|
119046
|
+
const { data: paywalls, isLoading } = useListPaywallsQuery({
|
|
119047
|
+
platform_key: platformKey,
|
|
119048
|
+
page,
|
|
119049
|
+
page_size: 8,
|
|
119050
|
+
...(statusFilter !== 'all' && { is_enabled: statusFilter === 'active' }),
|
|
119051
|
+
}, { refetchOnMountOrArgChange: true });
|
|
119052
|
+
return (jsxs("div", { className: "space-y-4", children: [jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", children: [jsx("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 mb-3", children: "Configure item for sale" }), jsx(ItemSearchDropdown, { platformKey: platformKey, onSelect: (itemType, uniqueId, name) => onSelectItem(itemType, uniqueId, name) })] }) }), jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-medium text-gray-500", children: "Configured Items" }), jsxs(Select$1, { value: statusFilter, onValueChange: (v) => {
|
|
119053
|
+
setStatusFilter(v);
|
|
119054
|
+
setPage(1);
|
|
119055
|
+
}, children: [jsx(SelectTrigger, { className: "w-[130px] h-8 text-xs", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: "All" }), jsx(SelectItem, { value: "active", children: "Active" }), jsx(SelectItem, { value: "disabled", children: "Disabled" })] })] })] }), isLoading ? (jsx("div", { className: "space-y-2", children: [1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-16 w-full" }, i))) })) : (paywalls === null || paywalls === void 0 ? void 0 : paywalls.results) && paywalls.results.length > 0 ? (jsxs(Fragment$1, { children: [paywalls.results.map((pw) => {
|
|
119056
|
+
var _a;
|
|
119057
|
+
return (jsx(Card, { className: "shadow-sm border hover:border-blue-200 transition-colors cursor-pointer", style: { borderColor: 'oklch(.922 0 0)' }, onClick: () => onSelectItem(pw.item_type, pw.item_id, pw.item_name), children: jsxs(CardContent, { className: "p-4 flex items-center justify-between", children: [jsx("div", { className: "flex items-center gap-3", children: jsxs("div", { children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: pw.item_name || pw.item_id }), jsxs("div", { className: "flex items-center gap-2 mt-0.5", children: [jsx(Badge, { variant: "secondary", className: "text-xs capitalize", children: pw.item_type }), ((_a = pw.prices) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
|
|
119058
|
+
(() => {
|
|
119059
|
+
const activeCount = pw.prices.filter((p) => p.is_active).length;
|
|
119060
|
+
return activeCount > 0 ? (jsxs("span", { className: "text-xs text-gray-400", children: [activeCount, " price", activeCount !== 1 ? 's' : ''] })) : null;
|
|
119061
|
+
})()] })] }) }), jsx(Badge, { className: pw.is_enabled
|
|
119062
|
+
? 'bg-blue-100 text-blue-700 border-blue-200 hover:bg-blue-100'
|
|
119063
|
+
: 'bg-gray-100 text-gray-500 border-gray-200 hover:bg-gray-100', children: pw.is_enabled ? 'Active' : 'Disabled' })] }) }, `${pw.item_type}-${pw.item_id}`));
|
|
119064
|
+
}), (paywalls.previous_page !== null || paywalls.next_page !== null) && (jsxs("div", { className: "flex items-center justify-between pt-2", children: [jsxs("span", { className: "text-xs text-gray-400", children: [paywalls.count, " item", paywalls.count !== 1 ? 's' : '', " total"] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button$1, { variant: "outline", size: "sm", disabled: paywalls.previous_page === null, onClick: () => paywalls.previous_page !== null && setPage(paywalls.previous_page), className: "h-7 text-xs cursor-pointer", children: "Previous" }), jsxs("span", { className: "text-xs text-gray-500", children: ["Page ", page] }), jsx(Button$1, { variant: "outline", size: "sm", disabled: paywalls.next_page === null, onClick: () => paywalls.next_page !== null && setPage(paywalls.next_page), className: "h-7 text-xs cursor-pointer", children: "Next" })] })] }))] })) : (jsx("p", { className: "text-sm text-gray-400 text-center py-6", children: statusFilter !== 'all'
|
|
119065
|
+
? `No ${statusFilter} items found.`
|
|
119066
|
+
: 'No items configured yet. Search and select a mentor above.' }))] })] }));
|
|
119067
|
+
}
|
|
119068
|
+
// ── Paywall Detail Editor ──
|
|
119069
|
+
function PaywallDetail({ platformKey, itemType, itemId, itemName, onBack, }) {
|
|
119070
|
+
const { data: config, isLoading, refetch: refetchConfig, } = useGetPaywallConfigQuery({ platform_key: platformKey, item_type: itemType, item_id: itemId }, { refetchOnMountOrArgChange: true });
|
|
119071
|
+
const [enablePaywall, { isLoading: isEnabling }] = useEnablePaywallMutation();
|
|
119072
|
+
const [disablePaywall, { isLoading: isDisabling }] = useDisablePaywallMutation();
|
|
119073
|
+
const [isEnabled, setIsEnabled] = useState(false);
|
|
119074
|
+
const [allowFreeTier, setAllowFreeTier] = useState(false);
|
|
119075
|
+
const [trialDays, setTrialDays] = useState(0);
|
|
119076
|
+
const [grandfathering, setGrandfathering] = useState('free_forever');
|
|
119077
|
+
useEffect(() => {
|
|
119078
|
+
if (config) {
|
|
119079
|
+
setIsEnabled(config.is_enabled);
|
|
119080
|
+
setAllowFreeTier(config.allow_free_tier);
|
|
119081
|
+
setTrialDays(config.trial_period_days);
|
|
119082
|
+
setGrandfathering(config.grandfathering_strategy);
|
|
119083
|
+
}
|
|
119084
|
+
}, [config]);
|
|
119085
|
+
const handleTogglePaywall = async (enabled) => {
|
|
119086
|
+
try {
|
|
119087
|
+
if (enabled) {
|
|
119088
|
+
await enablePaywall({
|
|
119089
|
+
platform_key: platformKey,
|
|
119090
|
+
item_type: itemType,
|
|
119091
|
+
item_id: itemId,
|
|
119092
|
+
is_enabled: true,
|
|
119093
|
+
allow_free_tier: allowFreeTier,
|
|
119094
|
+
trial_period_days: trialDays,
|
|
119095
|
+
grandfathering_strategy: grandfathering,
|
|
119096
|
+
}).unwrap();
|
|
119097
|
+
toast.success('Paywall enabled');
|
|
119098
|
+
}
|
|
119099
|
+
else {
|
|
119100
|
+
await disablePaywall({
|
|
119101
|
+
platform_key: platformKey,
|
|
119102
|
+
item_type: itemType,
|
|
119103
|
+
item_id: itemId,
|
|
119104
|
+
}).unwrap();
|
|
119105
|
+
toast.success('Paywall disabled');
|
|
119106
|
+
}
|
|
119107
|
+
setIsEnabled(enabled);
|
|
119108
|
+
refetchConfig();
|
|
119109
|
+
}
|
|
119110
|
+
catch (_a) {
|
|
119111
|
+
toast.error(`Failed to ${enabled ? 'enable' : 'disable'} paywall`);
|
|
119112
|
+
}
|
|
119113
|
+
};
|
|
119114
|
+
const handleSaveConfig = async () => {
|
|
119115
|
+
try {
|
|
119116
|
+
await enablePaywall({
|
|
119117
|
+
platform_key: platformKey,
|
|
119118
|
+
item_type: itemType,
|
|
119119
|
+
item_id: itemId,
|
|
119120
|
+
is_enabled: isEnabled,
|
|
119121
|
+
allow_free_tier: allowFreeTier,
|
|
119122
|
+
trial_period_days: trialDays,
|
|
119123
|
+
grandfathering_strategy: grandfathering,
|
|
119124
|
+
}).unwrap();
|
|
119125
|
+
toast.success('Paywall configuration updated');
|
|
119126
|
+
refetchConfig();
|
|
119127
|
+
}
|
|
119128
|
+
catch (_a) {
|
|
119129
|
+
toast.error('Failed to update paywall configuration');
|
|
119130
|
+
}
|
|
119131
|
+
};
|
|
119132
|
+
if (isLoading) {
|
|
119133
|
+
return (jsxs("div", { className: "space-y-4", children: [jsx(Skeleton, { className: "h-8 w-48" }), jsx(Skeleton, { className: "h-64 w-full" })] }));
|
|
119134
|
+
}
|
|
119135
|
+
const displayName = (config === null || config === void 0 ? void 0 : config.item_name) || itemName || itemId;
|
|
119136
|
+
return (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsxs(Button$1, { variant: "ghost", size: "sm", onClick: onBack, className: "cursor-pointer", children: [jsx(ChevronLeft, { className: "h-4 w-4 mr-1" }), "Back"] }), jsxs("div", { children: [jsx("h4", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: displayName }), jsx("span", { className: "text-xs text-gray-400 capitalize", children: itemType })] })] }), jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-6 space-y-5", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Paywall Enabled" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "Require payment to access this item" })] }), jsx(Switch, { checked: isEnabled, onCheckedChange: handleTogglePaywall, disabled: isEnabling || isDisabling, className: "cursor-pointer data-[state=checked]:bg-blue-500" })] }), jsxs("div", { className: !isEnabled ? 'opacity-50 pointer-events-none' : '', children: [jsxs("div", { className: "flex items-center justify-between py-3 border-t", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Allow Free Tier" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "Let users access basic features without paying" })] }), jsx(Switch, { checked: allowFreeTier, onCheckedChange: setAllowFreeTier, className: "cursor-pointer data-[state=checked]:bg-blue-500" })] }), jsxs("div", { className: "flex items-center justify-between py-3 border-t", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Trial Period (days)" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "Free trial before charging subscribers" })] }), jsx(Input, { type: "number", min: 0, value: trialDays, onChange: (e) => setTrialDays(parseInt(e.target.value) || 0), className: "w-24 text-right" })] }), jsxs("div", { className: "flex items-center justify-between py-3 border-t", children: [jsxs("div", { children: [jsx(Label, { className: "text-sm font-medium", children: "Existing Users" }), jsx("p", { className: "text-xs text-gray-400 mt-0.5", children: "How to treat users who had access before the paywall" })] }), jsxs(Select$1, { value: grandfathering, onValueChange: (v) => setGrandfathering(v), children: [jsx(SelectTrigger, { className: "w-[180px]", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "free_forever", children: "Free Forever" }), jsx(SelectItem, { value: "require_subscription", children: "Require Subscription" })] })] })] }), jsx("div", { className: "pt-3 border-t", children: jsxs(Button$1, { onClick: handleSaveConfig, disabled: isEnabling, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white cursor-pointer", children: [isEnabling ? (jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" })) : (jsx(Check, { className: "h-4 w-4 mr-2" })), "Save Configuration"] }) })] })] }) }), isEnabled && (jsx(PriceManagement, { platformKey: platformKey, itemType: itemType, itemId: itemId }))] }));
|
|
119137
|
+
}
|
|
119138
|
+
// ── Main Export ──
|
|
119139
|
+
function PaywallConfig({ platformKey, disabled }) {
|
|
119140
|
+
const [selectedItem, setSelectedItem] = useState(null);
|
|
119141
|
+
if (disabled) {
|
|
119142
|
+
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." })] }) }));
|
|
119143
|
+
}
|
|
119144
|
+
if (selectedItem) {
|
|
119145
|
+
return (jsx(PaywallDetail, { platformKey: platformKey, itemType: selectedItem.type, itemId: selectedItem.id, itemName: selectedItem.name, onBack: () => setSelectedItem(null) }));
|
|
119146
|
+
}
|
|
119147
|
+
return (jsx(PaywalledItemsList, { platformKey: platformKey, onSelectItem: (type, id, name) => setSelectedItem({ type, id, name }) }));
|
|
119148
|
+
}
|
|
119149
|
+
|
|
119150
|
+
function MonetizationTab({ platformKey }) {
|
|
119151
|
+
var _a;
|
|
119152
|
+
const { data: stripeStatus } = useGetStripeConnectStatusQuery({ platform_key: platformKey }, { refetchOnMountOrArgChange: true });
|
|
119153
|
+
const isStripeReady = (_a = stripeStatus === null || stripeStatus === void 0 ? void 0 : stripeStatus.is_ready_for_payments) !== null && _a !== void 0 ? _a : false;
|
|
119154
|
+
return (jsxs("div", { className: "container mx-auto max-w-7xl !mt-0 space-y-6", children: [jsx(StripeConnect, { platformKey: platformKey }), jsx(PaywallConfig, { platformKey: platformKey, disabled: !isStripeReady })] }));
|
|
119155
|
+
}
|
|
119156
|
+
|
|
118640
119157
|
function Account({ tenant, tenants = [], username, onInviteClick, billingURL = '', topUpURL = '', userActiveApp = null, showPlatformName = false, isAdmin = false, targetTab = 'basic', currentPlan: _currentPlan = '', currentSPA = '', authURL, onTenantUpdate, currentPlatformBaseDomain = '', enableRbac = false, rbacPermissions = {}, onLoadGroupPermissions, onTabChange, onUpgradeClick, }) {
|
|
118641
119158
|
const TABS = [
|
|
118642
119159
|
{ id: 'organization', label: 'Organization', icon: Briefcase },
|
|
118643
119160
|
{ id: 'management', label: 'Management', icon: Users },
|
|
118644
119161
|
{ id: 'integrations', label: 'Integrations', icon: KeyRound },
|
|
119162
|
+
{ id: 'monetization', label: 'Monetization', icon: Coins },
|
|
118645
119163
|
{ id: 'advanced', label: 'Advanced', icon: Settings },
|
|
118646
119164
|
];
|
|
118647
119165
|
const [activeTab, setActiveTab] = useState(targetTab);
|
|
@@ -118678,10 +119196,15 @@ function Account({ tenant, tenants = [], username, onInviteClick, billingURL = '
|
|
|
118678
119196
|
}
|
|
118679
119197
|
}).map((tab) => (jsxs("button", { onClick: () => {
|
|
118680
119198
|
setActiveTab(tab.id);
|
|
118681
|
-
// Clear URL param when switching away from billing
|
|
118682
|
-
if (activeTab === 'billing'
|
|
119199
|
+
// Clear URL param when switching away from billing/monetization
|
|
119200
|
+
if ((activeTab === 'billing' || activeTab === 'monetization') &&
|
|
119201
|
+
tab.id !== 'billing' &&
|
|
119202
|
+
tab.id !== 'monetization') {
|
|
118683
119203
|
onTabChange === null || onTabChange === void 0 ? void 0 : onTabChange('');
|
|
118684
119204
|
}
|
|
119205
|
+
if (tab.id === 'monetization') {
|
|
119206
|
+
onTabChange === null || onTabChange === void 0 ? void 0 : onTabChange('monetization');
|
|
119207
|
+
}
|
|
118685
119208
|
}, className: `w-full justify-start px-4 py-3 text-left rounded-lg transition-all flex items-center text-base ${activeTab === tab.id
|
|
118686
119209
|
? 'bg-blue-50 text-blue-700 font-medium'
|
|
118687
119210
|
: 'hover:bg-gray-50 text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100'}`, children: [jsx(tab.icon, { className: "h-5 w-5 mr-3 flex-shrink-0" }), jsx("span", { className: "truncate", children: tab.label })] }, tab.id))), (billingURL || topUpURL) && (jsxs("button", { onClick: () => {
|
|
@@ -118699,10 +119222,15 @@ function Account({ tenant, tenants = [], username, onInviteClick, billingURL = '
|
|
|
118699
119222
|
}
|
|
118700
119223
|
}).map((tab) => (jsxs("button", { onClick: () => {
|
|
118701
119224
|
setActiveTab(tab.id);
|
|
118702
|
-
// Clear URL param when switching away from billing
|
|
118703
|
-
if (activeTab === 'billing'
|
|
119225
|
+
// Clear URL param when switching away from billing/monetization
|
|
119226
|
+
if ((activeTab === 'billing' || activeTab === 'monetization') &&
|
|
119227
|
+
tab.id !== 'billing' &&
|
|
119228
|
+
tab.id !== 'monetization') {
|
|
118704
119229
|
onTabChange === null || onTabChange === void 0 ? void 0 : onTabChange('');
|
|
118705
119230
|
}
|
|
119231
|
+
if (tab.id === 'monetization') {
|
|
119232
|
+
onTabChange === null || onTabChange === void 0 ? void 0 : onTabChange('monetization');
|
|
119233
|
+
}
|
|
118706
119234
|
}, className: `flex items-center gap-2 px-3 py-2 rounded-lg whitespace-nowrap text-sm transition-all ${activeTab === tab.id
|
|
118707
119235
|
? 'bg-blue-50 text-blue-600 font-medium'
|
|
118708
119236
|
: 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(tab.icon, { className: "h-4 w-4" }), jsx("span", { className: "hidden sm:inline", children: tab.label }), jsx("span", { className: "sm:hidden", children: tab.label })] }, tab.id))), (billingURL || topUpURL) && (jsxs("button", { onClick: () => {
|
|
@@ -118711,10 +119239,10 @@ function Account({ tenant, tenants = [], username, onInviteClick, billingURL = '
|
|
|
118711
119239
|
onTabChange === null || onTabChange === void 0 ? void 0 : onTabChange('billing');
|
|
118712
119240
|
}, className: `flex items-center gap-2 px-3 py-2 rounded-lg whitespace-nowrap text-sm transition-all ${activeTab === 'billing'
|
|
118713
119241
|
? 'bg-blue-50 text-blue-600 font-medium'
|
|
118714
|
-
: 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(CreditCard, { className: "h-4 w-4" }), jsx("span", { className: "hidden sm:inline", children: "Billing" }), jsx("span", { className: "sm:hidden", children: "Billing" })] }, 'billing'))] }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsxs("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'management' && 'Manage users and their permissions in the system.', activeTab === 'organization' && 'Manage your organization settings.', activeTab === 'integrations' && 'Manage your integrations with other services.', activeTab === 'billing' && 'Manage your billing and subscription.', activeTab === 'advanced' && 'Configure advanced organization settings.'] })] }), jsxs("div", { className: "flex-1 p-6 space-y-6", style: {
|
|
119242
|
+
: 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(CreditCard, { className: "h-4 w-4" }), jsx("span", { className: "hidden sm:inline", children: "Billing" }), jsx("span", { className: "sm:hidden", children: "Billing" })] }, 'billing'))] }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsxs("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'management' && 'Manage users and their permissions in the system.', activeTab === 'organization' && 'Manage your organization settings.', activeTab === 'integrations' && 'Manage your integrations with other services.', activeTab === 'billing' && 'Manage your billing and subscription.', activeTab === 'monetization' && 'Configure paywalls, pricing, and revenue.', activeTab === 'advanced' && 'Configure advanced organization settings.'] })] }), jsxs("div", { className: "flex-1 p-6 space-y-6", style: {
|
|
118715
119243
|
overflowY: 'auto',
|
|
118716
119244
|
overflowX: 'hidden',
|
|
118717
|
-
}, children: [jsxs("div", { className: "lg:hidden mb-6", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'basic' && 'Manage your basic account information and preferences.', activeTab === 'social' && 'Connect and manage your social media accounts.', activeTab === 'security' && 'Update your security settings and password.', activeTab === 'management' && 'Manage users and their permissions in the system.', activeTab === 'organization' && 'Manage your organization settings.', activeTab === 'advanced' && 'Configure advanced organization settings.'] })] }), activeTab === 'management' && hasManagementPermissions && (jsx(Admin, { onInviteClick: onInviteClick, tenant: tenant, hasUserTabPermission: hasUserTabPermission, hasGroupsTabPermission: hasGroupsTabPermission, hasPoliciesTabPermission: hasPoliciesTabPermission, hasRolesTabPermission: hasRolesTabPermission, hasTeamsTabPermission: hasTeamsTabPermission, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac })), activeTab === 'organization' && (jsx(OrganizationTab, { platformKey: tenant, tenant: tenants.find((t) => t.key === tenant), onTenantUpdate: onTenantUpdate, setOrganizationLogoFromOutside: setOrganizationLogo })), activeTab === 'integrations' && (jsx(IntegrationsTab, { tenantKey: tenant, username: username })), activeTab === 'billing' && (jsx(BillingTab, { tenant: tenant, topUpURL: topUpURL, userActiveApp: userActiveApp, username: username, onUpgradeClick: onUpgradeClick })), activeTab === 'advanced' && (jsx(AdvancedTab, { platformKey: tenant, currentSPA: currentSPA, username: username, authURL: authURL, currentPlatformBaseDomain: currentPlatformBaseDomain }))] })] }), jsx(ToastProvider, {})] }));
|
|
119245
|
+
}, children: [jsxs("div", { className: "lg:hidden mb-6", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'basic' && 'Manage your basic account information and preferences.', activeTab === 'social' && 'Connect and manage your social media accounts.', activeTab === 'security' && 'Update your security settings and password.', activeTab === 'management' && 'Manage users and their permissions in the system.', activeTab === 'organization' && 'Manage your organization settings.', activeTab === 'monetization' && 'Configure paywalls, pricing, and revenue.', activeTab === 'advanced' && 'Configure advanced organization settings.'] })] }), activeTab === 'management' && hasManagementPermissions && (jsx(Admin, { onInviteClick: onInviteClick, tenant: tenant, hasUserTabPermission: hasUserTabPermission, hasGroupsTabPermission: hasGroupsTabPermission, hasPoliciesTabPermission: hasPoliciesTabPermission, hasRolesTabPermission: hasRolesTabPermission, hasTeamsTabPermission: hasTeamsTabPermission, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac })), activeTab === 'organization' && (jsx(OrganizationTab, { platformKey: tenant, tenant: tenants.find((t) => t.key === tenant), onTenantUpdate: onTenantUpdate, setOrganizationLogoFromOutside: setOrganizationLogo })), activeTab === 'integrations' && (jsx(IntegrationsTab, { tenantKey: tenant, username: username })), activeTab === 'billing' && (jsx(BillingTab, { tenant: tenant, topUpURL: topUpURL, userActiveApp: userActiveApp, username: username, onUpgradeClick: onUpgradeClick })), activeTab === 'monetization' && jsx(MonetizationTab, { platformKey: tenant }), activeTab === 'advanced' && (jsx(AdvancedTab, { platformKey: tenant, currentSPA: currentSPA, username: username, authURL: authURL, currentPlatformBaseDomain: currentPlatformBaseDomain }))] })] }), jsx(ToastProvider, {})] }));
|
|
118718
119246
|
}
|
|
118719
119247
|
|
|
118720
119248
|
function UserProfileModal({ isOpen, onClose, params, billingEnabled = false, billingURL = '', topUpEnabled = false, topUpURL = '', showMentorAIDisplayCheckbox = false, showLeaderboardDisplayCheckbox = false, showUsernameField = false, showPlatformName = false, useGravatarPicFallback = true, enableCatalogInvite = false, targetTab = 'basic', currentPlan = '', currentSPA = '', userActiveApp = null, authURL, tenants = [], onTenantUpdate, currentPlatformBaseDomain = '', rbacPermissions = {}, enableRbac = false, onLoadGroupPermissions, onTabChange, onUpgradeClick, onBillingTabRequest, onAccountDeleted, enableMemoryTab = false, localLLMProps, }) {
|
|
@@ -118793,7 +119321,7 @@ function UserProfileModal({ isOpen, onClose, params, billingEnabled = false, bil
|
|
|
118793
119321
|
showUsernameField: showUsernameField,
|
|
118794
119322
|
showPlatformName: showPlatformName,
|
|
118795
119323
|
useGravatarPicFallback: useGravatarPicFallback,
|
|
118796
|
-
}, isAdmin: params.isAdmin, targetTab: targetTab, onClose: onClose, onAccountDeleted: onAccountDeleted, enableMemoryTab: enableMemoryTab, localLLMProps: localLLMProps })), ['organization', 'management', 'integrations', 'billing'].includes(targetTab) && (jsxs(Fragment$1, { children: [jsx(Account, { onInviteClick: () => setIsInviteUserDialogOpen(true), tenant: params.tenantKey, tenants: tenants, username: getUserName(), billingEnabled: !!stripeBillingURL, billingURL: stripeBillingURL, topUpEnabled: !!stripeTopUpURL, topUpURL: stripeTopUpURL, showUsernameField: showUsernameField, showPlatformName: showPlatformName, useGravatarPicFallback: useGravatarPicFallback, onClose: onClose, isAdmin: params.isAdmin, targetTab: targetTab, currentPlan: currentPlan, currentSPA: currentSPA, userActiveApp: userActiveApp, authURL: authURL, onTenantUpdate: onTenantUpdate, currentPlatformBaseDomain: currentPlatformBaseDomain, rbacPermissions: rbacPermissions, enableRbac: enableRbac, onLoadGroupPermissions: onLoadGroupPermissions, onTabChange: onTabChange, onUpgradeClick: onUpgradeClick }), isInviteUserDialogOpen && (jsx(InviteUserDialog, { tenant: params.tenantKey, onClose: () => setIsInviteUserDialogOpen(false), isOpen: isInviteUserDialogOpen, enableCatalogInvite: enableCatalogInvite, hasManageUsersPermission: hasManageUsersPermission })), isInvitedUsersDialogOpen && (jsx(InvitedUsersDialog, { onClose: () => setIsInvitedUsersDialogOpen(false), tenant: params.tenantKey }))] }))] }) }) }));
|
|
119324
|
+
}, isAdmin: params.isAdmin, targetTab: targetTab, onClose: onClose, onAccountDeleted: onAccountDeleted, enableMemoryTab: enableMemoryTab, localLLMProps: localLLMProps })), ['organization', 'management', 'integrations', 'billing', 'monetization'].includes(targetTab) && (jsxs(Fragment$1, { children: [jsx(Account, { onInviteClick: () => setIsInviteUserDialogOpen(true), tenant: params.tenantKey, tenants: tenants, username: getUserName(), billingEnabled: !!stripeBillingURL, billingURL: stripeBillingURL, topUpEnabled: !!stripeTopUpURL, topUpURL: stripeTopUpURL, showUsernameField: showUsernameField, showPlatformName: showPlatformName, useGravatarPicFallback: useGravatarPicFallback, onClose: onClose, isAdmin: params.isAdmin, targetTab: targetTab, currentPlan: currentPlan, currentSPA: currentSPA, userActiveApp: userActiveApp, authURL: authURL, onTenantUpdate: onTenantUpdate, currentPlatformBaseDomain: currentPlatformBaseDomain, rbacPermissions: rbacPermissions, enableRbac: enableRbac, onLoadGroupPermissions: onLoadGroupPermissions, onTabChange: onTabChange, onUpgradeClick: onUpgradeClick }), isInviteUserDialogOpen && (jsx(InviteUserDialog, { tenant: params.tenantKey, onClose: () => setIsInviteUserDialogOpen(false), isOpen: isInviteUserDialogOpen, enableCatalogInvite: enableCatalogInvite, hasManageUsersPermission: hasManageUsersPermission })), isInvitedUsersDialogOpen && (jsx(InvitedUsersDialog, { onClose: () => setIsInvitedUsersDialogOpen(false), tenant: params.tenantKey }))] }))] }) }) }));
|
|
118797
119325
|
}
|
|
118798
119326
|
|
|
118799
119327
|
// Tauri types for model download functionality
|