Leon 2 years ago
parent
commit
17f44d3250

BIN
src/assets/images/arrow2.png


BIN
src/assets/images/check.png


BIN
src/assets/images/timeline_done.png


BIN
src/assets/images/timeline_pedding.png


BIN
src/assets/images/timeline_undone.png


BIN
src/assets/images/x.png


+ 7 - 0
src/components/basic/CheckBox.scss

@@ -0,0 +1,7 @@
+.checkbox {
+    border-color: #fff;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    box-sizing: border-box;
+}

+ 41 - 0
src/components/basic/CheckBox.tsx

@@ -0,0 +1,41 @@
+import { CheckBoxType } from "@/utils/types";
+import { View, Image } from "@tarojs/components";
+import './CheckBox.scss'
+
+
+export default function Component(props: {
+    type: CheckBoxType,
+    width?: number,
+    borderWidth?: number,
+    opacity?: number,
+    onClick?: Function
+}) {
+    var outerWidth = props.width ? props.width : 16
+    var iconBorderWidth = props.borderWidth ? props.borderWidth : 1
+    var innerWidth = outerWidth * 3 / 4
+    var alpha = props.opacity ? props.opacity : 1
+
+
+    return <View className="checkbox" style={{
+        opacity: alpha,
+        borderWidth: iconBorderWidth,
+        width: outerWidth,
+        height: outerWidth,
+        borderRadius: outerWidth / 2.0,
+        borderStyle: 'solid',
+        backgroundColor: props.type == CheckBoxType.empty ? 'transparent' : 'rgba(255,255,255,0.4)'
+    }}>
+        {
+            props.type == CheckBoxType.cross &&
+            <Image src={require('@assets/images/x.png')} style={{ width: innerWidth, height: innerWidth }} />
+        }
+        {
+            props.type == CheckBoxType.check &&
+            <Image src={require('@assets/images/check.png')} style={{ width: innerWidth, height: innerWidth }} />
+        }
+        {
+            props.type == CheckBoxType.arrow &&
+            <Image src={require('@assets/images/arrow2.png')} style={{ width: innerWidth, height: innerWidth }} />
+        }
+    </View>
+}

+ 36 - 0
src/components/navigation/Segment.scss

