refactor(subscriptions): content update, remove footer link, forgejo svg #14

Closed
opened 2026-08-07 17:43:16 +03:00 by slaid098 · 0 comments
Owner

Контекст

Страница /subscriptions (PR #9, issue #7) влита и в проде. При ревью заказчиком выявлены правки контента и UI:

  1. Title — «Подписки» → «Проверенные подписки» (точнее отражает суть).
  2. H1 — «Подписки, которыми пользуюсь сам» → «Подписки, которые я проверил на себе».
  3. Metadata description — «...без конкретных цифр» → «AI подписки, которые я проверил на себе.» (в Umans теперь есть конкретика — 20 USD, 400 запросов — фраза «без цифр» неактуальна).
  4. Ссылки только в заголовках карточек — кнопка «Перейти →»/«Open →» избыточна, убрать. Заголовок-ссылка (имя + ↗) достаточно.
  5. Заголовки карточек серые (не видно) — добавить text-fg к классу заголовка. Сейчас text-base font-semibold tracking-tight transition hover:text-accent наследует серый от родителя, на тёмном фоне почти невидим.
  6. Контент карточек обновить (verbatim тексты заказчика, см. «Контракты»).
  7. Umans — 2 абзаца — сейчас структура cards: { description: string }[] (одно описание). Изменить на cards: { descriptions: string[] }[] (массив абзацев), Umans получит 2 элемента.
  8. Footer-ссылка на /subscriptions — убрать. В футере (src/components/site-footer.tsx) ссылка «Подписки»/«Subscriptions» (добавлена в PR #9) не нужна — доступ через ☰-меню шапки (PR #11) достаточен.
  9. Иконка репо в футере — GitHub-SVG → Forgejo-SVG. Сейчас SVG в стиле GitHub octocat, но href ведёт на git.slaid098.dev (Forgejo). Визуальный диссонанс (GitHub-аккаунт забанен). Заменить на логотип Forgejo (упрощённая circular mark если точный path недоступен).

Задача

  1. src/lib/i18n.ts:
    • Удалить footer.subscriptions (поле типа Dict + ruDict + enDict).
    • Удалить subscriptions.openButton (поле типа Dict + ruDict + enDict).
    • subscriptions.cards[].description: stringsubscriptions.cards[].descriptions: string[] (тип Dict + оба словаря).
    • Новые тексты RU: title, description, heading, 4 карточки (Umans — 2 абзаца в массиве descriptions).
    • Новые тексты EN: title, description, heading, 4 карточки (адаптированные переводы, Umans — 2 абзаца).
    • Сноска — без изменений.
  2. src/app/[locale]/subscriptions/page.tsx:
    • Класс заголовка карточки (:62): добавить text-fg.
    • Удалить кнопку «Перейти →» (вторая <a>, строки 67-74).
    • Рендер описаний: card.descriptions.map((d, j) => <p ...>{d}</p>) с обёрткой space-y-3 (или mt-2/mt-3 по индексу).
  3. src/components/site-footer.tsx:
    • Удалить <Link> на /subscriptions (весь блок: разделитель · + Link).
    • Заменить SVG в forgejo-link: GitHub-octocat path → Forgejo logo path (упрощённая circular mark если точный path недоступен). aria-label остаётся «Forgejo», href остаётся git.slaid098.dev/slaid098, размер 16x16.
  4. src/lib/subscriptions.ts — без изменений (URL/имена те же).
  5. Тесты:
    • src/__tests__/subscriptions-page.test.tsx — удалить файл (тестировал только footer-ссылку на /subscriptions).
    • src/__tests__/subscriptions.test.tsc.descriptionc.descriptions (длина массива + каждый элемент), удалить проверки openButton.
    • src/__tests__/subscriptions-metadata.test.ts — новые title/description для ru/en.
    • src/__tests__/contacts.test.tsx — проверить что не падает (SVG path меняется но <svg> count и aria-label остаются — должно пройти).

Контракты

Тексты RU (verbatim от заказчика)

  • Title: «Проверенные подписки»
  • Description: «AI подписки, которые я проверил на себе.»
  • H1 (heading): «Подписки, которые я проверил на себе»
  • Сноска: без изменений (* По ссылкам могут действовать бонусы для новых пользователей. Лимиты, тарифы и условия сервисов периодически меняются — актуальные детали уточняйте на сайтах сервисов.)

Карточки RU (verbatim)

  • OpenCode Go (descriptions: ["Доступная подписка от авторов OpenCode. Лимиты по окнам: 5-часовое, недельное и месячное — какое израсходуешь первым, то и ограничивает."])
  • Synthetic.new (descriptions: ["Скользящие лимиты: 5-часовой и недельный, оба постоянно восстанавливаются. Лимиты масштабируются пакетами. Внутри — Kimi K3."])
  • Ollama (descriptions: ["Прозрачный расчёт за серверное время: экономишь токены — получаешь больше запросов. Тестировал, как Pro так и Max."])
  • Umans (descriptions: ["Успел попробовать подписку за 20 USD. Было 400 запросов на 5 часов без недельных лимитов. Code Max попробовать не успел. Единственным ограничением было количество одновременных потоков. Без 5-часовых и недельных лимитов.", "Есть оплата за токены (pay-as-you-go). Иногда дают кредиты на тестирование новых моделей. Мою подписку однажды отменили без объяснений за несколько дней до продления — но деньги вернули в полном объёме."])

Тексты EN (адаптированные переводы, утверждены заказчиком)

  • Title: «Verified Subscriptions»
  • Description: «AI subscriptions I've tested myself.»
  • H1 (heading): «Subscriptions I've tested myself»
  • Сноска: без изменений (* Bonuses for new users may apply via the links. Limits, pricing, and terms change periodically — check the services' sites for current details.)

Карточки EN (адаптированные)

  • OpenCode Go: ["An affordable subscription from the makers of OpenCode. Limits by windows: 5-hour, weekly, and monthly — whichever you exhaust first is the one that limits you."]
  • Synthetic.new: ["Sliding limits: 5-hour and weekly, both continuously refill. Limits scale in packages. Inside — Kimi K3."]
  • Ollama: ["Transparent billing for server time: save tokens — get more requests. Tested both Pro and Max."]
  • Umans: ["Tried the $20 subscription. Had 400 requests per 5 hours with no weekly limits. Didn't get to try Code Max. The only constraint was the number of concurrent threads. No 5-hour or weekly limits.", "There's also pay-as-you-go token billing. Sometimes credits are given for testing new models. My subscription was once cancelled without explanation a few days before renewal — but the money was fully refunded."]

Forgejo SVG (запасной план)

Точный SVG path Forgejo недоступен через webfetch (Codeberg anti-scraping, GitHub mirror 404). Fallback: упрощённая circular mark (круг с заливкой, схожая с Gitea/forgejo brand). Не бренд-точная, но однозначно не GitHub octocat. aria-label="Forgejo", размер 16x16, fill="currentColor" (наследует text-muted).

Инварианты

  • Страница остаётся статической (SSG), никаких cookies()/headers()/fetch к внешним API.
  • Внешние ссылки: target="_blank" rel="noopener noreferrer".
  • Имена брендов (OpenCode Go и др.) НЕ локализуются — только в src/lib/subscriptions.ts.
  • Header ☰-меню (PR #11) содержит «Подписки» — после удаления footer-ссылки доступ через меню сохраняется.
  • Biome стиль: 2 пробела, двойные кавычки, semicolons, trailing commas, 100 ширина, no any.
  • TypeScript: noUncheckedIndexedAccess (индексный доступ T | undefined → guard ?? []/?? ""), exactOptionalPropertyTypes.

Граничные случаи

  • /ru/subscriptions и /en/subscriptions — обе локали рендерятся с новыми текстами.
  • Umans 2 абзаца — визуальный отступ между ними (space-y-3 или mt-3 на втором <p>).
  • Footer после удаления subscriptions-link: madeBy · heart(contacts) · forgejo-link(SVG). Разделители · сохраняются.
  • contacts.test.tsx SVG-index тест (svgs[0] heart, svgs[1] forgejo) — если новый Forgejo SVG имеет несколько <path> элементов внутри одного <svg>, тест svgs.length >= 2 проходит (проверяет количество <svg>, не <path>).
  • subscriptions-page.test.tsx удаляется — покрытые им 2 теста (footer-ссылка ru/en) больше не нужны.

Влияние на связанные компоненты

  • src/lib/i18n.ts — секция subscriptions (тип, ruDict, enDict), поле footer.subscriptions (тип, ruDict, enDict). Удаление полей → typecheck ловит stale-ссылки в потребителях.
  • src/app/[locale]/subscriptions/page.tsx — рендер карточек, заголовок, кнопка удалена.
  • src/components/site-footer.tsx — удаление subscriptions-Link, замена SVG.
  • src/__tests__/subscriptions-page.test.tsx — удалить.
  • src/__tests__/subscriptions.test.ts — обновить проверки (descriptions вместо description, убрать openButton).
  • src/__tests__/subscriptions-metadata.test.ts — новые title/description.
  • src/__tests__/contacts.test.tsx — проверить (должен пройти, SVG count/aria-label не меняются).
  • src/components/site-header.tsx — НЕ трогать (☰-меню содержит «Подписки», остаётся).
  • src/app/sitemap.ts — НЕ трогать (роут /subscriptions уже есть).
  • biome.json — НЕ трогать (override для subscriptions/page.tsx уже есть).

Вне scope

  • Редизайн шапки (сделан в PR #11).
  • Добавление новых сервисов подписок (4 сервиса зафиксированы).
  • Изменение URL сервисов (реферальные параметры сохранены).
  • Страница 404 (влита в PR #138).
  • Issue #13 (npm cache bug на push) — отдельная задача, не блокер.

Критерии приемки

  • /ru/subscriptions и /en/subscriptions рендерятся с новыми title/H1/description/карточками.
  • Заголовки карточек видимые (text-fg), кликабельные (имя + ↗), ведут на URL из конфига.
  • Кнопки «Перейти →»/«Open →» НЕТ — только заголовки-ссылки.
  • Umans рендерит 2 абзаца с отступом между ними.
  • Footer НЕ содержит ссылку «Подписки»/«Subscriptions».
  • Footer содержит Forgejo-SVG (не GitHub-octocat), aria-label="Forgejo", href="git.slaid098.dev/slaid098".
  • ☰-меню шапки содержит «Подписки» (не затронуто).
  • Сноска отображается под списком (без изменений).
  • Sitemap содержит /subscriptions (не затронуто).
  • Build, lint, typecheck, тесты — зелёные. CI на PR — success (ci.yml теперь в .forgejo/workflows/, триггер восстановлен issue #10).
## Контекст Страница `/subscriptions` (PR #9, issue #7) влита и в проде. При ревью заказчиком выявлены правки контента и UI: 1. **Title** — «Подписки» → «Проверенные подписки» (точнее отражает суть). 2. **H1** — «Подписки, которыми пользуюсь сам» → «Подписки, которые я проверил на себе». 3. **Metadata description** — «...без конкретных цифр» → «AI подписки, которые я проверил на себе.» (в Umans теперь есть конкретика — 20 USD, 400 запросов — фраза «без цифр» неактуальна). 4. **Ссылки только в заголовках карточек** — кнопка «Перейти →»/«Open →» избыточна, убрать. Заголовок-ссылка (имя + ↗) достаточно. 5. **Заголовки карточек серые (не видно)** — добавить `text-fg` к классу заголовка. Сейчас `text-base font-semibold tracking-tight transition hover:text-accent` наследует серый от родителя, на тёмном фоне почти невидим. 6. **Контент карточек обновить** (verbatim тексты заказчика, см. «Контракты»). 7. **Umans — 2 абзаца** — сейчас структура `cards: { description: string }[]` (одно описание). Изменить на `cards: { descriptions: string[] }[]` (массив абзацев), Umans получит 2 элемента. 8. **Footer-ссылка на /subscriptions — убрать**. В футере (`src/components/site-footer.tsx`) ссылка «Подписки»/«Subscriptions» (добавлена в PR #9) не нужна — доступ через ☰-меню шапки (PR #11) достаточен. 9. **Иконка репо в футере — GitHub-SVG → Forgejo-SVG**. Сейчас SVG в стиле GitHub octocat, но `href` ведёт на `git.slaid098.dev` (Forgejo). Визуальный диссонанс (GitHub-аккаунт забанен). Заменить на логотип Forgejo (упрощённая circular mark если точный path недоступен). ## Задача 1. `src/lib/i18n.ts`: - Удалить `footer.subscriptions` (поле типа Dict + ruDict + enDict). - Удалить `subscriptions.openButton` (поле типа Dict + ruDict + enDict). - `subscriptions.cards[].description: string` → `subscriptions.cards[].descriptions: string[]` (тип Dict + оба словаря). - Новые тексты RU: title, description, heading, 4 карточки (Umans — 2 абзаца в массиве `descriptions`). - Новые тексты EN: title, description, heading, 4 карточки (адаптированные переводы, Umans — 2 абзаца). - Сноска — без изменений. 2. `src/app/[locale]/subscriptions/page.tsx`: - Класс заголовка карточки (`:62`): добавить `text-fg`. - Удалить кнопку «Перейти →» (вторая `<a>`, строки 67-74). - Рендер описаний: `card.descriptions.map((d, j) => <p ...>{d}</p>)` с обёрткой `space-y-3` (или `mt-2`/`mt-3` по индексу). 3. `src/components/site-footer.tsx`: - Удалить `<Link>` на `/subscriptions` (весь блок: разделитель `·` + Link). - Заменить SVG в forgejo-link: GitHub-octocat path → Forgejo logo path (упрощённая circular mark если точный path недоступен). `aria-label` остаётся «Forgejo», `href` остаётся `git.slaid098.dev/slaid098`, размер 16x16. 4. `src/lib/subscriptions.ts` — без изменений (URL/имена те же). 5. Тесты: - `src/__tests__/subscriptions-page.test.tsx` — удалить файл (тестировал только footer-ссылку на /subscriptions). - `src/__tests__/subscriptions.test.ts` — `c.description` → `c.descriptions` (длина массива + каждый элемент), удалить проверки `openButton`. - `src/__tests__/subscriptions-metadata.test.ts` — новые title/description для ru/en. - `src/__tests__/contacts.test.tsx` — проверить что не падает (SVG path меняется но `<svg>` count и `aria-label` остаются — должно пройти). ## Контракты ### Тексты RU (verbatim от заказчика) - **Title**: «Проверенные подписки» - **Description**: «AI подписки, которые я проверил на себе.» - **H1 (heading)**: «Подписки, которые я проверил на себе» - **Сноска**: без изменений (`* По ссылкам могут действовать бонусы для новых пользователей. Лимиты, тарифы и условия сервисов периодически меняются — актуальные детали уточняйте на сайтах сервисов.`) ### Карточки RU (verbatim) - **OpenCode Go** (`descriptions: ["Доступная подписка от авторов OpenCode. Лимиты по окнам: 5-часовое, недельное и месячное — какое израсходуешь первым, то и ограничивает."]`) - **Synthetic.new** (`descriptions: ["Скользящие лимиты: 5-часовой и недельный, оба постоянно восстанавливаются. Лимиты масштабируются пакетами. Внутри — Kimi K3."]`) - **Ollama** (`descriptions: ["Прозрачный расчёт за серверное время: экономишь токены — получаешь больше запросов. Тестировал, как Pro так и Max."]`) - **Umans** (`descriptions: ["Успел попробовать подписку за 20 USD. Было 400 запросов на 5 часов без недельных лимитов. Code Max попробовать не успел. Единственным ограничением было количество одновременных потоков. Без 5-часовых и недельных лимитов.", "Есть оплата за токены (pay-as-you-go). Иногда дают кредиты на тестирование новых моделей. Мою подписку однажды отменили без объяснений за несколько дней до продления — но деньги вернули в полном объёме."]`) ### Тексты EN (адаптированные переводы, утверждены заказчиком) - **Title**: «Verified Subscriptions» - **Description**: «AI subscriptions I've tested myself.» - **H1 (heading)**: «Subscriptions I've tested myself» - **Сноска**: без изменений (`* Bonuses for new users may apply via the links. Limits, pricing, and terms change periodically — check the services' sites for current details.`) ### Карточки EN (адаптированные) - **OpenCode Go**: `["An affordable subscription from the makers of OpenCode. Limits by windows: 5-hour, weekly, and monthly — whichever you exhaust first is the one that limits you."]` - **Synthetic.new**: `["Sliding limits: 5-hour and weekly, both continuously refill. Limits scale in packages. Inside — Kimi K3."]` - **Ollama**: `["Transparent billing for server time: save tokens — get more requests. Tested both Pro and Max."]` - **Umans**: `["Tried the $20 subscription. Had 400 requests per 5 hours with no weekly limits. Didn't get to try Code Max. The only constraint was the number of concurrent threads. No 5-hour or weekly limits.", "There's also pay-as-you-go token billing. Sometimes credits are given for testing new models. My subscription was once cancelled without explanation a few days before renewal — but the money was fully refunded."]` ### Forgejo SVG (запасной план) Точный SVG path Forgejo недоступен через webfetch (Codeberg anti-scraping, GitHub mirror 404). Fallback: упрощённая circular mark (круг с заливкой, схожая с Gitea/forgejo brand). Не бренд-точная, но однозначно не GitHub octocat. `aria-label="Forgejo"`, размер 16x16, `fill="currentColor"` (наследует `text-muted`). ## Инварианты - Страница остаётся статической (SSG), никаких `cookies()`/`headers()`/fetch к внешним API. - Внешние ссылки: `target="_blank" rel="noopener noreferrer"`. - Имена брендов (OpenCode Go и др.) НЕ локализуются — только в `src/lib/subscriptions.ts`. - Header ☰-меню (PR #11) содержит «Подписки» — после удаления footer-ссылки доступ через меню сохраняется. - Biome стиль: 2 пробела, двойные кавычки, semicolons, trailing commas, 100 ширина, no `any`. - TypeScript: `noUncheckedIndexedAccess` (индексный доступ `T | undefined` → guard `?? []`/`?? ""`), `exactOptionalPropertyTypes`. ## Граничные случаи - `/ru/subscriptions` и `/en/subscriptions` — обе локали рендерятся с новыми текстами. - Umans 2 абзаца — визуальный отступ между ними (`space-y-3` или `mt-3` на втором `<p>`). - Footer после удаления subscriptions-link: `madeBy` · `heart(contacts)` · `forgejo-link(SVG)`. Разделители `·` сохраняются. - `contacts.test.tsx` SVG-index тест (`svgs[0]` heart, `svgs[1]` forgejo) — если новый Forgejo SVG имеет несколько `<path>` элементов внутри одного `<svg>`, тест `svgs.length >= 2` проходит (проверяет количество `<svg>`, не `<path>`). - `subscriptions-page.test.tsx` удаляется — покрытые им 2 теста (footer-ссылка ru/en) больше не нужны. ## Влияние на связанные компоненты - `src/lib/i18n.ts` — секция `subscriptions` (тип, ruDict, enDict), поле `footer.subscriptions` (тип, ruDict, enDict). Удаление полей → typecheck ловит stale-ссылки в потребителях. - `src/app/[locale]/subscriptions/page.tsx` — рендер карточек, заголовок, кнопка удалена. - `src/components/site-footer.tsx` — удаление subscriptions-Link, замена SVG. - `src/__tests__/subscriptions-page.test.tsx` — удалить. - `src/__tests__/subscriptions.test.ts` — обновить проверки (`descriptions` вместо `description`, убрать `openButton`). - `src/__tests__/subscriptions-metadata.test.ts` — новые title/description. - `src/__tests__/contacts.test.tsx` — проверить (должен пройти, SVG count/aria-label не меняются). - `src/components/site-header.tsx` — НЕ трогать (☰-меню содержит «Подписки», остаётся). - `src/app/sitemap.ts` — НЕ трогать (роут `/subscriptions` уже есть). - `biome.json` — НЕ трогать (override для `subscriptions/page.tsx` уже есть). ## Вне scope - Редизайн шапки (сделан в PR #11). - Добавление новых сервисов подписок (4 сервиса зафиксированы). - Изменение URL сервисов (реферальные параметры сохранены). - Страница 404 (влита в PR #138). - Issue #13 (npm cache bug на push) — отдельная задача, не блокер. ## Критерии приемки - `/ru/subscriptions` и `/en/subscriptions` рендерятся с новыми title/H1/description/карточками. - Заголовки карточек видимые (`text-fg`), кликабельные (имя + ↗), ведут на URL из конфига. - Кнопки «Перейти →»/«Open →» НЕТ — только заголовки-ссылки. - Umans рендерит 2 абзаца с отступом между ними. - Footer НЕ содержит ссылку «Подписки»/«Subscriptions». - Footer содержит Forgejo-SVG (не GitHub-octocat), `aria-label="Forgejo"`, `href="git.slaid098.dev/slaid098"`. - ☰-меню шапки содержит «Подписки» (не затронуто). - Сноска отображается под списком (без изменений). - Sitemap содержит `/subscriptions` (не затронуто). - Build, lint, typecheck, тесты — зелёные. CI на PR — success (ci.yml теперь в `.forgejo/workflows/`, триггер восстановлен issue #10).
Sign in to join this conversation.
No labels
bug
performance
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
slaid098/slaid098-dev#14
No description provided.