fix: lưu ghi chú ở địa điểm vào ghi chú
This commit is contained in:
+105
@@ -0,0 +1,105 @@
|
||||
Markdown
|
||||
# To AI Agent: Implement Automatic Tour Note Generation & Dynamic Timeline Quick Note Insertion
|
||||
|
||||
## 1. Context & Feature Overview
|
||||
We are implementing an interconnected Note System for the Yotrip Travel Planner application. The feature spans across three core components: `TourDetailPage.tsx`, `MyNotePage.tsx`, and `ItineraryTimeline.tsx`.
|
||||
|
||||
### Core Requirements:
|
||||
1. **Auto-Note Initialization:** When a new Tour is created in `TourDetailPage.tsx`, the system must automatically instantiate a matching master note record inside the `MyNotePage.tsx` system linked by `tourId`.
|
||||
2. **Strict Document Schema Hierarchy:** The note content must format itself using structured headings reflecting the tour's legs (stages) and location points.
|
||||
3. **Timeline Quick Note Insertion:** Inside `ItineraryTimeline.tsx`, each location node must feature a "Quick Note Button". Clicking it must immediately stringify location metadata (Timestamp + Reverse-Geocoded Address + User Text) and `INSERT` it dynamically under the correct Stage section inside the master note.
|
||||
|
||||
---
|
||||
|
||||
## 2. Note Structure & Markdown Payload Template
|
||||
|
||||
When initializing a tour or syncing content, the document data payload within the database/state framework must stringify exactly to this structural template:
|
||||
|
||||
```markdown
|
||||
# [Tên Tour]
|
||||
|
||||
## Ghi chú chung
|
||||
*(Nội dung ghi chú tổng quan của chuyến đi...)*
|
||||
|
||||
## Ghi chú: [Tên Chặng 1]
|
||||
#### 📅 [Ngày giờ] | 📍 [Tên địa điểm - Phân giải từ tọa độ]
|
||||
- **Nhật ký:** [Nội dung người dùng nhập vào ở Điểm này trên Timeline]
|
||||
|
||||
## Ghi chú: [Tên Chặng 2]
|
||||
#### ...
|
||||
|
||||
## 3. Detailed Logic & Component Specifications
|
||||
### Step 1: TourDetailPage.tsx - Creation Hook Handler
|
||||
When the user submits the "Create Tour" form successfully, inject an asynchronous action handler to create the accompanying node container:
|
||||
|
||||
TypeScript
|
||||
// Blueprint for Tour Creation Action Hook
|
||||
const handleCreateTour = async (tourData: any) => {
|
||||
const newTour = await api.tours.create(tourData);
|
||||
|
||||
if (newTour) {
|
||||
// Generate the initial markdown note layout template
|
||||
const initialNoteBody = `# ${newTour.title}\n\n## Ghi chú chung\n\n`;
|
||||
|
||||
await api.notes.create({
|
||||
tourId: newTour.id,
|
||||
title: `Ghi chú: ${newTour.title}`,
|
||||
content: initialNoteBody,
|
||||
createdAt: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
### Step 2: ItineraryTimeline.tsx - Quick Note Component Injection
|
||||
Locate the location list renderer (leg.locations.map) adjacent to the white circular checkpoint nodes. Insert a small "Quick Note" button (utilizing Lucide icon FileText or similar).
|
||||
|
||||
JSX Target Insertion Blueprint
|
||||
JavaScript
|
||||
|
||||
{/* Quick Note Button Interface sitting right near the action buttons of the card */}
|
||||
<button
|
||||
onClick={() => handleQuickNoteInsert(leg.id, location.id, location)}
|
||||
className="p-1.5 text-yotripLight-steel hover:text-yotripLight-text dark:text-yotripDark-muted dark:hover:text-yotripDark-lime rounded-lg hover:bg-gray-100 dark:hover:bg-yotripDark-surface-muted transition-colors"
|
||||
title="Ghi chú nhanh điểm này"
|
||||
>
|
||||
<FileText className="w-4 h-4" />
|
||||
</button>
|
||||
|
||||
### Step 3: Coordinate Resolution & String Insertion Engine
|
||||
Implement the core method to reverse-geocode latitudes/longitudes, construct the standard string layout, and push the patch to the existing text repository of the note.
|
||||
|
||||
TypeScript
|
||||
|
||||
const handleQuickNoteInsert = async (legId: string, locationId: string, locationData: any) => {
|
||||
// 1. Resolve coordinates to a readable address string
|
||||
const resolvedAddress = await reverseGeocode(locationData.lat, locationData.lng) || locationData.addressName;
|
||||
|
||||
// 2. Format localized Date/Time
|
||||
const formattedTime = locationData.plannedStart
|
||||
? new Date(locationData.plannedStart).toLocaleString('vi-VN')
|
||||
: "Thời gian tùy hứng";
|
||||
|
||||
// 3. Extract user text inputted on the timeline card
|
||||
const userInputText = locationData.timelineComment || "Không có ghi chú thêm.";
|
||||
|
||||
// 4. Synthesize the injection block
|
||||
const noteSnippet = `#### 📅 ${formattedTime} | 📍 ${resolvedAddress}\n- **Nhật ký:** ${userInputText}\n\n`;
|
||||
|
||||
// 5. Trigger API/State update to find the master note by tourId,
|
||||
// locate or append the '## Ghi chú: [Tên Chặng]' marker, and inject the snippet directly below it.
|
||||
await api.notes.insertSectionByTourId(tourId, legId, noteSnippet);
|
||||
};
|
||||
|
||||
## 4. UI Style Integration Constraints
|
||||
Apply the application design system colors directly to the new buttons.
|
||||
|
||||
In Light mode, buttons must remain a clean #28536b (Yale Blue) or soft #7ea8be (Steel Blue).
|
||||
|
||||
In Dark mode, hover interactions must transition to #bce784 (Lime Cream) with a smooth transition-colors duration-200 modifier.
|
||||
|
||||
## 5. Acceptance Criteria for Verification
|
||||
[ ] Instantiation Check: Create a test Tour titled "Hoa vàng cỏ xanh 2026". Navigate to MyNotePage and confirm a note document with the exact title has been instantly spawned.
|
||||
|
||||
[ ] Geocoding & String Format Check: Click the Quick Note button on a location card with coordinates (e.g., 15.56, 108.49). The string appended to the note must fully resolve the address (e.g., "Tam Kỳ, Quảng Nam") instead of dumping raw coordinate numbers.
|
||||
|
||||
[ ] Structural Targeting: Ensure that inserting a quick note from Chặng 2 appends the text directly beneath the ## Ghi chú: Chặng 2 markdown anchor block, without scrambling or overwriting the text blocks of Chặng 1.
|
||||
Reference in New Issue
Block a user