User feedback 2026-05-07: muốn thêm nút edit kế bên row trong Panel 1, click →
Panel 2 sáng nội dung Section 1 lên cho user sửa header inline (KHÔNG cần đi
"Sửa header" page). Cũng muốn create new interface gần giống detail view
sectioned (defer cho chunk sau, hoặc keep PeHeaderForm nếu user OK).
Implementation:
~ PeDetailTabs.tsx
- InfoTab thêm prop `readOnly` + `autoEdit` (trigger edit mode tự động khi
mount nếu URL ?editHeader=1)
- canEdit = !readOnly && isDraft (DangSoanThao):
→ display mode: hiển thị FormRow + button "✎ Sửa" góc trên phải Section 1
→ editing mode (click Sửa hoặc autoEdit): card border brand-200 + 4 input
(Tên * / Dự án disabled / Địa điểm / Mô tả / Payment) + nút Lưu/Hủy
- Save: PUT /pe/:id full payload (current ev values + new editable fields).
onSuccess: invalidate ['pe-detail', 'pe-list'] + setEditing(false)
- PeDetailTabs prop `autoEditHeader` mới — pass-through xuống InfoTab
~ PeListPanel.tsx
- Thêm prop `onEditClick?: (id) => void`
- Pencil icon (lucide) absolute right-2 top-2 trong mỗi <li>, opacity-0
group-hover:opacity-100 — chỉ hiện khi user hover row + onEditClick set
- Click → trigger onEditClick(id) callback (different from row click)
~ PurchaseEvaluationWorkspacePage.tsx
- Đọc URL ?editHeader=1 → pass autoEditHeader xuống PeDetailTabs
- PeListPanel onEditClick → setParams({ id, mode: null, editHeader: '1' })
- onSelect (click row thường) → editHeader: null (clear flag)
- onBack → clear editHeader
Verify: npm run build fe-admin pass · 0 TS error.
Pending: workspace "new" mode wrap PeHeaderForm trong sectioned layout giống
detail view (defer — user có thể chấp nhận PeHeaderForm hiện tại nếu OK).
Next: Chunk 2 fe-user mirror.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- @vitejs/plugin-react uses Oxc
- @vitejs/plugin-react-swc uses SWC
React Compiler
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.
Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
You can also install eslint-plugin-react-x and eslint-plugin-react-dom for React-specific lint rules:
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])