guide_eat.tsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. import { View, Text, Image } from "@tarojs/components";
  2. import './guide.scss'
  3. import '@/_health/pages/schedules.scss'
  4. import NewHeader, { NewHeaderType } from "../components/new_header";
  5. import { useEffect, useState } from "react";
  6. import { createSchedule, delSchedule, getLabelsEvent, getSchedules } from "@/services/health";
  7. import { setFooter, setSchedules } from "@/store/health";
  8. import { useDispatch, useSelector } from "react-redux";
  9. import Card from "../components/card";
  10. import { rpxToPx } from "@/utils/tools";
  11. import { getScenario, getThemeColor } from "@/features/health/hooks/health_hooks";
  12. import Modal from "@/components/layout/Modal.weapp";
  13. import TimePicker from "@/features/common/TimePicker";
  14. import NewButton, { NewButtonType } from "../base/new_button";
  15. import { MainColorType } from "@/context/themes/color";
  16. import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
  17. import { IconAdd } from "@/components/basic/Icons";
  18. import AddLabel from "../components/add_label";
  19. import ScheduleItem from "../components/schedule_item";
  20. import { useTranslation } from "react-i18next";
  21. import showAlert from "@/components/basic/Alert";
  22. import CellFooter, { CellFooterType } from "../base/cell_footer";
  23. import CellFooterText from "../base/cell_footer_text";
  24. import StatusIndicator, { StatusType } from "../base/status_indicator";
  25. import Taro from "@tarojs/taro";
  26. let useRoute;
  27. let useNavigation;
  28. let scenario = '';
  29. if (process.env.TARO_ENV == 'rn') {
  30. useRoute = require("@react-navigation/native").useRoute
  31. useNavigation = require("@react-navigation/native").useNavigation
  32. }
  33. export default function GuideEat() {
  34. const systemInfo: any = Taro.getWindowInfo();
  35. const navigationBarHeight = systemInfo.statusBarHeight + 44;
  36. const user = useSelector((state: any) => state.user);
  37. const health = useSelector((state: any) => state.health);
  38. const [list, setList] = useState<any>(health.schedules)
  39. const [errors, setErrors] = useState<any>([])
  40. const [highlight, setHighlight] = useState(true)
  41. const [showModal, setShowModal] = useState(false)
  42. const [labels, setLabels] = useState<any>([])
  43. const [posting, setPosting] = useState(false)
  44. const { t } = useTranslation()
  45. let navigation, showActionSheetWithOptions;
  46. let router
  47. if (useNavigation) {
  48. navigation = useNavigation()
  49. }
  50. const dispatch = useDispatch()
  51. const selMode = 'EAT'
  52. useEffect(() => {
  53. getLabelsEvent({ window: 'EAT' }).then(res => {
  54. setLabels((res as any).labels)
  55. })
  56. setTimeout(() => {
  57. setHighlight(false)
  58. }, 2000)
  59. }, [])
  60. useEffect(() => {
  61. var temps: any = []
  62. list.map(item => {
  63. if (item.id) {
  64. var isFind = false
  65. health.schedules.map(obj => {
  66. if (obj.id == item.id) {
  67. isFind = true
  68. }
  69. })
  70. if (!isFind) {
  71. temps.push(item)
  72. }
  73. }
  74. })
  75. var array = JSON.parse(JSON.stringify(list))
  76. var filterArray = array.filter(item => !temps.some(itemA => itemA.id == item.id))
  77. setList(filterArray)
  78. }, [health.schedules])
  79. function check(array, tapDone = false) {
  80. if (tapDone) {
  81. if (posting) return
  82. setPosting(true)
  83. }
  84. createSchedule({
  85. schedules: array,
  86. only_check: true,
  87. return_all: true,
  88. op_page: 'SCHEDULE_WALKTHROUGH_3', sort_by: 'EVENT'
  89. }).then(res => {
  90. if ((res as any).result) {
  91. dispatch(setSchedules((res as any).schedules))
  92. dispatch(setFooter((res as any).footer))
  93. setList((res as any).schedules)
  94. setErrors([])
  95. if (tapDone) {
  96. jumpPage('./guide_active')
  97. }
  98. }
  99. else {
  100. setList((res as any).schedules)
  101. dispatch(setFooter((res as any).footer))
  102. setErrors((res as any).error_messages ? (res as any).error_messages : [])
  103. }
  104. setPosting(false)
  105. }).catch(e => {
  106. setPosting(false)
  107. })
  108. }
  109. function add() {
  110. const scenario = getScenario(health.windows, 'EAT')
  111. var items = list.filter(item => item.window == 'EAT')
  112. if (scenario.access.max && scenario.access.max <= items.length) {
  113. showAlert({
  114. title: '会员',
  115. content: '会员desc',
  116. showCancel: true,
  117. confirm: () => {
  118. jumpPage('/pages/store/product_list', 'ProductList', navigation)
  119. }
  120. })
  121. return;
  122. }
  123. setShowModal(true)
  124. }
  125. function isDisable(obj) {
  126. if ((obj.window == 'FAST' || obj.window == 'SLEEP') && !obj.is_conflict) {
  127. return true
  128. }
  129. return false
  130. }
  131. function footerTitle() {
  132. if (health.footer) {
  133. return health.footer.eat.title
  134. }
  135. return ''
  136. }
  137. function footerDesc() {
  138. if (health.footer) {
  139. return health.footer.eat.description
  140. }
  141. return ''
  142. }
  143. function items() {
  144. var items = list.filter(item => item.window == 'EAT')
  145. return <Card>
  146. {
  147. errors.map((item1, index) => {
  148. return <View key={index} className='error_tip'>{item1}</View>
  149. })
  150. }
  151. {
  152. items.map((obj, i) => {
  153. return <ScheduleItem
  154. index={i}
  155. count={items.length + 1}
  156. key={i * 100}
  157. obj={obj}
  158. highlight={highlight ? obj.window == 'EAT' : false}
  159. showLine={true}
  160. errors={errors}
  161. selMode={selMode}
  162. disable={isDisable(obj)}
  163. gray={isDisable(obj)}
  164. days={obj.plus_days != 0 ? obj.plus_days : null}
  165. hideReminderIcon={true}
  166. onDelete={() => {
  167. const scenario = getScenario(health.windows, 'EAT')
  168. if (scenario.access.min >= items.length) {
  169. showAlert({
  170. title: '删除',
  171. content: '最少保留' + items.length + '个',
  172. showCancel: true,
  173. confirm: () => {
  174. }
  175. })
  176. return
  177. }
  178. if (errors.length > 0) {
  179. Taro.showToast({
  180. title: '请先解决冲突',
  181. icon: 'none'
  182. })
  183. return
  184. }
  185. delSchedule(obj.id).then(res => {
  186. var temps = JSON.parse(JSON.stringify(health.schedules))
  187. var temps2 = temps.filter(item => item.id != obj.id)
  188. dispatch(setSchedules(temps2))
  189. dispatch(setFooter((res as any).footer))
  190. var array = JSON.parse(JSON.stringify(list))
  191. for (var j = 0; j < array.length; j++) {
  192. if (array[j].id == obj.id) {
  193. array.splice(j, 1)
  194. }
  195. }
  196. setList(array)
  197. check(array)
  198. global.refreshWindow()
  199. })
  200. }}
  201. onChange={(time) => {
  202. var array = JSON.parse(JSON.stringify(list))
  203. array.map(item => {
  204. if ((item.id && item.id == obj.id) || (!item.id && item.title == obj.title)) {
  205. item.time = time
  206. item.op_ms = new Date().getTime()
  207. }
  208. })
  209. dispatch(setSchedules(array))
  210. check(array)
  211. }}
  212. />
  213. })
  214. }
  215. <View className='item_add'
  216. onClick={() => add()}>
  217. <StatusIndicator type={StatusType.img} text={t('health.add_meal')}
  218. space={rpxToPx(12)}
  219. color={MainColorType.eat} fontColor={MainColorType.eat} fontSize={rpxToPx(34)} >
  220. <IconAdd color="#fff" width={rpxToPx(20)} />
  221. </StatusIndicator>
  222. <View style={{ flex: 1 }} />
  223. </View>
  224. </Card>
  225. }
  226. function fastSleepItems() {
  227. var items = list.filter(item => item.window == 'FAST')
  228. return <Card>
  229. {
  230. items.map((obj, i) => {
  231. return <ScheduleItem
  232. index={i}
  233. count={items.length}
  234. key={i * 100}
  235. obj={obj}
  236. highlight={false}
  237. showLine={i < items.length - 1}
  238. errors={errors}
  239. selMode={selMode}
  240. disable={isDisable(obj)}
  241. gray={isDisable(obj)}
  242. days={obj.plus_days != 0 ? obj.plus_days : null}
  243. hideReminderIcon={true}
  244. onDelete={() => {
  245. var array = JSON.parse(JSON.stringify(list))
  246. for (var j = 0; j < array.length; j++) {
  247. if (array[j].id == obj.id) {
  248. array.splice(j, 1)
  249. }
  250. }
  251. setList(array)
  252. check(array)
  253. global.refreshWindow()
  254. }}
  255. onChange={(time) => {
  256. var array = JSON.parse(JSON.stringify(list))
  257. array.map(item => {
  258. if ((item.id && item.id == obj.id) || (!item.id && item.title == obj.title)) {
  259. item.time = time
  260. item.op_ms = new Date().getTime()
  261. }
  262. })
  263. setList(array)
  264. check(array)
  265. }}
  266. />
  267. })
  268. }
  269. </Card>
  270. }
  271. return <View style={{ flex: 1, display: 'flex', flexDirection: 'column', height: '100vh' }}>
  272. <View style={{ height: navigationBarHeight, backgroundColor: MainColorType.g05, flexShrink: 0 }} />
  273. <View className="navi-bar" style={{ height: navigationBarHeight, zIndex: 1000, backgroundColor: MainColorType.g05 }}>
  274. <View style={{
  275. position: 'absolute',
  276. left: 0,
  277. right: 0,
  278. bottom: 0,
  279. height: 44,
  280. display: 'flex',
  281. alignItems: 'center',
  282. justifyContent: 'center'
  283. }}>
  284. <Image src={require('@assets/_health/navi_back.png')} style={{
  285. position: 'absolute',
  286. width: rpxToPx(92),
  287. height: rpxToPx(64),
  288. left: 0,
  289. top: 22 - rpxToPx(32)
  290. }}
  291. onClick={() => {
  292. Taro.navigateBack()
  293. }}
  294. />
  295. <Image src={user.avatar} mode="aspectFill" style={{
  296. background: user.isLogin ? 'transparent' : '#fff',
  297. width: rpxToPx(64),
  298. height: rpxToPx(64),
  299. borderRadius: rpxToPx(32)
  300. }} />
  301. </View>
  302. </View>
  303. <NewHeader type={NewHeaderType.center_subtitle} title={t('health.guide_2_title')} subtitle={t('health.guide_2_desc')} />
  304. {
  305. items()
  306. }
  307. <CellFooter type={CellFooterType.left}>
  308. <View style={{ display: 'flex', flexDirection: 'column' }}>
  309. <CellFooterText text={footerTitle()} isBold />
  310. <CellFooterText text={footerDesc()} />
  311. </View>
  312. </CellFooter>
  313. <View style={{ height: 20, flexShrink: 0 }} />
  314. {
  315. fastSleepItems()
  316. }
  317. <View style={{ height: 300, flexShrink: 0 }} />
  318. <View style={{ flex: 1 }} />
  319. <View className="main_footer">
  320. <NewButton
  321. type={NewButtonType.fill}
  322. title="下一步"
  323. disable={errors.length > 0}
  324. color={MainColorType.eat}
  325. width={rpxToPx(646)}
  326. height={rpxToPx(96)}
  327. onClick={() => {
  328. check(list, true)
  329. }}
  330. />
  331. </View>
  332. {
  333. showModal && <AddLabel labels={labels}
  334. window='EAT'
  335. op_page='SCHEDULE_WALKTHROUGH_3'
  336. disMiss={() => setShowModal(false)}
  337. onlyCheck={true}
  338. schedules={list}
  339. confirm={(res) => {
  340. setShowModal(false)
  341. if ((res as any).result) {
  342. dispatch(setSchedules((res as any).schedules))
  343. dispatch(setFooter((res as any).footer))
  344. setList((res as any).schedules)
  345. setErrors([])
  346. }
  347. else {
  348. setList((res as any).schedules)
  349. dispatch(setFooter((res as any).footer))
  350. setErrors((res as any).error_messages ? (res as any).error_messages : [])
  351. }
  352. }}
  353. color={MainColorType.eat} />
  354. }
  355. {/* {
  356. showModal && <Modal testInfo={null}
  357. dismiss={() => {
  358. setShowModal(false)
  359. }}
  360. confirm={() => { }}>
  361. <AddLabel labels={labels}
  362. window='EAT'
  363. disMiss={() => setShowModal(false)}
  364. onlyCheck={true}
  365. schedules={list}
  366. confirm={(res) => {
  367. if ((res as any).result) {
  368. dispatch(setSchedules((res as any).schedules))
  369. dispatch(setFooter((res as any).footer))
  370. setList((res as any).schedules)
  371. setErrors([])
  372. }
  373. else {
  374. setList((res as any).schedules)
  375. dispatch(setFooter((res as any).footer))
  376. setErrors((res as any).error_messages ? (res as any).error_messages : [])
  377. }
  378. }}
  379. color={MainColorType.eat} />
  380. </Modal>
  381. } */}
  382. </View>
  383. }