BadgerBakery.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. import { useEffect,useState } from "react";
  2. import { Text,View,Alert,StyleSheet,Image } from "react-native";
  3. import BadgerBakedGood from "./BadgerBakedGood";
  4. import Button from './Button'
  5. const baseAPIPath = 'https://www.cs571.org/s23/hw8/api/bakery'
  6. const baseHeaders = {
  7. Accept: 'application/json',
  8. 'Content-Type': 'application/json',
  9. 'X-CS571-ID': 'bid_2359f9728468cc49987c'
  10. }
  11. const getItems = () => {
  12. return fetch(`${ baseAPIPath }/items`,{
  13. headers: baseHeaders
  14. })
  15. .then(response => response.json())
  16. .then(json => {
  17. return json;
  18. })
  19. .catch(error => {
  20. console.error(error);
  21. });
  22. };
  23. const orderPush = ( params ) => {
  24. return fetch(`${ baseAPIPath }/order`,{
  25. headers: baseHeaders,
  26. method: 'POST',
  27. body: JSON.stringify(params),
  28. })
  29. .then(response => response.json())
  30. .then(json => {
  31. return json;
  32. })
  33. .catch(error => {
  34. console.error(error);
  35. });
  36. };
  37. export default function BadgerBakery() {
  38. const [preBtnDisabled,setPreBtnDisabled] = useState(true)
  39. const [items,setItems] = useState({})
  40. const [itemKeys,setItemKeys] = useState([])
  41. const [item,setItem] = useState()
  42. const [index,setIndex] = useState(0)
  43. const [total,setTotal] = useState(0)
  44. const styles = StyleSheet.create({
  45. btnBase: {
  46. backgroundColor: '#4898E7',
  47. color: '#ffffff',
  48. width: '40%',
  49. borderRadius: 4,
  50. },
  51. image: {
  52. width: 250,
  53. height: 250,
  54. },
  55. title: {
  56. fontSize: 35,
  57. fontWeight: 'bold'
  58. },
  59. btnMethod: {
  60. width: 50,
  61. height: 50,
  62. marginRight: 30,
  63. marginLeft: 30,
  64. borderRadius: 4,
  65. }
  66. });
  67. useEffect(() => {
  68. pageInit()
  69. },[])
  70. function onPrevious() {
  71. if ( index ) {
  72. setPreBtnDisabled(index - 1 < 1)
  73. setIndex(index - 1)
  74. items[itemKeys[index]] = item
  75. setItems(items)
  76. setItem(items[itemKeys[index - 1]])
  77. }
  78. }
  79. function onNext() {
  80. if ( index < itemKeys.length - 1 ) {
  81. setPreBtnDisabled(false)
  82. setIndex(index + 1)
  83. items[itemKeys[index]] = item
  84. setItems(items)
  85. setItem(items[itemKeys[index + 1]])
  86. }
  87. }
  88. async function pageInit() {
  89. const res = await getItems()
  90. const arr = []
  91. if ( res ) {
  92. Object.keys(res).forEach(key => {
  93. arr.push(key)
  94. })
  95. }
  96. setItemKeys(arr)
  97. setItems(res)
  98. setItem(res[arr[index]])
  99. }
  100. function onMinus() {
  101. if ( item?.number ) {
  102. const newItem = {
  103. ...item,
  104. number: ( item?.number || 0 ) - 1,
  105. upperBound: item.upperBound + 1
  106. }
  107. const newOrders = {
  108. ...items,
  109. [itemKeys[index]]: newItem
  110. }
  111. setItem(newItem)
  112. setItems(newOrders)
  113. setTotal(total - item.price)
  114. }
  115. }
  116. function onPlus() {
  117. if ( item.upperBound ) {
  118. const newItem = {
  119. ...item,
  120. number: ( item?.number || 0 ) + 1,
  121. upperBound: item.upperBound - 1
  122. }
  123. const newOrders = {
  124. ...items,
  125. [itemKeys[index]]: newItem
  126. }
  127. setItem(newItem)
  128. setItems(newOrders)
  129. setTotal(total + item.price)
  130. }
  131. }
  132. async function placeOrder() {
  133. if ( !total ) {
  134. Alert.alert("Empty Basket","You must order something!");
  135. return
  136. }
  137. const params = {}
  138. Object.keys(items).forEach(key => {
  139. const {number} = items[key]
  140. params[key] = number
  141. })
  142. const res = await orderPush(params)
  143. if ( res?.id ) {
  144. // Alert.alert("Success!","Successfully placed order!");
  145. // 以下这段可选择性删除
  146. setTotal(0)
  147. setTimeout(() => {
  148. pageInit()
  149. }, 300)
  150. // 以上这段可选择性删除
  151. Alert.alert("Success!",res.msg);
  152. } else {
  153. Alert.alert("Empty Basket",res.msg);
  154. }
  155. }
  156. return <View>
  157. <Text>Welcome to Badger Bakery!</Text>
  158. <View style={ {flexDirection: 'row',justifyContent: 'space-around'} }>
  159. <Button
  160. mode="contained"
  161. style={ {
  162. ...styles.btnBase,
  163. backgroundColor: '#4994EC',
  164. // marginRight: 10
  165. } }
  166. disabled={ preBtnDisabled }
  167. onPress={ () => onPrevious() }
  168. >
  169. PREVIOUS
  170. </Button>
  171. <Button
  172. mode="contained"
  173. style={ {
  174. ...styles.btnBase,
  175. backgroundColor: '#4994EC',
  176. // marginLeft: 10
  177. } }
  178. onPress={ () => onNext() }
  179. >
  180. NEXT
  181. </Button>
  182. </View>
  183. <View style={ {
  184. display: 'flex',
  185. alignItems: 'center'
  186. } }>
  187. <Image
  188. style={ styles.image }
  189. resizeMode={ "contain" }
  190. source={ {
  191. uri: item?.img
  192. } }></Image>
  193. <Text style={ styles.title }>{ itemKeys[index - 1] }</Text>
  194. <Text>${ item?.price }</Text>
  195. <Text>You can order up to { item?.upperBound } unites!</Text>
  196. </View>
  197. <View style={ {
  198. // flex: 1,
  199. flexDirection: 'row',
  200. justifyContent: 'center',
  201. height: 100,
  202. overflow: 'hidden'
  203. } }>
  204. <Button
  205. mode="contained"
  206. style={ {
  207. ...styles.btnMethod,
  208. marginLeft: 0,
  209. backgroundColor: '#4994EC',
  210. // marginLeft: 10
  211. } }
  212. onPress={ () => onMinus() }
  213. >
  214. -
  215. </Button>
  216. <Text style={ {
  217. textAlign: 'center',
  218. lineHeight: 60,
  219. width: 40,
  220. } }>{ item?.number || 0 }</Text>
  221. <Button
  222. mode="contained"
  223. style={ {
  224. ...styles.btnMethod,
  225. marginLeft: 20,
  226. backgroundColor: '#4994EC',
  227. } }
  228. onPress={ () => onPlus() }
  229. >
  230. +
  231. </Button>
  232. </View>
  233. <View style={ {alignItems: 'center'} }><Text>Order Total: ${ total }</Text></View>
  234. <View>
  235. <Button
  236. mode="contained"
  237. style={ {
  238. ...styles.btnBase,
  239. width: '100%',
  240. backgroundColor: '#4994EC',
  241. } }
  242. onPress={ () => placeOrder() }
  243. >
  244. PLACE ORDER
  245. </Button>
  246. </View>
  247. </View>
  248. }