FormInput.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. import * as WebBrowser from "expo-web-browser";
  2. import * as React from "react";
  3. import { View, StyleSheet, TouchableWithoutFeedback } from "react-native";
  4. import {
  5. Layout,
  6. Input,
  7. Button,
  8. useTheme,
  9. Icon,
  10. Text,
  11. SelectItem,
  12. } from "@ui-kitten/components";
  13. import { Cascader, BottomModal } from "beeshell";
  14. import variables from "../constants/customTheme";
  15. import { useModel } from "flooks";
  16. import OpenTime from "./OpenTime";
  17. import UpLoadImage from "./UpLoadImage";
  18. import moment from "moment";
  19. const AlertIcon = (props) => <Icon {...props} name='alert-circle-outline' />;
  20. function* flattenSelect(array, key) {
  21. for (const item of array) {
  22. let _array = key ? item[key] : item;
  23. if (Array.isArray(_array) && _array.length > 0) {
  24. yield* flattenSelect(_array, key);
  25. } else {
  26. yield item;
  27. }
  28. }
  29. }
  30. const FormInput = React.memo((props) => {
  31. const [secureTextEntry, setSecureTextEntry] = React.useState(true);
  32. const { cancel, confirm } = useModel("wordsModel");
  33. const toggleSecureEntry = () => {
  34. setSecureTextEntry(!secureTextEntry);
  35. };
  36. const renderIcon = (props) => (
  37. <TouchableWithoutFeedback onPress={toggleSecureEntry}>
  38. <Icon {...props} name={secureTextEntry ? "eye-off" : "eye"} />
  39. </TouchableWithoutFeedback>
  40. );
  41. function getInputProps(props) {
  42. let _props = {
  43. value: props.value || "",
  44. placeholder: props.placeholder,
  45. };
  46. if (props.type === "phone") {
  47. _props = {
  48. ..._props,
  49. dataDetectorTypes: "phoneNumber",
  50. maxLength: 11,
  51. keyboardType: "phone-pad",
  52. };
  53. } else if (props.type === "password") {
  54. _props = {
  55. ..._props,
  56. accessoryRight: (ImageProps) => renderIcon(ImageProps),
  57. secureTextEntry: secureTextEntry,
  58. };
  59. } else if (props.type == "code") {
  60. _props = {
  61. ..._props,
  62. dataDetectorTypes: "phoneNumber",
  63. maxLength: 6,
  64. keyboardType: "phone-pad",
  65. };
  66. }
  67. if (props.onChange) {
  68. _props = {
  69. ..._props,
  70. onChangeText: (nextValue) => props.onChange(nextValue),
  71. };
  72. }
  73. return _props;
  74. }
  75. const inputProps = getInputProps(props);
  76. // const myInput = () => {
  77. // if (inputProps != null) {
  78. // return;
  79. // }
  80. // };
  81. const Label = (props) => {
  82. return (
  83. <View
  84. style={[
  85. styles.label,
  86. props.type === "img" ? { alignSelf: "flex-start" } : {},
  87. ]}
  88. >
  89. <Text category='c1' style={{ textAlign: "right" }}>
  90. {props.label}
  91. </Text>
  92. </View>
  93. );
  94. };
  95. const ForwardIcon = (props) => <Icon {...props} name='arrow-ios-forward' />;
  96. const selectList = props.selectList ? props.selectList : [];
  97. const [bottomModalX, changeBottomModalx] = React.useState("");
  98. const [selectVal, setSelectVal] = React.useState("");
  99. const selectInfo = React.useMemo(() => {
  100. if (props.type === "select" && props.value && selectList.length > 0) {
  101. const childrens = [...flattenSelect(selectList, "children")];
  102. return (
  103. childrens.find((item) => {
  104. return item.id == props.value;
  105. }) || { name: " " }
  106. );
  107. } else {
  108. return { name: " " };
  109. }
  110. }, [props.value, props.type, selectList]);
  111. const [open, ChangeOpen] = React.useState(false);
  112. function submitEvent(val) {
  113. console.log(val);
  114. }
  115. const theme = useTheme();
  116. function getMain(type, props) {
  117. if (type == "select") {
  118. return (
  119. <>
  120. <SelectItem
  121. appearance='form'
  122. style={{ flex: 1 }}
  123. accessoryRight={ForwardIcon}
  124. title={selectInfo.name}
  125. onPress={() => {
  126. bottomModalX.open();
  127. }}
  128. />
  129. <BottomModal
  130. ref={(c) => {
  131. changeBottomModalx(c);
  132. }}
  133. title={props.selectTitle}
  134. titleStyle={styles.titleStyle}
  135. cancelable={true}
  136. leftLabelText={cancel}
  137. leftLabelTextStyle={styles.leftLabelTextStyle}
  138. rightLabelText={confirm}
  139. rightLabelTextStyle={styles.rightLabelTextStyle}
  140. rightCallback={() => {
  141. props.onChange(selectVal);
  142. }}
  143. >
  144. <Cascader
  145. style={{ height: 200, marginBottom: 50 }}
  146. data={selectList}
  147. fieldKeys={{
  148. labelKey: "name",
  149. idKey: "id",
  150. activeKey: "choose",
  151. }}
  152. onChange={(value, info) => {
  153. setSelectVal(value[0]);
  154. }}
  155. />
  156. </BottomModal>
  157. </>
  158. );
  159. } else if (type == "openTime") {
  160. return (
  161. <OpenTime
  162. open={open}
  163. submit={(start, end, week) => {
  164. ChangeOpen(false);
  165. props.onChange(
  166. week.join(","),
  167. moment(start, "HH:mm").format("HH:mm:ss"),
  168. moment(end, "HH:mm").format("HH:mm:ss")
  169. );
  170. console.log(
  171. moment(start, "HH:mm").format("HH:mm:ss"),
  172. moment(end, "HH:mm").format("HH:mm:ss"),
  173. week
  174. );
  175. }}
  176. cancelEvent={() => {
  177. ChangeOpen(false);
  178. }}
  179. openModal={() => {
  180. ChangeOpen(true);
  181. }}
  182. />
  183. );
  184. } else if (type == "url") {
  185. return (
  186. <SelectItem
  187. appearance='form'
  188. style={{ flex: 1 }}
  189. accessoryRight={ForwardIcon}
  190. title={props.value}
  191. onPress={props.changePath}
  192. />
  193. );
  194. } else if (type == "img") {
  195. return (
  196. <UpLoadImage
  197. style={styles.upload}
  198. value={props.value}
  199. changeIcon={props.onChange}
  200. />
  201. );
  202. } else {
  203. return <Input {...inputProps} size='small' style={styles.input} />;
  204. }
  205. }
  206. return (
  207. <Layout
  208. level='1'
  209. style={[
  210. styles.inputContainer,
  211. { ...props.style },
  212. props.type === "img" ? { flexDirection: "column" } : {},
  213. ]}
  214. >
  215. <Label {...props} />
  216. {(!props.value || props.value == " ") && (
  217. <Text category='c1' style={styles.sub}>
  218. {props.sub}
  219. </Text>
  220. )}
  221. {getMain(props.type, props)}
  222. {props.type == "code" && (
  223. <Button
  224. appearance='ghost'
  225. size='tiny'
  226. style={{ paddingVertical: 8, marginLeft: 5 }}
  227. >
  228. {props.btnText}
  229. </Button>
  230. )}
  231. </Layout>
  232. );
  233. });
  234. function ChnageTime(sendNum, isSend, changeSend_Num) {
  235. let num = sendNum - 1;
  236. console.log(num);
  237. changeSend_Num(true, num);
  238. setTimeout(() => {
  239. ChnageTime(num, isSend, changeSend_Num);
  240. }, 1000);
  241. }
  242. const styles = StyleSheet.create({
  243. inputContainer: {
  244. flexDirection: "row",
  245. alignItems: "center",
  246. paddingVertical: 10,
  247. paddingHorizontal: 4,
  248. },
  249. input: {
  250. flex: 1,
  251. },
  252. label: {
  253. width: 90,
  254. marginRight: 19,
  255. flexShrink: 0,
  256. },
  257. right: {
  258. flexDirection: "row",
  259. },
  260. code: {
  261. paddingHorizontal: 5,
  262. marginLeft: 5,
  263. },
  264. selectContent: {
  265. backgroundColor: "#F0F0F0",
  266. },
  267. titleStyle: {
  268. fontSize: 15,
  269. },
  270. leftLabelTextStyle: {
  271. fontSize: 13,
  272. },
  273. rightLabelTextStyle: {
  274. fontSize: 13,
  275. },
  276. sub: {
  277. color: "#787878",
  278. position: "absolute",
  279. left: 90,
  280. zIndex: 2,
  281. },
  282. upload: {
  283. marginTop: 20,
  284. },
  285. });
  286. export default FormInput;