Фильтры стран и городов показывают только значения из БД; отключено автозаполнение поиска. Вкладки дашборда приведены к line tabs по REUI. VPS без проекта больше не считается проблемой.
Co-authored-by: Cursor <cursoragent@cursor.com>
Актуализирован backend-mcp под SQLite/Context7/shadcn; в settings включены shadcn и context7, отключён cloudflare.
Co-authored-by: Cursor <cursoragent@cursor.com>
Добавлены syncLog в snapshot, API статистики дашборда и маппинг цен тарифов; переработаны shell, главная страница, empty states и новые экраны журнала синка и проектов.
Co-authored-by: Cursor <cursoragent@cursor.com>
Node в Docker не мог импортировать .ts из workspace-пакетов; exports
переключены на dist, добавлен tsc build и сборка в Dockerfile.
Co-authored-by: Cursor <cursoragent@cursor.com>
Портированы BILLmanager sync/test/balance, планировщик и Telegram,
импорт/экспорт бэкапов и migrate API; Docker по умолчанию на fastify.
Добавлен .understand-anything/ в gitignore, исправлен path codegraph в MCP.
Co-authored-by: Cursor <cursoragent@cursor.com>
SVG-флаги через flagcdn и resolveCountryCode; поле «Оплачено до» — компактный Popover+Calendar на русском; DataGridCard без вложенной обводки.
Co-authored-by: Cursor <cursoragent@cursor.com>
Строка поиска вынесена выше кнопки «Фильтр» и чипов активных фильтров для более понятной иерархии тулбара.
Co-authored-by: Cursor <cursoragent@cursor.com>
Без пропа trigger компонент Filters рендерил пустую кнопку, из-за чего фильтры были невидимы на странице.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Регистр @reui в components.json (URL https://reui.io/r/{style}/{name}.json)
- Установлены @reui/filters, @reui/autocomplete, @reui/number-field,
@reui/date-selector и shadcn slider через shadcn CLI
- Поправлены TS-импорты в ReUI-исходниках (type-only) и удалены неиспользуемые
объявления; в packages/ui добавлены react-day-picker и date-fns для calendar
- Новый VpsFiltersToolbar: тулбар с поиском, кнопкой «Фильтр» (ReUI Filters),
chips с операторами, Popover «Вид» (группировка/компактность/пресеты)
- vps-filters.tsx переписан под массивы значений (мультивыбор) с поддержкой
операторов is_any_of / contains / gte; applyVpsFilters принимает как state,
так и Filter[] (stateToActiveFilters)
- В форме VPS vcpu/ramGb/diskGb/monthlyRate/dailyRate — @reui/number-field
через Controller, paidUntil — @reui/date-selector (одиночная дата)
- AutoCompleteInput: отступы флага size-4 leading-none, CommandList py-1,
CommandItem gap-2.5, PopoverContent min-w-[220px]
- build + tsc --noEmit без ошибок
Co-authored-by: Cursor <cursoragent@cursor.com>
- переделан по документации shadcn: Button trigger + Popover + Command
с CommandInput внутри (вместо нативного Input в триггере)
- CommandInput с autoComplete="off" / autoCorrect="off" / spellCheck=false —
браузерные подсказки больше не появляются
- поддержан произвольный ввод: пункт «Использовать: <запрос>» при отсутствии
совпадений
Co-authored-by: Cursor <cursoragent@cursor.com>
- packages/shared/src/geo: страны ISO 3166-1 alpha-2 + топ-города по странам
- vps.tsx: countryOptions/cityOptions из справочника + существующих VPS,
города фильтруются по выбранной стране
- auto-complete-input: убран onBlur-хак с setTimeout, фильтрация по
основному полю, initialFocus=false чтобы popover не закрывался
- vite.config.ts + tsconfig.json: алиас @cfdm/shared/geo
Co-authored-by: Cursor <cursoragent@cursor.com>
- Новый компонент AutoCompleteInput (Popover + Command/cmdk):
ввод с подсказками, поддержка leading-иконки (эмодзи-флаг).
- Страна: в списке вариантов и в самом инпуте показывается
эмодзи-флаг через getCountryFlagEmoji.
- Город: автокомплит без флага.
- Источник данных — уникальные значения из snapshot.vps
(server-side API для стран/городов отсутствует).
- Подключено в форме VPS и в фильтрах страницы.
- Добавлены shadcn-компоненты command, popover, input-group;
зависимость cmdk в packages/ui.
Co-authored-by: Cursor <cursoragent@cursor.com>
Поля country/city/datacenter были потеряны при миграции формы на shadcn.
Добавлены в zod-схему, EMPTY_FORM, openEdit и в JSX формы (грид из 3
колонок после «Проект»).
Co-authored-by: Cursor <cursoragent@cursor.com>
Раньше в колонке тарифа вызывался formatInBaseCurrency с ratesData=null,
поэтому 0.8 EUR отображались как «0,80 ₽» (без конвертации, но в базовой
валюте). Теперь:
- ratesData грузится через ratesQueryOptions (как на dashboard/reports);
- валюта тарифа определяется через effectiveVpsTariffCurrency (приоритет
baseCurrency провайдера, затем vps.currency);
- форматирование через formatInProviderCurrency — учитывает курсы
провайдера (usdRate/eurRate) и глобальные курсы, при их отсутствии
показывает сумму в исходной валюте, а не в базовой.
Co-authored-by: Cursor <cursoragent@cursor.com>
Ставка/мес и Ставка/день теперь принимают дробные значения (например,
0.8 EUR), а не только целые. Раньше browser-native валидация type=number
со step=1 блокировала сохранение.
Co-authored-by: Cursor <cursoragent@cursor.com>
В SelectContent по умолчанию было alignItemWithTrigger=true (стиль macOS:
поповер перекрывает триггер) и align=center. Заменил на align=start и
alignItemWithTrigger=false — меню появляется под триггером, как в
стандартном shadcn.
Co-authored-by: Cursor <cursoragent@cursor.com>
- SelectField: обёртка над base-ui Select с items prop
(Select.Value рендерит label выбранного элемента, а не raw value)
- все Select в forms (vps/providers/accounts/payments/balance/settings)
переписаны на SelectField
- FormSheetRhf: useEffect reset(defaultValues) при открытии sheet
— теперь форма редактирования заполняется текущими данными
Co-authored-by: Cursor <cursoragent@cursor.com>
- Добавлен /api/rates-proxy для загрузки курсов без CORS
- Фронтенд загружает курсы через прокси, а не напрямую
- convertWithProviderRate возвращает source=no-rates при отсутствии ratesData
- ConvertedAmount показывает «Курсы не загружены» (жёлтый) вместо ложного «Глобальный курс»
Made-with: Cursor
- effectiveVpsTariffCurrency всегда берёт provider.baseCurrency
- Убран селектор валюты из формы VPS (подпись из хостера)
- DashboardPage, ResourcesPage, ReportsPage: вместо item.currency — baseCurrency провайдера
- Конвертация по глобальным курсам теперь корректно находит EUR/USD
Made-with: Cursor
- parseProviderFxRate: пусто/auto/невалид → конвертация по ссылке из настроек
- normalizeRatesPayload + App: JSON ЦБ с Valute → base+rates как у latest.js
- Подсказка в форме хостера про курсы USD/EUR
Made-with: Cursor
- baseCurrency хостера не подставлять при пустой валюте VPS, если есть API (дефолт RUB)
- Подстановка валюты хостера только для провайдеров без API
- RUR → RUB для курсов ЦБ; проверка курсов через Number.isFinite
Made-with: Cursor
- Вынесен accountSelectLabel в src/lib/account-select-label.js
- Модалка списания, таблица баланса и журнал на BalancePage
- VpsPage переведён на общий модуль
Made-with: Cursor
- Для хостеров без API USD в VPS трактуется как дефолт формы, берётся baseCurrency хостера
- В форме VPS добавлен выбор валюты тарифа; при смене хостера подставляется его валюта
- Прогноз по проектам и ConvertedAmount для тарифа используют effectiveVpsTariffCurrency
Made-with: Cursor