fix(ui): выровнять chrome Frame и убрать Card-оболочки
Docker images / prepare-release (push) Successful in 4s
Docker images / backend-image (push) Failing after 2m36s
Docker images / frontend-image (push) Successful in 2m22s
Docker images / notify-webhook (push) Skipped
Docker images / updater-image (push) Successful in 55s
Docker images / publish-release (push) Skipped

Подключить App Switcher, NavUser, OpsPanel и AlertDialog вместо Card-shell.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-08-17 15:36:56 +07:00
co-authored by Cursor
parent d2de8d3188
commit 5f29cfaf0f
47 changed files with 1972 additions and 860 deletions
+29 -41
View File
@@ -12,7 +12,9 @@ import { DataPageCard } from "@/components/data-page-card"
import { DataPageToolbarFrame } from "@/components/data-page-toolbar"
import { FormField, FormToggle, SectionTitle, SegmentedControl } from "@/components/form-kit"
import { firewallRules, type FirewallRule } from "@/lib/data"
import { Card, CardContent } from "@/components/ui/card"
import { Frame, FramePanel } from "@/components/reui/frame"
import { IconTile } from "@/components/reui/icon-tile"
import { OpsPanel } from "@/components/ops-panel"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import {
@@ -36,7 +38,7 @@ import {
CheckIcon, PowerIcon, CheckCircleIcon,
PlayIcon, SquareIcon, RotateCcwIcon, ZapIcon,
CheckCircle2Icon, XCircleIcon, MinusCircleIcon, SkipForwardIcon,
PackageIcon, SlidersHorizontalIcon,
SlidersHorizontalIcon,
} from "lucide-react"
// ─── Types ────────────────────────────────────────────────────────────────────
@@ -725,7 +727,8 @@ function AddressListsTab({ entries, onAdd }: {
{/* groups */}
<div className="flex flex-col gap-3">
{Object.entries(grouped).map(([listName, listEntries]) => (
<Card key={listName}>
<Frame key={listName} dense className="w-full">
<FramePanel className="p-0">
<div className="flex items-center justify-between px-4 py-2.5 border-b bg-muted/20">
<div className="flex items-center gap-2">
<ListFilterIcon className="size-3.5 text-muted-foreground" />
@@ -765,7 +768,8 @@ function AddressListsTab({ entries, onAdd }: {
</div>
))}
</div>
</Card>
</FramePanel>
</Frame>
))}
</div>
</div>
@@ -1309,14 +1313,7 @@ function SimulatorTab({ rules: allRules }: { rules: FirewallRule[] }) {
<div className="flex flex-col gap-4">
{/* ── Presets + Scenarios card ─────────────────────────────────────────── */}
<Card>
<CardContent className="px-5 py-4 flex flex-col gap-4">
{/* Built-in traffic presets */}
<div>
<p className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground mb-2.5">
Пресеты трафика
</p>
<OpsPanel title="Пресеты трафика" contentClassName="px-5 py-4 flex flex-col gap-4">
<div className="flex flex-wrap gap-2">
{SIM_PRESETS.map(p => (
<button key={p.id} type="button" onClick={() => applyPreset(p)}
@@ -1335,7 +1332,6 @@ function SimulatorTab({ rules: allRules }: { rules: FirewallRule[] }) {
</button>
))}
</div>
</div>
<div className="h-px bg-border" />
@@ -1400,17 +1396,11 @@ function SimulatorTab({ rules: allRules }: { rules: FirewallRule[] }) {
</div>
)}
</div>
</CardContent>
</Card>
</OpsPanel>
{/* ── Packet editor ───────────────────────────────────────────────────── */}
<Card>
<CardContent className="px-5 py-4 flex flex-col gap-4">
<div className="flex items-center justify-between flex-wrap gap-2">
<p className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground flex items-center gap-2">
<PackageIcon className="size-3.5" />Параметры пакета
</p>
<OpsPanel title="Параметры пакета" contentClassName="px-5 py-4 flex flex-col gap-4">
<div className="flex items-center justify-end flex-wrap gap-2">
<div className="flex items-center gap-3">
<span className={cn(
"text-[11px] font-mono px-2 py-0.5 rounded border",
@@ -1539,8 +1529,7 @@ function SimulatorTab({ rules: allRules }: { rules: FirewallRule[] }) {
)}
</div>
</div>
</CardContent>
</Card>
</OpsPanel>
{/* ── Verdict banner ──────────────────────────────────────────────────── */}
{verdict && simState === "done" && verdictColors && (
@@ -1568,7 +1557,8 @@ function SimulatorTab({ rules: allRules }: { rules: FirewallRule[] }) {
{/* ── Trace list ──────────────────────────────────────────────────────── */}
{steps.length > 0 && (
<Card>
<Frame dense className="w-full">
<FramePanel className="p-0">
<div className="px-5 py-3 border-b flex items-center justify-between">
<p className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground">
Трассировка · цепочка: <span className="text-foreground normal-case font-mono">{packet.chain}</span>
@@ -1608,7 +1598,8 @@ function SimulatorTab({ rules: allRules }: { rules: FirewallRule[] }) {
)
})}
</div>
</Card>
</FramePanel>
</Frame>
)}
{/* ── Empty state ─────────────────────────────────────────────────────── */}
@@ -1745,15 +1736,17 @@ export default function FirewallPage() {
{ label: "Блокирующих", value: dropRules, icon: <ShieldOffIcon className="size-4 text-red-500" /> },
{ label: "Срабатываний", value: fmtHits(totalHits), icon: <ListFilterIcon className="size-4 text-sky-400" /> },
].map((s) => (
<Card key={s.label}>
<CardContent className="px-5 py-4 flex items-start justify-between">
<div>
<p className="text-sm text-muted-foreground">{s.label}</p>
<p className="text-2xl font-semibold tabular-nums mt-0.5">{s.value}</p>
<Frame key={s.label} className="h-full">
<FramePanel className="relative isolate flex h-full items-start gap-3">
<IconTile variant="elevated" aria-hidden="true" className="size-10.5 text-muted-foreground">
{s.icon}
</IconTile>
<div className="flex min-w-0 flex-1 flex-col gap-0.5">
<p className="text-muted-foreground text-sm font-medium">{s.label}</p>
<p className="text-2xl leading-none font-bold tabular-nums">{s.value}</p>
</div>
<div className="mt-0.5">{s.icon}</div>
</CardContent>
</Card>
</FramePanel>
</Frame>
))}
</div>
@@ -1829,11 +1822,7 @@ export default function FirewallPage() {
)}
{/* RouterOS reference */}
<Card>
<CardContent className="px-5 py-4">
<p className="text-xs font-medium text-muted-foreground mb-3">
RouterOS 7.20+ · /ip firewall + /ipv6 firewall цепочки и новые матчеры
</p>
<OpsPanel title="RouterOS 7.20+ · /ip firewall + /ipv6 firewall — цепочки и новые матчеры" contentClassName="px-5 py-4">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 text-xs">
{[
{
@@ -1874,8 +1863,7 @@ export default function FirewallPage() {
</div>
))}
</div>
</CardContent>
</Card>
</OpsPanel>
</div>
</div>