feat: implement debug logging cleanup and i18n coverage proposals

## cleanup-debug-logging
- Create environment-aware logger utility (logger.ts)
- Replace 60+ console.log/error statements across 28 files
- Production: only warn/error logs visible
- Development: all log levels with prefixes

Updated files:
- Contexts: NotificationContext, ProjectSyncContext, AuthContext
- Components: GanttChart, CalendarView, ErrorBoundary, and 11 others
- Pages: Tasks, Projects, Dashboard, and 7 others
- Services: api.ts

## complete-i18n-coverage
- WeeklyReportPreview: all strings translated, dynamic locale
- ReportHistory: all strings translated, dynamic locale
- AuditPage: detail modal and verification modal translated
- WorkloadPage: error message translated

Locale files updated:
- en/common.json, zh-TW/common.json: reports section
- en/audit.json, zh-TW/audit.json: modal sections
- en/workload.json, zh-TW/workload.json: errors section

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
beabigegg
2026-01-13 21:37:29 +08:00
parent ed8d30e9bd
commit 4b7e523f84
37 changed files with 430 additions and 207 deletions

View File

@@ -12,6 +12,7 @@ import { useProjectSync, TaskEvent } from '../contexts/ProjectSyncContext'
import { customFieldsApi, CustomField, CustomValueResponse } from '../services/customFields'
import { CustomFieldInput } from '../components/CustomFieldInput'
import { SkeletonTable, SkeletonKanban, Skeleton } from '../components/Skeleton'
import { logger } from '../utils/logger'
interface Task {
id: string
@@ -135,7 +136,7 @@ export default function Tasks() {
const response = await customFieldsApi.getCustomFields(projectId!)
setCustomFields(response.fields)
} catch (err) {
console.error('Failed to load custom fields:', err)
logger.error('Failed to load custom fields:', err)
}
}
@@ -315,7 +316,7 @@ export default function Tasks() {
setTasks(tasksRes.data.tasks)
setStatuses(statusesRes.data)
} catch (err) {
console.error('Failed to load data:', err)
logger.error('Failed to load data:', err)
} finally {
setLoading(false)
}
@@ -377,7 +378,7 @@ export default function Tasks() {
setSelectedAssignee(null)
loadData()
} catch (err) {
console.error('Failed to create task:', err)
logger.error('Failed to create task:', err)
} finally {
setCreating(false)
}
@@ -417,7 +418,7 @@ export default function Tasks() {
} catch (err) {
// Rollback on error
setTasks(originalTasks)
console.error('Failed to update status:', err)
logger.error('Failed to update status:', err)
// Could add toast notification here for better UX
}
}
@@ -455,7 +456,7 @@ export default function Tasks() {
time_estimate: updatedTask.original_estimate,
})
} catch (err) {
console.error('Failed to refresh selected task:', err)
logger.error('Failed to refresh selected task:', err)
}
}
}
@@ -474,7 +475,7 @@ export default function Tasks() {
setSelectedTask(subtaskWithProject)
// Modal is already open, just update the task
} catch (err) {
console.error('Failed to load subtask:', err)
logger.error('Failed to load subtask:', err)
}
}