130 lines
7.5 KiB
Markdown
130 lines
7.5 KiB
Markdown
# To AI Agent: Deprecate MemberDashboard Page and Re-architect All User Features into Dedicated Modals on LandingPage
|
|
|
|
## 1. Architectural Strategy & Goal
|
|
We are completely removing the standalone `MemberDashboard` route/page. When a user logs in successfully, they must **remain directly on the `LandingPage`** (or `ExplorerMap`), with their authentication state shifting cleanly to display the member avatar dropdown menu in the top-bar header.
|
|
|
|
Every core feature previously hosted on the dashboard page must now be converted into a high-performance, responsive **Modal Overlay Component**. Clicking an item in the avatar dropdown menu will toggle the visibility state of its respective modal over the current viewport, ensuring zero page-redirection disruption.
|
|
|
|
---
|
|
|
|
## 2. Route Deletion & Auth Redirection Clean-up
|
|
### 1. **Route Removal:** Open your router configuration (`App.tsx` or `routes.tsx`) and permanently delete the `<Route path="/dashboard" ... />` node.
|
|
### 2. **Auth Hook Modification:** Inside the login handler lifecycle (e.g., `LoginModal.tsx` or `AuthContext.tsx`), replace `Maps('/dashboard')` with a simple state closer that preserves the current page instance:
|
|
```typescript
|
|
// ❌ OLD: navigate('/dashboard');
|
|
// ✅ NEW: Keep user on context page, close login overlay, update profile states
|
|
setIsLoginModalOpen(false);
|
|
|
|
## 3. Technical Specifications for Each Target Modal
|
|
Implement the following modal architectures inside frontend/src/components/modals/:
|
|
|
|
### 3.1. Modal Chat Trực Tiếp (LiveChatModal.tsx)
|
|
Layout Architecture: A wide responsive viewport split into two main functional vertical columns (flex flex-col md:flex-row h-[80vh]).
|
|
|
|
Left Column (w-full md:w-80 border-r border-slate-800): Interactive scrollable contact strip displaying the User's Friend List with online status indicators and latest message snippets.
|
|
|
|
Right Column (flex-1 flex flex-col bg-slate-950): Active conversation window.
|
|
|
|
Bottom Input Tray Wrapper: A rich-text typing container bar fixed at the baseline containing:
|
|
|
|
Text input area field.
|
|
|
|
Attachment Trigger buttons: Icon for Image uploads (accept="image/*") and an Icon for transmitting spatial GPS Coordinates/Locations directly into the text stream.
|
|
|
|
### 3.2. Modal Hành Trình Của Tôi (MyToursModal.tsx)
|
|
Layout Architecture: A dynamic card explorer view featuring structural chronological timeline tabs at the top:
|
|
|
|
Tabs Grid: Đang thực hiện (Ongoing), Sắp khởi hành (Upcoming), and Đã hoàn thành (Past).
|
|
|
|
Core Content Panel: Clicking a tab renders a fluid inner grid loop of compact trip tiles. Each tile houses a banner photo, progress indicators, and quick action links to open the standalone TourNavigationPage or route maps directly.
|
|
|
|
### 3.3. Modal Thư Viện Ảnh (PhotoGalleryModal.tsx)
|
|
Layout Architecture: A dedicated media repository browser displaying all images uploaded by the member.
|
|
|
|
Filtering Header Matrix: Dual filter select boxes pinned at the top:
|
|
|
|
Filter 1: Filter by Itinerary/Trip (Theo hành trình).
|
|
|
|
Filter 2: Filter by Media Hashtags (Theo tags).
|
|
|
|
Core Workspace: A masonry-style gallery layout grid with hover micro-interactions enabling the user to view full resolution views, edit asset tagging descriptions, or delete pictures directly.
|
|
|
|
### 3.4. Modal Danh Sách Bạn Bè (FriendsManagerModal.tsx)
|
|
Layout Architecture: A centralized social dashboard layout built to handle user connections.
|
|
|
|
Functional Subsections:
|
|
|
|
Search engine bar to lookup new profiles via display name or telephone metrics.
|
|
|
|
Tab views separating Danh sách bạn bè (Active Friends) and Lời mời kết bạn (Pending Requests).
|
|
|
|
Row items equipped with direct context action triggers: Hủy kết bạn (Unfriend), Chấp nhận (Accept), or Nhắn tin (Quick Message - which bridges states to auto-toggle the Chat Modal).
|
|
|
|
## 4. Top-Bar Profile Dropdown Structure Integration
|
|
Refactor the items list container within MapProfileDropdown.tsx to match the localized modal toggles state logic:
|
|
|
|
TypeScript
|
|
import React, { useState } from 'react';
|
|
import { Compass, Map, Image, Settings, ShieldAlert, Users, LogOut } from 'lucide-react';
|
|
|
|
export const HeaderMemberDropdown = ({ openModal }) => {
|
|
return (
|
|
<div className="absolute right-0 top-14 w-64 bg-slate-900 border border-slate-800 rounded-xl p-1.5 shadow-2xl flex flex-col space-y-0.5 text-xs text-slate-200 z-[999999]">
|
|
|
|
{/* 1. Nút "Tạo tour" */}
|
|
<button onClick={() => openModal('create_tour')} className="flex items-center gap-3 w-full px-4 py-2.5 hover:bg-slate-800 rounded-lg text-left transition-colors">
|
|
<Compass className="w-4 h-4 text-amber-400" />
|
|
<span className="font-medium">Tạo tour</span>
|
|
</button>
|
|
|
|
{/* 2. Nút "Hành trình của tôi" */}
|
|
<button onClick={() => openModal('my_tours')} className="flex items-center gap-3 w-full px-4 py-2.5 hover:bg-slate-800 rounded-lg text-left transition-colors">
|
|
<Map className="w-4 h-4 text-blue-400" />
|
|
<span className="font-medium">Hành trình của tôi</span>
|
|
</button>
|
|
|
|
{/* 3. Nút "Thư viện ảnh" */}
|
|
<button onClick={() => openModal('gallery')} className="flex items-center gap-3 w-full px-4 py-2.5 hover:bg-slate-800 rounded-lg text-left transition-colors">
|
|
<Image className="w-4 h-4 text-emerald-400" />
|
|
<span className="font-medium">Thư viện ảnh</span>
|
|
</button>
|
|
|
|
{/* 4. Nút "Cài đặt" */}
|
|
<button onClick={() => openModal('settings')} className="flex items-center gap-3 w-full px-4 py-2.5 hover:bg-slate-800 rounded-lg text-left transition-colors">
|
|
<Settings className="w-4 h-4 text-slate-400" />
|
|
<span className="font-medium">Cài đặt</span>
|
|
</button>
|
|
|
|
{/* 5. Nút "Báo cáo vi phạm" */}
|
|
<button onClick={() => openModal('reports')} className="flex items-center gap-3 w-full px-4 py-2.5 hover:bg-slate-800 rounded-lg text-left transition-colors">
|
|
<ShieldAlert className="w-4 h-4 text-rose-400" />
|
|
<span className="font-medium">Báo cáo vi phạm</span>
|
|
</button>
|
|
|
|
<div className="h-[1px] bg-slate-800/80 my-1 mx-2" />
|
|
|
|
{/* 6. Nút "Danh sách bạn bè" */}
|
|
<button onClick={() => openModal('friends')} className="flex items-center gap-3 w-full px-4 py-2.5 hover:bg-slate-800 rounded-lg text-left transition-colors">
|
|
<Users className="w-4 h-4 text-indigo-400" />
|
|
<span className="font-medium">Danh sách bạn bè</span>
|
|
</button>
|
|
|
|
{/* 7. Nút "Đăng xuất" */}
|
|
<button onClick={() => openModal('logout')} className="flex items-center gap-3 w-full px-4 py-2.5 text-rose-400 hover:bg-slate-800 rounded-lg text-left font-bold transition-colors">
|
|
<LogOut className="w-4 h-4 text-rose-500" />
|
|
<span>Đăng xuất</span>
|
|
</button>
|
|
|
|
</div>
|
|
);
|
|
};
|
|
|
|
## 5. Automation Checklists for Quality Verification
|
|
[ ] Redirection Invalidation Check: Perform a successful user login sweep. Verify the active URL hash parameter remains exactly / or /map, completely dropping dashboard transitions.
|
|
|
|
[ ] Chat Modal Layout Sizing: Trigger the Live Chat button. Ensure the workspace scales to an explicit split-view pane framework (Left: Contacts / Right: Dialog Thread) with working attachment trays.
|
|
|
|
[ ] Gallery Filter Interception: Confirm that filtering options inside the Photo modal dynamically re-index asset cards based on itinerary tags or custom upload parameters.
|
|
|
|
[ ] Global Z-Index Verification: All new modals must enforce a strict z-[999999] utility layer rule to pop up cleanly above the underlying map viewport layer without clip cutting.
|