perf: replace @tabler packages with lucide-react and static CSS (-70 MB node_modules)
Docker / build (push) Failing after 16s
Docker / build (push) Failing after 16s
Made-with: Cursor
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>vps-tracker</title>
|
||||
<link rel="stylesheet" href="/css/tabler.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
Generated
+11
-79
@@ -14,8 +14,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.1",
|
||||
"@tabler/core": "^1.4.0",
|
||||
"@tabler/icons-react": "^3.40.0",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^5.1.1",
|
||||
@@ -25,6 +23,7 @@
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.4.24",
|
||||
"globals": "^16.5.0",
|
||||
"lucide-react": "^0.577.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-router-dom": "^7.13.1",
|
||||
@@ -1021,17 +1020,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@popperjs/core": {
|
||||
"version": "2.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/pluginutils": {
|
||||
"version": "1.0.0-rc.3",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz",
|
||||
@@ -1389,52 +1377,6 @@
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@tabler/core": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tabler/core/-/core-1.4.0.tgz",
|
||||
"integrity": "sha512-5BigzOlbOH9N0Is4u0rYNRCiwtnUXWO57K9zwuscygcicAa8UV9MGaS4zTgQsZEtZ9tsNANhN/YD8gCBGKYCiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"bootstrap": "5.3.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/codecalm"
|
||||
}
|
||||
},
|
||||
"node_modules/@tabler/icons": {
|
||||
"version": "3.40.0",
|
||||
"resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.40.0.tgz",
|
||||
"integrity": "sha512-V/Q4VgNPKubRTiLdmWjV/zscYcj5IIk+euicUtaVVqF6luSC9rDngYWgST5/yh3Mrg/mYUwRv1YVTk71Jp0twQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/codecalm"
|
||||
}
|
||||
},
|
||||
"node_modules/@tabler/icons-react": {
|
||||
"version": "3.40.0",
|
||||
"resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.40.0.tgz",
|
||||
"integrity": "sha512-oO5+6QCnna4a//mYubx4euZfECtzQZFDGsDMIdzZUhbdyBCT+3bRVFBPueGIcemWld4Vb/0UQ39C/cmGfGylAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tabler/icons": "3.40.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/codecalm"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">= 16"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||
@@ -1686,26 +1628,6 @@
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bootstrap": {
|
||||
"version": "5.3.7",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.7.tgz",
|
||||
"integrity": "sha512-7KgiD8UHjfcPBHEpDNg+zGz8L3LqR3GVwqZiBRFX04a1BCArZOz1r2kjly2HQ0WokqTO0v1nF+QAt8dsW4lKlw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/twbs"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/bootstrap"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@popperjs/core": "^2.11.8"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
@@ -3030,6 +2952,16 @@
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/lucide-react": {
|
||||
"version": "0.577.0",
|
||||
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.577.0.tgz",
|
||||
"integrity": "sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peerDependencies": {
|
||||
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
|
||||
+1
-2
@@ -17,8 +17,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.1",
|
||||
"@tabler/core": "^1.4.0",
|
||||
"@tabler/icons-react": "^3.40.0",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^5.1.1",
|
||||
@@ -28,6 +26,7 @@
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.4.24",
|
||||
"globals": "^16.5.0",
|
||||
"lucide-react": "^0.577.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-router-dom": "^7.13.1",
|
||||
|
||||
Vendored
+9
File diff suppressed because one or more lines are too long
@@ -1,28 +1,28 @@
|
||||
import { NavLink, useLocation } from 'react-router-dom'
|
||||
import {
|
||||
IconBuildingSkyscraper,
|
||||
IconChartBar,
|
||||
IconChartHistogram,
|
||||
IconCoin,
|
||||
IconCreditCardPay,
|
||||
IconLayoutDashboard,
|
||||
IconSettings,
|
||||
IconServer,
|
||||
IconServer2,
|
||||
IconWallet,
|
||||
} from '@tabler/icons-react'
|
||||
Building2,
|
||||
BarChart,
|
||||
BarChart2,
|
||||
Coins,
|
||||
CreditCard,
|
||||
LayoutDashboard,
|
||||
Settings,
|
||||
Server,
|
||||
ServerCog,
|
||||
Wallet,
|
||||
} from 'lucide-react'
|
||||
|
||||
const menuItems = [
|
||||
{ to: '/dashboard', label: 'Дашборд', icon: IconLayoutDashboard },
|
||||
{ to: '/vps', label: 'VPS', icon: IconServer },
|
||||
{ to: '/tariffs', label: 'Активные тарифы', icon: IconServer2 },
|
||||
{ to: '/providers', label: 'Хостеры', icon: IconBuildingSkyscraper },
|
||||
{ to: '/accounts', label: 'Аккаунты хостеров', icon: IconWallet },
|
||||
{ to: '/payments', label: 'Платежи', icon: IconCreditCardPay },
|
||||
{ to: '/balance', label: 'Баланс и списания', icon: IconCoin },
|
||||
{ to: '/reports', label: 'Отчёты', icon: IconChartHistogram },
|
||||
{ to: '/resources', label: 'Ресурсы', icon: IconChartBar },
|
||||
{ to: '/settings', label: 'Настройки', icon: IconSettings },
|
||||
{ to: '/dashboard', label: 'Дашборд', icon: LayoutDashboard },
|
||||
{ to: '/vps', label: 'VPS', icon: Server },
|
||||
{ to: '/tariffs', label: 'Активные тарифы', icon: ServerCog },
|
||||
{ to: '/providers', label: 'Хостеры', icon: Building2 },
|
||||
{ to: '/accounts', label: 'Аккаунты хостеров', icon: Wallet },
|
||||
{ to: '/payments', label: 'Платежи', icon: CreditCard },
|
||||
{ to: '/balance', label: 'Баланс и списания', icon: Coins },
|
||||
{ to: '/reports', label: 'Отчёты', icon: BarChart2 },
|
||||
{ to: '/resources', label: 'Ресурсы', icon: BarChart },
|
||||
{ to: '/settings', label: 'Настройки', icon: Settings },
|
||||
]
|
||||
|
||||
export function AppLayout({ children }) {
|
||||
@@ -44,7 +44,7 @@ export function AppLayout({ children }) {
|
||||
}`}
|
||||
>
|
||||
<span className="nav-link-icon d-md-none d-lg-inline-block">
|
||||
<item.icon size={18} stroke={1.75} />
|
||||
<item.icon size={18} strokeWidth={1.75} />
|
||||
</span>
|
||||
<span className="nav-link-title">{item.label}</span>
|
||||
</NavLink>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { IconFolder } from '@tabler/icons-react'
|
||||
import { Folder } from 'lucide-react'
|
||||
import { fetchProjectSuggestions } from '../lib/api'
|
||||
import { noBrowserSuggestProps } from '../lib/noBrowserSuggestProps'
|
||||
|
||||
@@ -184,7 +184,7 @@ export function ProjectSuggestInput({
|
||||
onMouseEnter={() => setActiveIndex(idx)}
|
||||
>
|
||||
<span className="text-secondary project-suggest-folder">
|
||||
<IconFolder size={18} stroke={1.5} />
|
||||
<Folder size={18} strokeWidth={1.5} />
|
||||
</span>
|
||||
<span className="text-truncate">{highlightMatch(name, value)}</span>
|
||||
</button>
|
||||
|
||||
@@ -2,8 +2,6 @@ import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import './index.css'
|
||||
import App from './App.jsx'
|
||||
import '@tabler/core/dist/css/tabler.min.css'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
accountBillmanagerUiReady,
|
||||
accountUsesBillmanagerBalanceApi,
|
||||
} from '../lib/billmanager-ui'
|
||||
import { IconRefresh, IconPlugConnected } from '@tabler/icons-react'
|
||||
import { RefreshCw, PlugZap } from 'lucide-react'
|
||||
|
||||
const emptyForm = {
|
||||
providerId: '',
|
||||
@@ -314,7 +314,7 @@ export function AccountsPage({ db, actions, settings, ratesData }) {
|
||||
{syncLoadingAll ? (
|
||||
<span className="spinner-border spinner-border-sm me-1" role="status" />
|
||||
) : (
|
||||
<IconRefresh size={16} className="me-1" />
|
||||
<RefreshCw size={16} className="me-1" />
|
||||
)}
|
||||
Синхронизировать VPS
|
||||
</button>
|
||||
@@ -400,7 +400,7 @@ export function AccountsPage({ db, actions, settings, ratesData }) {
|
||||
{balanceLoadingId === account.id ? (
|
||||
<span className="spinner-border spinner-border-sm me-1" role="status" />
|
||||
) : (
|
||||
<IconRefresh size={14} className="me-1" />
|
||||
<RefreshCw size={14} className="me-1" />
|
||||
)}
|
||||
Баланс
|
||||
</button>
|
||||
@@ -414,7 +414,7 @@ export function AccountsPage({ db, actions, settings, ratesData }) {
|
||||
{syncLoadingId === account.id ? (
|
||||
<span className="spinner-border spinner-border-sm me-1" role="status" />
|
||||
) : (
|
||||
<IconRefresh size={14} className="me-1" />
|
||||
<RefreshCw size={14} className="me-1" />
|
||||
)}
|
||||
Синхронизировать
|
||||
</button>
|
||||
@@ -568,7 +568,7 @@ export function AccountsPage({ db, actions, settings, ratesData }) {
|
||||
{testConnectionLoading ? (
|
||||
<span className="spinner-border spinner-border-sm me-1" role="status" />
|
||||
) : (
|
||||
<IconPlugConnected size={14} className="me-1" />
|
||||
<PlugZap size={14} className="me-1" />
|
||||
)}
|
||||
Проверить соединение
|
||||
</button>
|
||||
|
||||
@@ -9,12 +9,7 @@ import { EmptyState } from '../components/EmptyState'
|
||||
import { ExpenseChart } from '../components/ExpenseChart'
|
||||
import { PageHeader } from '../components/PageHeader'
|
||||
import { ProviderPieChart } from '../components/ProviderPieChart'
|
||||
import {
|
||||
IconCash,
|
||||
IconClockHour4,
|
||||
IconServer,
|
||||
IconWallet,
|
||||
} from '@tabler/icons-react'
|
||||
import { Banknote, Clock4, Server, Wallet } from 'lucide-react'
|
||||
|
||||
export function DashboardPage({ db = {}, settings, ratesData }) {
|
||||
const [dashTab, setDashTab] = useState('overview')
|
||||
@@ -273,7 +268,7 @@ export function DashboardPage({ db = {}, settings, ratesData }) {
|
||||
<div className="d-flex align-items-center justify-content-between">
|
||||
<div className="text-secondary">Активные VPS</div>
|
||||
<span className="metric-icon bg-blue-lt text-blue">
|
||||
<IconServer size={18} />
|
||||
<Server size={18} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="stat-value">{activeVpsCount}</div>
|
||||
@@ -286,7 +281,7 @@ export function DashboardPage({ db = {}, settings, ratesData }) {
|
||||
<div className="d-flex align-items-center justify-content-between">
|
||||
<div className="text-secondary">Расходы за месяц</div>
|
||||
<span className="metric-icon bg-green-lt text-green">
|
||||
<IconCash size={18} />
|
||||
<Banknote size={18} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="stat-value">{formatCurrency(monthExpenses, baseCurrency)}</div>
|
||||
@@ -305,7 +300,7 @@ export function DashboardPage({ db = {}, settings, ratesData }) {
|
||||
<div className="d-flex align-items-center justify-content-between">
|
||||
<div className="text-secondary">Аккаунтов хостеров</div>
|
||||
<span className="metric-icon bg-yellow-lt text-yellow">
|
||||
<IconClockHour4 size={18} />
|
||||
<Clock4 size={18} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="stat-value">{providerAccounts.length}</div>
|
||||
@@ -318,7 +313,7 @@ export function DashboardPage({ db = {}, settings, ratesData }) {
|
||||
<div className="d-flex align-items-center justify-content-between">
|
||||
<div className="text-secondary">Суммарный баланс</div>
|
||||
<span className="metric-icon bg-purple-lt text-purple">
|
||||
<IconWallet size={18} />
|
||||
<Wallet size={18} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="stat-value">{formatCurrency(totalBalance, baseCurrency)}</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
import { IconEdit } from '@tabler/icons-react'
|
||||
import { Pencil } from 'lucide-react'
|
||||
import { paymentTypeLabel } from '../lib/utils'
|
||||
import { UiModal } from '../components/UiModal'
|
||||
import { EmptyState } from '../components/EmptyState'
|
||||
@@ -155,7 +155,7 @@ export function PaymentsPage({ db, actions, settings, ratesData }) {
|
||||
className="btn btn-sm btn-outline-primary me-1"
|
||||
onClick={() => onEdit(payment)}
|
||||
>
|
||||
<IconEdit size={14} className="me-1" />
|
||||
<Pencil size={14} className="me-1" />
|
||||
Изменить
|
||||
</button>
|
||||
<button
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { IconPlus, IconSend, IconTrash } from '@tabler/icons-react'
|
||||
import { Plus, Send, Trash2 } from 'lucide-react'
|
||||
import { PageHeader } from '../components/PageHeader'
|
||||
import {
|
||||
downloadBackupDatabaseBlob,
|
||||
@@ -231,7 +231,7 @@ export function SettingsPage({ db, actions, ratesData, ratesError }) {
|
||||
className="btn btn-primary"
|
||||
onClick={addCustomField}
|
||||
>
|
||||
<IconPlus size={16} />
|
||||
<Plus size={16} />
|
||||
</button>
|
||||
</div>
|
||||
{customFields.length > 0 ? (
|
||||
@@ -244,7 +244,7 @@ export function SettingsPage({ db, actions, ratesData, ratesError }) {
|
||||
className="btn btn-sm btn-outline-danger"
|
||||
onClick={() => removeCustomField(f.key)}
|
||||
>
|
||||
<IconTrash size={14} />
|
||||
<Trash2 size={14} />
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
@@ -422,7 +422,7 @@ export function SettingsPage({ db, actions, ratesData, ratesError }) {
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<IconSend size={16} className="me-1" />
|
||||
<Send size={16} className="me-1" />
|
||||
Тестовое уведомление
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
import { convertCurrency, formatCurrency, faviconUrlFromWebsite, normalizeWebsiteUrl } from '../lib/utils'
|
||||
import {
|
||||
IconArrowDown,
|
||||
IconArrowUp,
|
||||
IconMapPin,
|
||||
IconRefresh,
|
||||
IconSearch,
|
||||
IconServer,
|
||||
} from '@tabler/icons-react'
|
||||
import { ArrowDown, ArrowUp, MapPin, RefreshCw, Search, Server } from 'lucide-react'
|
||||
import { syncAccount } from '../lib/api'
|
||||
import { EmptyState } from '../components/EmptyState'
|
||||
import { PageHeader } from '../components/PageHeader'
|
||||
@@ -26,7 +19,7 @@ function SortHeader({ column, children, onSort, sortBy, sortDir }) {
|
||||
style={SORT_COLUMNS.includes(column) ? { cursor: 'pointer', userSelect: 'none' } : undefined}
|
||||
>
|
||||
{children}
|
||||
{sortBy === column && (sortDir === 'asc' ? <IconArrowUp size={14} className="ms-1" /> : <IconArrowDown size={14} className="ms-1" />)}
|
||||
{sortBy === column && (sortDir === 'asc' ? <ArrowUp size={14} className="ms-1" /> : <ArrowDown size={14} className="ms-1" />)}
|
||||
</th>
|
||||
)
|
||||
}
|
||||
@@ -201,7 +194,7 @@ export function TariffsPage({ db, actions, settings, ratesData }) {
|
||||
<div className="card">
|
||||
<div className="card-header">
|
||||
<h3 className="card-title">
|
||||
<IconMapPin size={18} className="me-1" />
|
||||
<MapPin size={18} className="me-1" />
|
||||
Доступные датацентры и страны
|
||||
</h3>
|
||||
</div>
|
||||
@@ -249,7 +242,7 @@ export function TariffsPage({ db, actions, settings, ratesData }) {
|
||||
<div className="col-xl-3 col-lg-4 col-md-6">
|
||||
<div className="input-icon">
|
||||
<span className="input-icon-addon">
|
||||
<IconSearch size={16} />
|
||||
<Search size={16} />
|
||||
</span>
|
||||
<input {...noBrowserSuggestProps}
|
||||
className="form-control"
|
||||
@@ -370,7 +363,7 @@ export function TariffsPage({ db, actions, settings, ratesData }) {
|
||||
{syncLoading ? (
|
||||
<span className="spinner-border spinner-border-sm me-1" role="status" />
|
||||
) : (
|
||||
<IconRefresh size={16} className="me-1" />
|
||||
<RefreshCw size={16} className="me-1" />
|
||||
)}
|
||||
Синхронизировать
|
||||
</button>
|
||||
@@ -423,7 +416,7 @@ export function TariffsPage({ db, actions, settings, ratesData }) {
|
||||
<td>
|
||||
<div className="d-flex align-items-center gap-2">
|
||||
<span className="avatar avatar-sm bg-blue-lt">
|
||||
<IconServer size={16} />
|
||||
<Server size={16} />
|
||||
</span>
|
||||
<div>
|
||||
<div className="fw-medium">{item.name || '—'}</div>
|
||||
|
||||
+9
-18
@@ -9,16 +9,7 @@ import {
|
||||
tariffTypeLabel,
|
||||
vpsStatusLabel,
|
||||
} from '../lib/utils'
|
||||
import {
|
||||
IconEdit,
|
||||
IconFilter,
|
||||
IconMapPin,
|
||||
IconPlus,
|
||||
IconRefresh,
|
||||
IconSearch,
|
||||
IconServer,
|
||||
IconTrash,
|
||||
} from '@tabler/icons-react'
|
||||
import { Pencil, Filter, MapPin, Plus, RefreshCw, Search, Server, Trash2 } from 'lucide-react'
|
||||
import { syncAccount, bulkUpdateVps } from '../lib/api'
|
||||
import { UiModal } from '../components/UiModal'
|
||||
import { ConvertedAmount } from '../components/ConvertedAmount'
|
||||
@@ -689,7 +680,7 @@ export function VpsPage({ db, actions, settings, ratesData }) {
|
||||
<div className="col-xl-3 col-lg-4 col-md-6">
|
||||
<div className="input-icon">
|
||||
<span className="input-icon-addon">
|
||||
<IconSearch size={16} />
|
||||
<Search size={16} />
|
||||
</span>
|
||||
<input {...noBrowserSuggestProps}
|
||||
className="form-control"
|
||||
@@ -822,7 +813,7 @@ export function VpsPage({ db, actions, settings, ratesData }) {
|
||||
<div className="col-xl-2 col-lg-4 col-md-6">
|
||||
<div className="input-icon">
|
||||
<span className="input-icon-addon">
|
||||
<IconFilter size={16} />
|
||||
<Filter size={16} />
|
||||
</span>
|
||||
<input {...noBrowserSuggestProps}
|
||||
className="form-control"
|
||||
@@ -840,7 +831,7 @@ export function VpsPage({ db, actions, settings, ratesData }) {
|
||||
<div className="col-xl-2 col-lg-4 col-md-6">
|
||||
<div className="input-icon">
|
||||
<span className="input-icon-addon">
|
||||
<IconMapPin size={16} />
|
||||
<MapPin size={16} />
|
||||
</span>
|
||||
<input {...noBrowserSuggestProps}
|
||||
className="form-control"
|
||||
@@ -1086,7 +1077,7 @@ export function VpsPage({ db, actions, settings, ratesData }) {
|
||||
{syncLoading ? (
|
||||
<span className="spinner-border spinner-border-sm me-1" role="status" />
|
||||
) : (
|
||||
<IconRefresh size={16} className="me-1" />
|
||||
<RefreshCw size={16} className="me-1" />
|
||||
)}
|
||||
Синхронизировать
|
||||
</button>
|
||||
@@ -1104,7 +1095,7 @@ export function VpsPage({ db, actions, settings, ratesData }) {
|
||||
setIsModalOpen(true)
|
||||
}}
|
||||
>
|
||||
<IconPlus size={16} className="me-1" />
|
||||
<Plus size={16} className="me-1" />
|
||||
Добавить VPS
|
||||
</button>
|
||||
</div>
|
||||
@@ -1332,7 +1323,7 @@ export function VpsPage({ db, actions, settings, ratesData }) {
|
||||
className="btn btn-sm btn-outline-primary"
|
||||
onClick={() => onEdit(item)}
|
||||
>
|
||||
<IconEdit size={14} className="me-1" />
|
||||
<Pencil size={14} className="me-1" />
|
||||
Изменить
|
||||
</button>
|
||||
<button
|
||||
@@ -1340,7 +1331,7 @@ export function VpsPage({ db, actions, settings, ratesData }) {
|
||||
className="btn btn-sm btn-outline-danger"
|
||||
onClick={() => actions.remove('vps', item.id)}
|
||||
>
|
||||
<IconTrash size={14} className="me-1" />
|
||||
<Trash2 size={14} className="me-1" />
|
||||
Удалить
|
||||
</button>
|
||||
</div>
|
||||
@@ -1379,7 +1370,7 @@ export function VpsPage({ db, actions, settings, ratesData }) {
|
||||
Отмена
|
||||
</button>
|
||||
<button type="submit" form="vps-form" className="btn btn-primary">
|
||||
<IconPlus size={16} className="me-1" />
|
||||
<Plus size={16} className="me-1" />
|
||||
{editingId ? 'Сохранить' : 'Добавить'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user