matiru
Blockchain-Based Supply Chain Transparency for Agricultural Producegit clone https://github.com/maydayv7/matiru
frontend/screens/Inspector.js (4001B)
1import { useContext, useState } from "react";
2import {
3 Alert,
4 ScrollView,
5 Switch,
6 Text,
7 TextInput,
8 TouchableOpacity,
9 View,
10} from "react-native";
11import { SafeAreaView } from "react-native-safe-area-context";
12
13import ScreenHeader from "../components/ScreenHeader";
14import Scanner from "../components/Scanner";
15import DatePicker from "../components/DatePicker";
16
17import { api } from "../services/api";
18import styles, { colors } from "../styles";
19import { AuthContext } from "../AuthContext";
20
21export default function InspectorScreen({ navigation, route }) {
22 const { user } = useContext(AuthContext);
23 const userId = route.params?.userId || user?.id;
24 const token = user?.token;
25
26 const [produceId, setProduceId] = useState("");
27 const [quality, setQuality] = useState("");
28 const [expiryDate, setExpiryDate] = useState("");
29 const [markFailed, setMarkFailed] = useState(false);
30 const [reason, setReason] = useState("");
31
32 const resetCommon = () => {
33 setProduceId("");
34 setQuality("");
35 setExpiryDate("");
36 setMarkFailed(false);
37 setReason("");
38 };
39
40 const inspectProduce = async () => {
41 if (!produceId) return Alert.alert("Error", "Enter a Produce ID");
42
43 try {
44 const body = {
45 produceId,
46 inspectorId: userId,
47 qualityUpdate: {
48 quality,
49 expiryDate,
50 failed: markFailed,
51 reason: markFailed ? reason || "Failed Inspection" : undefined,
52 },
53 };
54
55 await api.inspectProduce(body, token);
56
57 Alert.alert(
58 markFailed ? "Marked as Failed" : "Inspection Recorded",
59 markFailed
60 ? "Produce marked as failed"
61 : "Inspection data submitted successfully"
62 );
63 resetCommon();
64 } catch (err) {
65 Alert.alert("Error", err.message);
66 }
67 };
68
69 return (
70 <SafeAreaView style={styles.container}>
71 <ScreenHeader
72 title="Inspect Produce"
73 navigation={navigation}
74 role="Inspector"
75 />
76 <ScrollView>
77 <View>
78 <Scanner value={produceId} onChange={setProduceId} />
79 <TextInput
80 style={styles.input}
81 placeholder="Quality (e.g. A+, Good)"
82 value={quality}
83 onChangeText={setQuality}
84 />
85 <DatePicker
86 label="Expiry Date"
87 value={expiryDate}
88 onChange={setExpiryDate}
89 />
90 <View
91 style={{
92 flexDirection: "row",
93 alignItems: "center",
94 marginTop: 10,
95 }}
96 >
97 <Text style={{ flex: 1, fontWeight: "600", color: colors.gray }}>
98 Mark as Failed
99 </Text>
100 <Switch
101 value={markFailed}
102 onValueChange={setMarkFailed}
103 thumbColor={markFailed ? colors.danger : colors.gray}
104 />
105 </View>
106
107 {markFailed && (
108 <TextInput
109 style={styles.input}
110 placeholder="Failure Reason"
111 value={reason}
112 onChangeText={setReason}
113 />
114 )}
115
116 <TouchableOpacity
117 style={[
118 styles.primaryButton,
119 markFailed && { backgroundColor: colors.danger },
120 ]}
121 onPress={inspectProduce}
122 >
123 <Text style={styles.buttonText}>
124 {markFailed ? "Mark as Failed" : "Submit Inspection"}
125 </Text>
126 </TouchableOpacity>
127 </View>
128 </ScrollView>
129
130 <View style={{ padding: 12 }}>
131 <TouchableOpacity
132 style={styles.secondaryButton}
133 onPress={() =>
134 navigation.navigate("Inventory", {
135 userId: userId,
136 role: "Inspector",
137 title: "Inspected Produce",
138 })
139 }
140 >
141 <Text style={styles.secondaryButtonText}>View Inspected Produce</Text>
142 </TouchableOpacity>
143 </View>
144 </SafeAreaView>
145 );
146}