feat(ui): theme-aware logo, dashboard bar graph, server-side client sorting (v0.14.1-beta)

UI/UX refinements on top of v0.14.0-beta, all validated on the test server:

- Logo: new theme-aware compass iconmark (light/dark SVGs swapped via the
  dark class), sized to 45px; favicon updated to match. Wordmark casing
  corrected to "MikroTik Manager" (font size unchanged).
- Navigation icons enlarged 15 -> 17px.
- Dashboard: "Connected clients" line chart converted to a bar chart with a
  category axis + light downsampling so bars stay readably thick across ranges.
- Clients: sorting is now server-side across the whole dataset (was sorting
  only the current page, so Type/others appeared to do nothing on a uniform
  page); table uses a fixed column layout + keepPreviousData so columns no
  longer jump or blank out when sorting/paging. Backend clients route gains
  whitelisted sort/dir params (safe numeric IP sort, deterministic tiebreaker).
- Connections tab: surfaces the live /ip/firewall/connection/tracking state
  (on/auto/off pill) and clearer empty-state copy explaining auto-mode.

Lint/typecheck/build/jest green in both workspaces; npm audit --audit-level=high
clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2GT-Rich
2026-06-18 13:37:11 -07:00
co-authored by Claude Opus 4.8
parent ee9c9ff9f7
commit d79eb13119
18 changed files with 402 additions and 93 deletions
+158 -6
View File
@@ -1,7 +1,159 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
<rect width="32" height="32" rx="8" fill="#2563eb"/>
<path d="M6 16h4M22 16h4M10 16a6 6 0 0 1 12 0" stroke="white" stroke-width="2.5" stroke-linecap="round"/>
<circle cx="16" cy="16" r="3" fill="white"/>
<circle cx="8" cy="16" r="2" fill="#93c5fd"/>
<circle cx="24" cy="16" r="2" fill="#93c5fd"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="64"
height="64"
viewBox="0 0 64 64"
fill="none"
role="img"
aria-labelledby="title desc"
version="1.1"
id="svg10"
sodipodi:docname="mikrotik-manager-config-compass-favicon.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview10"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="10.429825"
inkscape:cx="19.415474"
inkscape:cy="41.419679"
inkscape:window-width="1240"
inkscape:window-height="809"
inkscape:window-x="546"
inkscape:window-y="1729"
inkscape:window-maximized="0"
inkscape:current-layer="svg10" />
<title
id="title">MikroTik Manager Favicon</title>
<desc
id="desc">A simplified compass favicon with central M mark and four connected network nodes.</desc>
<defs
id="defs3">
<linearGradient
id="favRing"
x1="12"
y1="12"
x2="52"
y2="52"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#7C6DFF"
id="stop1" />
<stop
offset="0.48"
stop-color="#2EA8FF"
id="stop2" />
<stop
offset="1"
stop-color="#23E0C1"
id="stop3" />
</linearGradient>
</defs>
<rect
x="2"
y="2"
width="60"
height="60"
rx="14"
fill="#07111F"
id="rect3" />
<circle
cx="32"
cy="32"
r="19"
stroke="url(#favRing)"
stroke-width="4.5"
stroke-linecap="round"
id="circle3" />
<circle
cx="32"
cy="32"
r="9"
stroke="#F4F7FB"
stroke-width="3.5"
id="circle4" />
<line
x1="32"
y1="11"
x2="32"
y2="22"
stroke="#F4F7FB"
stroke-width="3.5"
stroke-linecap="round"
id="line4" />
<line
x1="42"
y1="32"
x2="53"
y2="32"
stroke="#F4F7FB"
stroke-width="3.5"
stroke-linecap="round"
id="line5" />
<line
x1="32"
y1="42"
x2="32"
y2="53"
stroke="#F4F7FB"
stroke-width="3.5"
stroke-linecap="round"
id="line6" />
<line
x1="11"
y1="32"
x2="22"
y2="32"
stroke="#F4F7FB"
stroke-width="3.5"
stroke-linecap="round"
id="line7" />
<circle
cx="32"
cy="10"
r="4.2"
fill="#07111F"
stroke="#23E0C1"
stroke-width="3"
id="circle7" />
<circle
cx="54"
cy="32"
r="4.2"
fill="#07111F"
stroke="#2EA8FF"
stroke-width="3"
id="circle8" />
<circle
cx="32"
cy="54"
r="4.2"
fill="#07111F"
stroke="#79E044"
stroke-width="3"
id="circle9" />
<circle
cx="10"
cy="32"
r="4.2"
fill="#07111F"
stroke="#7C6DFF"
stroke-width="3"
id="circle10" />
<path
d="M 28.513435,36.116485 V 27.924724 L 32,33.044574 l 3.486564,-5.11985 v 8.191761"
stroke="#f4f7fb"
stroke-width="2.98101"
stroke-linecap="round"
stroke-linejoin="round"
id="path10" />
</svg>

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 3.4 KiB

