From c5ec43cefe8d78b0e6fd7a98ebf962c601e718dc Mon Sep 17 00:00:00 2001 From: Teddy Date: Sun, 10 May 2026 19:30:36 +1000 Subject: [PATCH 1/2] feat(i18n): add translations for payroll and incident reports - Added `payroll` translation strings to `zh-CN` and `zh-TW` locales. - Added `incidentReport` translation block to `en`, `zh-CN`, and `zh-TW` locales. - Refactored `IncidentReportScreen` to replace hardcoded strings with dynamic `useTranslation` references. - Updated `AppNavigator` to dynamically translate the "Incident Reports" header title. --- guard_app/src/locales/zh-CN.json | 62 +++++++++++++++++++ guard_app/src/locales/zh-TW.json | 62 +++++++++++++++++++ guard_app/src/navigation/AppNavigator.tsx | 2 +- guard_app/src/screen/IncidentReportScreen.tsx | 32 +++++----- 4 files changed, 142 insertions(+), 16 deletions(-) diff --git a/guard_app/src/locales/zh-CN.json b/guard_app/src/locales/zh-CN.json index 2d5285507..53cfd38ae 100644 --- a/guard_app/src/locales/zh-CN.json +++ b/guard_app/src/locales/zh-CN.json @@ -286,5 +286,67 @@ "testNotif": "测试通知", "notifTitle": "已分配班次", "notifBody": "您已被分配到医院综合楼班次。" + }, + "payroll": { + "period": "期间:", + "guardID": "保安ID:", + "site": "地点:", + "department": "部门:", + "notFound": "未找到工资单", + "error": "加载工资单记录失败", + "types": { + "daily": "每日", + "weekly": "每周", + "monthly": "每月" + }, + "filter": "筛选", + "startDateHead": "开始日期*", + "selectStart": "选择开始日期", + "endDateHead": "结束日期*", + "selectEnd": "选择结束日期", + "periodHead": "期间类型*", + "selectPeriod": "选择期间", + "optional": "可选", + "ID": "ID", + "siteHead": "地点", + "siteHint": "地点名称", + "departmentHead": "部门", + "departmentHint": "部门名称", + "missingAlertHead": "信息缺失", + "missingAlertMsg": "请选择开始日期、结束日期以及期间类型。", + "invalidAlertHead": "无效信息", + "invalidAlertMsg": "开始日期必须早于结束日期。", + "cancel": "取消" + }, + "incidentReport": { + "title": "事件报告", + "newReport": "新建报告", + "reportId": "报告ID:", + "date": "日期:", + "time": "时间:", + "location": "地点:", + "description": "描述:", + "reportedBy": "报告人:", + "severity": "严重程度:", + "status": "状态:", + "types": { + "low": "低", + "medium": "中", + "high": "高", + "critical": "严重" + }, + "statusTypes": { + "open": "开启", + "inProgress": "处理中", + "resolved": "已解决", + "closed": "已关闭" + }, + "noReports": "未找到事件报告", + "error": "加载事件报告失败", + "submit": "提交报告", + "submitting": "提交中...", + "submitSuccess": "事件报告提交成功", + "submitFailed": "提交事件报告失败", + "cancel": "取消" } } diff --git a/guard_app/src/locales/zh-TW.json b/guard_app/src/locales/zh-TW.json index 57858afbd..b543bc98f 100644 --- a/guard_app/src/locales/zh-TW.json +++ b/guard_app/src/locales/zh-TW.json @@ -286,5 +286,67 @@ "testNotif": "測試通知", "notifTitle": "已分配班次", "notifBody": "您已被分配到醫院綜合大樓班次。" + }, + "payroll": { + "period": "期間:", + "guardID": "保安ID:", + "site": "地點:", + "department": "部門:", + "notFound": "未找到薪資單", + "error": "載入薪資單紀錄失敗", + "types": { + "daily": "每日", + "weekly": "每週", + "monthly": "每月" + }, + "filter": "篩選", + "startDateHead": "開始日期*", + "selectStart": "選擇開始日期", + "endDateHead": "結束日期*", + "selectEnd": "選擇結束日期", + "periodHead": "期間類型*", + "selectPeriod": "選擇期間", + "optional": "可選", + "ID": "ID", + "siteHead": "地點", + "siteHint": "地點名稱", + "departmentHead": "部門", + "departmentHint": "部門名稱", + "missingAlertHead": "資訊缺失", + "missingAlertMsg": "請選擇開始日期、結束日期以及期間類型。", + "invalidAlertHead": "無效資訊", + "invalidAlertMsg": "開始日期必須早於結束日期。", + "cancel": "取消" + }, + "incidentReport": { + "title": "事件報告", + "newReport": "新增報告", + "reportId": "報告ID:", + "date": "日期:", + "time": "時間:", + "location": "地點:", + "description": "描述:", + "reportedBy": "報告人:", + "severity": "嚴重程度:", + "status": "狀態:", + "types": { + "low": "低", + "medium": "中", + "high": "高", + "critical": "嚴重" + }, + "statusTypes": { + "open": "開啟", + "inProgress": "處理中", + "resolved": "已解決", + "closed": "已關閉" + }, + "noReports": "未找到事件報告", + "error": "載入事件報告失敗", + "submit": "提交報告", + "submitting": "提交中...", + "submitSuccess": "事件報告提交成功", + "submitFailed": "提交事件報告失敗", + "cancel": "取消" } } diff --git a/guard_app/src/navigation/AppNavigator.tsx b/guard_app/src/navigation/AppNavigator.tsx index 50ce03532..27dbaf712 100644 --- a/guard_app/src/navigation/AppNavigator.tsx +++ b/guard_app/src/navigation/AppNavigator.tsx @@ -144,7 +144,7 @@ export default function AppNavigator() { 0 - ? `Incident report submitted successfully, but ${failedUploads} photo(s) failed to upload.` - : 'Incident report submitted successfully.'; + ? `${t('incidentReport.submitSuccess')}, but ${failedUploads} photo(s) failed to upload.` + : t('incidentReport.submitSuccess'); Alert.alert('Success', successMessage); setSelectedShift(null); @@ -183,7 +185,7 @@ export default function IncidentReportScreen() { (err as { response?: { data?: { message?: string } } })?.response?.data?.message ?? (err instanceof Error ? err.message - : 'Could not submit the incident report. Please try again.'); + : t('incidentReport.submitFailed')); setErrorState({ title: 'Submission Failed', message }); } finally { setSubmitting(false); @@ -194,11 +196,11 @@ export default function IncidentReportScreen() { <> {/* Incident List */} - My Reports + {t('incidentReport.title')} {loadingList ? ( ) : incidents.length === 0 ? ( - No incidents reported yet. + {t('incidentReport.noReports')} ) : ( incidents.map((item) => ( @@ -208,7 +210,7 @@ export default function IncidentReportScreen() { {item.severity} - {!!item.status && Status: {item.status}} + {!!item.status && {t('incidentReport.status')} {item.status}} {!!item.createdAt && ( {new Date(item.createdAt).toLocaleString()} )} @@ -217,7 +219,7 @@ export default function IncidentReportScreen() { )} {/* Submit Form */} - Incident Report + {t('incidentReport.newReport')} Shift * setShowShiftPicker(true)}> @@ -228,20 +230,20 @@ export default function IncidentReportScreen() { - Incident Description * + {t('incidentReport.description')} - Date & Time * + {t('incidentReport.date')} & {t('incidentReport.time')} {dateTime} - Severity * + {t('incidentReport.severity')} {(['Low', 'Medium', 'High'] as Severity[]).map((lvl) => ( - {lvl} + {t(`incidentReport.types.${lvl.toLowerCase()}`)} ))} @@ -273,7 +275,7 @@ export default function IncidentReportScreen() { {submitting ? ( ) : ( - Submit Report + {t('incidentReport.submit')} )} @@ -303,7 +305,7 @@ export default function IncidentReportScreen() { )} setShowShiftPicker(false)}> - Cancel + {t('incidentReport.cancel')} From 3ab6f249700447ca5a698f53953317d794da956e Mon Sep 17 00:00:00 2001 From: Teddy Date: Sun, 10 May 2026 20:00:15 +1000 Subject: [PATCH 2/2] eslint and format --- guard_app/src/screen/IncidentReportScreen.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/guard_app/src/screen/IncidentReportScreen.tsx b/guard_app/src/screen/IncidentReportScreen.tsx index d223d4ff4..5b0a4de22 100644 --- a/guard_app/src/screen/IncidentReportScreen.tsx +++ b/guard_app/src/screen/IncidentReportScreen.tsx @@ -183,9 +183,7 @@ export default function IncidentReportScreen() { } catch (err: unknown) { const message = (err as { response?: { data?: { message?: string } } })?.response?.data?.message ?? - (err instanceof Error - ? err.message - : t('incidentReport.submitFailed')); + (err instanceof Error ? err.message : t('incidentReport.submitFailed')); setErrorState({ title: 'Submission Failed', message }); } finally { setSubmitting(false); @@ -210,7 +208,11 @@ export default function IncidentReportScreen() { {item.severity} - {!!item.status && {t('incidentReport.status')} {item.status}} + {!!item.status && ( + + {t('incidentReport.status')} {item.status} + + )} {!!item.createdAt && ( {new Date(item.createdAt).toLocaleString()} )} @@ -240,7 +242,9 @@ export default function IncidentReportScreen() { style={s.textArea} /> - {t('incidentReport.date')} & {t('incidentReport.time')} + + {t('incidentReport.date')} & {t('incidentReport.time')} + {dateTime} {t('incidentReport.severity')}