beerbuddy/react-native/app/item/new/[storeKey].tsx
2024-02-10 15:22:19 -08:00

192 lines
5.4 KiB
TypeScript

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 { styled } from "nativewind";
declare function isNaN(x: string | number): boolean;
export default function () {
const [itemName, onitemName] = useState("");
const [itemVolume, onitemVolume] = useState("");
const [itemPrice, onitemPrice] = useState("");
const { storeKey } = useLocalSearchParams();
const StyledText = styled(Text);
const handleSubmit = (price: string, vol: string, name: string) => {
if (price === "" || vol === "" || name === "") {
Alert.alert(
"Insufficient information!",
"Please double-check to ensure all fields have been filled"
);
} else {
// send data to flask
fetch(
`${process.env.EXPO_PUBLIC_BACKEND_URL}/?` +
new URLSearchParams({
storeKey: storeKey.toString(),
itemName: name,
itemPrice: price,
itemVolume: vol,
}),
{
method: "POST",
mode: "cors",
redirect: "follow",
}
).then((res) => {
if (res.ok) {
Alert.alert(
"Success!",
"Item has been successfully added. Thank you!",
[
{
text: "OK",
onPress: () => {
router.back();
},
},
]
);
} else {
switch (res.status) {
case 400:
Alert.alert(
"Error!",
"Please double-check all fields are filled in."
);
break;
case 409:
Alert.alert(
"Error!",
"Duplicate of existing item. Please go to that item to edit its price.",
[
{
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;
}
}
});
}
};
return (
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
<View
style={{
flex: 1,
alignItems: "center",
height: "100%",
paddingBottom: "5%",
}}
>
<Stack.Screen
options={{
title: "New Item",
}}
/>
<View
style={{
flex: 1,
justifyContent: "space-between",
}}
>
<View
style={{
display: "flex",
}}
>
<TextInput
className="w-[90vw] mt-4 h-12 text-xl border rounded text-center dark:border-white dark:text-white"
onChangeText={onitemName}
placeholder="Item Name"
placeholderTextColor={
Appearance.getColorScheme() === "dark" ? "#fff" : "#000"
}
value={itemName}
/>
<TextInput
className="w-[90vw] mt-4 h-12 text-xl border rounded text-center dark:border-white dark:text-white"
onChangeText={(text) => {
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}
/>
<TextInput
className="w-[90vw] mt-4 h-12 text-xl border rounded text-center dark:border-white dark:text-white"
onChangeText={(text) => {
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}`}
/>
</View>
<TouchableOpacity
className="px-8 py-4 my-4 bg-green-700 rounded"
onPress={() => handleSubmit(itemPrice, itemVolume, itemName)}
>
<StyledText className="text-white text-center text-2xl">
Submit
</StyledText>
</TouchableOpacity>
</View>
</View>
</ScrollView>
);
}