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:
1 parent
3deb1c00ac
commit
a07b42e493
1 file changed
+51
-35
+51
-35
@@ -1,6 +1,7 @@
|
|||||||
import { useCallback, useMemo } from "react";
|
import { useCallback, useMemo, type ReactNode } from "react";
|
||||||
import { CircleNotch, TerminalWindow } from "@phosphor-icons/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 { CompanyOnboarding } from "./components/CompanyOnboarding";
|
||||||
import TitleBar from "./components/TitleBar";
|
import TitleBar from "./components/TitleBar";
|
||||||
import ToastContainer from "./components/Toast";
|
import ToastContainer from "./components/Toast";
|
||||||
@@ -15,6 +16,31 @@ import { useCommandPaletteHotkeys } from "./hooks/useCommandPaletteHotkeys";
|
|||||||
import { AppActionsContext, type AppActions } from "./hooks/useAppActions";
|
import { AppActionsContext, type AppActions } from "./hooks/useAppActions";
|
||||||
import { unwrap } from "./lib/desktop";
|
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() {
|
export function App() {
|
||||||
const ui = useUIController();
|
const ui = useUIController();
|
||||||
const company = useCompanyController();
|
const company = useCompanyController();
|
||||||
@@ -99,44 +125,34 @@ export function App() {
|
|||||||
|
|
||||||
if (!company.snapshot) {
|
if (!company.snapshot) {
|
||||||
return (
|
return (
|
||||||
<LocaleContext.Provider value={ui.locale}>
|
<Shell locale={ui.locale} t={ui.t} showCustomTitleBar={showCustomTitleBar}>
|
||||||
<TranslationContext.Provider value={ui.t}>
|
<div className="flex min-h-0 flex-1 flex-col items-center justify-center gap-3">
|
||||||
<div className="flex h-[100dvh] flex-col overflow-hidden">
|
<CircleNotch size={24} className="animate-spin text-primary" />
|
||||||
{showCustomTitleBar && <TitleBar />}
|
<span className="text-[13px] text-muted-foreground">{ui.t("app.loading")}</span>
|
||||||
<div className="flex min-h-0 flex-1 flex-col items-center justify-center gap-3">
|
</div>
|
||||||
<CircleNotch size={24} className="animate-spin text-primary" />
|
</Shell>
|
||||||
<span className="text-[13px] text-muted-foreground">{ui.t("app.loading")}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TranslationContext.Provider>
|
|
||||||
</LocaleContext.Provider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (company.snapshot.companies.length === 0 || ui.showOnboarding || ui.initialOnboardingLocked) {
|
if (company.snapshot.companies.length === 0 || ui.showOnboarding || ui.initialOnboardingLocked) {
|
||||||
return (
|
return (
|
||||||
<LocaleContext.Provider value={ui.locale}>
|
<Shell locale={ui.locale} t={ui.t} showCustomTitleBar={showCustomTitleBar}>
|
||||||
<TranslationContext.Provider value={ui.t}>
|
<div className="min-h-0 flex-1 overflow-auto">
|
||||||
<div className="flex h-[100dvh] flex-col overflow-hidden">
|
<CompanyOnboarding
|
||||||
{showCustomTitleBar && <TitleBar />}
|
connectors={company.snapshot.connectors}
|
||||||
<div className="min-h-0 flex-1 overflow-auto">
|
onDone={company.handleOnboardingDone}
|
||||||
<CompanyOnboarding
|
canCancel={company.snapshot.companies.length > 0 && !ui.initialOnboardingLocked}
|
||||||
connectors={company.snapshot.connectors}
|
onCancel={() => {
|
||||||
onDone={company.handleOnboardingDone}
|
ui.setShowOnboarding(false);
|
||||||
canCancel={company.snapshot.companies.length > 0 && !ui.initialOnboardingLocked}
|
ui.setInitialOnboardingLocked(false);
|
||||||
onCancel={() => {
|
setError(null);
|
||||||
ui.setShowOnboarding(false);
|
}}
|
||||||
ui.setInitialOnboardingLocked(false);
|
currentLocale={ui.locale}
|
||||||
setError(null);
|
onLocaleChange={ui.handleLocaleChange}
|
||||||
}}
|
isFirstLaunch={company.snapshot.companies.length === 0}
|
||||||
currentLocale={ui.locale}
|
/>
|
||||||
onLocaleChange={ui.handleLocaleChange}
|
</div>
|
||||||
isFirstLaunch={company.snapshot.companies.length === 0}
|
</Shell>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TranslationContext.Provider>
|
|
||||||
</LocaleContext.Provider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user