refactor(App): extract Shell wrapper for locale+titlebar chrome (P1-20)

Collapse two near-identical LocaleContext/TranslationContext/TitleBar
wrapper blocks into a single Shell component.
This commit is contained in:
ZacharyZhang-NY committed 2026-04-16 22:53:56 -04:00
1 parent 3deb1c00ac
commit a07b42e493
1 file changed
+51 -35
+51 -35
View File
@@ -1,6 +1,7 @@
import { useCallback, useMemo } from "react";
import { useCallback, useMemo, type ReactNode } from "react";
import { CircleNotch, TerminalWindow } from "@phosphor-icons/react";
import { LocaleContext, TranslationContext } from "./i18n";
import { LocaleContext, TranslationContext, type TranslationFn } from "./i18n";
import type { AppLocale } from "@shared/locale";
import { CompanyOnboarding } from "./components/CompanyOnboarding";
import TitleBar from "./components/TitleBar";
import ToastContainer from "./components/Toast";
@@ -15,6 +16,31 @@ import { useCommandPaletteHotkeys } from "./hooks/useCommandPaletteHotkeys";
import { AppActionsContext, type AppActions } from "./hooks/useAppActions";
import { unwrap } from "./lib/desktop";
function Shell({
locale,
t,
showCustomTitleBar,
className,
children,
}: {
locale: AppLocale;
t: TranslationFn;
showCustomTitleBar: boolean;
className?: string;
children: ReactNode;
}) {
return (
<LocaleContext.Provider value={locale}>
<TranslationContext.Provider value={t}>
<div className={`flex h-[100dvh] flex-col overflow-hidden${className ? " " + className : ""}`}>
{showCustomTitleBar && <TitleBar />}
{children}
</div>
</TranslationContext.Provider>
</LocaleContext.Provider>
);
}
export function App() {
const ui = useUIController();
const company = useCompanyController();
@@ -99,44 +125,34 @@ export function App() {
if (!company.snapshot) {
return (
<LocaleContext.Provider value={ui.locale}>
<TranslationContext.Provider value={ui.t}>
<div className="flex h-[100dvh] flex-col overflow-hidden">
{showCustomTitleBar && <TitleBar />}
<div className="flex min-h-0 flex-1 flex-col items-center justify-center gap-3">
<CircleNotch size={24} className="animate-spin text-primary" />
<span className="text-[13px] text-muted-foreground">{ui.t("app.loading")}</span>
</div>
</div>
</TranslationContext.Provider>
</LocaleContext.Provider>
<Shell locale={ui.locale} t={ui.t} showCustomTitleBar={showCustomTitleBar}>
<div className="flex min-h-0 flex-1 flex-col items-center justify-center gap-3">
<CircleNotch size={24} className="animate-spin text-primary" />
<span className="text-[13px] text-muted-foreground">{ui.t("app.loading")}</span>
</div>
</Shell>
);
}
if (company.snapshot.companies.length === 0 || ui.showOnboarding || ui.initialOnboardingLocked) {
return (
<LocaleContext.Provider value={ui.locale}>
<TranslationContext.Provider value={ui.t}>
<div className="flex h-[100dvh] flex-col overflow-hidden">
{showCustomTitleBar && <TitleBar />}
<div className="min-h-0 flex-1 overflow-auto">
<CompanyOnboarding
connectors={company.snapshot.connectors}
onDone={company.handleOnboardingDone}
canCancel={company.snapshot.companies.length > 0 && !ui.initialOnboardingLocked}
onCancel={() => {
ui.setShowOnboarding(false);
ui.setInitialOnboardingLocked(false);
setError(null);
}}
currentLocale={ui.locale}
onLocaleChange={ui.handleLocaleChange}
isFirstLaunch={company.snapshot.companies.length === 0}
/>
</div>
</div>
</TranslationContext.Provider>
</LocaleContext.Provider>
<Shell locale={ui.locale} t={ui.t} showCustomTitleBar={showCustomTitleBar}>
<div className="min-h-0 flex-1 overflow-auto">
<CompanyOnboarding
connectors={company.snapshot.connectors}
onDone={company.handleOnboardingDone}
canCancel={company.snapshot.companies.length > 0 && !ui.initialOnboardingLocked}
onCancel={() => {
ui.setShowOnboarding(false);
ui.setInitialOnboardingLocked(false);
setError(null);
}}
currentLocale={ui.locale}
onLocaleChange={ui.handleLocaleChange}
isFirstLaunch={company.snapshot.companies.length === 0}
/>
</div>
</Shell>
);
}