DI2: удаление старого модуля финансов — пул БД и аудит перенесены в finance-di2
- server/finance/ (19 файлов) удалён: пул финансовой БД перенесён в server/finance-di2/db-core.ts, db-client.ts теперь реэкспортирует из ./db-core - Шедулер аудита перенесён в server/finance-di2/audit-scheduler.ts (03:00 МСК, setInterval, без node-cron), запуск из registerDi2Routes с защитой от повторного старта - История аудита DI2 теперь персистентна: загрузка/запись data/finance-audit-history.json в audit-agent.ts (порт из удалённого server/finance/audit.ts) - registerFinanceRoutes убран из server/routes/index.ts, registerDi2Routes остался на его месте - Клиент: удалены pages/finance/, components/finance/, hooks/useFinance.ts, hooks/useColumnLabels.ts, lib/format.ts, pages/salary.tsx; роуты /finance*, /income*, /expenses*, /salary и lazy-импорты убраны из App.tsx - Навигация: «Финансы» в Sidebar и MobileBottomNav ведёт на субапп /di2 (внешняя ссылка), гейт moduleAccess.finance + finance.view сохранён - index.css: удалён блок .hover-elevate/.hover-elevate-2/.active-elevate (использовался только старым модульным DataTable) - FinanceBottomNav.tsx сохранён как референс для этапа 3 (.superpowers/sdd/di2-restyle/FinanceBottomNav.reference.tsx) - Не тронуто: client-di2/, сиды прав finance.view/manage, finance_access (module-access)
This commit is contained in:
144
.superpowers/sdd/di2-restyle/FinanceBottomNav.reference.tsx
Normal file
144
.superpowers/sdd/di2-restyle/FinanceBottomNav.reference.tsx
Normal file
@@ -0,0 +1,144 @@
|
||||
import { Link, useLocation } from "wouter";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
LayoutDashboard,
|
||||
Wallet,
|
||||
Calculator,
|
||||
ShieldCheck,
|
||||
Tags,
|
||||
TrendingUp,
|
||||
TrendingDown,
|
||||
Settings,
|
||||
Menu,
|
||||
ExternalLink,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import type { FinanceTab } from "./FinanceNav";
|
||||
|
||||
interface FinanceBottomNavProps {
|
||||
active: FinanceTab;
|
||||
onChange: (tab: FinanceTab) => void;
|
||||
}
|
||||
|
||||
export function FinanceBottomNav({ active, onChange }: FinanceBottomNavProps) {
|
||||
const [location, setLocation] = useLocation();
|
||||
// путь в wouter может включать search-параметр
|
||||
const onDashboard = location.split("?")[0] === "/finance";
|
||||
|
||||
const goDashboardTab = (tab: FinanceTab) => {
|
||||
if (onDashboard) {
|
||||
onChange(tab);
|
||||
} else {
|
||||
setLocation(tab === "dashboard" ? "/finance" : `/finance?tab=${tab}`);
|
||||
}
|
||||
};
|
||||
|
||||
const btnClass = (isActive: boolean) =>
|
||||
cn(
|
||||
"flex flex-col items-center justify-center gap-0.5 flex-1 h-full rounded-lg transition-colors",
|
||||
isActive ? "text-primary" : "text-muted-foreground hover:text-foreground"
|
||||
);
|
||||
|
||||
const sectionsActive =
|
||||
active === "debt" ||
|
||||
active === "calculations" ||
|
||||
active === "audit" ||
|
||||
active === "income" ||
|
||||
active === "expenses" ||
|
||||
active === "income-categories" ||
|
||||
active === "expense-categories";
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-0 left-0 right-0 bg-background border-t border-border z-50 md:hidden safe-area-bottom">
|
||||
<nav className="flex items-stretch justify-around h-14 px-2" aria-label="Навигация по финансам">
|
||||
<button
|
||||
onClick={() => goDashboardTab("dashboard")}
|
||||
aria-label="Обзор"
|
||||
className={btnClass(active === "dashboard")}
|
||||
>
|
||||
<LayoutDashboard className="w-5 h-5" aria-hidden="true" />
|
||||
<span className="text-[10px] font-medium">Обзор</span>
|
||||
</button>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<button
|
||||
aria-label="Разделы"
|
||||
className={cn(btnClass(false), "relative", sectionsActive && "text-primary")}
|
||||
>
|
||||
<Menu className="w-5 h-5" aria-hidden="true" />
|
||||
<span className="text-[10px] font-medium">Разделы</span>
|
||||
{sectionsActive && (
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="absolute top-1 right-1/2 translate-x-4 w-1.5 h-1.5 rounded-full bg-primary"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent side="top" align="center" className="w-56 mb-2">
|
||||
<DropdownMenuItem className="text-xs cursor-pointer" onSelect={() => goDashboardTab("income")}>
|
||||
<TrendingUp className="w-3.5 h-3.5 mr-2" />
|
||||
Доходы
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="text-xs cursor-pointer" onSelect={() => goDashboardTab("expenses")}>
|
||||
<TrendingDown className="w-3.5 h-3.5 mr-2" />
|
||||
Расходы
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<Link href="/finance/debt">
|
||||
<DropdownMenuItem className="text-xs cursor-pointer">
|
||||
<Wallet className="w-3.5 h-3.5 mr-2" />
|
||||
Дебиторка
|
||||
</DropdownMenuItem>
|
||||
</Link>
|
||||
<Link href="/finance/calculations">
|
||||
<DropdownMenuItem className="text-xs cursor-pointer">
|
||||
<Calculator className="w-3.5 h-3.5 mr-2" />
|
||||
Расчёты
|
||||
</DropdownMenuItem>
|
||||
</Link>
|
||||
<Link href="/finance/audit">
|
||||
<DropdownMenuItem className="text-xs cursor-pointer">
|
||||
<ShieldCheck className="w-3.5 h-3.5 mr-2" />
|
||||
Аудит
|
||||
</DropdownMenuItem>
|
||||
</Link>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem className="text-xs cursor-pointer" onSelect={() => goDashboardTab("income-categories")}>
|
||||
<Tags className="w-3.5 h-3.5 mr-2" />
|
||||
Категории доходов
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="text-xs cursor-pointer" onSelect={() => goDashboardTab("expense-categories")}>
|
||||
<Tags className="w-3.5 h-3.5 mr-2" />
|
||||
Категории расходов
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
{/* Внешняя ссылка на субапп Data-Insight2 — полная версия финансов */}
|
||||
<a href="/di2" target="_blank" rel="noopener">
|
||||
<DropdownMenuItem className="text-xs cursor-pointer">
|
||||
<ExternalLink className="w-3.5 h-3.5 mr-2" />
|
||||
Data-Insight (полная версия)
|
||||
</DropdownMenuItem>
|
||||
</a>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
<Link
|
||||
href="/finance/settings"
|
||||
aria-label="Настройки"
|
||||
className={btnClass(active === "settings")}
|
||||
>
|
||||
<Settings className="w-5 h-5" aria-hidden="true" />
|
||||
<span className="text-[10px] font-medium">Настройки</span>
|
||||
</Link>
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user