You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
6.4 KiB

  1. import React, { useState } from "react";
  2. import { Text, TouchableOpacity, View, StyleSheet, Image } from "react-native";
  3. import { MaterialCommunityIcons } from "@expo/vector-icons";
  4. import SelfClosingModal from "../components/SelfClosingModal";
  5. import colors from "../config/colors";
  6. import { showMessage } from "react-native-flash-message";
  7. import { dimensions, screen_height } from "../config/dimensions";
  8. import { Svg, Image as ImageSvg } from "react-native-svg";
  9. import { ScrollView } from "react-native-gesture-handler";
  10. import PluviometerGraphics from "./PluviometerGraphics";
  11. const chartHeight = screen_height * 0.3;
  12. /* NOTE: `Edit` and `Delete` icons behavior not implemented yet.
  13. *
  14. * Waiting for API handler to implement this functionality and avoid overwork
  15. */
  16. function notImplemented() {
  17. showMessage({
  18. message: "Comportamento ainda não implementado",
  19. duration: 1950,
  20. icon: "warning",
  21. type: "warning",
  22. });
  23. }
  24. function topBar(props) {
  25. return (
  26. <View style={styles.topBar}>
  27. <TouchableOpacity
  28. style={styles.topBarIcon}
  29. onPress={() => notImplemented()}
  30. >
  31. <MaterialCommunityIcons
  32. name="pencil"
  33. size={20}
  34. color={colors.dark}
  35. alignItems="center"
  36. />
  37. </TouchableOpacity>
  38. <TouchableOpacity
  39. style={styles.topBarIcon}
  40. onPress={() => notImplemented()}
  41. >
  42. <MaterialCommunityIcons
  43. name="trash-can"
  44. size={20}
  45. color={colors.dark}
  46. alignItems="center"
  47. />
  48. </TouchableOpacity>
  49. <TouchableOpacity
  50. style={styles.topBarIcon}
  51. onPress={() => props.setIsVisible(!props.isVisible)}
  52. >
  53. <MaterialCommunityIcons
  54. name="close"
  55. size={20}
  56. color={colors.dark}
  57. alignItems="center"
  58. />
  59. </TouchableOpacity>
  60. </View>
  61. );
  62. }
  63. function iconTextRow(props) {
  64. return (
  65. <View flexDirection="row" alignSelf="flex-start" marginVertical={3}>
  66. <View alignSelf="flex-start" marginRight={10}>
  67. <MaterialCommunityIcons
  68. name={props.name}
  69. size={18}
  70. color={colors.dark}
  71. />
  72. </View>
  73. <Text style={styles.text}>{props.description}</Text>
  74. </View>
  75. );
  76. }
  77. function iconImageRow(props) {
  78. return (
  79. <View flexDirection="row" alignSelf="flex-start" marginVertical={3}>
  80. <View alignSelf="flex-start" marginRight={10}>
  81. <MaterialCommunityIcons
  82. name={props.name}
  83. size={18}
  84. color={colors.dark}
  85. />
  86. </View>
  87. <View alignSelf="flex-start">
  88. <Svg width={100} height={100}>
  89. <ImageSvg
  90. width="100%"
  91. height="100%"
  92. preserveAspectRatio="xMinYMin stretch"
  93. href={{ uri: props.pic[0] }}
  94. />
  95. </Svg>
  96. </View>
  97. </View>
  98. );
  99. }
  100. function reviews(props) {
  101. const [likes, setLikes] = useState(0);
  102. const [dislikes, setDislikes] = useState(0);
  103. const updateLikes = () => {
  104. setLikes(likes + 1);
  105. notImplemented();
  106. };
  107. const updatedislikes = () => {
  108. setDislikes(dislikes + 1);
  109. notImplemented();
  110. };
  111. return (
  112. <View style={styles.reviewsContainer}>
  113. <TouchableOpacity onPress={() => updatedislikes()}>
  114. <View style={styles.review}>
  115. <View marginRight={5}>
  116. <MaterialCommunityIcons
  117. name={"thumb-down"}
  118. size={18}
  119. color={colors.dark}
  120. />
  121. </View>
  122. <Text style={styles.text}>{dislikes}</Text>
  123. </View>
  124. </TouchableOpacity>
  125. <TouchableOpacity
  126. onPress={() => {
  127. updateLikes();
  128. }}
  129. >
  130. <View style={styles.review}>
  131. <View marginRight={5}>
  132. <MaterialCommunityIcons
  133. name={"thumb-up"}
  134. size={18}
  135. color={colors.dark}
  136. />
  137. </View>
  138. <Text style={styles.text}>{likes}</Text>
  139. </View>
  140. </TouchableOpacity>
  141. </View>
  142. );
  143. }
  144. function moreInfo() {
  145. return (
  146. <View style={styles.pluviometer_diary}>
  147. <PluviometerGraphics chartHeight={chartHeight} />
  148. </View>
  149. );
  150. }
  151. function componentBody(props) {
  152. // NOTE: This code is refered to our local SQLite solution. Revise this when implement rest API.
  153. const pictures = JSON.parse(props.pictures);
  154. const date = props.date ? props.date : "implementando...";
  155. const address = props.address ? props.address : "Erro ao carregar endereço";
  156. return (
  157. <View style={styles.bodyRow}>
  158. <Image
  159. style={styles.bodyIcon}
  160. resizeMode="stretch"
  161. source={props.image}
  162. />
  163. <View style={styles.bodyInfo}>
  164. <Text style={styles.bodyTitle}>{props.title}</Text>
  165. {iconTextRow({ name: "map-marker", description: address })}
  166. {iconTextRow({ name: "calendar", description: date })}
  167. {iconTextRow({ name: "account", description: "Usuário ativo" })}
  168. {pictures.length > 0 && iconImageRow({ name: "camera", pic: pictures })}
  169. </View>
  170. </View>
  171. );
  172. }
  173. function MapModal(props) {
  174. return (
  175. <SelfClosingModal
  176. animationType="slide"
  177. transparent={true}
  178. visible={props.isVisible}
  179. setVisible={props.setIsVisible}
  180. >
  181. {topBar(props)}
  182. {componentBody(props)}
  183. {props.name === "pluviometer" ? moreInfo(props) : null}
  184. {props.name !== "pluviometer" ? reviews(props) : null}
  185. </SelfClosingModal>
  186. );
  187. }
  188. const styles = StyleSheet.create({
  189. bodyRow: {
  190. flexDirection: "row",
  191. alignSelf: "flex-start",
  192. alignContent: "space-between",
  193. },
  194. bodyTitle: {
  195. fontWeight: "700",
  196. fontSize: dimensions.text.secondary,
  197. marginBottom: 5,
  198. },
  199. bodyInfo: {
  200. flexDirection: "column",
  201. alignContent: "flex-start",
  202. },
  203. bodyIcon: {
  204. alignSelf: "flex-start",
  205. marginHorizontal: 20,
  206. height: 53,
  207. width: 53,
  208. },
  209. reviewsContainer: {
  210. flexDirection: "row",
  211. alignSelf: "flex-end",
  212. margin: 10,
  213. },
  214. review: {
  215. flexDirection: "row",
  216. alignSelf: "flex-end",
  217. alignContent: "space-around",
  218. marginHorizontal: 10,
  219. },
  220. topBar: {
  221. flexDirection: "row",
  222. alignSelf: "flex-end",
  223. },
  224. topBarIcon: {
  225. margin: 10,
  226. },
  227. text: {
  228. fontWeight: "500",
  229. fontSize: dimensions.text.default,
  230. },
  231. link: {
  232. alignSelf: "center",
  233. color: colors.lightBlue,
  234. fontWeight: "500",
  235. fontSize: dimensions.text.default,
  236. },
  237. pluviometer_diary: {
  238. height: chartHeight * 1.4,
  239. paddingVertical: 20,
  240. },
  241. });
  242. export default MapModal;