Import remaining project documentation and reference notes

Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
arsam
2026-09-18 23:33:04 +03:30
parent 4791bc2da0
commit e9cd12dda6
43 changed files with 20604 additions and 0 deletions
@@ -0,0 +1,159 @@
# Phase 11 Track 1 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:** Close 5 functional gaps in the Teknav Admin Panel where backend support is already present but UI wiring is missing.
**Architecture:** Modify existing React components in `teknav-admin.jsx` to add form fields, filters, dedicated tabs, and bulk operation controls.
**Tech Stack:** React 18, Fastify (Backend), Prisma, custom CSS-in-JS (via `teknav-ui.jsx`).
---
### Task 1: Article Editor Flags Toggles
**Files:**
- Modify: `teknav-admin.jsx`
- [ ] **Step 1: Locate flags group in ArticleEditor**
Find the "نشانه‌گذاری" group in the `ArticleEditor` component (approx line 1500-1600).
- [ ] **Step 2: Add toggles for premiumOnly, sponsored, and featured**
Update the array of flags to include all three fields. Ensure `premiumOnly` uses a lock icon, `sponsored` uses a star/badge, and `featured` uses a star.
```javascript
// Inside ArticleEditor flags group
{[
{ key: 'premiumOnly', label: 'فقط اعضای ویژه', icon: '🔒' },
{ key: 'sponsored', label: 'محتوای حمایت‌شده', icon: '⭐' },
{ key: 'featured', label: 'مقاله ویژه', icon: '★' },
].map(({ key, label, icon }) => (
<div key={key} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
<label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: '#263238', cursor: 'pointer' }}>
<span style={{ fontSize: 14 }}>{icon}</span>
<span>{label}</span>
</label>
<button
type="button"
onClick={() => set(key, !form[key])}
style={{
width: 44, height: 24, borderRadius: 12, border: 'none', cursor: 'pointer',
background: form[key] ? BRAND.primary : '#D0CCC5',
position: 'relative', transition: 'background 0.2s', flexShrink: 0,
}}
>
<span style={{
position: 'absolute', top: 3, width: 18, height: 18, borderRadius: '50%', background: '#fff',
transition: 'inset-inline-start 0.2s',
insetInlineStart: form[key] ? 23 : 3,
}} />
</button>
</div>
))}
```
- [ ] **Step 3: Verify form state update**
Ensure `handleSave` correctly includes these new boolean fields in the `data` object sent to `adminApi.createArticle` or `adminApi.updateArticle`.
- [ ] **Step 4: Manual verification**
Open a "Published" article in the editor, toggle "Premium Only", save, and verify it persists (check local browser network tab).
---
### Task 2: Content Freshness Filter
**Files:**
- Modify: `teknav-admin.jsx`
- [ ] **Step 1: Locate filter bar in ArticlesManagement**
Find the `ArticlesManagement` component and its filter inputs (approx line 300-400).
- [ ] **Step 2: Add freshness filter dropdown**
Add a new `<select>` for `freshnessFilter` with options: همه | به‌روز | نیاز به بازنگری | قدیمی.
```javascript
<select value={freshnessFilter} onChange={e => setFreshnessFilter(e.target.value)} style={{ ...inputStyle, maxWidth: 180 }} dir="rtl">
<option value="">همه تازگی‌ها</option>
<option value="up_to_date">به‌روز</option>
<option value="needs_update">نیاز به بازنگری</option>
<option value="outdated">قدیمی</option>
</select>
```
- [ ] **Step 3: Update filtering logic**
Ensure `filtered` useMemo includes the freshness filter logic:
```javascript
if (freshnessFilter) list = list.filter(a => a.contentFreshnessStatus === freshnessFilter);
```
- [ ] **Step 4: Manual verification**
Change the dropdown value and ensure the table updates to show only articles with the matching status.
---
### Task 3: Dedicated SEO Audit Tab
**Files:**
- Modify: `teknav-admin.jsx`
- [ ] **Step 1: Register new tab in SIDEBAR_ITEMS**
Add `{ id: 'seo-audit', label: 'ممیزی SEO', icon: '◈' }` to the `admin` role in `SIDEBAR_ITEMS`.
- [ ] **Step 2: Update AdminPanel to handle 'seo-audit' tab**
In the main `AdminPanel` render loop, add a case for `activeTab === 'seo-audit'`.
- [ ] **Step 3: Move SeoAuditPanel rendering**
Ensure `SeoAuditPanel` is rendered as the primary component for the new tab.
- [ ] **Step 4: Manual verification**
Click the "SEO Audit" item in the sidebar and verify it renders the full audit table.
---
### Task 4: Engagement Analytics Enhancements
**Files:**
- Modify: `teknav-admin.jsx`
- [ ] **Step 1: Expand EngagementAnalyticsPanel**
Enhance the existing `EngagementAnalyticsPanel` to show more detail.
- [ ] **Step 2: Add 7-day event count chart**
Re-use `WeeklyChart` or the area-SVG pattern to visualize `engagement.weeklyData`.
- [ ] **Step 3: Add Top 5 articles table**
Render `engagement.topArticles` in a simple list or table.
- [ ] **Step 4: Manual verification**
Open Analytics -> Engagement tab and verify charts and tables populate with real data.
---
### Task 5: Bulk Comment Moderation UI
**Files:**
- Modify: `teknav-admin.jsx`
- [ ] **Step 1: Add selection state to CommentsModeration**
Ensure `selected` Set state is active (it seems partially present in the current code section).
- [ ] **Step 2: Add floating action bar**
Render the bulk action bar at the bottom of the screen when `selected.size > 0`.
```javascript
{selected.size > 0 && (
<div style={{ position: 'fixed', bottom: 24, left: '50%', transform: 'translateX(-50%)', background: BRAND.ink, color: '#fff', borderRadius: 14, padding: '12px 20px', display: 'flex', alignItems: 'center', gap: 12, zIndex: 600 }}>
<span style={{ fontWeight: 700 }}>{selected.size.toLocaleString('fa-IR')} مورد انتخاب شده</span>
<button onClick={() => bulkAction('delete')} style={bulkBtnStyle}>حذف</button>
<button onClick={() => bulkAction('approve')} style={bulkBtnStyle}>تأیید</button>
<button onClick={() => setSelected(new Set())}>لغو</button>
</div>
)}
```
- [ ] **Step 3: Wire bulkAction to API**
Call `adminApi.bulkModerateComments(ids, action)` and refresh the list.
- [ ] **Step 4: Manual verification**
Check 2-3 comments, click "Approve", and verify they are processed and the selection is cleared.