WP-FE-DELIVERY-ORDER-01 — Đặt hàng (chim một cánh quắp cục hàng)
Domain: D-DELIVERY · Surfaces: CON (+ API contract) · Ngày: 2026-08-18
Ô dịch vụ «Đặt hàng» trên Home + icon vector riêng + màn tạo đơn dùng GPS/địa chỉ thật.
1. Yêu cầu
- Thêm chức năng đặt hàng (gửi/giao bưu kiện A→B) vào bề mặt Consumer.
- Icon là chim một cánh quắp cục hàng.
- Audit + hoàn thiện chức năng này.
2. Audit hiện trạng (trước WP)
| Lớp |
Hiện trạng |
Kết luận |
API delivery |
10 ops IMP: quote, orders, orders/me, orders/:id, status, driver/* |
Đủ |
| Prisma |
DeliveryOrder + enum NEW/QUOTED/PICKED/DELIVERED/CANCELLED · index driverId,status |
Đủ |
| CON màn hình |
DeliveryHome · DeliveryOrders · DeliveryDetail (đăng ký trong MapStackNavigator) |
Có |
| DRV |
Card «Đơn giao mới / đang giao» trong HomeScreen + DeliveryDriverApi |
Có |
| PAR · ADM |
Không có màn ops giao hàng |
Gap (ngoài WP) |
| Điểm vào Home |
HOME_SERVICE_GRID không có ô nào → phải «Xem thêm» → Tất cả dịch vụ → «Giao hàng» |
Gap chính |
| Toạ độ đơn |
DeliveryHomeScreen dùng DEFAULT_GEO + preset dLat/dLng cứng → đơn sai vị trí |
Gap chính |
| Icon danh mục |
Toàn bộ grid là tên glyph MaterialCommunityIcons; không có asset icon danh mục nào |
Cần cơ chế mới |
3. Thay đổi
| File |
Nội dung |
Status |
mobile/src/shared/ui/icons/BirdParcelIcon.tsx |
Mới — icon SVG chim một cánh quắp cục hàng |
IMP |
mobile/src/shared/ui/icons/serviceSvgIcons.ts |
Mới — registry icon vector cho ô dịch vụ (bird-parcel) |
IMP |
mobile/src/features/home/serviceCatalog.ts |
ServiceItem.iconSvg? · ô Home «Đặt hàng» (thay ô «Cà phê») · Tất cả dịch vụ đổi nhãn |
IMP |
mobile/src/features/home/components/ServiceGridItem.tsx |
Render iconSvg (22px Home / 28px Tất cả dịch vụ), fallback glyph icon |
IMP |
mobile/src/features/delivery/deliveryOrder.ts |
Mới — guard điểm lấy/giao + body gửi BE + nhãn điểm (module thuần, không import chéo) |
IMP |
mobile/src/features/delivery/deliveryOrder.test.ts |
Mới — 12 test node:test |
IMP |
mobile/src/features/delivery/screens/DeliveryHomeScreen.tsx |
Viết lại: GPS + reverse-geocode điểm lấy · autocomplete điểm giao · báo giá tự động |
IMP |
mobile/src/features/delivery/screens/DeliveryDetailScreen.tsx |
Hero dùng BirdParcelIcon |
IMP |
mobile/package.json |
react-native-svg@15.12.1 (npx expo install, khớp SDK 54 · có trong Expo Go) |
— |
3.1 Ô Home
Grid Home là 2×5 = 10 ô cố định theo mockup Figma 365:10. «Đặt hàng» thay ô «Cà phê» —
cà phê vẫn vào được qua Tất cả dịch vụ → nhóm «Ăn uống & Mua sắm» (MerchantList kind=FNB),
nên không mất đường đi nào. Route delivery → DeliveryHome đã có sẵn trong navigateService.
3.2 Icon
- Hình: chim bay chếch lên, một cánh dựng cao, đuôi chẻ, mỏ + mắt, quắp thùng hàng có dây buộc chữ thập dưới bụng.
- Khe giữa bụng chim và thùng hàng là mask trong suốt, không tô màu nền → dùng được cả trên vòng tròn màu đặc (Home) và vòng tròn tint nhạt (Tất cả dịch vụ).
- Hình minh hoạ nhiều chi tiết hơn glyph nên render 22px trong vòng 40px (glyph MCI là 17px) và 28px trong vòng 48px.
ServiceItem.icon vẫn giữ truck-delivery làm fallback cho renderer chưa đọc iconSvg (badge pin map, ServiceStubScreen).
3.3 Màn Đặt hàng
| Trước |
Sau |
| 2 chip preset «Bến Thành → Landmark…» |
Ô «Lấy hàng ở đâu?» + «Giao đến đâu?» có gợi ý địa chỉ realtime |
pickup = DEFAULT_GEO cứng |
GPS thiết bị (useDeviceLocation) + RoutingApi.reverseGeocode ra nhãn |
dropoff = DEFAULT_GEO + dLat/dLng |
RoutingApi.autocomplete (Google-first, fallback OSM) → toạ độ thật |
| Bấm «Báo giá» thủ công |
Tự báo giá (debounce 250ms) khi đủ 2 điểm hợp lệ |
| Tạo đơn được với mọi input |
Chặn khi thiếu điểm / toạ độ sai / hai điểm cách nhau < 80 m |
| Nút GPS: không có |
Nút crosshairs-gps lấy lại vị trí hiện tại |
4. Verify local
| Kiểm tra |
Kết quả |
node --test deliveryOrder.test.ts |
12/12 PASS |
npm run test:unit (mobile) |
35/35 PASS (gồm navigateService phủ mọi ô Home có route thật) |
| Metro bundle Android |
HTTP 200 · 14.7 MB · bundle chứa mask id wlBirdCut + react-native-svg |
POST /delivery/quote |
201 · 3.64 km → feeAmount 18195 |
GET /routing/reverse-geocode |
200 · 12 Lê Lợi, Quận 1 |
GET /routing/autocomplete?q=Landmark |
200 · 5 hit có toạ độ |
tsc --noEmit (mobile) |
12 lỗi tồn tại trước WP (fnb · medical · rides · support · home) · 0 lỗi ở file của WP này |
API smoke chạy trên https://api.minhtien.cloud/api/v1 vì API local (:3011) không bật trong session này;
BE delivery không đổi trong WP này nên contract smoke là đủ.
5. Gap còn lại (không thuộc WP này)
| Gap |
Đề xuất |
| Không có GPS WS theo dõi shipper (CON đang poll 4s) |
WP-DELIVERY-GPS-LIVE-01 |
| DRV chưa có màn giao hàng riêng (chỉ card trong Home) |
WP-DRV-DELIVERY-TRIP-01 |
| PAR/ADM chưa có ops đơn giao |
WP-ADM-DELIVERY-OPS-01 |
paymentIntentId chưa dùng — chưa trừ ví/thanh toán phí giao |
OWNER Pay gate |
Enum QUOTED không có code path nào set |
dọn enum hoặc dùng khi giữ giá |
EAS preview APK cũ chưa có native react-native-svg |
build lại preview khi phát hành |
Domain: D-DELIVERY
WP: WP-FE-DELIVERY-ORDER-01
Surfaces: CON (API contract only)
Status: IMP
Local: PASS
Next: WP-DELIVERY-GPS-LIVE-01 | OWNER Pay