matiru

Blockchain-Based Supply Chain Transparency for Agricultural Produce

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}