refactor(scanner): more basic work to get the scanner just running
All checks were successful
Build and Push LST Docker Image / docker (push) Successful in 2m33s

This commit is contained in:
2026-04-19 17:20:57 -05:00
parent 3734d9daac
commit 82f8369640
19 changed files with 642 additions and 323 deletions

View File

@@ -0,0 +1,151 @@
import AsyncStorage from "@react-native-async-storage/async-storage";
import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";
export type ValidationStatus = "idle" | "pending" | "passed" | "failed";
export type AppState = {
serverIp: string;
serverPort: string;
scannerId?: string;
stageId?: string;
deviceName?: string;
setupCompleted: boolean;
isRegistered: boolean;
lastValidationStatus: ValidationStatus;
lastValidationAt?: string;
appVersion?: string;
hasHydrated: boolean;
};
type AppActions = {
setServerIp: (value: string) => void;
setServerPort: (value: string) => void;
setScannerId: (value?: string) => void;
setStageId: (value?: string) => void;
setDeviceName: (value?: string) => void;
setSetupCompleted: (value: boolean) => void;
setIsRegistered: (value: boolean) => void;
setValidationStatus: (status: ValidationStatus, validatedAt?: string) => void;
setAppVersion: (value?: string) => void;
setHasHydrated: (value: boolean) => void;
updateAppState: (updates: Partial<AppState>) => void;
resetApp: () => void;
hasValidSetup: () => boolean;
canEnterApp: () => boolean;
getServerUrl: () => string;
};
export type AppStore = AppState & AppActions;
const defaultAppState: AppState = {
serverIp: "",
serverPort: "",
scannerId: "0001",
stageId: undefined,
deviceName: undefined,
setupCompleted: false,
isRegistered: false,
lastValidationStatus: "idle",
lastValidationAt: undefined,
appVersion: undefined,
hasHydrated: false,
};
export const useAppStore = create<AppStore>()(
persist(
(set, get) => ({
...defaultAppState,
setServerIp: (value) => set({ serverIp: value }),
setServerPort: (value) => set({ serverPort: value }),
setScannerId: (value) => set({ scannerId: value }),
setStageId: (value) => set({ stageId: value }),
setDeviceName: (value) => set({ deviceName: value }),
setSetupCompleted: (value) => set({ setupCompleted: value }),
setIsRegistered: (value) => set({ isRegistered: value }),
setValidationStatus: (status, validatedAt) =>
set({
lastValidationStatus: status,
lastValidationAt: validatedAt,
}),
setAppVersion: (value) => set({ appVersion: value }),
setHasHydrated: (value) => set({ hasHydrated: value }),
updateAppState: (updates) =>
set((state) => ({
...state,
...updates,
})),
resetApp: () =>
set({
...defaultAppState,
hasHydrated: true,
}),
hasValidSetup: () => {
const state = get();
return Boolean(
state.serverIp?.trim() &&
state.serverPort?.trim() &&
state.setupCompleted,
);
},
canEnterApp: () => {
const state = get();
return Boolean(
state.serverIp?.trim() &&
state.serverPort?.trim() &&
state.setupCompleted &&
state.isRegistered,
);
},
getServerUrl: () => {
const { serverIp, serverPort } = get();
if (!serverIp?.trim() || !serverPort?.trim()) return "";
return `http://${serverIp.trim()}:${serverPort.trim()}`;
},
}),
{
name: "lst_mobile_app_store",
storage: createJSONStorage(() => AsyncStorage),
onRehydrateStorage: () => (state, error) => {
if (error) {
console.log("Failed to hydrate app state", error);
}
state?.setHasHydrated(true);
},
partialize: (state) => ({
serverIp: state.serverIp,
serverPort: state.serverPort,
scannerId: state.scannerId,
stageId: state.stageId,
deviceName: state.deviceName,
setupCompleted: state.setupCompleted,
isRegistered: state.isRegistered,
lastValidationStatus: state.lastValidationStatus,
lastValidationAt: state.lastValidationAt,
appVersion: state.appVersion,
}),
},
),
);