105 lines
5.3 KiB
Markdown
105 lines
5.3 KiB
Markdown
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. |