150 lines
4 KiB
TypeScript
150 lines
4 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import {
|
|
TouchableOpacity,
|
|
Image,
|
|
Text,
|
|
View,
|
|
ScrollView,
|
|
Alert,
|
|
} from "react-native";
|
|
|
|
import { useNavigation, Stack, useLocalSearchParams } from "expo-router";
|
|
|
|
import * as FileSystem from "expo-file-system";
|
|
|
|
import { styled } from "nativewind";
|
|
|
|
import StoreItem from "../../components/StoreItem";
|
|
|
|
import handleAddItem from "./handleAddItem";
|
|
import toUTM from "./toUTM";
|
|
import uploadImage from "./uploadImage";
|
|
|
|
declare function isNaN(x: string | number): boolean;
|
|
|
|
interface storeItemInterface {
|
|
key: String;
|
|
lastUpdated: String;
|
|
name: String;
|
|
perFloz: Number;
|
|
price: Number;
|
|
store: String;
|
|
volumeFloz: Number;
|
|
}
|
|
|
|
export default function () {
|
|
const [storeKey, setStoreKey] = useState("");
|
|
const [storeName, setStoreName] = useState("");
|
|
const [storeItems, setStoreItems] = useState([]);
|
|
const [image, setImage] = useState(null);
|
|
|
|
const navigation = useNavigation();
|
|
|
|
const StyledText = styled(Text);
|
|
|
|
const coords = useLocalSearchParams().coords.toString().split("%2B");
|
|
const lon = coords[0];
|
|
const lat = coords[1];
|
|
const utmCoords = toUTM(lat, lon);
|
|
|
|
const getStore = async () => {
|
|
const res = await fetch(
|
|
`${process.env.EXPO_PUBLIC_BACKEND_URL}/?` +
|
|
new URLSearchParams({
|
|
easting: utmCoords.Easting,
|
|
northing: utmCoords.Northing,
|
|
zone: utmCoords.ZoneNumber,
|
|
})
|
|
);
|
|
if (!res.ok)
|
|
return Alert.alert(
|
|
"Error!",
|
|
"Server error. Please report to ak95@riseup.net"
|
|
);
|
|
|
|
const json = await res.json();
|
|
setStoreName(json.name);
|
|
setStoreKey(json.key.toString());
|
|
const imageKey = json.key.toString();
|
|
|
|
const items = json.items.map((item: storeItemInterface, index: number) => {
|
|
const date = new Date(item.lastUpdated.replace(" ", "T") + "Z");
|
|
return (
|
|
<View className="flex flex-row w-[100vw]" key={index}>
|
|
<StoreItem
|
|
name={item.name.toString()}
|
|
volume={item.volumeFloz.toString()}
|
|
price={item.price.toString()}
|
|
date={date}
|
|
storeKey={item.store.toString()}
|
|
/>
|
|
</View>
|
|
);
|
|
});
|
|
setStoreItems(items);
|
|
|
|
const imageURL = `${process.env.EXPO_PUBLIC_BACKEND_URL}/img?imageKey=${imageKey}`;
|
|
await FileSystem.downloadAsync(
|
|
imageURL,
|
|
FileSystem.documentDirectory + imageKey
|
|
)
|
|
.then(({ uri }) => {
|
|
setImage(uri);
|
|
})
|
|
.catch(() => {});
|
|
console.log(image);
|
|
};
|
|
|
|
useEffect(() => {
|
|
return navigation.addListener("focus", () => getStore());
|
|
}, [navigation]);
|
|
|
|
return (
|
|
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
|
|
<View
|
|
style={{
|
|
flex: 1,
|
|
alignItems: "center",
|
|
height: "100%",
|
|
paddingBottom: "5%",
|
|
}}
|
|
>
|
|
<Stack.Screen
|
|
options={{
|
|
title: storeName,
|
|
}}
|
|
/>
|
|
<TouchableOpacity
|
|
onPress={() => {
|
|
uploadImage(storeKey).then((uri) => {
|
|
setImage(uri);
|
|
});
|
|
}}
|
|
>
|
|
{image ? (
|
|
<Image source={{ uri: image }} className="h-[33vh] w-[100vw]" />
|
|
) : (
|
|
<Image
|
|
source={require("../../assets/images/photo_placeholder.png")}
|
|
className="h-[33vh] w-[100vw]"
|
|
/>
|
|
)}
|
|
</TouchableOpacity>
|
|
<View className="flex w-[100vw] py-6 justify-center items-center border-b dark:border-white">
|
|
<StyledText className="text-2xl dark:text-white">
|
|
{storeName}
|
|
</StyledText>
|
|
</View>
|
|
<ScrollView style={{ flex: 1 }}>{storeItems}</ScrollView>
|
|
<TouchableOpacity
|
|
className="px-8 py-4 my-4 bg-green-700 rounded"
|
|
onPress={() => handleAddItem(storeKey)}
|
|
>
|
|
<StyledText className="text-white text-center text-2xl">
|
|
Add
|
|
</StyledText>
|
|
</TouchableOpacity>
|
|
</View>
|
|
</ScrollView>
|
|
);
|
|
}
|