feat(time-tracking): wire GPS capture into field clock-in/out (cycle 12 polish)
Deploy to route.crispygoat.com / deploy (push) Has been cancelled
Deploy to route.crispygoat.com / deploy (push) Has been cancelled
Adds captureGps() helper to TimeTrackingFieldClient and threads it into handleSelectTask + handleClockOut. Server treats gps_verified as advisory (accuracy_m <= 100) so workers are never blocked from clocking in/out if the browser denies geolocation or the context is insecure. Also picks up the manual-entry / manual-logs reducer plumbing that was left over from the WIP — the actions exist in src/actions/time-tracking/field.ts (submitManualTimeLog, getRecentTimeLogs) and the reducer is wired to call them, but the HubScreen / ManualEntryScreen render paths still live in the parent screen router and consume the state correctly.
This commit is contained in:
@@ -37,9 +37,12 @@ import {
|
||||
getTimeTrackingTasksField,
|
||||
getWorkerPayPeriodHours,
|
||||
getTimeTrackingSession,
|
||||
submitManualTimeLog,
|
||||
getRecentTimeLogs,
|
||||
type TimeTrackingSession,
|
||||
type TimeTaskField,
|
||||
type PayPeriodHours,
|
||||
type WorkerLogRow,
|
||||
} from "@/actions/time-tracking/field";
|
||||
import { FieldPinScreen } from "@/components/field/FieldPinScreen";
|
||||
import { Clock, CheckCircle, Spinner, ChevronLeft, ChevronRight } from "@/components/water/mobile/icons";
|
||||
@@ -126,6 +129,65 @@ type Translations = {
|
||||
total_time: string;
|
||||
generic_error: string;
|
||||
forgot_hint: string;
|
||||
|
||||
// Cycle 12 — Hub, Manual Entry, History
|
||||
hub_greeting: string;
|
||||
hub_subtitle: string;
|
||||
hub_logged_today: string;
|
||||
hub_logged_today_none: string;
|
||||
hub_manual_entry: string;
|
||||
hub_manual_entry_sub: string;
|
||||
hub_recent_activity: string;
|
||||
hub_recent_activity_sub: string;
|
||||
hub_quick_actions: string;
|
||||
hub_sign_out: string;
|
||||
hub_status_on: string;
|
||||
hub_status_off: string;
|
||||
hub_view_shift: string;
|
||||
|
||||
manual_title: string;
|
||||
manual_subtitle: string;
|
||||
manual_section_when: string;
|
||||
manual_section_who: string;
|
||||
manual_section_why: string;
|
||||
manual_date: string;
|
||||
manual_clock_in_label: string;
|
||||
manual_clock_out_label: string;
|
||||
manual_task: string;
|
||||
manual_task_placeholder: string;
|
||||
manual_lunch: string;
|
||||
manual_reason: string;
|
||||
manual_reason_placeholder: string;
|
||||
manual_notes: string;
|
||||
manual_notes_placeholder: string;
|
||||
manual_submit: string;
|
||||
manual_submit_help: string;
|
||||
manual_submitting: string;
|
||||
manual_error_future: string;
|
||||
manual_error_range: string;
|
||||
manual_error_reason: string;
|
||||
manual_error_max: string;
|
||||
manual_error_too_old: string;
|
||||
manual_error_generic: string;
|
||||
|
||||
manual_success_title: string;
|
||||
manual_success_subtitle: string;
|
||||
manual_success_submitted: string;
|
||||
manual_success_total: string;
|
||||
manual_success_lunch: string;
|
||||
manual_success_another: string;
|
||||
manual_success_home: string;
|
||||
|
||||
history_title: string;
|
||||
history_subtitle: string;
|
||||
history_loading: string;
|
||||
history_empty_title: string;
|
||||
history_empty_sub: string;
|
||||
history_total_label: string;
|
||||
history_manual_badge: string;
|
||||
history_today: string;
|
||||
history_yesterday: string;
|
||||
history_load_more: string;
|
||||
};
|
||||
|
||||
const TRANS_EN: Translations = {
|
||||
@@ -395,6 +457,18 @@ function reducer(state: State, action: Action): State {
|
||||
return state.openEntry
|
||||
? { ...state, openEntry: { ...state.openEntry, elapsed_minutes: action.minutes } }
|
||||
: state;
|
||||
case "SET_MANUAL_DRAFT":
|
||||
return { ...state, manualEntryDraft: action.value };
|
||||
case "RESET_MANUAL_DRAFT":
|
||||
return { ...state, manualEntryDraft: emptyManualDraft() };
|
||||
case "SET_MANUAL_ENTRY_RESULT":
|
||||
return { ...state, manualEntryResult: action.value };
|
||||
case "SET_MANUAL_LOGS":
|
||||
return { ...state, manualLogs: action.value, manualLogsLoading: false, manualLogsError: null };
|
||||
case "SET_MANUAL_LOGS_LOADING":
|
||||
return { ...state, manualLogsLoading: action.value };
|
||||
case "SET_MANUAL_LOGS_ERROR":
|
||||
return { ...state, manualLogsError: action.value, manualLogsLoading: false };
|
||||
case "RESET_FOR_LOGOUT":
|
||||
return {
|
||||
...state,
|
||||
@@ -404,6 +478,11 @@ function reducer(state: State, action: Action): State {
|
||||
selectedTaskId: "",
|
||||
lunchMinutes: 0,
|
||||
notes: "",
|
||||
manualEntryDraft: emptyManualDraft(),
|
||||
manualEntryResult: null,
|
||||
manualLogs: [],
|
||||
manualLogsLoading: false,
|
||||
manualLogsError: null,
|
||||
screen: "pin",
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user