diff --git a/frontend/src/core/components/onboarding/slides/DesktopInstallSlide.tsx b/frontend/src/core/components/onboarding/slides/DesktopInstallSlide.tsx
index 4cb587385..3416c0590 100644
--- a/frontend/src/core/components/onboarding/slides/DesktopInstallSlide.tsx
+++ b/frontend/src/core/components/onboarding/slides/DesktopInstallSlide.tsx
@@ -13,9 +13,26 @@ interface DesktopInstallSlideProps {
onDownloadUrlChange?: (url: string) => void;
}
-export default function DesktopInstallSlide({ osLabel, osUrl, osOptions = [], onDownloadUrlChange }: DesktopInstallSlideProps): SlideConfig {
+const DesktopInstallBody = () => {
const { t } = useTranslation();
+ return (
+
+ {t(
+ 'onboarding.desktopInstall.body',
+ 'Stirling works best as a desktop app. You can use it offline, access documents faster, and make edits locally on your computer.',
+ )}
+
+ );
+};
+
+export default function DesktopInstallSlide({
+ osLabel,
+ osUrl,
+ osOptions = [],
+ onDownloadUrlChange,
+}: DesktopInstallSlideProps): SlideConfig {
+
return {
key: 'desktop-install',
title: (
@@ -26,11 +43,7 @@ export default function DesktopInstallSlide({ osLabel, osUrl, osOptions = [], on
onDownloadUrlChange={onDownloadUrlChange}
/>
),
- body: (
-
- {t('onboarding.desktopInstall.body', 'Stirling works best as a desktop app. You can use it offline, access documents faster, and make edits locally on your computer.')}
-
- ),
+ body: ,
downloadUrl: osUrl,
background: {
gradientStops: ['#2563EB', '#0EA5E9'],
diff --git a/frontend/src/core/components/onboarding/slides/PlanOverviewSlide.tsx b/frontend/src/core/components/onboarding/slides/PlanOverviewSlide.tsx
index e777aeff8..029cc4f8f 100644
--- a/frontend/src/core/components/onboarding/slides/PlanOverviewSlide.tsx
+++ b/frontend/src/core/components/onboarding/slides/PlanOverviewSlide.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { useTranslation } from 'react-i18next';
+import { Trans, useTranslation } from 'react-i18next';
import { SlideConfig, LicenseNotice } from '../../../types/types';
import { UNIFIED_CIRCLE_CONFIG } from './unifiedBackgroundConfig';
@@ -11,52 +11,69 @@ interface PlanOverviewSlideProps {
const DEFAULT_FREE_TIER_LIMIT = 5;
+const PlanOverviewTitle: React.FC<{ isAdmin: boolean }> = ({ isAdmin }) => {
+ const { t } = useTranslation();
+ return (
+ <>
+ {isAdmin
+ ? t('onboarding.planOverview.adminTitle', 'Admin Overview')
+ : t('onboarding.planOverview.userTitle', 'Plan Overview')}
+ >
+ );
+};
+
+const AdminOverviewBody: React.FC<{ freeTierLimit: number; loginEnabled: boolean }> = ({
+ freeTierLimit,
+ loginEnabled,
+}) => {
+ const adminBodyKey = loginEnabled
+ ? 'onboarding.planOverview.adminBodyLoginEnabled'
+ : 'onboarding.planOverview.adminBodyLoginDisabled';
+
+ const defaultValue = loginEnabled
+ ? 'As an admin, you can manage users, configure settings, and monitor server health. The first {{freeTierLimit}} people on your server get to use Stirling free of charge.'
+ : 'Once you enable login mode, you can manage users, configure settings, and monitor server health. The first {{freeTierLimit}} people on your server get to use Stirling free of charge.';
+
+ return (
+ }}
+ defaults={defaultValue}
+ />
+ );
+};
+
+const UserOverviewBody: React.FC = () => {
+ const { t } = useTranslation();
+ return (
+
+ {t(
+ 'onboarding.planOverview.userBody',
+ "Invite teammates, assign roles, and keep your documents organized in one secure workspace. Enable login mode whenever you're ready to grow beyond solo use.",
+ )}
+
+ );
+};
+
+const PlanOverviewBody: React.FC<{ isAdmin: boolean; freeTierLimit: number; loginEnabled: boolean }> = ({
+ isAdmin,
+ freeTierLimit,
+ loginEnabled,
+}) =>
+ isAdmin ? : ;
+
export default function PlanOverviewSlide({
isAdmin,
licenseNotice,
loginEnabled = false,
}: PlanOverviewSlideProps): SlideConfig {
- const { t } = useTranslation();
const freeTierLimit = licenseNotice?.freeTierLimit ?? DEFAULT_FREE_TIER_LIMIT;
- const adminBodyKey = loginEnabled
- ? 'onboarding.planOverview.adminBodyLoginEnabled'
- : 'onboarding.planOverview.adminBodyLoginDisabled';
- const adminBodyTemplate = t(adminBodyKey, {
- freeTierLimit: '{{freeTierLimit}}',
- defaultValue: loginEnabled
- ? 'As an admin, you can manage users, configure settings, and monitor server health. The first {{freeTierLimit}} people on your server get to use Stirling free of charge.'
- : 'Once you enable login mode, you can manage users, configure settings, and monitor server health. The first {{freeTierLimit}} people on your server get to use Stirling free of charge.',
- });
-
- const renderAdminBody = () => {
- const [before, after] = adminBodyTemplate.split('{{freeTierLimit}}');
- if (after !== undefined) {
- return (
-
- {before}
- {freeTierLimit}
- {after}
-
- );
- }
- return (
-
- {adminBodyTemplate.replace('{{freeTierLimit}}', String(freeTierLimit))}
-
- );
- };
-
return {
key: isAdmin ? 'admin-overview' : 'plan-overview',
- title: isAdmin
- ? t('onboarding.planOverview.adminTitle', 'Admin Overview')
- : t('onboarding.planOverview.userTitle', 'Plan Overview'),
- body: isAdmin ? renderAdminBody() : (
-
- {t('onboarding.planOverview.userBody', 'Invite teammates, assign roles, and keep your documents organized in one secure workspace. Enable login mode whenever you\'re ready to grow beyond solo use.')}
-
- ),
+ title: ,
+ body: ,
background: {
gradientStops: isAdmin ? ['#4F46E5', '#0EA5E9'] : ['#F97316', '#EF4444'],
circles: UNIFIED_CIRCLE_CONFIG,
diff --git a/frontend/src/core/components/onboarding/slides/WelcomeSlide.tsx b/frontend/src/core/components/onboarding/slides/WelcomeSlide.tsx
index 4c5dca2d2..0065da23a 100644
--- a/frontend/src/core/components/onboarding/slides/WelcomeSlide.tsx
+++ b/frontend/src/core/components/onboarding/slides/WelcomeSlide.tsx
@@ -4,28 +4,32 @@ import { SlideConfig } from '../../../types/types';
import styles from '../InitialOnboardingModal/InitialOnboardingModal.module.css';
import { UNIFIED_CIRCLE_CONFIG } from './unifiedBackgroundConfig';
-export default function WelcomeSlide(): SlideConfig {
+function WelcomeSlideTitle() {
const { t } = useTranslation();
+ return (
+
+ {t('onboarding.welcomeSlide.title', 'Welcome to Stirling')}
+ V2
+
+ );
+}
+
+const WelcomeSlideBody = () => (
+
+ }}
+ defaults="Stirling PDF is now ready for teams of all sizes. This update includes a new layout, powerful new admin capabilities, and our most requested feature - Edit Text."
+ />
+
+);
+
+export default function WelcomeSlide(): SlideConfig {
return {
key: 'welcome',
- title: (
-
- {t('onboarding.welcomeSlide.title', 'Welcome to Stirling')}
-
- V2
-
-
- ),
- body: (
-
- }}
- defaults="Stirling PDF is now ready for teams of all sizes. This update includes a new layout, powerful new admin capabilities, and our most requested feature - Edit Text."
- />
-
- ),
+ title: ,
+ body: ,
background: {
gradientStops: ['#7C3AED', '#EC4899'],
circles: UNIFIED_CIRCLE_CONFIG,