@@ -0,0 +1,36 @@
+
+.segment{
+    background-color: #979797;
+    height: 60px;
+    border-radius: 16px;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    padding: 4px;
+    box-sizing: border-box;
+
+}
+
+.segment_item{
+    height: 52px;
+    border-radius: 16px;
+    min-width: 164px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.segment_item_sel{
+    background-color: #fff;
+}
+
+.segment_text_sel{
+    font-size: 32px;
+    font-weight: 500;
+    color: #000;
+}
+
+.segment_text{
+    font-size: 32px;
+    color: #000;
+}

+ 27 - 0
src/components/navigation/Segment.tsx

@@ -0,0 +1,27 @@
+import { View, Text } from '@tarojs/components'
+import './Segment.scss'
+import { useState } from 'react'
+
+export default function Component(props: {
+    index?: number,
+    titles: Array<string>,
+    changed: Function
+}) {
+    const [current, setCurrent] = useState(props.index ? props.index : 0)
+
+
+    function selItem(index) {
+        setCurrent(index);
+        props.changed(index);
+    }
+
+    return <View className='segment'>
+        <View className={current == 0 ? 'segment_item segment_item_sel' : 'segment_item'} onClick={() => { selItem(0) }}>
+            <Text className={current == 0 ? 'segment_text_sel' : 'segment_text'}>{props.titles[0]}</Text>
+        </View>
+        <View style={{ width: 16 }} />
+        <View className={current == 1 ? 'segment_item segment_item_sel' : 'segment_item'} onClick={() => { selItem(1) }}>
+            <Text className={current == 1 ? 'segment_text_sel' : 'segment_text'}>{props.titles[1]}</Text>
+        </View>
+    </View>
+}

+ 85 - 64
src/components/view/Timeline.scss

@@ -1,65 +1,86 @@
 .timeline {
-    display: flex;
-    flex-direction: column;
-    color: #fff;
-    width: 100%;
-  }
-  
-  .timeline-item {
-    display: flex;
-    // align-items: center;
-    margin-bottom: 20px;
-    position: relative;
-  }
-  
-  .timeline-icon {
-    width: 20px;
-    height: 20px;
-    border-radius: 50%;
-    margin-right: 10px;
-  }
-  
-  .padding {
-    background-color: #ccc;
-  }
-  
-  .done {
-    background-color: green;
-  }
-  
-  .un_done {
-    background-color: red;
-  }
-  
-  .timeline-line {
-    width: 2px;
-    background-color: #FFFFFF66;
-    position: absolute;
-    top: 25px;
-    left: 10px;
-    bottom: -15px;
-    
-  }
-
-  .dash{
-    background-color: transparent;
-    border-left-style: dashed;
-    border-left-color: #FFFFFF66;
-    border-left-width: 2px;
-  }
-
-
-  
-  .timeline-content {
-    display: flex;
-    flex-direction: column;
-    color: #fff;
-  }
-  
-  .timeline-text {
-    margin-bottom: 5px;
-  }
-  
-  .timeline-time {
-    color: #999;
-  }
+  display: flex;
+  flex-direction: column;
+  color: #fff;
+  // width: 100%;
+  // margin-top: 20px;
+  // background-color: aqua;
+}
+
+.timeline-item {
+  display: flex;
+  // align-items: center;
+  margin-bottom: 20px;
+  position: relative;
+}
+
+.timeline-icon {
+  width: 20px;
+  height: 20px;
+  border-radius: 50%;
+  margin-right: 10px;
+}
+
+.padding {
+  background-color: #ccc;
+}
+
+.done {
+  background-color: green;
+}
+
+.un_done {
+  background-color: red;
+}
+
+
+
+
+
+.timeline-content {
+  display: flex;
+  flex-direction: column;
+  color: #fff;
+}
+
+.timeline-text {
+  margin-bottom: 5px;
+}
+
+.timeline-time {
+  color: #999;
+}
+
+.timeline-content-row {
+  margin-left: 20px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  width: 406px;
+  // justify-content: space-between;
+  padding-bottom: 16px;
+  border-bottom-style: solid;
+  border-bottom-color: rgba(255, 255, 255, 0.1);
+  border-bottom-width: 1px;
+}
+
+.timeline-icon-bg{
+  margin-top: 6px;
+}
+
+.timeline-line {
+  width: 2px;
+  background-color: #FFFFFF66;
+  position: absolute;
+  top: 50px;
+  left: 14px;
+  bottom: -15px;
+
+}
+
+.dash {
+  background-color: transparent;
+  border-left-style: dashed;
+  border-left-color: #FFFFFF66;
+  border-left-width: 2px;
+}

+ 27 - 7
src/components/view/Timeline.tsx

@@ -1,5 +1,7 @@
 import { View, Image, Text } from '@tarojs/components'
 import './Timeline.scss'
+import { CheckBoxType, TimelineType } from '@/utils/types'
+import CheckBox from '../basic/CheckBox'
 
 // interface TimelineItem {
 //     status: 'padding' | 'done' | 'not_done';
@@ -8,19 +10,37 @@ import './Timeline.scss'
 // }
 
 