+56
View File
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" role="img" aria-labelledby="title desc" version="1.1" id="svg24" xmlns="http://www.w3.org/2000/svg">
<title id="title">MikroTik Manager Config Compass Icon - Dark Mode</title>
<desc id="desc">A dark-mode SVG app icon showing a network compass with a central manager node and four directional service nodes.</desc>
<defs id="defs13">
<linearGradient id="bgDark" x1="96" y1="80" x2="928" y2="944" gradientUnits="userSpaceOnUse">
<stop stop-color="#111D2E" id="stop1" />
<stop offset="1" stop-color="#06111F" id="stop2" />
</linearGradient>
<linearGradient id="ringDark" x1="236" y1="244" x2="788" y2="780" gradientUnits="userSpaceOnUse">
<stop stop-color="#7C6DFF" id="stop3" />
<stop offset="0.48" stop-color="#2EA8FF" id="stop4" />
<stop offset="1" stop-color="#23E0C1" id="stop5" />
</linearGradient>
<linearGradient id="northDark" x1="512" y1="136" x2="512" y2="318" gradientUnits="userSpaceOnUse">
<stop stop-color="#35F4E4" id="stop6" />
<stop offset="1" stop-color="#1CA7FF" id="stop7" />
</linearGradient>
<linearGradient id="eastDark" x1="702" y1="512" x2="900" y2="512" gradientUnits="userSpaceOnUse">
<stop stop-color="#1CA7FF" id="stop8" />
<stop offset="1" stop-color="#35F4E4" id="stop9" />
</linearGradient>
<linearGradient id="southDark" x1="512" y1="708" x2="512" y2="900" gradientUnits="userSpaceOnUse">
<stop stop-color="#A7F542" id="stop10" />
<stop offset="1" stop-color="#43D868" id="stop11" />
</linearGradient>
<linearGradient id="westDark" x1="320" y1="512" x2="126" y2="512" gradientUnits="userSpaceOnUse">
<stop stop-color="#7C6DFF" id="stop12" />
<stop offset="1" stop-color="#A36BFF" id="stop13" />
</linearGradient>
<filter id="softGlowDark" x="-0.052830189" y="-0.052830189" width="1.1056604" height="1.1056604" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="14" result="blur" id="feGaussianBlur13" />
<feColorMatrix in="blur" type="matrix" values="0 0 0 0 0.10 0 0 0 0 0.60 0 0 0 0 1.00 0 0 0 0.35 0" id="feColorMatrix13" />
<feBlend in="SourceGraphic" id="feBlend13" />
</filter>
</defs>
<rect x="64" y="64" width="896" height="896" rx="208" fill="url(#bgDark)" id="rect13" />
<rect x="76" y="76" width="872" height="872" rx="196" stroke="#223855" stroke-width="20" opacity="0.85" id="rect14" />
<g filter="url(#softGlowDark)" id="g24">
<circle cx="512" cy="512" r="262" stroke="url(#ringDark)" stroke-width="32" stroke-linecap="round" stroke-dasharray="360 70 360 70" id="circle14" />
<circle cx="512" cy="512" r="116" stroke="#F4F7FB" stroke-width="28" id="circle15" />
<path d="M512 194 L552 306 H472 L512 194Z" fill="url(#northDark)" id="path15" />
<path d="M830 512 L718 552 V472 L830 512Z" fill="url(#eastDark)" id="path16" />
<path d="M512 830 L472 718 H552 L512 830Z" fill="url(#southDark)" id="path17" />
<path d="M194 512 L306 472 V552 L194 512Z" fill="url(#westDark)" id="path18" />
<line x1="512" y1="300" x2="512" y2="396" stroke="#F4F7FB" stroke-width="28" stroke-linecap="round" id="line18" />
<line x1="628" y1="512" x2="724" y2="512" stroke="#F4F7FB" stroke-width="28" stroke-linecap="round" id="line19" />
<line x1="512" y1="628" x2="512" y2="724" stroke="#F4F7FB" stroke-width="28" stroke-linecap="round" id="line20" />
<line x1="300" y1="512" x2="396" y2="512" stroke="#F4F7FB" stroke-width="28" stroke-linecap="round" id="line21" />
<circle cx="512" cy="294" r="46" fill="#07111F" stroke="url(#northDark)" stroke-width="28" id="circle21" />
<circle cx="730" cy="512" r="46" fill="#07111F" stroke="url(#eastDark)" stroke-width="28" id="circle22" />
<circle cx="512" cy="730" r="46" fill="#07111F" stroke="url(#southDark)" stroke-width="28" id="circle23" />
<circle cx="294" cy="512" r="46" fill="#07111F" stroke="url(#westDark)" stroke-width="28" id="circle24" />
<path d="m 454.87455,565.67016 v -108.409 l 57.12546,77.09084 57.12545,-77.09084 v 108.409" stroke="#f4f7fb" stroke-width="34.5308" stroke-linecap="round" stroke-linejoin="round" id="path24" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

