test commit
This commit is contained in:
@@ -2,7 +2,7 @@ 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 { Package, Store } from 'lucide-react'
|
||||
import { PICKUP_ADDRESS_FULL } from '@/shared/constants/pickup-point'
|
||||
|
||||
const deliveries = [
|
||||
@@ -12,16 +12,7 @@ const deliveries = [
|
||||
lines: ['Бесплатно.', PICKUP_ADDRESS_FULL, 'Перед визитом согласуем время — чтобы заказ точно был готов к выдаче.'],
|
||||
},
|
||||
{
|
||||
title: 'Курьер по городу',
|
||||
icon: <Truck size={28} />,
|
||||
lines: [
|
||||
'Доставка в пределах города.',
|
||||
'Сроки и стоимость зависят от адреса и веса заказа.',
|
||||
'Мастер свяжется с вами для уточнения деталей после оформления.',
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Почта / СДЭК',
|
||||
title: 'Почта / Службы доставки',
|
||||
icon: <Package size={28} />,
|
||||
lines: [
|
||||
'Отправка в другие города.',
|
||||
|
||||
@@ -15,7 +15,7 @@ const methods = [
|
||||
{
|
||||
icon: <Banknote size={22} />,
|
||||
primary: 'Оплата при получении',
|
||||
secondary: 'Оплата наличными или картой при получении заказа у курьера или в пункте самовывоза.',
|
||||
secondary: 'Оплата наличными или картой при получении заказа.',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,636 @@
|
||||
# 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: <ShoppingCart size={20} />,
|
||||
text: "Найдите нужные изделия в каталоге и добавьте их в корзину. Вы можете выбрать несколько товаров от разных мастеров — все они соберутся в одном заказе.",
|
||||
},
|
||||
{
|
||||
label: "Проверьте корзину",
|
||||
icon: <ClipboardList size={20} />,
|
||||
text: "Перейдите в корзину и проверьте состав заказа: названия товаров, количество и итоговую сумму. Здесь же можно изменить количество или удалить позиции.",
|
||||
},
|
||||
{
|
||||
label: "Укажите контакты и адрес",
|
||||
icon: <Mail size={20} />,
|
||||
text: "Заполните имя, телефон и email для связи. Укажите адрес доставки — город, улицу, дом и квартиру. Эти данные нужны для расчёта стоимости и сроков.",
|
||||
},
|
||||
{
|
||||
label: "Выберите доставку и оплату",
|
||||
icon: <Truck size={20} />,
|
||||
text: "Выберите способ доставки: самовывоз, курьер или почта/СДЭК. Затем укажите способ оплаты: картой онлайн или при получении.",
|
||||
},
|
||||
{
|
||||
label: "Подтвердите заказ",
|
||||
icon: <CheckCircle size={20} />,
|
||||
text: "Проверьте все данные ещё раз и нажмите «Оформить заказ». После этого мастер получит уведомление и начнёт подготовку вашего изделия.",
|
||||
},
|
||||
];
|
||||
|
||||
export function HowToOrderSection() {
|
||||
return (
|
||||
<Paper variant="outlined" sx={{ p: 3, borderRadius: 2 }}>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Как оформить заказ
|
||||
</Typography>
|
||||
<Stepper orientation="vertical" activeStep={-1}>
|
||||
{steps.map((step, idx) => (
|
||||
<Step key={idx} completed={false}>
|
||||
<StepLabel StepIconComponent={() => step.icon}>
|
||||
{step.label}
|
||||
</StepLabel>
|
||||
<StepContent>
|
||||
<Typography color="text.secondary">{step.text}</Typography>
|
||||
</StepContent>
|
||||
</Step>
|
||||
))}
|
||||
</Stepper>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **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: <Store size={28} />,
|
||||
lines: [
|
||||
"Бесплатно.",
|
||||
PICKUP_ADDRESS_FULL,
|
||||
"Перед визитом согласуем время — чтобы заказ точно был готов к выдаче.",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Курьер по городу",
|
||||
icon: <Truck size={28} />,
|
||||
lines: [
|
||||
"Доставка в пределах города.",
|
||||
"Сроки и стоимость зависят от адреса и веса заказа.",
|
||||
"Мастер свяжется с вами для уточнения деталей после оформления.",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Почта / СДЭК",
|
||||
icon: <Package size={28} />,
|
||||
lines: [
|
||||
"Отправка в другие города.",
|
||||
"Каждому заказу присваивается трек-номер для отслеживания.",
|
||||
"Стоимость рассчитывается по тарифу перевозчика при оформлении.",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export function DeliverySection() {
|
||||
return (
|
||||
<Paper variant="outlined" sx={{ p: 3, borderRadius: 2 }}>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Доставка
|
||||
</Typography>
|
||||
<Grid container spacing={2}>
|
||||
{deliveries.map((d) => (
|
||||
<Grid key={d.title} size={{ xs: 12, sm: 6, md: 4 }}>
|
||||
<Paper
|
||||
variant="outlined"
|
||||
sx={{ p: 2, borderRadius: 2, height: "100%" }}
|
||||
>
|
||||
<Stack spacing={1.5}>
|
||||
<Stack
|
||||
direction="row"
|
||||
spacing={1}
|
||||
sx={{ alignItems: "center" }}
|
||||
>
|
||||
{d.icon}
|
||||
<Typography variant="h6">{d.title}</Typography>
|
||||
</Stack>
|
||||
{d.lines.map((line, i) => (
|
||||
<Typography key={i} variant="body2" color="text.secondary">
|
||||
{line}
|
||||
</Typography>
|
||||
))}
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **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: <CreditCard size={22} />,
|
||||
primary: "Банковская карта онлайн",
|
||||
secondary:
|
||||
"Оплата картой Visa, Mastercard или МИР сразу при оформлении заказа.",
|
||||
},
|
||||
{
|
||||
icon: <Banknote size={22} />,
|
||||
primary: "Оплата при получении",
|
||||
secondary: "Оплата наличными или картой при получении заказа.",
|
||||
},
|
||||
];
|
||||
|
||||
export function PaymentSection() {
|
||||
return (
|
||||
<Paper variant="outlined" sx={{ p: 3, borderRadius: 2 }}>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Оплата
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 1 }}>
|
||||
Оплата происходит после подтверждения заказа мастером. Вы получите
|
||||
уведомление, когда заказ будет подтверждён и готов к оплате.
|
||||
</Typography>
|
||||
<List disablePadding>
|
||||
{methods.map((m) => (
|
||||
<ListItem key={m.primary} disableGutters>
|
||||
<ListItemIcon sx={{ minWidth: 40 }}>{m.icon}</ListItemIcon>
|
||||
<ListItemText primary={m.primary} secondary={m.secondary} />
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **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 (
|
||||
<Paper variant="outlined" sx={{ p: 3, borderRadius: 2 }}>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Возврат и гарантии
|
||||
</Typography>
|
||||
<Stack spacing={2}>
|
||||
<Paper variant="outlined" sx={{ p: 2, borderRadius: 2 }}>
|
||||
<Typography variant="subtitle1" sx={{ fontWeight: 600 }} gutterBottom>
|
||||
Возврат
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Если товар не соответствует описанию или имеет производственный
|
||||
дефект, свяжитесь с нами в течение 7 дней после получения. Мы
|
||||
заменим изделие на аналогичное или вернём деньги. Возврат товара
|
||||
надлежащего качества возможен в течение 14 дней, если изделие не
|
||||
было в употреблении и сохранён его товарный вид.
|
||||
</Typography>
|
||||
</Paper>
|
||||
<Paper variant="outlined" sx={{ p: 2, borderRadius: 2 }}>
|
||||
<Typography variant="subtitle1" sx={{ fontWeight: 600 }} gutterBottom>
|
||||
Гарантия качества
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Мы отвечаем за качество каждого изделия ручной работы. Все дефекты,
|
||||
возникшие не по вине покупателя, устраняются или компенсируются
|
||||
заменой изделия. Если у вас возникли вопросы по качеству — напишите
|
||||
нам, и мы решим проблему в кратчайшие сроки.
|
||||
</Typography>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **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 (
|
||||
<Box>
|
||||
<Typography variant="h4" gutterBottom>
|
||||
Информация для покупателей
|
||||
</Typography>
|
||||
<Typography color="text.secondary" sx={{ mb: 3 }}>
|
||||
Как оформить заказ, как проходит доставка, оплата и другие важные
|
||||
детали.
|
||||
</Typography>
|
||||
|
||||
<Stack spacing={3}>
|
||||
<HowToOrderSection />
|
||||
<DeliverySection />
|
||||
<PaymentSection />
|
||||
<ReturnsSection />
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **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: <FileText /> },
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Remove route**
|
||||
|
||||
Remove the route line 192:
|
||||
|
||||
```tsx
|
||||
<Route path="info" element={<AdminInfoPage />} />
|
||||
```
|
||||
|
||||
- [ ] **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"
|
||||
```
|
||||
@@ -0,0 +1,102 @@
|
||||
# 2026-05-19 — Статическая страница «О покупке» (удаление админ-CRUD)
|
||||
|
||||
## Цель
|
||||
|
||||
Убрать ручное наполнение информационной страницы админом через `InfoPageBlock` CRUD.
|
||||
Заменить на статическую страницу с хардкод-контентом в React-компонентах: схемы процессов,
|
||||
пошаговые инструкции, карточки доставки, список оплат, условия возврата.
|
||||
|
||||
## Что удаляется
|
||||
|
||||
| Файл/директория | Действие |
|
||||
|---|---|
|
||||
| `client/src/pages/admin-info/` | Удалить целиком (AdminInfoPage + index.ts) |
|
||||
| `client/src/entities/info/` | Удалить целиком (api, model, index.ts) |
|
||||
| `server/src/routes/api/info-page.js` | Удалить целиком |
|
||||
| `server/src/routes/api.js` | Убрать `import` + вызов `registerInfoPageRoutes` |
|
||||
| `server/prisma/schema.prisma` | Удалить модель `InfoPageBlock` и связанный индекс |
|
||||
| `client/src/pages/admin-layout/ui/AdminLayoutPage.tsx` | Убрать пункт меню «Инфо-страница», импорт и роут |
|
||||
| Миграция `20260503144425_...` | Не трогать, Prisma обработает через `db:migrate` |
|
||||
|
||||
После удаления модели Prisma нужно выполнить `npm run db:migrate` в `server/`.
|
||||
|
||||
## Что остаётся
|
||||
|
||||
- Публичный роут `GET /api/info-page/blocks` удаляется — страница больше не ходит на сервер
|
||||
- Роут `/info` в `client/src/app/routes/index.tsx` остаётся как есть
|
||||
- Ссылка «О покупке» в футере `MainLayout.tsx` остаётся как есть
|
||||
|
||||
## Новая структура страницы
|
||||
|
||||
```
|
||||
client/src/pages/info/
|
||||
ui/
|
||||
InfoPage.tsx -- контейнер: заголовок + секции
|
||||
sections/
|
||||
HowToOrderSection.tsx -- Stepper: 5 шагов покупки
|
||||
DeliverySection.tsx -- Grid-карточки: самовывоз, курьер, почта
|
||||
PaymentSection.tsx -- List со способами оплаты
|
||||
ReturnsSection.tsx -- Paper-блоки: возврат, гарантия
|
||||
index.ts -- export { InfoPage }
|
||||
```
|
||||
|
||||
## Дизайн секций
|
||||
|
||||
### InfoPage (контейнер)
|
||||
|
||||
- Typography `variant="h4"`: «Информация для покупателей»
|
||||
- Typography `color="text.secondary"` с текущим подзаголовком
|
||||
- Секции рендерятся последовательно с `Stack spacing={4}`
|
||||
|
||||
### HowToOrderSection
|
||||
|
||||
- MUI `Stepper` вертикальный, `activeStep=-1` (все шаги видны, не активные)
|
||||
- 5 шагов с `StepLabel`, каждый содержит:
|
||||
- Заголовок шага
|
||||
- Пояснительный текст
|
||||
- Иконку через `StepIconComponent` или проп icon в `Step`
|
||||
|
||||
Шаги:
|
||||
1. «Выберите товары» (ShoppingCart) — Найдите нужное в каталоге, добавьте в корзину
|
||||
2. «Проверьте корзину» (ClipboardList) — Проверьте состав заказа, количество и итоговую сумму
|
||||
3. «Укажите контакты и адрес» (Mail) — Заполните имя, телефон, email и адрес доставки
|
||||
4. «Выберите доставку и оплату» (Truck) — Выберите удобный способ получения и оплаты
|
||||
5. «Подтвердите заказ» (CheckCircle) — Проверьте всё ещё раз и нажмите «Оформить заказ»
|
||||
|
||||
### DeliverySection
|
||||
|
||||
- Три карточки в `Grid container spacing={2}` с `Paper variant="outlined"`:
|
||||
- **Самовывоз** (Store) — Бесплатно. Адрес. Перед визитом согласуем время.
|
||||
- **Курьер по городу** (Truck) — Доставка в пределах города. Сроки и стоимость уточняются.
|
||||
- **Почта / СДЭК** (Package) — Отправка с трек-номером. Стоимость по тарифу перевозчика.
|
||||
|
||||
### PaymentSection
|
||||
|
||||
- MUI `List` с `ListItem` элементами, каждый с `ListItemIcon`:
|
||||
- Банковская карта онлайн (CreditCard)
|
||||
- Оплата при получении (Banknote)
|
||||
- Текст: «Оплата происходит после подтверждения заказа мастером.»
|
||||
|
||||
### ReturnsSection
|
||||
|
||||
- Два `Paper variant="outlined"` блока:
|
||||
- «Возврат» — Если товар не соответствует описанию или есть дефект, свяжитесь с нами. Мы заменим изделие или вернём деньги.
|
||||
- «Гарантия» — Мы отвечаем за качество каждого изделия. Все дефекты, возникшие не по вине покупателя, устраняем или меняем изделие.
|
||||
|
||||
## Константы
|
||||
|
||||
Использовать существующие:
|
||||
- `PICKUP_ADDRESS_FULL`, `PICKUP_COORDINATES` из `@/shared/constants/pickup-point`
|
||||
- `STORE_EMAIL` из `@/shared/constants/store`
|
||||
- Для способов оплаты — текст захардкожен, т.к. payment-method из shared/constants содержит только ключи
|
||||
|
||||
## Иконки
|
||||
|
||||
Все иконки из `lucide-react`: ShoppingCart, ClipboardList, Mail, Truck, CheckCircle, Store, Package, CreditCard, Banknote.
|
||||
|
||||
## Что НЕ входит в scope
|
||||
|
||||
- Сохранение обратной совместимости с текущей динамической страницей
|
||||
- Миграция существующих данных InfoPageBlock (они просто удаляются)
|
||||
- Автообновление контента админом (страница статическая)
|
||||
- Телефоны поддержки (если понадобятся — отдельной задачей)
|
||||
Binary file not shown.
Reference in New Issue
Block a user