# Static Info Page Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Replace admin-managed dynamic InfoPageBlock CRUD with a hardcoded static React page featuring process schemas, delivery cards, and payment info. **Architecture:** New `InfoPage.tsx` container composes four hardcoded section components (no API calls, no DB reads). All admin CRUD files, server routes, Prisma model, and entity layer are removed. **Tech Stack:** React + TypeScript + MUI, lucide-react icons. --- ## File Structure ### Created - `client/src/pages/info/ui/sections/HowToOrderSection.tsx` — Stepper with 5 purchase steps - `client/src/pages/info/ui/sections/DeliverySection.tsx` — 3 delivery option cards in Grid - `client/src/pages/info/ui/sections/PaymentSection.tsx` — List of payment methods - `client/src/pages/info/ui/sections/ReturnsSection.tsx` — Returns & warranty Paper blocks ### Modified - `client/src/pages/info/ui/InfoPage.tsx` — Rewrite as static container without useQuery - `client/src/pages/admin-layout/ui/AdminLayoutPage.tsx` — Remove info page nav item and import - `server/src/routes/api.js` — Remove import and registration call - `server/prisma/schema.prisma` — Remove InfoPageBlock model ### Deleted - `client/src/pages/admin-info/ui/AdminInfoPage.tsx` - `client/src/pages/admin-info/index.ts` - `client/src/entities/info/api/info-page-api.ts` - `client/src/entities/info/model/types.ts` - `client/src/entities/info/index.ts` - `server/src/routes/api/info-page.js` --- ### Task 1: Create HowToOrderSection **Files:** - Create: `client/src/pages/info/ui/sections/HowToOrderSection.tsx` - [ ] **Step 1: Write the component** ```tsx import Paper from "@mui/material/Paper"; import Step from "@mui/material/Step"; import StepContent from "@mui/material/StepContent"; import StepLabel from "@mui/material/StepLabel"; import Stepper from "@mui/material/Stepper"; import Typography from "@mui/material/Typography"; import { CheckCircle, ClipboardList, Mail, ShoppingCart, Truck, } from "lucide-react"; const steps = [ { label: "Выберите товары", icon: , text: "Найдите нужные изделия в каталоге и добавьте их в корзину. Вы можете выбрать несколько товаров от разных мастеров — все они соберутся в одном заказе.", }, { label: "Проверьте корзину", icon: , text: "Перейдите в корзину и проверьте состав заказа: названия товаров, количество и итоговую сумму. Здесь же можно изменить количество или удалить позиции.", }, { label: "Укажите контакты и адрес", icon: , text: "Заполните имя, телефон и email для связи. Укажите адрес доставки — город, улицу, дом и квартиру. Эти данные нужны для расчёта стоимости и сроков.", }, { label: "Выберите доставку и оплату", icon: , text: "Выберите способ доставки: самовывоз, курьер или почта/СДЭК. Затем укажите способ оплаты: картой онлайн или при получении.", }, { label: "Подтвердите заказ", icon: , text: "Проверьте все данные ещё раз и нажмите «Оформить заказ». После этого мастер получит уведомление и начнёт подготовку вашего изделия.", }, ]; export function HowToOrderSection() { return ( Как оформить заказ {steps.map((step, idx) => ( step.icon}> {step.label} {step.text} ))} ); } ``` - [ ] **Step 2: Commit** ```bash git add client/src/pages/info/ui/sections/HowToOrderSection.tsx git commit -m "feat: add HowToOrderSection with purchase step stepper" ``` --- ### Task 2: Create DeliverySection **Files:** - Create: `client/src/pages/info/ui/sections/DeliverySection.tsx` - [ ] **Step 1: Write the component** ```tsx import Grid from "@mui/material/Grid"; import Paper from "@mui/material/Paper"; import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; import { Package, Store, Truck } from "lucide-react"; import { PICKUP_ADDRESS_FULL } from "@/shared/constants/pickup-point"; const deliveries = [ { title: "Самовывоз", icon: , lines: [ "Бесплатно.", PICKUP_ADDRESS_FULL, "Перед визитом согласуем время — чтобы заказ точно был готов к выдаче.", ], }, { title: "Курьер по городу", icon: , lines: [ "Доставка в пределах города.", "Сроки и стоимость зависят от адреса и веса заказа.", "Мастер свяжется с вами для уточнения деталей после оформления.", ], }, { title: "Почта / СДЭК", icon: , lines: [ "Отправка в другие города.", "Каждому заказу присваивается трек-номер для отслеживания.", "Стоимость рассчитывается по тарифу перевозчика при оформлении.", ], }, ]; export function DeliverySection() { return ( Доставка {deliveries.map((d) => ( {d.icon} {d.title} {d.lines.map((line, i) => ( {line} ))} ))} ); } ``` - [ ] **Step 2: Commit** ```bash git add client/src/pages/info/ui/sections/DeliverySection.tsx git commit -m "feat: add DeliverySection with pickup, courier, and postal cards" ``` --- ### Task 3: Create PaymentSection **Files:** - Create: `client/src/pages/info/ui/sections/PaymentSection.tsx` - [ ] **Step 1: Write the component** ```tsx import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; import ListItemIcon from "@mui/material/ListItemIcon"; import ListItemText from "@mui/material/ListItemText"; import Paper from "@mui/material/Paper"; import Typography from "@mui/material/Typography"; import { Banknote, CreditCard } from "lucide-react"; const methods = [ { icon: , primary: "Банковская карта онлайн", secondary: "Оплата картой Visa, Mastercard или МИР сразу при оформлении заказа.", }, { icon: , primary: "Оплата при получении", secondary: "Оплата наличными или картой при получении заказа.", }, ]; export function PaymentSection() { return ( Оплата Оплата происходит после подтверждения заказа мастером. Вы получите уведомление, когда заказ будет подтверждён и готов к оплате. {methods.map((m) => ( {m.icon} ))} ); } ``` - [ ] **Step 2: Commit** ```bash git add client/src/pages/info/ui/sections/PaymentSection.tsx git commit -m "feat: add PaymentSection with card and cash methods" ``` --- ### Task 4: Create ReturnsSection **Files:** - Create: `client/src/pages/info/ui/sections/ReturnsSection.tsx` - [ ] **Step 1: Write the component** ```tsx import Paper from "@mui/material/Paper"; import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; export function ReturnsSection() { return ( Возврат и гарантии Возврат Если товар не соответствует описанию или имеет производственный дефект, свяжитесь с нами в течение 7 дней после получения. Мы заменим изделие на аналогичное или вернём деньги. Возврат товара надлежащего качества возможен в течение 14 дней, если изделие не было в употреблении и сохранён его товарный вид. Гарантия качества Мы отвечаем за качество каждого изделия ручной работы. Все дефекты, возникшие не по вине покупателя, устраняются или компенсируются заменой изделия. Если у вас возникли вопросы по качеству — напишите нам, и мы решим проблему в кратчайшие сроки. ); } ``` - [ ] **Step 2: Commit** ```bash git add client/src/pages/info/ui/sections/ReturnsSection.tsx git commit -m "feat: add ReturnsSection with return and warranty blocks" ``` --- ### Task 5: Rewrite InfoPage as static container **Files:** - Modify: `client/src/pages/info/ui/InfoPage.tsx` - [ ] **Step 1: Rewrite InfoPage.tsx** ```tsx import Box from "@mui/material/Box"; import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; import { DeliverySection } from "./sections/DeliverySection"; import { HowToOrderSection } from "./sections/HowToOrderSection"; import { PaymentSection } from "./sections/PaymentSection"; import { ReturnsSection } from "./sections/ReturnsSection"; export function InfoPage() { return ( Информация для покупателей Как оформить заказ, как проходит доставка, оплата и другие важные детали. ); } ``` - [ ] **Step 2: Commit** ```bash git add client/src/pages/info/ui/InfoPage.tsx git commit -m "feat: rewrite InfoPage as static container with section components" ``` --- ### Task 6: Delete admin info page **Files:** - Delete: `client/src/pages/admin-info/ui/AdminInfoPage.tsx` - Delete: `client/src/pages/admin-info/index.ts` - [ ] **Step 1: Delete files** ```bash rm client/src/pages/admin-info/ui/AdminInfoPage.tsx rm client/src/pages/admin-info/index.ts ``` - [ ] **Step 2: Commit** ```bash git add client/src/pages/admin-info/ git commit -m "feat: remove admin info page CRUD" ``` --- ### Task 7: Delete entities/info **Files:** - Delete: `client/src/entities/info/api/info-page-api.ts` - Delete: `client/src/entities/info/model/types.ts` - Delete: `client/src/entities/info/index.ts` - [ ] **Step 1: Delete files** ```bash rm client/src/entities/info/api/info-page-api.ts rm client/src/entities/info/model/types.ts rm client/src/entities/info/index.ts ``` - [ ] **Step 2: Commit** ```bash git add client/src/entities/info/ git commit -m "feat: remove info entity (admin CRUD layer)" ``` --- ### Task 8: Clean up AdminLayoutPage **Files:** - Modify: `client/src/pages/admin-layout/ui/AdminLayoutPage.tsx` - [ ] **Step 1: Remove import** ```tsx // REMOVE line 23: import { AdminInfoPage } from "@/pages/admin-info"; ``` Execute this edit: In `client/src/pages/admin-layout/ui/AdminLayoutPage.tsx`, remove the import line: ```tsx import { AdminInfoPage } from "@/pages/admin-info"; ``` - [ ] **Step 2: Remove FileText from lucide-react import** In line 18, change: ```tsx import { Bell, FileText, Image, LayoutGrid, ListOrdered, MessageSquare, Store, Users, } from "lucide-react"; ``` to: ```tsx import { Bell, Image, LayoutGrid, ListOrdered, MessageSquare, Store, Users, } from "lucide-react"; ``` - [ ] **Step 3: Remove nav item** Remove the nav item entry (line 64): ```tsx { to: '/admin/info', label: 'Инфо-страница', icon: }, ``` - [ ] **Step 4: Remove route** Remove the route line 192: ```tsx } /> ``` - [ ] **Step 5: Commit** ```bash git add client/src/pages/admin-layout/ui/AdminLayoutPage.tsx git commit -m "feat: remove info page from admin navigation and routes" ``` --- ### Task 9: Delete server info-page routes **Files:** - Delete: `server/src/routes/api/info-page.js` - Modify: `server/src/routes/api.js` - [ ] **Step 1: Delete the routes file** ```bash rm server/src/routes/api/info-page.js ``` - [ ] **Step 2: Clean up api.js** In `server/src/routes/api.js`: Remove the import line 10: ```js import { registerInfoPageRoutes } from "./api/info-page.js"; ``` Remove the call line 21: ```js await registerInfoPageRoutes(fastify); ``` - [ ] **Step 3: Commit** ```bash git add server/src/routes/api/info-page.js server/src/routes/api.js git commit -m "feat: remove server info-page routes" ``` --- ### Task 10: Remove InfoPageBlock model from Prisma schema **Files:** - Modify: `server/prisma/schema.prisma` - [ ] **Step 1: Remove model from schema** Remove lines 262-273 from `server/prisma/schema.prisma`: ```prisma model InfoPageBlock { id String @id @default(cuid()) key String @unique title String body String sort Int @default(0) published Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([published, sort]) } ``` Also remove the blank line before it (line 261). - [ ] **Step 2: Run migration** ```bash cd server && npm run db:migrate ``` Expected: Prisma creates a new migration dropping the `InfoPageBlock` table. - [ ] **Step 3: Commit** ```bash git add server/prisma/schema.prisma server/prisma/migrations/ git commit -m "feat: remove InfoPageBlock model from Prisma schema" ``` --- ### Task 11: Verify build and lint - [ ] **Step 1: Run server tests** ```bash cd server && npm test ``` Expected: all tests pass (no info-page tests exist, but other tests should still pass after removing routes). - [ ] **Step 2: Run client lint** ```bash cd client && npm run lint ``` Expected: no errors. - [ ] **Step 3: Run client format check** ```bash cd client && npm run format:check ``` Expected: all files formatted. - [ ] **Step 4: Run client tests** ```bash cd client && npm test ``` Expected: all tests pass. - [ ] **Step 5: Build client** ```bash cd client && npm run build ``` Expected: tsc + Vite build succeed with no errors. - [ ] **Step 6: Commit if any fixes** ```bash git add -A git commit -m "chore: lint and build fixes after info page migration" ```