feat(mobile): update notifications and more error handling added
All checks were successful
Build and Push LST Docker Image / docker (push) Successful in 1m24s

This commit is contained in:
2026-04-30 17:02:21 -05:00
parent bb6155c969
commit 30ffd843c7
24 changed files with 2784 additions and 200 deletions

View File

@@ -1,3 +1,4 @@
import axios from "axios";
import { format } from "date-fns-tz";
import { useCallback, useEffect, useState } from "react";
import { Text, View } from "react-native";
@@ -7,6 +8,8 @@ import { scannerFeedback } from "../lib/feedbackScan";
import { sendTcpMessage } from "../lib/tcpScan";
import { type ZebraScanResult, zebraScanner } from "../lib/ZebraScanner";
import { ScannedLabelBox } from "./ScannedLabels";
import { GlobalFooter } from "./UpdateFooter";
import { Separator } from "./ui/separator";
const STX = "\x02";
const ETX = "\x03";
@@ -23,12 +26,6 @@ export default function ProdScanner() {
const handleScan = useCallback(
async (scan: ZebraScanResult) => {
let commandToSend = `${STX}${scannerIdFromStore}@${scan.data}${ETX}`;
await scannerFeedback({
type: "good",
sound: true,
vibrate: true,
led: true,
});
// if we are sscc we need to scan like this .... <STX>98@]C100090087710038712256<ETX>
if (scan.data.startsWith("000")) {
@@ -42,41 +39,54 @@ export default function ProdScanner() {
]);
}
// if we change commands we want to zero out the last scanned labels
if (/^[a-zA-Z]/.test(scan.data)) {
setTagScans([]);
}
const scanned = (await sendTcpMessage(
commandToSend,
serverIp,
parseInt(serverPort || "0", 10),
)) as any;
// Later this is where your TCP send goes.
// const response = await sendTcpMessage(tcpMessage);
console.log(scanned);
await scannerFeedback({
type: scanned.data[0]?.type === "error" ? "bad" : "good",
sound: true,
vibrate: true,
led: true,
});
// send the logs to lst but allow it to time out if it dose not exist just bc.
if (scanned.data[0]?.type !== "error") {
try {
await axios.post(
`http://${serverIp.trim()}:3000/lst/api/mobile/logs`,
scanned,
);
} catch (error) {
console.log(error);
}
// const response = await sendTcpMessage(tcpMessage);
console.log(scanned.data);
if (scanned.data.status !== "error") {
await scannerFeedback({
type: "good",
sound: true,
vibrate: true,
led: true,
});
setBGColor("bg-green-500");
setTimeout(() => {
setBGColor(null);
}, 1 * 1000);
}
if (scanned.data[0]?.type === "error") {
if (scanned.data.status === "error") {
await scannerFeedback({
type: scanned.data.status === "error" ? "bad" : "good",
sound: true,
vibrate: true,
led: true,
});
setBGColor("bg-red-500");
setTimeout(() => {
setBGColor(null);
}, 1 * 1000);
}
setLastScan(scanned.data[0]);
//console.log("TCP response:", something);
setLastScan(scanned.data);
// if we change commands we want to zero out the last scanned labels
if (/^[a-zA-Z]/.test(scan.data)) {
setTagScans([]);
}
},
[scannerIdFromStore, serverIp, serverPort, setLastScan],
);
@@ -85,7 +95,7 @@ export default function ProdScanner() {
setTagScans([]);
};
console.log(lastScan);
//console.log(lastScan);
useEffect(() => {
zebraScanner.ensureProfile();
@@ -109,6 +119,7 @@ export default function ProdScanner() {
Scanner ID: {parseInt(scannerIdFromStore || "0", 10)}
</Text>
</View>
<Separator />
{!lastScan ? (
<View style={{ marginTop: 10, alignItems: "center" }}>
<Text className="text-xl font-bold">Ready to scan</Text>
@@ -121,18 +132,19 @@ export default function ProdScanner() {
alignItems: "center",
}}
>
<View style={{ marginTop: 10, alignItems: "center" }}>
<Text style={{ fontSize: 20, fontWeight: "600" }}>
{lastScan.action}
</Text>
<Text style={{ fontSize: 20, fontWeight: "600" }}>
{lastScan.message}
</Text>
</View>
{lastScan.lines
?.filter((line) => !/^\d+@$/.test(line))
.map((i) => {
return (
<View style={{ marginTop: 10, alignItems: "center" }} key={i}>
<Text style={{ fontSize: 20, fontWeight: "600" }}>{i}</Text>
</View>
);
})}
</View>
)}
</View>
<Separator className="m-2" />
<View className="flex-1 w-full px-4">
<ScannedLabelBox
labels={tagScans}
@@ -140,6 +152,9 @@ export default function ProdScanner() {
clearScan={clearScans}
/>
</View>
<View>
<GlobalFooter />
</View>
</View>
);
}

View File

@@ -2,6 +2,7 @@ import { ScrollView, View } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { Button } from "@/components/ui/button";
import { Text } from "@/components/ui/text";
import { Card } from "./ui/card";
type ScannedLabel = {
label: string;
@@ -29,27 +30,29 @@ export function ScannedLabelBox({
<ScrollView className="w-full flex-1">
{labels.length === 0 ? (
<Text className="text-center">No labels scanned yet</Text>
<Text className="text-center">
pending new labels to be scanned...
</Text>
) : (
<View className="flex items-center gap-2 w-full">
{labels.map((i, index) => (
<View
<Card
key={`${i.label}-${index}`}
className={`p-2 border rounded items-center ${color ?? ""}`}
className={`p-2 border rounded items-center ${color ?? ""} w-full`}
>
<Text style={{ fontSize: 18, fontWeight: "700" }}>
{i.label} - {i.date.toString()}
</Text>
</View>
</Card>
))}
</View>
)}
</ScrollView>
{labels.length !== 0 && (
{/* {labels.length !== 0 && (
<Button onPress={clearScan} variant="secondary">
<Text>Clear Scans</Text>
</Button>
)}
)} */}
</SafeAreaView>
);
}

View File

@@ -0,0 +1,40 @@
import Constants from "expo-constants";
import { Link } from "expo-router";
import { Text, View } from "react-native";
import { useServerStore } from "../hooks/useServerCheck";
export function GlobalFooter() {
const build = Constants.expoConfig?.android?.versionCode ?? 1;
const serverVersion = useServerStore((s) => s.serverVersion);
const hasUpdate =
serverVersion && serverVersion?.minSupportedVersionCode > build;
const shouldUpdate = serverVersion && serverVersion?.versionCode > build;
if (serverVersion && serverVersion?.versionCode <= build) return;
return (
<View>
<View>
{hasUpdate && (
<View className="items-center h-[75px] bg-[#EB091A]">
<Link href={"/updateScreen"}>
<Text className="h-[75px] font-medium text-base text-wrap text-center">
Critical updates pending, once you are completed with your task
please click me for instructions to update
</Text>
</Link>
</View>
)}
{!hasUpdate && shouldUpdate && (
<View className="bg-[#FDBA74]">
<Link href={"/updateScreen"}>
<Text className="h-[32] font-medium text-lg text-wrap text-center">
There is an update click me for instructions
</Text>
</Link>
</View>
)}
</View>
</View>
);
}

View File

@@ -0,0 +1,24 @@
import { cn } from '@/lib/utils';
import * as SeparatorPrimitive from '@rn-primitives/separator';
function Separator({
className,
orientation = 'horizontal',
decorative = true,
...props
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
return (
<SeparatorPrimitive.Root
decorative={decorative}
orientation={orientation}
className={cn(
'bg-border shrink-0',
orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',
className
)}
{...props}
/>
);
}
export { Separator };