import React, { useState } from "react"; import { TouchableOpacity, Text, Image, View, ScrollView, TextInput, Appearance, Alert, } from "react-native"; import { Stack, useLocalSearchParams, router } from "expo-router"; import utmObj from "utm-latlng"; import { styled } from "nativewind"; import mime from "mime"; import uploadImage from "./uploadImage"; declare function isNaN(x: string | number): boolean; export default function () { const utm = new utmObj(); const [image, setImage] = useState(null); const [storeName, onstoreName] = useState(""); const [itemName, onitemName] = useState(""); const [itemVolume, onitemVolume] = useState(""); const [itemPrice, onitemPrice] = useState(""); let { coords } = useLocalSearchParams(); const handleSubmit = async () => { coords = coords.split("%2B"); const lon = coords[0]; const lat = coords[1]; const utmCoords = utm.convertLatLngToUtm(lat, lon, 5); if ( itemPrice === "" || itemVolume === "" || itemName === "" || storeName === "" ) { Alert.alert( "Insufficient information!", "Please double-check to ensure all fields have been filled" ); } else { let res; // add image if image if (image) { const formData = new FormData(); formData.append("file", { uri: image.uri, type: mime.getType(image.uri), name: "file", } as unknown as File); res = await fetch( `${process.env.EXPO_PUBLIC_BACKEND_URL}/?` + new URLSearchParams({ easting: utmCoords.Easting, northing: utmCoords.Northing, zone: utmCoords.ZoneNumber, zoneLetter: utmCoords.ZoneLetter, name: storeName, itemName: itemName, itemPrice: itemPrice, itemVolume: itemVolume, }), { method: "POST", body: formData, mode: "cors", redirect: "follow", } ); } else { res = await fetch( `${process.env.EXPO_PUBLIC_BACKEND_URL}/?` + new URLSearchParams({ easting: utmCoords.Easting, northing: utmCoords.Northing, zone: utmCoords.ZoneNumber, zoneLetter: utmCoords.ZoneLetter, name: storeName, itemName: itemName, itemPrice: itemPrice, itemVolume: itemVolume, }), { method: "POST", mode: "cors", redirect: "follow", } ); } if (res.ok) { Alert.alert( "Success!", "Store has been successfully added. Thank you!", [ { text: "OK", onPress: () => { router.push("/"); }, }, ] ); } else { switch (res.status) { case 400: Alert.alert( "Error!", "Please double-check all fields are filled in." ); break; case 409: Alert.alert( "Error!", "This store already exists! Please click 'More' on its pin and upload an item there.", [ { text: "OK", onPress: () => { router.push("/"); }, }, ] ); break; case 500: Alert.alert( "Error!", "Backend server error. Please report to ak95@riseup.net" ); break; default: Alert.alert( "Error!", "Unspecified error. Please report to ak95@riseup.net" ); break; } } } }; const StyledText = styled(Text); return ( setImage(uploadImage())}> {image ? ( ) : ( )} { const split = text.split(""); let numeric = true; split.forEach((char: string | number) => { if (isNaN(char)) { numeric = false; } }); if (numeric) onitemVolume(text); }} placeholder="Item Volume (fl. oz.)" placeholderTextColor={ Appearance.getColorScheme() === "dark" ? "#fff" : "#000" } inputMode="numeric" value={itemVolume} /> { text = text.slice(2); if (text.includes(".")) { const split = text.split("."); if (split.length < 3) { const righthand = split[1]; if (righthand.length <= 2) { onitemPrice(text); } } } else onitemPrice(text); }} placeholder="Item Price" inputMode="decimal" placeholderTextColor={ Appearance.getColorScheme() === "dark" ? "#fff" : "#000" } value={`$ ${itemPrice}`} /> Submit ); }