236 lines
5.4 KiB
TypeScript
236 lines
5.4 KiB
TypeScript
import { StatusBar } from 'expo-status-bar';
|
|
import React, { useState, useReducer } from 'react';
|
|
import { StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';
|
|
import { request, GraphQLClient, gql } from 'graphql-request';
|
|
import moment from 'moment';
|
|
import { buildExecutionContext } from 'graphql/execution/execute';
|
|
|
|
const client = new GraphQLClient("http://localhost:4000/graphql", { headers: {} });
|
|
|
|
const Whisky = (props : { active?: boolean, whisky: any, style: any }) => {
|
|
const whisky = props.whisky;
|
|
let quantity = 0,
|
|
time = moment.unix(0);
|
|
|
|
const locations: any[] = [];
|
|
|
|
if (whisky.inventories) {
|
|
whisky.inventories.forEach((item : { location: any, quantity: number, updated: string }) => {
|
|
quantity += item.quantity;
|
|
const updated = moment(item.updated, 'YYYY-MM-DD');
|
|
if (time < updated) {
|
|
time = updated;
|
|
}
|
|
locations.push(
|
|
<View key={item.location.code} style={[styles.horizontal,styles.container]}>
|
|
<Text style={whiskyStyles.address}>{item.location.address}</Text>
|
|
<Text style={whiskyStyles.phone}>{item.location.phone}</Text>
|
|
<Text style={whiskyStyles.quantity}>{item.quantity}</Text>
|
|
</View>
|
|
)
|
|
});
|
|
}
|
|
const date = (time.unix() == 0) ? "" : time.format("YYYY-MM-DD");
|
|
|
|
return (
|
|
<View style={[...props.style, whiskyStyles.container]}>
|
|
<View style={[styles.container, styles.horizontal, {width: "100%"}]}>
|
|
<View style={whiskyStyles.code}><Text>{whisky.code}</Text></View>
|
|
<View style={whiskyStyles.description}><Text>{whisky.description}</Text></View>
|
|
<View style={whiskyStyles.date}><Text>{date}</Text></View>
|
|
<View style={whiskyStyles.quantity}><Text>{whisky.quantity}</Text></View>
|
|
</View>
|
|
{ props.active && <View style={styles.vertical}>
|
|
{ locations }
|
|
</View> }
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const textStyle = {
|
|
paddingTop: 5,
|
|
paddingRight: 10,
|
|
paddingBottom: 5,
|
|
paddingLeft: 10
|
|
};
|
|
|
|
const whiskyStyles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
minHeight: 25,
|
|
},
|
|
code: {
|
|
...textStyle
|
|
},
|
|
description: {
|
|
flexGrow: 10,
|
|
...textStyle
|
|
},
|
|
date: {
|
|
...textStyle
|
|
},
|
|
address: {
|
|
flex: 1,
|
|
flexGrow: 1,
|
|
...textStyle
|
|
},
|
|
phone: {
|
|
...textStyle
|
|
},
|
|
quantity: {
|
|
flexShrink: 10,
|
|
minWidth: 50,
|
|
...textStyle
|
|
}
|
|
});
|
|
|
|
export default function App() {
|
|
const [whiskies, setWhiskies] = useState<any>(null),
|
|
[search, setSearch] = useState<string>(""),
|
|
[lastSearch, setLastSearch] = useState<string>(""),
|
|
[activeWhisky, setActiveWhisky] = useState<string>("");
|
|
|
|
const [, forceUpdate] = useReducer(x => x + 1, 0);
|
|
|
|
const updateWhisky = (code : string) => {
|
|
const query = gql` {
|
|
Whisky(code: "${code}") {
|
|
inventories {
|
|
location {
|
|
code
|
|
address
|
|
city
|
|
phone
|
|
longitude
|
|
latitude
|
|
}
|
|
quantity
|
|
updated
|
|
}
|
|
code
|
|
size
|
|
description
|
|
updated
|
|
quantity
|
|
}
|
|
}`;
|
|
|
|
client.request(query)
|
|
.then(data => {
|
|
for (let i = 0; i < whiskies.length; i++) {
|
|
if (whiskies[i].code == data.Whisky.code) {
|
|
whiskies[i] = data.Whisky;
|
|
break;
|
|
}
|
|
}
|
|
setWhiskies(whiskies);
|
|
forceUpdate();
|
|
})
|
|
.catch (error => {
|
|
console.error(error);
|
|
});
|
|
};
|
|
|
|
const onPress = (code : string) => {
|
|
if (code == activeWhisky) {
|
|
setActiveWhisky("");
|
|
} else {
|
|
setActiveWhisky(code);
|
|
updateWhisky(code);
|
|
}
|
|
};
|
|
|
|
const items = whiskies ? whiskies
|
|
.filter((item : any) => item.size == 750)
|
|
.sort((a : any, b : any) => a.description.localeCompare(b.description))
|
|
.map((whisky : any) => {
|
|
const active = whisky.code == activeWhisky;
|
|
return (
|
|
<TouchableOpacity key={whisky.code} onPress={() => onPress(whisky.code)}>
|
|
<Whisky
|
|
active={active}
|
|
style={[styles.container, styles.whisky]}
|
|
whisky={whisky}/>
|
|
</TouchableOpacity>
|
|
);
|
|
}) : [];
|
|
|
|
const submitSearch = () => {
|
|
if (search.trim() == "") {
|
|
setWhiskies([]);
|
|
return;
|
|
}
|
|
|
|
if (lastSearch == search) {
|
|
return;
|
|
}
|
|
|
|
const _query = gql` {
|
|
Whiskies(code:"${search}") {
|
|
code
|
|
description
|
|
price
|
|
size
|
|
lastSeen
|
|
quantity
|
|
updated
|
|
}
|
|
}`;
|
|
|
|
setLastSearch(search);
|
|
|
|
client.request(_query)
|
|
.then(data => {
|
|
setWhiskies(data.Whiskies);
|
|
})
|
|
.catch (error => {
|
|
console.error(error);
|
|
});
|
|
};
|
|
|
|
const keyPress = (event : KeyboardEvent) => {
|
|
if (event.code == "\n") {
|
|
submitSearch();
|
|
}
|
|
};
|
|
|
|
return (
|
|
<View style={[styles.container]}>
|
|
<TextInput style={[{borderWidth: 1 }]}
|
|
onBlur={submitSearch}
|
|
onKeyPress={(event : any) => keyPress(event)}
|
|
onChange={(value) => setSearch(value.target.value)}></TextInput>
|
|
<View style={[styles.container]}>
|
|
{ items }
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: '#fff',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
horizontal: {
|
|
flex: 1,
|
|
display: "flex",
|
|
flexGrow: 1,
|
|
flexDirection: "row",
|
|
},
|
|
vertical: {
|
|
flex: 1,
|
|
display: "flex",
|
|
flexGrow: 1,
|
|
flexDirection: "column",
|
|
},
|
|
whisky: {
|
|
width: 500,
|
|
borderWidth: 1,
|
|
borderColor: "black",
|
|
margin: 2
|
|
}
|
|
});
|