diff --git a/app/layout-content.tsx b/app/layout-content.tsx index 6cb5e9d..ef1e128 100644 --- a/app/layout-content.tsx +++ b/app/layout-content.tsx @@ -17,7 +17,7 @@ export default function LayoutContent({ children }: { children: React.ReactNode const isOnline = useOnlineStatus() const [orgs, setOrgs] = useState([]) - // * Fetch organizations for the header workspace switcher + // * Fetch organizations for the header organization switcher useEffect(() => { if (auth.user) { getUserOrganizations() @@ -27,7 +27,7 @@ export default function LayoutContent({ children }: { children: React.ReactNode }, [auth.user]) const handleSwitchOrganization = async (orgId: string | null) => { - if (!orgId) return // Pulse doesn't support personal workspace + if (!orgId) return // Pulse doesn't support personal organization context try { const { access_token } = await switchContext(orgId) await setSessionAction(access_token) diff --git a/app/welcome/page.tsx b/app/welcome/page.tsx index efd0a23..7193206 100644 --- a/app/welcome/page.tsx +++ b/app/welcome/page.tsx @@ -2,7 +2,7 @@ /** * Guided onboarding wizard for new Pulse users. - * Steps: Welcome → Workspace (create org) → Plan / trial → First site (optional) → Done. + * Steps: Welcome → Organization (create org) → Plan / trial → First site (optional) → Done. * Supports ?step= in URL for back/refresh. Handles pulse_pending_checkout from pricing. */ @@ -45,6 +45,7 @@ import { } from '@ciphera-net/ui' import Link from 'next/link' import ScriptSetupBlock from '@/components/sites/ScriptSetupBlock' +import VerificationModal from '@/components/sites/VerificationModal' const TOTAL_STEPS = 5 const DEFAULT_ORG_NAME = 'My organization' @@ -97,6 +98,7 @@ function WelcomeContent() { const [siteLoading, setSiteLoading] = useState(false) const [siteError, setSiteError] = useState('') const [createdSite, setCreatedSite] = useState(null) + const [showVerificationModal, setShowVerificationModal] = useState(false) const [redirectingCheckout, setRedirectingCheckout] = useState(false) const [hadPendingCheckout, setHadPendingCheckout] = useState(null) @@ -176,7 +178,7 @@ function WelcomeContent() { ) } - const handleWorkspaceSubmit = async (e: React.FormEvent) => { + const handleOrganizationSubmit = async (e: React.FormEvent) => { e.preventDefault() setOrgLoading(true) setOrgError('') @@ -333,7 +335,7 @@ function WelcomeContent() { 'bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-2xl shadow-sm p-8 max-w-lg mx-auto' return ( -
+
setStep(1)} - className="flex items-center gap-1.5 text-sm text-neutral-500 dark:text-neutral-400 hover:text-neutral-700 dark:hover:text-neutral-300 mb-6" + className="flex items-center gap-1.5 text-sm text-neutral-500 dark:text-neutral-400 hover:text-neutral-700 dark:hover:text-neutral-300 mb-6 focus:outline-none focus:ring-2 focus:ring-brand-orange rounded" aria-label="Back to welcome" > @@ -483,14 +485,14 @@ function WelcomeContent() {
-

+

Name your organization -

+

You can change this later in settings.

-
+
- {showPendingCheckoutInStep3 && ( + {showPendingCheckoutInStep3 ? (

+ ) : ( +

+ + View pricing + +

)} )} @@ -630,7 +631,7 @@ function WelcomeContent() {
@@ -723,9 +724,9 @@ function WelcomeContent() {
-

+

You're all set -

+

{createdSite ? `"${createdSite.name}" is ready. Add the script to your site to start collecting data.` @@ -742,6 +743,21 @@ function WelcomeContent() {

)} + {createdSite && ( +
+ +

+ Check if your site is sending data correctly. +

+
+ )} +
)}
+ + {createdSite && ( + setShowVerificationModal(false)} + site={createdSite} + /> + )} )} diff --git a/components/WorkspaceSwitcher.tsx b/components/WorkspaceSwitcher.tsx index 123b2c9..a177337 100644 --- a/components/WorkspaceSwitcher.tsx +++ b/components/WorkspaceSwitcher.tsx @@ -7,16 +7,16 @@ import { switchContext, OrganizationMember } from '@/lib/api/organization' import { setSessionAction } from '@/app/actions/auth' import Link from 'next/link' -export default function WorkspaceSwitcher({ orgs, activeOrgId }: { orgs: OrganizationMember[], activeOrgId: string | null }) { +export default function OrganizationSwitcher({ orgs, activeOrgId }: { orgs: OrganizationMember[], activeOrgId: string | null }) { const router = useRouter() const [switching, setSwitching] = useState(null) - + const handleSwitch = async (orgId: string | null) => { - console.log('Switching to workspace:', orgId) + console.log('Switching to organization:', orgId) setSwitching(orgId || 'personal') try { // * If orgId is null, we can't switch context via API in the same way if strict mode is on - // * BUT, Pulse doesn't support personal workspace. + // * Pulse doesn't support personal organization context. // * So we should probably NOT show the "Personal" option in Pulse if strict mode is enforced. // * However, to match Drop exactly, we might want to show it but have it fail or redirect? // * Let's assume for now we want to match Drop's UI structure. @@ -38,7 +38,7 @@ export default function WorkspaceSwitcher({ orgs, activeOrgId }: { orgs: Organiz window.location.reload() } catch (err) { - console.error('Failed to switch workspace', err) + console.error('Failed to switch organization', err) setSwitching(null) } } @@ -46,10 +46,10 @@ export default function WorkspaceSwitcher({ orgs, activeOrgId }: { orgs: Organiz return (
- Workspaces + Organizations
- - {/* Personal Workspace - HIDDEN IN PULSE (Strict Mode) */} + + {/* Personal organization - HIDDEN IN PULSE (Strict Mode) */} {/* */} - {/* Organization Workspaces */} + {/* Organization list */} {orgs.map((org) => (
) }