refactor: decompose monolithic App.tsx into per-component files
- Extract views to src/components/views/ (Overview, Logbook, Trends, Settings, Auth) - Extract standalone components (EntryModal, ImportPreviewModal, ConfirmDialog, Sidebar, TopBar, MobileNav, EntryLedger, FiltersPanel, QuickAddPanel, etc.) - Move shared helpers to src/lib (dashboard, filters, userDisplay) and static data to src/data (accents, quickAdds) - App.tsx now orchestration-only (2971 -> 777 lines); no behavior change
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { AlertTriangle, Loader2 } from "lucide-react";
|
||||
import type { SetupStatus } from "../types";
|
||||
|
||||
type StatusRailProps = {
|
||||
busyAction: string | null;
|
||||
syncError: string;
|
||||
setupStatus: SetupStatus;
|
||||
};
|
||||
|
||||
export function StatusRail({ busyAction, syncError, setupStatus }: StatusRailProps) {
|
||||
if (!busyAction && !syncError && setupStatus.state === "ok") return null;
|
||||
return (
|
||||
<div className="mt-3 grid gap-2">
|
||||
{busyAction && (
|
||||
<div className="status-card">
|
||||
<Loader2 className="animate-spin" size={17} aria-hidden="true" />
|
||||
Working on {actionLabel(busyAction)}...
|
||||
</div>
|
||||
)}
|
||||
{syncError && (
|
||||
<div className="status-card" style={{ borderColor: "#ffc9c2", background: "#fff3f1", color: "#9f1c16" }}>
|
||||
<AlertTriangle size={17} aria-hidden="true" />
|
||||
{syncError}
|
||||
</div>
|
||||
)}
|
||||
{setupStatus.state === "error" && (
|
||||
<div className="status-card" style={{ borderColor: "#f9e3b0", background: "#fff8e8", color: "#7a4e00" }}>
|
||||
<AlertTriangle size={17} aria-hidden="true" />
|
||||
{setupStatus.message}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function actionLabel(value: string) {
|
||||
return value
|
||||
.replace(/^quick-/, "quick add ")
|
||||
.replace(/-/g, " ");
|
||||
}
|
||||
Reference in New Issue
Block a user