velxio/frontend/src/lib/proSaveAction.ts

50 lines
1.7 KiB
TypeScript
Raw Normal View History

refactor(oss-split): remove auth/admin/profile frontend from OSS Phase 3 of the OSS / pro split — frontend side. Phase 2 already moved the auth/DB stack out of the OSS backend; this commit does the same for the React app. After this, the OSS image is editor + simulator + landing + docs only. What moved to the private overlay (pro/frontend/src/pro/): pages/{Login,Register,ForgotPassword,ResetPassword}Page.tsx pages/{Admin,UserProfile,Project,ProjectById}Page.tsx components/admin/{AdminBoardsTab,AdminDashboardTab,UserActivityModal}.tsx components/layout/{SaveProjectModal,LoginPromptModal}.tsx services/{authService,adminService}.ts store/useAuthStore.ts hooks/autoSaveImpl.ts New seams added so OSS components stay decoupled: * lib/proRoutes.ts — registerProRoutes()/useProRoutes() via useSyncExternalStore. mountPro() injects the moved pages at runtime; App.tsx subscribes to the registry, so registration after the initial render re-renders without a Not-Found flash. * lib/proSession.ts — registerSessionCheck()/triggerSessionCheck(). App.tsx fires this on mount instead of useAuthStore.checkSession(); pure OSS no-ops. * lib/proSaveAction.ts — installSaveActionImpl()/triggerSaveAction(). EditorPage's Save button dispatches through this; the overlay decides whether to show SaveProjectModal or LoginPromptModal based on auth state. In OSS without an overlay it's a no-op today; in Phase 4 of the split it becomes the .vlx Export entry point. OSS-side rewrites: * App.tsx drops the 8 page imports + 8 route entries; uses triggerSessionCheck() instead of useAuthStore directly. * AppHeader.tsx drops the user/login/register block entirely. The header-auth slot (introduced in Phase 1) now stays empty in OSS and gets filled by the overlay's portal mount. * EditorPage.tsx drops useAuthStore + SaveProjectModal + LoginPromptModal imports. The Save handler is now triggerSaveAction(). * LandingPage.tsx drops the dead UserMenu component (defined but never rendered) + its useAuthStore imports. * main.tsx drops the side-effect import of hooks/autoSaveImpl — the impl lives in pro now and self-registers via mountPro(). Build config: * vite.config.ts adds @velxio alias → src/. Lets the overlay import upstream modules (lib/proRoutes etc.) by stable name regardless of whether it's symlinked (local dev) or COPYed (Docker). * preserveSymlinks now gated on VITE_PRO_BUILD only (not on serve mode). Needed so Rollup keeps the overlay logically inside src/pro/ during local junction-based builds. Build verification: * OSS-only: 20-ish routes, no /login, /admin, /:username — 285 SEO pages prerendered. Bundle drops ~80-120 KB. * OSS + overlay: full 38 routes (30 upstream + 8 from registerProRoutes), HeaderAuth dropdown injected via slot, save action wired to the overlay's modal flow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 01:31:12 +07:00
/**
* Pro save-action registry.
*
* EditorPage used to import useAuthStore + SaveProjectModal + LoginPromptModal
* directly, branching on `user` to decide which modal to open when the
* user pressed Save. After Phase 3 of the OSS split, all of those live
* in the pro overlay. The OSS editor exposes a stable `triggerSaveAction()`
* that:
*
* - In OSS without an overlay no-op (in Phase 4 this becomes the
* entry point for the .vlx Export dialog so anonymous users still
* have a way to persist work).
* - With the pro overlay loaded dispatches to the registered impl,
* which inspects the auth store and opens SaveProjectModal (logged
* in) or LoginPromptModal (anonymous).
*
* Impl receives no arguments and returns nothing. State lives in the
* overlay's React tree (modal open/close, project data) this registry
* is just the doorbell.
*/
let _impl: (() => void) | null = null;
export function installSaveActionImpl(impl: (() => void) | null): void {
_impl = impl;
}
export function triggerSaveAction(): void {
if (_impl) {
try {
_impl();
} catch (err) {
// eslint-disable-next-line no-console
console.warn('[oss] save-action impl threw:', err);
}
} else {
// eslint-disable-next-line no-console
console.info(
'[oss] No save handler is installed. Builds without the pro overlay ' +
'will gain a local .vlx export in Phase 4 of the OSS split.',
);
}
}
/** Whether an implementation has been installed. Lets UI conditionally
* show the Save button without an impl, clicking it does nothing useful. */
export function hasSaveActionImpl(): boolean {
return _impl !== null;
}