refactor: strip stats and unit switcher from top bar
Remove weight unit switcher pills and collection stats (items, weight, spent) from TotalsBar. Top bar now shows only logo/title and user menu. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,48 +1,16 @@
|
|||||||
import { Link } from "@tanstack/react-router";
|
import { Link } from "@tanstack/react-router";
|
||||||
import { useAuth } from "../hooks/useAuth";
|
import { useAuth } from "../hooks/useAuth";
|
||||||
import { useFormatters } from "../hooks/useFormatters";
|
|
||||||
import { useUpdateSetting } from "../hooks/useSettings";
|
|
||||||
import { useTotals } from "../hooks/useTotals";
|
|
||||||
import type { WeightUnit } from "../lib/formatters";
|
|
||||||
import { LucideIcon } from "../lib/iconData";
|
import { LucideIcon } from "../lib/iconData";
|
||||||
import { UserMenu } from "./UserMenu";
|
import { UserMenu } from "./UserMenu";
|
||||||
|
|
||||||
const UNITS: WeightUnit[] = ["g", "oz", "lb", "kg"];
|
|
||||||
|
|
||||||
interface TotalsBarProps {
|
interface TotalsBarProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
stats?: Array<{ label: string; value: string }>;
|
|
||||||
linkTo?: string;
|
linkTo?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TotalsBar({
|
export function TotalsBar({ title = "GearBox", linkTo }: TotalsBarProps) {
|
||||||
title = "GearBox",
|
|
||||||
stats,
|
|
||||||
linkTo,
|
|
||||||
}: TotalsBarProps) {
|
|
||||||
const { data } = useTotals();
|
|
||||||
const { data: auth } = useAuth();
|
const { data: auth } = useAuth();
|
||||||
const isAuthenticated = !!auth?.user;
|
const isAuthenticated = !!auth?.user;
|
||||||
const { weight, price, unit } = useFormatters();
|
|
||||||
const updateSetting = useUpdateSetting();
|
|
||||||
|
|
||||||
// When no stats provided, use global totals (backward compatible)
|
|
||||||
const displayStats =
|
|
||||||
stats ??
|
|
||||||
(data?.global
|
|
||||||
? [
|
|
||||||
{ label: "items", value: String(data.global.itemCount) },
|
|
||||||
{
|
|
||||||
label: "total",
|
|
||||||
value: weight(data.global.totalWeight),
|
|
||||||
},
|
|
||||||
{ label: "spent", value: price(data.global.totalCost) },
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
{ label: "items", value: "0" },
|
|
||||||
{ label: "total", value: weight(null) },
|
|
||||||
{ label: "spent", value: price(null) },
|
|
||||||
]);
|
|
||||||
|
|
||||||
const titleContent = (
|
const titleContent = (
|
||||||
<span className="flex items-center gap-2">
|
<span className="flex items-center gap-2">
|
||||||
@@ -62,48 +30,12 @@ export function TotalsBar({
|
|||||||
<h1 className="text-lg font-semibold text-gray-900">{titleContent}</h1>
|
<h1 className="text-lg font-semibold text-gray-900">{titleContent}</h1>
|
||||||
);
|
);
|
||||||
|
|
||||||
// If stats prop is explicitly an empty array, show title only (dashboard mode)
|
|
||||||
const showStats = stats === undefined || stats.length > 0;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="sticky top-0 z-10 bg-white border-b border-gray-100">
|
<div className="sticky top-0 z-10 bg-white border-b border-gray-100">
|
||||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||||
<div className="flex items-center justify-between h-14">
|
<div className="flex items-center justify-between h-14">
|
||||||
{titleElement}
|
{titleElement}
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div className="flex items-center gap-1 bg-gray-100 rounded-full px-1 py-0.5">
|
|
||||||
{UNITS.map((u) => (
|
|
||||||
<button
|
|
||||||
key={u}
|
|
||||||
type="button"
|
|
||||||
onClick={() =>
|
|
||||||
updateSetting.mutate({
|
|
||||||
key: "weightUnit",
|
|
||||||
value: u,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
className={`px-2 py-0.5 text-xs rounded-full transition-colors ${
|
|
||||||
unit === u
|
|
||||||
? "bg-white text-gray-700 shadow-sm font-medium"
|
|
||||||
: "text-gray-400 hover:text-gray-600"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{u}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
{showStats && (
|
|
||||||
<div className="flex items-center gap-6 text-sm text-gray-500">
|
|
||||||
{displayStats.map((stat) => (
|
|
||||||
<span key={stat.label}>
|
|
||||||
<span className="font-medium text-gray-700">
|
|
||||||
{stat.value}
|
|
||||||
</span>{" "}
|
|
||||||
{stat.label}
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{isAuthenticated ? (
|
{isAuthenticated ? (
|
||||||
<UserMenu />
|
<UserMenu />
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -114,23 +114,8 @@ function RootLayout() {
|
|||||||
const currentThreadId = threadMatch ? Number(threadMatch.threadId) : null;
|
const currentThreadId = threadMatch ? Number(threadMatch.threadId) : null;
|
||||||
|
|
||||||
const isDashboard = !!matchRoute({ to: "/" });
|
const isDashboard = !!matchRoute({ to: "/" });
|
||||||
const isCollection = !!matchRoute({ to: "/collection", fuzzy: true });
|
|
||||||
const isSetupDetail = !!matchRoute({ to: "/setups/$setupId", fuzzy: true });
|
|
||||||
|
|
||||||
// Determine TotalsBar props based on current route
|
const totalsBarProps = isDashboard ? {} : { linkTo: "/" };
|
||||||
const _totalsBarProps = isDashboard
|
|
||||||
? { stats: [] as Array<{ label: string; value: string }> } // Title only, no stats, no link
|
|
||||||
: isSetupDetail
|
|
||||||
? { linkTo: "/" } // Setup detail will render its own local bar; root bar just has link
|
|
||||||
: { linkTo: "/" }; // All other pages: default stats + link to dashboard
|
|
||||||
|
|
||||||
// On dashboard, don't show the default global stats - pass empty stats
|
|
||||||
// On collection, let TotalsBar fetch its own global stats (default behavior)
|
|
||||||
const finalTotalsProps = isDashboard
|
|
||||||
? { stats: [] as Array<{ label: string; value: string }> }
|
|
||||||
: isCollection
|
|
||||||
? { linkTo: "/" }
|
|
||||||
: { linkTo: "/" };
|
|
||||||
|
|
||||||
// Show loading while checking auth
|
// Show loading while checking auth
|
||||||
if (authLoading) {
|
if (authLoading) {
|
||||||
@@ -170,7 +155,7 @@ function RootLayout() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-gray-50">
|
||||||
<TotalsBar {...finalTotalsProps} />
|
<TotalsBar {...totalsBarProps} />
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
|
||||||
{/* Item Confirm Delete Dialog */}
|
{/* Item Confirm Delete Dialog */}
|
||||||
|
|||||||
Reference in New Issue
Block a user