fast_sleep_console.tsx 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. import { View, Text, Image } from "@tarojs/components";
  2. import './fast_sleep_console.scss'
  3. import { rpxToPx } from "@/utils/tools";
  4. import NewButton, { NewButtonType } from "../base/new_button";
  5. import { getThemeColor } from "@/features/health/hooks/health_hooks";
  6. import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
  7. import dayjs from "dayjs";
  8. import { MainColorType } from "@/context/themes/color";
  9. import showAlert from "@/components/basic/Alert";
  10. import { IconArrow, IconCellArrow, IconCircle, IconError, IconNotification, IconNotificationOff } from "@/components/basic/Icons";
  11. import { useSelector } from "react-redux";
  12. import { delRecord } from "@/services/health";
  13. import { TimeFormatter } from "@/utils/time_format";
  14. import showActionSheet from "@/components/basic/ActionSheet";
  15. import { useTranslation } from "react-i18next";
  16. import ConsoleCell from "./console_cell";
  17. import StatusIndicator, { StatusType } from "../base/status_indicator";
  18. export default function FastSleepConsole(props: { step: number, data: any, del: any }) {
  19. const health = useSelector((state: any) => state.health);
  20. let navigation, showActionSheetWithOptions;
  21. const { t } = useTranslation()
  22. function tapLogBtn(index: number) {
  23. const { fast, sleep, status } = props.data
  24. var single = 0;
  25. var is_start = 0;
  26. var window = 'FAST'
  27. switch (index) {
  28. case 0:
  29. {
  30. single = 1;
  31. is_start = 1;
  32. }
  33. break;
  34. case 1:
  35. {
  36. if (status == 'OG1') {
  37. single = 1;
  38. is_start = 1;
  39. window = 'SLEEP'
  40. }
  41. else {
  42. single = 0;
  43. }
  44. }
  45. break;
  46. case 2:
  47. {
  48. if (status == 'OG2') {
  49. single = 1;
  50. is_start = 0;
  51. window = 'SLEEP'
  52. }
  53. else {
  54. single = 0;
  55. }
  56. }
  57. break;
  58. case 3:
  59. {
  60. if (status == 'OG3') {
  61. single = 1;
  62. is_start = 0;
  63. window = 'FAST'
  64. }
  65. else {
  66. single = 0;
  67. }
  68. }
  69. break;
  70. }
  71. jumpPage(`/_health/pages/log_time?is_fast_with_sleep=1&index=${index}&initCheck=${health.fast_with_sleep.status == 'OG2_MISALIGNED' ? 1 : 0}&single=${index == 0 ? 1 : 0}&is_start=${is_start}&window=${window}`)
  72. /*
  73. const isSingle = router.params.single == '1'
  74. const isFast = router.params.window == 'FAST'
  75. const isStart = router.params.is_start == '1'
  76. */
  77. }
  78. function goDetail(index) {
  79. if (index == 0 && props.data.fast.status == 'OG') {
  80. const { event_id, schedule_id } = props.data.fast.timeline[0]
  81. jumpPage(`/_health/pages/timeline_detail?event_id=${event_id}&schedule_id=${schedule_id}`)
  82. }
  83. else if (index == 1 && (props.data.sleep.status == 'OG' || props.data.status == 'OG3')) {
  84. const { event_id, schedule_id } = props.data.sleep.timeline[0]
  85. jumpPage(`/_health/pages/timeline_detail?event_id=${event_id}&schedule_id=${schedule_id}`)
  86. }
  87. }
  88. function itemDisableStatus(index) {
  89. if (index == 0 && props.data.fast.status == 'OG') {
  90. return false
  91. }
  92. else if (index == 1 && (props.data.sleep.status == 'OG' || props.data.status == 'OG3')) {
  93. return false
  94. }
  95. return true
  96. }
  97. function delConfirm() {
  98. const { fast, sleep } = props.data
  99. let array: any = []
  100. if (fast.window_id) {
  101. array.push(fast.window_id)
  102. }
  103. if (sleep.window_id) {
  104. array.push(sleep.window_id)
  105. }
  106. showAlert({
  107. title: 'del',
  108. content: '确认删除此记录?',
  109. showCancel: true,
  110. confirm: () => {
  111. delRecord(array[0], { ids: array }).then(res => {
  112. global.refreshWindow()
  113. props.del()
  114. })
  115. }
  116. })
  117. }
  118. function getIconColor(index: number, finish: boolean) {
  119. const { fast, sleep } = props.data
  120. // if (new Date().getTime() <= fast.target.start_timestamp && health.fast_with_sleep.status == 'WFS') {
  121. // return MainColorType.g03
  122. // }
  123. switch (index) {
  124. case 0:
  125. if (!fast.timeline[0].real) {
  126. return MainColorType.g02
  127. }
  128. break
  129. case 1:
  130. if (!sleep.timeline[0].real) {
  131. return MainColorType.g02
  132. }
  133. break
  134. case 2:
  135. if (!sleep.timeline[1].real) {
  136. return MainColorType.g02
  137. }
  138. break
  139. case 3:
  140. if (!fast.timeline[1].real) {
  141. return MainColorType.g02
  142. }
  143. break
  144. }
  145. var color = MainColorType.g02
  146. if (index == 1 || index == 2) {
  147. color = MainColorType.sleep
  148. }
  149. else {
  150. color = MainColorType.fast
  151. }
  152. return color;
  153. }
  154. function processIcon(item, finish, isError) {
  155. if (isError) {
  156. return <IconError color="#fff" width={rpxToPx(24)} />
  157. }
  158. if (finish) {
  159. return <Image style={{ width: rpxToPx(24), height: rpxToPx(24) }} src={require('@assets/_health/checked.png')} />
  160. }
  161. return <IconCircle width={rpxToPx(32)} color={MainColorType.g02}/>
  162. // return <View style={{ width: rpxToPx(26), height: rpxToPx(26), borderRadius: rpxToPx(13), backgroundColor: '#fff' }} />
  163. // if (item.timeline.reminder) {
  164. // return <IconNotification color="#fff" width={rpxToPx(24)} />
  165. // }
  166. // return <IconNotificationOff color="#fff" width={rpxToPx(24)} />
  167. }
  168. function actionList() {
  169. var list: any = []
  170. if (!health.finish_setup) {
  171. list.push(t('health.finish_setup'))
  172. }
  173. if (props.data.status != 'WFS') {
  174. list.push(t('health.delete_current_record'))
  175. }
  176. if (health.finish_setup) {
  177. list.push(t('health.edit_schedule'))
  178. }
  179. return list
  180. }
  181. function showAction() {
  182. showActionSheet({
  183. showActionSheetWithOptions: showActionSheetWithOptions,
  184. title: t('health.more_actions'),
  185. itemList: actionList(),
  186. success: (res) => {
  187. tapActionSheet(res)
  188. }
  189. });
  190. }
  191. function tapActionSheet(index) {
  192. var title = actionList()[index]
  193. switch (title) {
  194. case t('health.finish_setup'):
  195. jumpPage('/_health/pages/guide_begin')
  196. break;
  197. case t('health.delete_current_record'):
  198. delConfirm()
  199. break;
  200. case t('health.edit_schedule'):
  201. jumpPage('/_health/pages/schedules?mode=FAST&isFastSleep=1')
  202. break
  203. }
  204. }
  205. function timelineItem(item: any, index: number, count: number) {
  206. const { fast, sleep, status } = props.data
  207. var showBtn = true;
  208. var time = ''
  209. var hasDescription = item.moment && item.moment.description
  210. var finish = false;
  211. switch (index) {
  212. case 0:
  213. {
  214. if (status == 'OG2_NO1' || status == 'WFS') {
  215. showBtn = true
  216. }
  217. else {
  218. showBtn = false;
  219. finish = true;
  220. }
  221. time = TimeFormatter.dayjsFormat(fast.target.start_timestamp)//dayjs(fast.target.start_timestamp).format('MM-DD HH:mm')
  222. }
  223. break;
  224. case 1:
  225. {
  226. if (status == 'WFS' || status == 'OG1') {
  227. showBtn = true
  228. }
  229. else {
  230. showBtn = false
  231. finish = true;
  232. }
  233. if (status == 'OG3') {
  234. time = TimeFormatter.dayjsFormat(sleep.real.start_timestamp)//dayjs(sleep.real.start_timestamp).format('MM-DD HH:mm')
  235. }
  236. else {
  237. time = TimeFormatter.dayjsFormat(sleep.target.start_timestamp)//dayjs(sleep.target.start_timestamp).format('MM-DD HH:mm')
  238. }
  239. }
  240. break;
  241. case 2:
  242. {
  243. if (status == 'OG3') {
  244. showBtn = false
  245. finish = true;
  246. time = TimeFormatter.dayjsFormat(sleep.real.end_timestamp)//dayjs(sleep.real.end_timestamp).format('MM-DD HH:mm')
  247. }
  248. else {
  249. showBtn = true
  250. time = TimeFormatter.dayjsFormat(sleep.target.end_timestamp)//dayjs(sleep.target.end_timestamp).format('MM-DD HH:mm')
  251. }
  252. }
  253. break;
  254. case 3:
  255. {
  256. showBtn = true
  257. time = TimeFormatter.dayjsFormat(fast.target.end_timestamp)//dayjs(fast.target.end_timestamp).format('MM-DD HH:mm')
  258. }
  259. break;
  260. }
  261. var isError = false;
  262. if (health.fast_with_sleep.status == 'OG2_MISALIGNED' && (index == 0 || index == 1)) {
  263. isError = true;
  264. }
  265. function rightView() {
  266. if (isError) {
  267. return <View style={{
  268. borderColor: MainColorType.error,
  269. borderWidth: rpxToPx(2),
  270. borderRadius: rpxToPx(76 / 4),
  271. borderStyle: 'solid'
  272. }}>
  273. <NewButton
  274. type={NewButtonType.gray}
  275. title='Correct'
  276. // fontSize={rpxToPx(34)}
  277. width={rpxToPx(128)}
  278. height={rpxToPx(72)}
  279. onClick={() => {
  280. jumpPage(`/_health/pages/log_time?is_fast_with_sleep=1&index=${1}&single=0&initCheck=1&initIndex=${index}`)
  281. }}
  282. />
  283. </View>
  284. }
  285. else {
  286. // let themeColor: any = getThemeColor(health.mode)
  287. // if (item.target.timestamp >= new Date().getTime()) {
  288. // themeColor = MainColorType.g02
  289. // }
  290. if (item.timeline.action && item.timeline.action != 'NA') {
  291. if (item.timeline.action == 'POST_MOMENT') {
  292. return <IconArrow width={rpxToPx(34)} color={MainColorType.g03} />
  293. }
  294. return <NewButton
  295. color={item.timeline.target.timestamp >= new Date().getTime() ? MainColorType.g02 : getThemeColor(item.mode)}
  296. type={item.timeline.target.timestamp >= new Date().getTime() ? NewButtonType.alpha2 : NewButtonType.alpha}
  297. title={t('health.log')}
  298. width={rpxToPx(128)}
  299. height={rpxToPx(72)}
  300. bold={true}
  301. onClick={() => {
  302. tapLogBtn(index)
  303. }} />
  304. }
  305. if (item.timeline.action && item.timeline.action == 'NA') {
  306. // if (health.mode == 'FAST' || health.mode == 'SLEEP') {
  307. if (item.moment && item.moment.media && item.moment.media.length > 0) {
  308. return <Image
  309. src={item.moment.media[0].url}
  310. mode="aspectFill"
  311. className="console_item_img" />
  312. }
  313. else {
  314. return <IconArrow width={rpxToPx(34)} color={MainColorType.g03} />
  315. }
  316. // }
  317. }
  318. return <View />
  319. // if (item.timeline.action == 'POST_MOMENT'){
  320. // return <IconArrow color={MainColorType.g03} width={rpxToPx(34)} />
  321. // }
  322. // if (item.moment && item.moment.media && item.moment.media.length > 0)
  323. // return <Image
  324. // src={item.moment.media[0].url}
  325. // mode="aspectFill"
  326. // className="console_item_img" />
  327. // if (showBtn)
  328. // return <NewButton
  329. // color={item.timeline.target.timestamp >= new Date().getTime() ? MainColorType.link : getThemeColor(item.mode)}
  330. // type={item.timeline.target.timestamp >= new Date().getTime() ? NewButtonType.alpha2 : NewButtonType.alpha}
  331. // title={'Log'}
  332. // width={rpxToPx(128)}
  333. // height={rpxToPx(72)}
  334. // bold={true}
  335. // onClick={() => {
  336. // tapLogBtn(index)
  337. // }} />
  338. }
  339. }
  340. return <ConsoleCell
  341. status={
  342. <StatusIndicator type={StatusType.console}
  343. color={isError ? MainColorType.error : getIconColor(index, finish)==MainColorType.g02?'transparent':getIconColor(index, finish)}
  344. fontColor={isError ? MainColorType.error : getIconColor(index, finish)==MainColorType.g02?MainColorType.g01:getIconColor(index, finish)}
  345. bold={getIconColor(index, finish)!=MainColorType.g02}
  346. fontSize={rpxToPx(24)}
  347. text={time}
  348. >{
  349. processIcon(item, finish, isError)
  350. }</StatusIndicator>
  351. }
  352. title={(item.moment && item.moment.title) ? item.moment.title : item.title}
  353. description={hasDescription ? item.moment.description : null}
  354. disable={itemDisableStatus(index)}
  355. onClick={() => {
  356. goDetail(index)
  357. }}
  358. right={rightView()}
  359. showLine={true}
  360. fullLine={count - 1 == index}
  361. />
  362. }
  363. return <View style={{ backgroundColor: '#fff' }}>
  364. {
  365. health.fast_with_sleep.status == 'OG2_MISALIGNED' && <View className="error_bg" >
  366. <View className="error_icon_bg">
  367. <Image src={require('@assets/_health/tip_error.png')} style={{ width: rpxToPx(26), height: rpxToPx(26) }} />
  368. </View>
  369. <Text className="h24" style={{ lineHeight: rpxToPx(36) + 'px' }}>Logged times are not in their proper order</Text>
  370. </View>
  371. }
  372. {
  373. props.step != 2 && props.step != 3 && timelineItem({
  374. title: props.data.fast.timeline[0].title,
  375. mode: 'FAST',
  376. is_start: true,
  377. action: props.data.fast.timeline[0].action,
  378. moment: props.data.fast.timeline[0].moment,
  379. timeline: props.data.fast.timeline[0]
  380. }, 0, 4)
  381. }
  382. {
  383. props.step != 3 && timelineItem({
  384. title: props.data.sleep.timeline[0].title,
  385. mode: 'SLEEP',
  386. is_start: true,
  387. action: props.data.fast.timeline[0].action,
  388. moment: props.data.sleep.timeline[0].moment,
  389. timeline: props.data.sleep.timeline[0]
  390. }, 1, 4)
  391. }
  392. {
  393. props.step != 1 && timelineItem({
  394. title: props.data.sleep.timeline[1].title,
  395. mode: 'SLEEP',
  396. is_start: false,
  397. moment: props.data.sleep.timeline[1].moment,
  398. timeline: props.data.sleep.timeline[1]
  399. }, 2, 4)
  400. }
  401. {
  402. props.step != 1 && props.step != 2 && timelineItem({
  403. title: props.data.fast.timeline[1].title,
  404. mode: 'FAST',
  405. is_start: false,
  406. moment: props.data.fast.timeline[1].moment,
  407. timeline: props.data.fast.timeline[1]
  408. }, 3, 4)
  409. }
  410. {
  411. <View className="main_console_footer">
  412. <NewButton
  413. btnStyle={{
  414. position: 'absolute',
  415. top: rpxToPx(42),
  416. right: rpxToPx(40)
  417. }}
  418. type={NewButtonType.more}
  419. onClick={showAction}
  420. />
  421. </View>
  422. }
  423. </View>
  424. }