matiru

Blockchain-Based Supply Chain Transparency for Agricultural Produce

frontend/screens/Retailer.js (5370B)


  1import { useContext, useState } from "react";
  2import {
  3  Alert,
  4  ScrollView,
  5  Text,
  6  TextInput,
  7  TouchableOpacity,
  8  View,
  9} from "react-native";
 10import { SafeAreaView } from "react-native-safe-area-context";
 11
 12import ScreenHeader from "../components/ScreenHeader";
 13import ActionButton from "../components/ActionButton";
 14import Scanner from "../components/Scanner";
 15import LocationPicker from "../components/LocationPicker";
 16import TransferOwnershipForm from "../components/TransferOwnershipForm";
 17
 18import { api } from "../services/api";
 19import styles from "../styles";
 20import { AuthContext } from "../AuthContext";
 21
 22export default function RetailerScreen({ navigation, route }) {
 23  const { user } = useContext(AuthContext);
 24  const userId = route.params?.userId || user?.id;
 25  const token = user?.token;
 26
 27  const [active, setActive] = useState(null);
 28  const [produceId, setProduceId] = useState("");
 29  const [location, setLocation] = useState("");
 30  const [pricePerUnit, setPricePerUnit] = useState("");
 31  const [storageConditions, setStorageConditions] = useState("");
 32
 33  const resetCommon = () => {
 34    setProduceId("");
 35  };
 36
 37  const updateLocation = async () => {
 38    try {
 39      await api.updateLocation(
 40        {
 41          produceId,
 42          actorId: userId,
 43          newLocation: location,
 44        },
 45        token
 46      );
 47      Alert.alert("Location Updated", "Location updated successfully");
 48      resetCommon();
 49      setLocation("");
 50      setActive(null);
 51    } catch (err) {
 52      Alert.alert("Error", err.message);
 53    }
 54  };
 55
 56  const transferOwnership = async ({
 57    produceId,
 58    newOwnerId,
 59    qty,
 60    salePrice,
 61    onComplete,
 62  }) => {
 63    if (!produceId || !newOwnerId || !qty)
 64      return Alert.alert(
 65        "Error",
 66        "Please provide Produce ID, New Owner ID, and Quantity."
 67      );
 68    try {
 69      await api.transferOwnership(
 70        {
 71          produceId,
 72          newOwnerId,
 73          qty: parseFloat(qty),
 74          salePrice: parseFloat(salePrice),
 75        },
 76        token
 77      );
 78      Alert.alert("Transferred", "Transfer successful");
 79      onComplete();
 80      setActive(null);
 81    } catch (err) {
 82      Alert.alert("Error", err.message);
 83    }
 84  };
 85
 86  const updateDetails = async () => {
 87    try {
 88      await api.updateDetails(
 89        {
 90          produceId,
 91          actorId: userId,
 92          details: {
 93            pricePerUnit: parseFloat(pricePerUnit),
 94            storageConditions: storageConditions
 95              ? storageConditions.split(",").map((c) => c.trim())
 96              : [],
 97          },
 98        },
 99        token
100      );
101      Alert.alert("Updated Details", "Produce details updated successfully");
102      resetCommon();
103      setPricePerUnit("");
104      setStorageConditions("");
105      setActive(null);
106    } catch (err) {
107      Alert.alert("Error", err.message);
108    }
109  };
110
111  return (
112    <SafeAreaView style={styles.container}>
113      <ScreenHeader
114        title="Retailer Dashboard"
115        navigation={navigation}
116        role="Retailer"
117      />
118      <ScrollView>
119        <View style={styles.actionGrid}>
120          <ActionButton
121            icon="map-marker"
122            text="Update Location"
123            onPress={() => setActive("location")}
124          />
125          <ActionButton
126            icon="cash"
127            text="Sell / Transfer"
128            onPress={() => setActive("transfer")}
129          />
130          <ActionButton
131            icon="update"
132            text="Update Details"
133            onPress={() => setActive("update")}
134          />
135        </View>
136
137        {active === "location" && (
138          <View>
139            <Scanner value={produceId} onChange={setProduceId} />
140            <LocationPicker value={location} onChange={setLocation} />
141            <TouchableOpacity
142              style={styles.primaryButton}
143              onPress={updateLocation}
144            >
145              <Text style={styles.buttonText}>Update Location</Text>
146            </TouchableOpacity>
147          </View>
148        )}
149
150        {active === "transfer" && (
151          <TransferOwnershipForm onSubmit={transferOwnership} />
152        )}
153
154        {active === "update" && (
155          <View>
156            <Scanner value={produceId} onChange={setProduceId} />
157            <TextInput
158              style={styles.input}
159              placeholder="New Price Per Unit"
160              keyboardType="numeric"
161              value={pricePerUnit}
162              onChangeText={setPricePerUnit}
163            />
164            <TextInput
165              style={styles.input}
166              placeholder="Storage Conditions (comma separated)"
167              value={storageConditions}
168              onChangeText={setStorageConditions}
169            />
170            <TouchableOpacity
171              style={styles.primaryButton}
172              onPress={updateDetails}
173            >
174              <Text style={styles.buttonText}>Update</Text>
175            </TouchableOpacity>
176          </View>
177        )}
178      </ScrollView>
179
180      <View style={{ padding: 12 }}>
181        <TouchableOpacity
182          style={styles.secondaryButton}
183          onPress={() =>
184            navigation.navigate("Inventory", {
185              userId,
186              role: "Retailer",
187            })
188          }
189        >
190          <Text style={styles.secondaryButtonText}>View Inventory</Text>
191        </TouchableOpacity>
192      </View>
193    </SafeAreaView>
194  );
195}