frontend phase 3: geography — addresses, map-pin picker & nurse coverage areas
Three domain services (mirroring the patients/nurse template): services/geography (cached province→city→district lookups; Infinity staleTime + shared geographyKeys), services/addresses (address book CRUD + set-primary; single-primary invariant), and services/serviceAreas (coverage add/remove; areaExists dup-guard, districtId=null = whole city). Four tested composites in src/components/geography: CascadingRegionSelect (drives the cascade queries), AddressMapPicker (map-pin stand-in emitting real lat/lng), AddressForm, AddressCard. Screens: customer address book (/addresses, reached from the profile hub) and nurse coverage editor (/nurse/coverage, new sidebar tab, inline duplicate block + 409). Adds geo/address/coverage i18n namespaces (both locales), location/delete/coverage icons, ADDRESSES/NURSE_COVERAGE routes. Consumes the b4 geography-addresses contract; filed REQ-008 (accept the map pin on create/update) and REQ-009 (provinceId on CustomerAddressDto) for gaps. Gate: npm run check + npm run test:ci (129, +17) + npm run build all green. A 5-dimension adversarial review fixed 3 findings (map-marker RTL transform, page_size→pageSize pagination casing, coverage districts-scope dead-end on district-less cities). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
"wallet": "Wallet",
|
||||
"profile": "Profile",
|
||||
"bank": "Bank account",
|
||||
"coverage": "Coverage",
|
||||
"dashboard": "Dashboard",
|
||||
"verification": "Verification",
|
||||
"visits": "Visits",
|
||||
@@ -165,6 +166,75 @@
|
||||
"empty_title": "No bank account yet",
|
||||
"empty_body": "Add a bank account in your own name to receive payouts."
|
||||
},
|
||||
"geo": {
|
||||
"province": "Province",
|
||||
"city": "City",
|
||||
"district": "District",
|
||||
"whole_city": "Whole city",
|
||||
"city_needs_province": "Choose a province first",
|
||||
"district_needs_city": "Choose a city first",
|
||||
"district_optional": "Optional",
|
||||
"no_districts": "This city has no districts — whole city"
|
||||
},
|
||||
"address": {
|
||||
"title": "Addresses",
|
||||
"subtitle": "Where nurses will visit.",
|
||||
"add": "Add address",
|
||||
"add_title": "Add address",
|
||||
"edit_title": "Edit address",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"empty_title": "No addresses yet",
|
||||
"empty_body": "Add your first address so nurses know where to go.",
|
||||
"primary": "Primary",
|
||||
"set_primary": "Set as primary",
|
||||
"primary_set": "Primary address updated",
|
||||
"delete_title": "Delete address?",
|
||||
"delete_body": "This address is removed from your list.",
|
||||
"delete_confirm": "Delete",
|
||||
"deleted": "Address deleted",
|
||||
"saved": "Address saved",
|
||||
"save_error": "This address couldn't be saved. Please try again.",
|
||||
"unavailable": "This address isn't available to you.",
|
||||
"title_label": "Address label",
|
||||
"title_placeholder": "e.g. Home, Work",
|
||||
"title_required": "Enter a label for this address",
|
||||
"line_label": "Street address",
|
||||
"line_hint": "Building, street, unit — the detail a nurse needs to find the door.",
|
||||
"line_required": "Enter the street address",
|
||||
"city_required": "Select a city",
|
||||
"set_primary_toggle": "Set as primary address",
|
||||
"map_hint": "Tap or drag the marker to the patient's exact location.",
|
||||
"map_required": "Drop a pin on the map",
|
||||
"map_lat": "Lat",
|
||||
"map_lng": "Lng",
|
||||
"manage_title": "Your addresses",
|
||||
"manage_body": "Manage the places nurses visit.",
|
||||
"manage_cta": "Manage addresses"
|
||||
},
|
||||
"coverage": {
|
||||
"title": "Coverage areas",
|
||||
"subtitle": "The cities and districts you'll travel to.",
|
||||
"areas_heading": "Your areas",
|
||||
"add_title": "Add a coverage area",
|
||||
"scope_label": "Coverage",
|
||||
"scope_whole_city": "Whole city",
|
||||
"scope_districts": "Specific districts",
|
||||
"add": "Add area",
|
||||
"adding": "Adding…",
|
||||
"whole_city_chip": "Whole city",
|
||||
"empty_title": "No coverage areas yet",
|
||||
"empty_warning": "You won't appear in search until you add at least one coverage area.",
|
||||
"duplicate": "You already cover this area.",
|
||||
"city_required": "Select a city",
|
||||
"district_required": "Select a district, or switch to whole city.",
|
||||
"added": "Coverage area added",
|
||||
"add_error": "This area couldn't be added. Please try again.",
|
||||
"remove_title": "Remove coverage area?",
|
||||
"remove_body": "You'll no longer be matched for visits in this area.",
|
||||
"remove_confirm": "Remove",
|
||||
"removed": "Coverage area removed"
|
||||
},
|
||||
"auth": {
|
||||
"customer_title": "Sign in to Balinyaar",
|
||||
"customer_subtitle": "Sign in with your mobile number",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"wallet": "کیفپول",
|
||||
"profile": "پروفایل",
|
||||
"bank": "حساب بانکی",
|
||||
"coverage": "پوشش",
|
||||
"dashboard": "داشبورد",
|
||||
"verification": "احراز هویت",
|
||||
"visits": "ویزیتها",
|
||||
@@ -165,6 +166,75 @@
|
||||
"empty_title": "هنوز حسابی ثبت نشده",
|
||||
"empty_body": "برای دریافت درآمد، یک حساب بانکی به نام خودتان اضافه کنید."
|
||||
},
|
||||
"geo": {
|
||||
"province": "استان",
|
||||
"city": "شهر",
|
||||
"district": "منطقه",
|
||||
"whole_city": "کل شهر",
|
||||
"city_needs_province": "ابتدا استان را انتخاب کنید",
|
||||
"district_needs_city": "ابتدا شهر را انتخاب کنید",
|
||||
"district_optional": "اختیاری",
|
||||
"no_districts": "این شهر منطقهبندی ندارد — کل شهر"
|
||||
},
|
||||
"address": {
|
||||
"title": "آدرسها",
|
||||
"subtitle": "جایی که پرستار به آن مراجعه میکند.",
|
||||
"add": "افزودن آدرس",
|
||||
"add_title": "افزودن آدرس",
|
||||
"edit_title": "ویرایش آدرس",
|
||||
"edit": "ویرایش",
|
||||
"delete": "حذف",
|
||||
"empty_title": "هنوز آدرسی ثبت نشده",
|
||||
"empty_body": "اولین آدرس را اضافه کنید تا پرستار بداند کجا بیاید.",
|
||||
"primary": "آدرس اصلی",
|
||||
"set_primary": "انتخاب بهعنوان آدرس اصلی",
|
||||
"primary_set": "آدرس اصلی بهروزرسانی شد",
|
||||
"delete_title": "حذف آدرس؟",
|
||||
"delete_body": "این آدرس از فهرست شما حذف میشود.",
|
||||
"delete_confirm": "حذف",
|
||||
"deleted": "آدرس حذف شد",
|
||||
"saved": "آدرس ذخیره شد",
|
||||
"save_error": "ذخیرهٔ این آدرس ممکن نشد. دوباره تلاش کنید.",
|
||||
"unavailable": "این آدرس در دسترس شما نیست.",
|
||||
"title_label": "عنوان آدرس",
|
||||
"title_placeholder": "مثلاً خانه، محل کار",
|
||||
"title_required": "برای این آدرس یک عنوان وارد کنید",
|
||||
"line_label": "نشانی کامل",
|
||||
"line_hint": "پلاک، خیابان، واحد — جزئیاتی که پرستار برای یافتن در نیاز دارد.",
|
||||
"line_required": "نشانی کامل را وارد کنید",
|
||||
"city_required": "شهر را انتخاب کنید",
|
||||
"set_primary_toggle": "بهعنوان آدرس اصلی تنظیم شود",
|
||||
"map_hint": "برای تعیین محل دقیق بیمار، نشانگر را بکشید یا روی نقشه بزنید.",
|
||||
"map_required": "روی نقشه یک پین بگذارید",
|
||||
"map_lat": "عرض",
|
||||
"map_lng": "طول",
|
||||
"manage_title": "آدرسهای شما",
|
||||
"manage_body": "مکانهایی که پرستار به آنها میرود را مدیریت کنید.",
|
||||
"manage_cta": "مدیریت آدرسها"
|
||||
},
|
||||
"coverage": {
|
||||
"title": "مناطق تحت پوشش",
|
||||
"subtitle": "شهرها و مناطقی که به آنها میروید.",
|
||||
"areas_heading": "مناطق شما",
|
||||
"add_title": "افزودن منطقهٔ تحت پوشش",
|
||||
"scope_label": "گستره",
|
||||
"scope_whole_city": "کل شهر",
|
||||
"scope_districts": "مناطق خاص",
|
||||
"add": "افزودن منطقه",
|
||||
"adding": "در حال افزودن…",
|
||||
"whole_city_chip": "کل شهر",
|
||||
"empty_title": "هنوز منطقهای ثبت نشده",
|
||||
"empty_warning": "تا زمانی که حداقل یک منطقهٔ تحت پوشش اضافه نکنید، در جستوجو نمایش داده نمیشوید.",
|
||||
"duplicate": "این منطقه از قبل تحت پوشش شماست.",
|
||||
"city_required": "شهر را انتخاب کنید",
|
||||
"district_required": "یک منطقه انتخاب کنید یا به کل شهر تغییر دهید.",
|
||||
"added": "منطقهٔ تحت پوشش اضافه شد",
|
||||
"add_error": "افزودن این منطقه ممکن نشد. دوباره تلاش کنید.",
|
||||
"remove_title": "حذف منطقهٔ تحت پوشش؟",
|
||||
"remove_body": "دیگر برای ویزیت در این منطقه انتخاب نمیشوید.",
|
||||
"remove_confirm": "حذف",
|
||||
"removed": "منطقهٔ تحت پوشش حذف شد"
|
||||
},
|
||||
"auth": {
|
||||
"customer_title": "ورود به بلینیار",
|
||||
"customer_subtitle": "با شماره موبایل خود وارد شوید",
|
||||
|
||||
Reference in New Issue
Block a user