-export default function Component(props: { items: any[], title?: string }) {
+export default function Component(props: { items: any[], title?: string, type?: TimelineType }) {
     return <View className="timeline">
         {
             props.title && <Text>{props.title}</Text>
         }
         {props.items.map((item, index) => (
-            <View className="timeline-item" key={index}>
-                <View className={`timeline-icon ${item.status}`} />
-                {index !== props.items.length - 1 && <View className={(props.items[index + 1].status == 'done' && item.status == 'done') ? 'timeline-line' : 'timeline-line dash'} />}
-                <View className="timeline-content">
-                    <View className="timeline-text">{item.title}</View>
-                    <View className="timeline-time">{item.content}</View>
+            <View className="timeline-item" style={{marginBottom:index !== props.items.length - 1 ?10:0}} key={index}>
+                <View className='timeline-icon-bg'>
+                {
+                    item.status == 'padding' && <CheckBox type={CheckBoxType.empty} opacity={0.4} />
+                }
+                {
+                    item.status == 'done' && <CheckBox type={CheckBoxType.check} opacity={0.4} />
+                }
+                {
+                    item.status == 'un_done' && <CheckBox type={CheckBoxType.cross} opacity={0.4} />
+                }
                 </View>
+                {index !== props.items.length - 1 && <View className={(props.items[index + 1].status == 'done' && item.status == 'done') ? 'timeline-line' : 'timeline-line dash'} />}
+                {
+                    props.type == TimelineType.timeMutiLine ?
+                        <View className="timeline-content">
+                            <View className="timeline-text">{item.title}</View>
+                            <View className="timeline-time">{item.content}</View>
+                        </View> :
+                        <View className="timeline-content-row" style={{ marginBottom: index !== props.items.length - 1 ? 32 : 0 }}>
+                            <View className="timeline-text">{props.type == TimelineType.timeSecond ? item.title : item.content}</View>
+                            <View style={{ flex: 1 }} />
+                            <View className="timeline-text">{props.type == TimelineType.timeSecond ? item.content : item.title}</View>
+                        </View>
+                }
             </View>
         ))}
     </View>

+ 46 - 4
src/features/trackTimeDuration/components/RecordFastSleep.tsx

@@ -12,9 +12,12 @@ import { TimeFormatter } from "@/utils/time_format";
 import './RecordFastSleep.scss'
 import { getBgRing, getCommon, getDot, getReal, getTarget } from "../hooks/RingData";
 import Rings from "./Rings";
+import Segment from "@/components/navigation/Segment";
+import Stage from "./Stage";
 
 export default function RecordFastSleep(props: { data: any, type: string, delSuccess?: Function }) {
     const [showDetailModal, setShowDetailModal] = useState(false)
+    const [segmentIndex, setSegmentIndex] = useState(0)
     const canvasId = props.data.id
     const record = props.data;
     function header() {
@@ -40,11 +43,50 @@ export default function RecordFastSleep(props: { data: any, type: string, delSuc
     }
 
     function schedules() {
-        return <TimelineFastSleep data={props.data} title="Timeline" />
+        return <View style={{ display: 'flex', flexDirection: 'column' }}>
+
+            {
+                props.data.scenario != 'FAST_SLEEP' &&
+                <Text style={{
+                    marginBottom: 10,
+                    color: '#fff', fontWeight: 'bold', fontSize: 18
+                }}>Timeline</Text>
+            }
+            <View style={{
+                marginTop: 10,
+                display: 'flex', alignItems: 'center',
+                flexDirection: 'column', justifyContent: 'center', width: '100%'
+            }}>
+                {
+                    props.data.scenario == 'FAST_SLEEP' &&
+                    <View style={{ marginBottom: 20 }}>
+                        <Segment titles={['Timeline', 'Stage']} changed={(e) => {
+                            setSegmentIndex(e);
+                            global.segmentIndex = e
+                            console.log(e)
+                        }} />
+                    </View>
+                }
+                <View style={{ position: 'relative' }}>
+                    <View style={{ opacity: global.segmentIndex == 0 ? 1 : 0 }}>
+                        <TimelineFastSleep data={props.data} />
+                    </View>
+                    <View style={{
+                        position: 'absolute', left: 0, top: 0, right: 0, bottom: 0,
+                        opacity: global.segmentIndex == 1 ? 1 : 0
+                    }}>
+                        <Stage data={props.data} />
+                    </View>
+
+                </View>
+            </View>
+        </View>
     }
 
     function showDetail() {
         if (props.type == 'latest') {
+            setSegmentIndex(0)
+            global.segmentIndex = 0
             setShowDetailModal(true)
             return;
         }
@@ -161,14 +203,14 @@ export default function RecordFastSleep(props: { data: any, type: string, delSuc
         if (record.scenario == 'FAST_SLEEP') {
             fastDuration = getDuration(record.fast)
             sleepDuration = getDuration(record.sleep)
-            if (record.status == 'ONGOING3'){
+            if (record.status == 'ONGOING3') {
                 fastDuration = '待结束'
             }
 
-            if (record.sleep.status ==  "NOT_STARTED"){
+            if (record.sleep.status == "NOT_STARTED") {
                 sleepDuration = '未开始'
             }
-            else if (record.sleep.status == 'NOT_COMPLETED'){
+            else if (record.sleep.status == 'NOT_COMPLETED') {
                 sleepDuration = '未完成'
             }
             showFast = true

+ 8 - 1
src/features/trackTimeDuration/components/Schedule.tsx

@@ -12,6 +12,7 @@ import { TimeFormatter } from "@/utils/time_format";
 import Buttons from "@/components/basic/Buttons";
 import { ButtonType } from "@/utils/types";
 import { setStep } from "@/store/scenario";
+import Segment from "@/components/navigation/Segment";
 
 
 export default function Component(props: { type?: string, data?: any, delSuccess?: Function }) {
@@ -149,7 +150,13 @@ export default function Component(props: { type?: string, data?: any, delSuccess
             </View >
         }
 
-        return <TimelineFastSleep data={props.data} />
+        return <View style={{marginTop:10}}>
+            
+            <TimelineFastSleep data={props.data} />
+            <View>
+                <Text>show detail</Text>
+            </View>
+        </View>
     }
 
     function detailFooter() {

+ 0 - 8
src/features/trackTimeDuration/components/SetSchedule.tsx

@@ -4,13 +4,10 @@ import { setScenario, setStep } from "@/store/scenario";
 import { View, Text } from "@tarojs/components";
 import "./SetSchedule.scss";
 import Taro, { useReady } from "@tarojs/taro";
-import TimePickers from "@/components/input/TimePickers";
-// import { AtList, AtListItem } from 'taro-ui'
 import { useRef, useState } from "react";
 import { useDispatch, useSelector } from "react-redux";
 import Footer from "@/components/layout/Footer";
 import PickerViews from "@/components/input/PickerViews";
-// import "taro-ui/dist/style/components/float-layout.scss";
 import { durationDatas, durationIndex, durationTime, pickerDurations } from "../hooks/Console";
 import { TimeFormatter } from "@/utils/time_format";
 import Modal from "@/components/layout/Modal";
@@ -161,8 +158,6 @@ export default function Component() {
         }, sleep: {
           start_time: !isFastFirst ? scenario.schedule.sleep.start_time : startTime,
           end_time: !isFastFirst ? scenario.schedule.sleep.end_time : endTime,
-          // start_time: startTime,
-          // end_time: endTime,
         }
       }
     }).then(res => {
@@ -270,9 +265,6 @@ export default function Component() {
 
   function timeContent() {
     return <TimePicker time={chooseStart ? startTime : endTime} confirm={chooseStart ? onStartTimeChange : onEndTimeChange} cancel={() => { setIsTimeOpen(false) }} />
-    // return <View style={{ color: '#fff', backgroundColor: 'transparent' }}>
-    //     <PickerViews  onChange={durationChange} items={durationDatas(common)} value={isFast ? fastPickerValue : sleepPickerValue} showBtns={true} onCancel={() => { setIsOpenDurationPicker(false) }} />
-    // </View>
   }
 
   return <View >

+ 55 - 0
src/features/trackTimeDuration/components/Stage.scss

@@ -0,0 +1,55 @@
+.stage {
+    display: flex;
+    flex-direction: column;
+}
+
+.stage_item {
+    display: flex;
+    flex-direction: row;
+    height: 80px;
+    width: 500px;
+    box-sizing: border-box;
+    border-bottom-style: solid;
+    border-bottom-color: rgba(255, 255, 255, 0.1);
+    border-bottom-width: 1px;
+    align-items: center;
+}
+
+.stage_step {
+    font-size: 28px;
+    font-weight: 400px;
+    color: rgba(255, 255, 255, 0.2);
+    height: 48px;
+    line-height: 48px;
+    padding-right: 24px;
+}
+
+.stage_step_border {
+    border-right-style: dashed;
+    border-right-color: #FFFFFF66;
+    border-right-width: 2px;
+}
+
+.stage_step_border_ing{
+    border-right-style: solid;
+    border-right-color: #AAFF00;
+    border-right-width: 2px;
+}
+
+.stage_title {
+    margin-left: 20px;
+    font-size: 28px;
+    font-weight: 400;
+    height: 48px;
+    line-height: 48px;
+    color: rgba(255, 255, 255, 0.8);
+    flex: 1;
+}
+
+.stage_value {
+    font-size: 28px;
+    font-weight: 400;
+    height: 48px;
+    line-height: 48px;
+    color: rgba(255, 255, 255, 0.8);
+}

+ 80 - 0
src/features/trackTimeDuration/components/Stage.tsx

@@ -0,0 +1,80 @@
+import { View, Text } from "@tarojs/components";
+import './Stage.scss'
+import { TimeFormatter } from "@/utils/time_format";
+
+export default function Component(props: { data: any }) {
+    function getTime(t1: number, t2: number) {
+        return TimeFormatter.calculateTimeDifference(t1, t2)
+    }
+
+    function getStepATime(obj) {
+        if (obj.status == 'COMPLETED' && obj.sleep.status == 'NOT_STARTED') {
+            return '未知'
+        }
+        return obj.status == 'ONGOING1' ?
+            getTime(obj.fast.real_start_time, (new Date()).getTime()) :
+            obj.sleep.real_start_time ? getTime(obj.sleep.real_start_time, obj.fast.real_start_time ? obj.fast.real_start_time : obj.fast.target_start_time) :
+                getTime(obj.sleep.target_start_time, obj.fast.real_start_time ? obj.fast.real_start_time : obj.fast.target_start_time)
+    }
+
+    function getStepBTime(obj) {
+        if (obj.status == 'ONGOING1') return 'Next up'
+        if (obj.status == 'ONGOING2') return getTime(obj.sleep.real_start_time, (new Date()).getTime())
+        if (obj.status == 'WAIT_FOR_START') return getTime(obj.sleep.target_end_time, obj.sleep.target_start_time)
+        if (obj.sleep.status == 'NOT_COMPLETED' || obj.sleep.status == 'NOT_STARTED') return '未知'
+        return getTime(obj.sleep.real_end_time, obj.sleep.real_start_time)
+
+    }
+
+    function getStepCTime(obj) {
+        if (obj.status == 'ONGOING1') return 'Final stage'
+        if (obj.status == 'ONGOING2') return 'Next up'
+        if (obj.status == 'ONGOING3') return getTime(obj.sleep.real_end_time, (new Date()).getTime())
+        if (obj.status == 'WAIT_FOR_START') return getTime(obj.fast.target_end_time, obj.sleep.target_end_time)
+        if (obj.sleep.status == 'NOT_COMPLETED' || obj.sleep.status == 'NOT_STARTED') return '未知'
+        return getTime(obj.fast.real_end_time, obj.sleep.real_end_time)
+    }
+
+    return <View className="stage">
+        <View className="stage_item">
+            <Text className={props.data.status == 'ONGOING1' ?
+                'stage_step stage_step_border_ing' :
+                'stage_step stage_step_border'}>阶段A</Text>
+            <Text className="stage_title" style={{
+                color: props.data.status == 'ONGOING1' ?
+                    '#AAFF00' : 'rgba(255, 255, 255, 0.8)'
+            }}>睡前断食</Text>
+            <Text className="stage_value" style={{
+                color: props.data.status == 'ONGOING1' ?
+                    '#AAFF00' : 'rgba(255, 255, 255, 0.8)'
+            }}>{getStepATime(props.data)}</Text>
+        </View>
+        <View className="stage_item">
+            <Text className={props.data.status == 'ONGOING2' ?
+                'stage_step stage_step_border_ing' :
+                'stage_step stage_step_border'}>阶段B</Text>
+            <Text className="stage_title" style={{
+                color: props.data.status == 'ONGOING2' ?
+                    '#AAFF00' : 'rgba(255, 255, 255, 0.8)'
+            }}>睡眠中断食</Text>
+            <Text className="stage_value" style={{
+                color: props.data.status == 'ONGOING2' ?
+                    '#AAFF00' : 'rgba(255, 255, 255, 0.8)'
+            }}>{getStepBTime(props.data)}</Text>
+        </View>
+        <View className="stage_item">
+            <Text className={props.data.status == 'ONGOING3' ?
+                'stage_step stage_step_border_ing' :
+                'stage_step stage_step_border'}>阶段C</Text>
+            <Text className="stage_title" style={{
+                color: props.data.status == 'ONGOING3' ?
+                    '#AAFF00' : 'rgba(255, 255, 255, 0.8)'
+            }}>起床后断食</Text>
+            <Text className="stage_value" style={{
+                color: props.data.status == 'ONGOING3' ?
+                    '#AAFF00' : 'rgba(255, 255, 255, 0.8)'
+            }}>{getStepCTime(props.data)}</Text>
+        </View>
+
+    </View>
+}

+ 17 - 10
src/pages/clock/Clock.tsx

@@ -10,7 +10,6 @@ import { useDispatch, useSelector } from 'react-redux';
 import { getInfoSuccess, logoutSuccess } from '@/store/user';
 import { wxPubFollow } from '@/services/permission';
 import { gobalConfigs, staticResources, uploadSessionKey } from '@/services/common';
-import { use } from 'i18next';
 import Clocks from '@/features/trackTimeDuration/components/Clock';
 import Console from '@/features/trackTimeDuration/components/Console';
 import More from '@/features/trackTimeDuration/components/More';
@@ -28,7 +27,7 @@ import { setConfigs } from '@/store/common'
 import RecordFastSleep from '@/features/trackTimeDuration/components/RecordFastSleep'
 import Box from '@/components/layout/Box'
 import Layout from '@/components/layout/layout'
-import { NaviBarTitleShowType, TemplateType } from '@/utils/types'
+import { CheckBoxType, NaviBarTitleShowType, TemplateType } from '@/utils/types'
 import { updateScenario } from '@/store/time'
 import { showModal } from '@/store/modal'
 // import TabBar from '../../components/Tabbar';
@@ -38,7 +37,6 @@ export default function IndexPage() {
   const [checkData, setCheckData] = useState(null)
   const user = useSelector((state: any) => state.user);
   const time = useSelector((state: any) => state.time);
-  const permission = useSelector((state: any) => state.permission);
   const common = useSelector((state: any) => state.common);
   const [counter, setCounter] = useState(0)
   const [timerId, setTimerId] = useState(null)
@@ -52,6 +50,7 @@ export default function IndexPage() {
 
   const [showModal2, setShowModal2] = useState(false)
   const [modalDetail2, setModalDetail2] = useState<any>({})
+  const [showSingleFastEnd, setShowSingleFastEnd] = useState(false)
 
   global.dispatch = dispatch;
   useEffect(() => {
@@ -131,7 +130,7 @@ export default function IndexPage() {
       setCounter((prevCounter) => prevCounter + 1);
       //每天0点刷新一下打卡数据
       var now = new Date()
-      if (now.getHours()==0 && now.getMinutes()==0){
+      if (now.getHours() == 0 && now.getMinutes() == 0) {
         getCheckData()
       }
     }, 1000);
@@ -164,7 +163,6 @@ export default function IndexPage() {
   }
 
   usePageScroll((e) => {
-
   })
 
   useDidShow(() => {
@@ -194,8 +192,13 @@ export default function IndexPage() {
       setCheckData(res as any)
 
       if ((res as any).current_record.status == 'ONGOING1') {
-        setSwiperIndex(1)
-        setAutoPlay(true)
+        setShowSingleFastEnd(true)
+        setTimeout(() => {
+          setShowSingleFastEnd(false)
+          setSwiperIndex(1)
+          setAutoPlay(true)
+        }, 2000)
+
       }
       else {
         setSwiperIndex(0)
@@ -232,6 +235,9 @@ export default function IndexPage() {
       (time.status == 'WAIT_FOR_START' ||
         time.status == 'ONGOING1' ||
         time.status == 'ONGOING2')
+    if (showSingleFastEnd) {
+      return false;
+    }
     return isNeed
   }
 
@@ -258,7 +264,6 @@ export default function IndexPage() {
           <View className='clock_bg'>
             <Clocks />
           </View>
-
         </Box>
 
         {
@@ -283,7 +288,7 @@ export default function IndexPage() {
               <Console isNextStep={true} />
             </SwiperItem>
           </Swiper> :
-            <Console />
+            <Console isNextStep={showSingleFastEnd} />
 
         }
 
@@ -293,17 +298,19 @@ export default function IndexPage() {
           checkData && schedule()
         }
         {
-          checkData && (checkData as any).latest_record && 
+          checkData && (checkData as any).latest_record &&
           <RecordFastSleep type='latest' data={(checkData as any).latest_record} delSuccess={getCheckData} />
         }
         <View style={{ height: 100 }} />
       </View>
+
       {
         showModal && modalDetail
       }
       {
         showModal2 && modalDetail2
       }
+
     </Layout>
   )
 }

+ 14 - 0
src/utils/types.ts

@@ -44,4 +44,18 @@ export enum BoxType {
     big = 'big',
     small = 'small',
     outline = 'outline'
+}
+
+export enum TimelineType {
+    timeFirst = 'timeFirst',
+    timeSecond = 'timeSecond',
+    timeMutiLine = 'timeMutiLine'
+}
+
+export enum CheckBoxType {
+    empty = 'empty',
+    cross = 'cross',
+    check = 'check',
+    arrow = 'arrow',
+    dot = 'dot'
 }