refactor(cabinet): migrate inline SVG icons to the central react-icons set

Audit-driven sweep: replaced 168 hand-written inline <svg> icons across 77
files with the central Phosphor (react-icons/pi) components from
@/components/icons, preserving each icon's size classes and colour (dynamic
stroke colours via the parent's currentColor, RefreshIcon's spinning state,
conditional rotate-180 chevrons).

Verified: tsc + vite build + eslint clean; an adversarial diff review of all
changed files found the replacements correct (70 files clean, 0 blockers).
Remaining inline <svg> dropped from 262 to ~95 — the survivors are legitimate
non-icons (brand/provider logos, loading spinners & framer-motion animations,
charts/sparklines, background decoration) plus a few ambiguous glyphs.
This commit is contained in:
c0mrade
2026-05-31 23:37:12 +03:00
parent 08f12daa40
commit b5088c70a1
76 changed files with 331 additions and 1985 deletions

View File

@@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from 'react';
import { CheckIcon } from '@/components/icons';
import { ChevronDownIcon, GlobeIcon } from '../TrafficIcons';
import { getFlagEmoji } from '../trafficUsageHelpers';
@@ -71,17 +72,7 @@ export function CountryFilter({
allSelected ? 'border-accent-500 bg-accent-500' : 'border-dark-600'
}`}
>
{allSelected && (
<svg
className="h-3 w-3 text-white"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={3}
>
<path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
</svg>
)}
{allSelected && <CheckIcon className="h-3 w-3 text-white" />}
</span>
All
</button>
@@ -102,21 +93,7 @@ export function CountryFilter({
checked ? 'border-accent-500 bg-accent-500' : 'border-dark-600'
}`}
>
{checked && (
<svg
className="h-3 w-3 text-white"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={3}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M4.5 12.75l6 6 9-13.5"
/>
</svg>
)}
{checked && <CheckIcon className="h-3 w-3 text-white" />}
</span>
{getFlagEmoji(code)} {code.toUpperCase()}
<span className="ml-auto text-dark-500">{count}</span>

View File

@@ -1,6 +1,7 @@
import { useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ChevronDownIcon, ServerIcon } from '../TrafficIcons';
import { CheckIcon } from '@/components/icons';
import { getFlagEmoji } from '../trafficUsageHelpers';
import type { TrafficNodeInfo } from '../../../../api/adminTraffic';
@@ -75,17 +76,7 @@ export function NodeFilter({
allSelected ? 'border-accent-500 bg-accent-500' : 'border-dark-600'
}`}
>
{allSelected && (
<svg
className="h-3 w-3 text-white"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={3}
>
<path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
</svg>
)}
{allSelected && <CheckIcon className="h-3 w-3 text-white" />}
</span>
{t('admin.trafficUsage.allNodes')}
</button>
@@ -106,21 +97,7 @@ export function NodeFilter({
checked ? 'border-accent-500 bg-accent-500' : 'border-dark-600'
}`}
>
{checked && (
<svg
className="h-3 w-3 text-white"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={3}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M4.5 12.75l6 6 9-13.5"
/>
</svg>
)}
{checked && <CheckIcon className="h-3 w-3 text-white" />}
</span>
{getFlagEmoji(node.country_code)} {node.node_name}
</button>

View File

@@ -1,5 +1,6 @@
import { useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { CheckIcon } from '@/components/icons';
import { ChevronDownIcon, StatusIcon } from '../TrafficIcons';
// Status colour pills shared with the StatusFilter dropdown.
@@ -86,17 +87,7 @@ export function StatusFilter({
allSelected ? 'border-accent-500 bg-accent-500' : 'border-dark-600'
}`}
>
{allSelected && (
<svg
className="h-3 w-3 text-white"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={3}
>
<path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
</svg>
)}
{allSelected && <CheckIcon className="h-3 w-3 text-white" />}
</span>
{t('admin.trafficUsage.allStatuses')}
</button>
@@ -117,21 +108,7 @@ export function StatusFilter({
checked ? 'border-accent-500 bg-accent-500' : 'border-dark-600'
}`}
>
{checked && (
<svg
className="h-3 w-3 text-white"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={3}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M4.5 12.75l6 6 9-13.5"
/>
</svg>
)}
{checked && <CheckIcon className="h-3 w-3 text-white" />}
</span>
<span className={`h-2 w-2 rounded-full ${STATUS_COLORS[s] || 'bg-dark-500'}`} />
{statusLabel(s)}

View File

@@ -1,6 +1,7 @@
import { useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ChevronDownIcon, FilterIcon } from '../TrafficIcons';
import { CheckIcon } from '@/components/icons';
export function TariffFilter({
available,
@@ -73,17 +74,7 @@ export function TariffFilter({
allSelected ? 'border-accent-500 bg-accent-500' : 'border-dark-600'
}`}
>
{allSelected && (
<svg
className="h-3 w-3 text-white"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={3}
>
<path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
</svg>
)}
{allSelected && <CheckIcon className="h-3 w-3 text-white" />}
</span>
{t('admin.trafficUsage.allTariffs')}
</button>
@@ -104,21 +95,7 @@ export function TariffFilter({
checked ? 'border-accent-500 bg-accent-500' : 'border-dark-600'
}`}
>
{checked && (
<svg
className="h-3 w-3 text-white"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth={3}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M4.5 12.75l6 6 9-13.5"
/>
</svg>
)}
{checked && <CheckIcon className="h-3 w-3 text-white" />}
</span>
{tariff}
</button>