Commit Graph

8 Commits

Author SHA1 Message Date
Fringg
0ce74ea5fb fix: rename duplicate 'purchases' i18n key to 'purchaseCount'
The admin.landings namespace had two 'purchases' keys at the same level:
a string for purchase count label and an object for purchases section.
JSON last-key-wins caused the string to be overwritten by the object,
producing "returned an object instead of string" error on landings list.
2026-03-07 13:22:08 +03:00
Fringg
30190199ed feat: add landing page statistics page with recharts
Add AdminLandingStats page with:
- Summary cards (purchases, revenue, gifts, conversion)
- AreaChart with dual Y-axis (daily purchases + revenue)
- BarChart (tariff distribution)
- PieChart donut (gift vs regular breakdown)
- Responsive layout for desktop and mobile
- Stats button on landing cards list

Includes API types, route, translations (ru/en).
2026-03-07 09:36:20 +03:00
Fringg
f7afa002f0 feat: add discount UI for landing pages
Add discount configuration in admin editor and countdown timer
display on public purchase page.

- Add discount section to AdminLandingEditor with toggle, percent
  slider, datetime pickers, per-tariff overrides, live preview
- Add DiscountBanner with countdown timer to QuickPurchase page
  using AnimatePresence exit animation and proper interval cleanup
- Add strikethrough prices and discount badges to tariff cards,
  summary card and pay button with null/equality guards
- Add discount translations for ru and en locales
- Fix delete/toggle API return types to match backend contracts
- Fix isoToDatetimeLocal to preserve seconds on re-edit
- Fix preview rounding to match backend integer division
2026-03-07 07:01:46 +03:00
Fringg
b7c7decfd0 fix: adapt admin landings list for mobile layout
- Badges (active/inactive, gift) now wrap on narrow screens
- Action buttons move to a separate row on mobile (hidden/shown via sm:)
- Delete button pushed to the right on mobile for safety
- Reduced padding and gaps on small screens
- Desktop layout unchanged
2026-03-07 04:56:12 +03:00
Fringg
b9f1f59e3c fix: show total purchase count instead of paid on admin landings 2026-03-06 22:16:41 +03:00
Fringg
6755c1dc45 fix: landing list crash — title is now LocaleDict, not string
- Update LandingListItem.title type to LocaleDict
- Add resolveLocaleDisplay() helper for extracting display string
- Use resolveLocaleDisplay() in landing list and delete confirm
2026-03-06 17:00:05 +03:00
Fringg
3cea48235f fix: безопасность и UX лендингов — 16 исправлений
- CRITICAL: усиленная CSS-санитизация (escape-последовательности, at-rules)
- CRITICAL: очистка setTimeout при unmount
- HIGH: useMutation для создания покупки (вместо ручного fetch)
- HIGH: DOMPurify + rel="noopener noreferrer" на ссылках
- HIGH: ErrorBoundary для публичных страниц покупки
- MEDIUM: стабильные UUID для DnD элементов
- MEDIUM: race condition в delete timeout
- MEDIUM: клиентская валидация формы лендинга
- MEDIUM: staleTime для админ-запросов
- MEDIUM: общая утилита getApiErrorMessage
- MEDIUM: уведомление о таймауте поллинга
- LOW: ARIA роли для radio-карточек и форм
- LOW: дедупликация иконок в LandingIcons.tsx
- LOW: cn() вместо template literals
2026-03-06 07:23:11 +03:00
Fringg
8b5d777f0a feat: публичные лендинг-страницы для быстрой покупки VPN-подписок
- QuickPurchase: публичная страница покупки с выбором тарифа/периода/оплаты
- PurchaseSuccess: статус покупки с поллингом и копированием ссылки
- AdminLandings: управление лендингами (создание, сортировка, удаление)
- AdminLandingEditor: полнофункциональный редактор лендинга
- API-клиент landings.ts для всех эндпоинтов
- Роутинг /buy/:slug и /buy/success/:token
- Локализация ru/en/zh/fa для всех текстов лендинга
- Санитизация HTML/CSS, rate limit защита, DOMPurify
2026-03-06 07:02:21 +03:00