+49
View File
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" role="img" aria-labelledby="title desc" version="1.1" id="svg24" xmlns="http://www.w3.org/2000/svg">
<title id="title">MikroTik Manager Config Compass Icon - Light Mode</title>
<desc id="desc">A light-mode SVG app icon showing a network compass with a central manager node and four directional service nodes.</desc>
<defs id="defs13">
<linearGradient id="bgLight" x1="96" y1="80" x2="928" y2="944" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFFFFF" id="stop1" />
<stop offset="1" stop-color="#EAF2FF" id="stop2" />
</linearGradient>
<linearGradient id="ringLight" x1="236" y1="244" x2="788" y2="780" gradientUnits="userSpaceOnUse">
<stop stop-color="#6757F5" id="stop3" />
<stop offset="0.48" stop-color="#0777D8" id="stop4" />
<stop offset="1" stop-color="#00A98F" id="stop5" />
</linearGradient>
<linearGradient id="northLight" x1="512" y1="136" x2="512" y2="318" gradientUnits="userSpaceOnUse">
<stop stop-color="#00BFB3" id="stop6" />
<stop offset="1" stop-color="#0877D8" id="stop7" />
</linearGradient>
<linearGradient id="eastLight" x1="702" y1="512" x2="900" y2="512" gradientUnits="userSpaceOnUse">
<stop stop-color="#0877D8" id="stop8" />
<stop offset="1" stop-color="#00BFB3" id="stop9" />
</linearGradient>
<linearGradient id="southLight" x1="512" y1="708" x2="512" y2="900" gradientUnits="userSpaceOnUse">
<stop stop-color="#79C900" id="stop10" />
<stop offset="1" stop-color="#1CB85E" id="stop11" />
</linearGradient>
<linearGradient id="westLight" x1="320" y1="512" x2="126" y2="512" gradientUnits="userSpaceOnUse">
<stop stop-color="#6757F5" id="stop12" />
<stop offset="1" stop-color="#914AF8" id="stop13" />
</linearGradient>
</defs>
<rect x="64" y="64" width="896" height="896" rx="208" fill="url(#bgLight)" id="rect13" />
<rect x="76" y="76" width="872" height="872" rx="196" stroke="#D5E2F2" stroke-width="20" id="rect14" />
<circle cx="512" cy="512" r="262" stroke="url(#ringLight)" stroke-width="32" stroke-linecap="round" stroke-dasharray="360 70 360 70" id="circle14" />
<circle cx="512" cy="512" r="116" stroke="#152238" stroke-width="28" id="circle15" />
<path d="M512 194 L552 306 H472 L512 194Z" fill="url(#northLight)" id="path15" />
<path d="M830 512 L718 552 V472 L830 512Z" fill="url(#eastLight)" id="path16" />
<path d="M512 830 L472 718 H552 L512 830Z" fill="url(#southLight)" id="path17" />
<path d="M194 512 L306 472 V552 L194 512Z" fill="url(#westLight)" id="path18" />
<line x1="512" y1="300" x2="512" y2="396" stroke="#152238" stroke-width="28" stroke-linecap="round" id="line18" />
<line x1="628" y1="512" x2="724" y2="512" stroke="#152238" stroke-width="28" stroke-linecap="round" id="line19" />
<line x1="512" y1="628" x2="512" y2="724" stroke="#152238" stroke-width="28" stroke-linecap="round" id="line20" />
<line x1="300" y1="512" x2="396" y2="512" stroke="#152238" stroke-width="28" stroke-linecap="round" id="line21" />
<circle cx="512" cy="294" r="46" fill="#FFFFFF" stroke="url(#northLight)" stroke-width="28" id="circle21" />
<circle cx="730" cy="512" r="46" fill="#FFFFFF" stroke="url(#eastLight)" stroke-width="28" id="circle22" />
<circle cx="512" cy="730" r="46" fill="#FFFFFF" stroke="url(#southLight)" stroke-width="28" id="circle23" />
<circle cx="294" cy="512" r="46" fill="#FFFFFF" stroke="url(#westLight)" stroke-width="28" id="circle24" />
<path d="M 454.87456,567.20426 V 458.79529 L 512,535.88611 569.12545,458.79529 v 108.40897" stroke="#152238" stroke-width="38" stroke-linecap="round" stroke-linejoin="round" id="path24" />
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB