|
@@ -1,9 +1,281 @@
|
|
|
-import { View } from "@tarojs/components";
|
|
|
|
|
|
|
+import { View, ScrollView, Text, Image } from "@tarojs/components";
|
|
|
import './streak_calendar.scss'
|
|
import './streak_calendar.scss'
|
|
|
|
|
+import '@/features/health/calendar.scss'
|
|
|
|
|
+import NewHeader, { NewHeaderType } from "../components/new_header";
|
|
|
|
|
+import { useSelector } from "react-redux";
|
|
|
|
|
+import { rpxToPx } from "@/utils/tools";
|
|
|
|
|
+import { useEffect, useState } from "react";
|
|
|
|
|
+import { streaks } from "@/services/health";
|
|
|
|
|
+import { getScenario, getThemeColor } from "@/features/health/hooks/health_hooks";
|
|
|
|
|
+import NewButton, { NewButtonType } from "../base/new_button";
|
|
|
|
|
|
|
|
|
|
|
|
|
-export default function StreakCalendar(){
|
|
|
|
|
- return <View>
|
|
|
|
|
|
|
+export default function StreakCalendar() {
|
|
|
|
|
+ const health = useSelector((state: any) => state.health);
|
|
|
|
|
+ const [mode, setMode] = useState('EAT')
|
|
|
|
|
+ const [selIndex, setSelIndex] = useState(0);
|
|
|
|
|
+ const weeks = ['日', '一', '二', '三', '四', '五', '六']
|
|
|
|
|
+ const indexBeginWeek = 0;
|
|
|
|
|
+ const [spaces, setSpaces] = useState<any>([])
|
|
|
|
|
+ const [days, setDays] = useState<any>([])
|
|
|
|
|
+ const [year, setYear] = useState(new Date().getFullYear())
|
|
|
|
|
+ const [month, setMonth] = useState(new Date().getMonth()+1)
|
|
|
|
|
+ const [current, setCurrent] = useState<any>(null)
|
|
|
|
|
+ const [loaded, setLoaded] = useState(false)
|
|
|
|
|
+
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
|
+ loadData()
|
|
|
|
|
+ }, [month, mode])
|
|
|
|
|
+
|
|
|
|
|
+ function loadData() {
|
|
|
|
|
+
|
|
|
|
|
+ const firstDay = new Date(year, month - 1, 1);
|
|
|
|
|
+ const firstDayOfWeek = firstDay.getDay();
|
|
|
|
|
+ const spaceCount = firstDayOfWeek > indexBeginWeek ? firstDayOfWeek - indexBeginWeek : firstDayOfWeek - indexBeginWeek + 7
|
|
|
|
|
+ setSpaces(new Array(spaceCount).fill(''))
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // 创建一个 Date 对象来获取该月的最后一天
|
|
|
|
|
+ const lastDay = new Date(year, month, 0); // 0 表示上一个月的最后一天
|
|
|
|
|
+ const totalDays = lastDay.getDate();
|
|
|
|
|
+ var list: any = []
|
|
|
|
|
+ for (var i = 1; i <= totalDays; i++) {
|
|
|
|
|
+ var obj: any = {
|
|
|
|
|
+ day: i
|
|
|
|
|
+ }
|
|
|
|
|
+ // if (i == 1 || i == 10 || i == 15) {
|
|
|
|
|
+ // obj.begin = true
|
|
|
|
|
+ // }
|
|
|
|
|
+ // if (i == 2 || i == 11 || i == 16) {
|
|
|
|
|
+ // obj.right = true
|
|
|
|
|
+ // }
|
|
|
|
|
+
|
|
|
|
|
+ // if (i == 22) {
|
|
|
|
|
+ // obj.full = true
|
|
|
|
|
+ // }
|
|
|
|
|
+
|
|
|
|
|
+ list.push(obj)
|
|
|
|
|
+ }
|
|
|
|
|
+ setDays(list)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ streaks({
|
|
|
|
|
+ window: mode,
|
|
|
|
|
+ month: year + (month + '').padStart(2, '0')
|
|
|
|
|
+ }).then(res => {
|
|
|
|
|
+ const array = (res as any).streaks
|
|
|
|
|
+ for (var i = 0; i < list.length; i++) {
|
|
|
|
|
+ var obj = list[i]
|
|
|
|
|
+ var strMonth = month < 10 ? '0' + month : month + ''
|
|
|
|
|
+ var strDay = obj.day < 10 ? '0' + obj.day : obj.day
|
|
|
|
|
+
|
|
|
|
|
+ const d = parseInt(year + '' + strMonth + strDay)
|
|
|
|
|
+ for (var j = 0; j < array.length; j++) {
|
|
|
|
|
+ const streak = array[j]
|
|
|
|
|
+
|
|
|
|
|
+ if (d == streak.start_date && streak.start_date == streak.end_date) {
|
|
|
|
|
+ obj.full = true
|
|
|
|
|
+ obj.current = streak.is_current
|
|
|
|
|
+ obj.showStreak = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (d == streak.start_date && streak.start_date < streak.end_date) {
|
|
|
|
|
+ obj.begin = true
|
|
|
|
|
+ obj.current = streak.is_current
|
|
|
|
|
+ obj.showStreak = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (d == streak.end_date && streak.start_date < streak.end_date) {
|
|
|
|
|
+ obj.right = true
|
|
|
|
|
+ obj.current = streak.is_current
|
|
|
|
|
+ obj.showStreak = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (streak.start_date < d && d < streak.end_date) {
|
|
|
|
|
+ obj.center = true
|
|
|
|
|
+ obj.current = streak.is_current
|
|
|
|
|
+ obj.showStreak = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ obj.isToday = false
|
|
|
|
|
+ if (year == new Date().getFullYear() && month == new Date().getMonth() + 1 && obj.day == new Date().getDate()) {
|
|
|
|
|
+ obj.isToday = true
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ setDays([...list])
|
|
|
|
|
|
|
|
|
|
+ setLoaded(true)
|
|
|
|
|
+ setCurrent((res as any).current)
|
|
|
|
|
+ // console.log(list)
|
|
|
|
|
+ }).catch(e => {
|
|
|
|
|
+
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function itemClass(item) {
|
|
|
|
|
+ if (item.begin) {
|
|
|
|
|
+ if (item.isToday) {
|
|
|
|
|
+ return 'left_calendar_item today_content'
|
|
|
|
|
+ }
|
|
|
|
|
+ return 'left_calendar_item'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (item.center) {
|
|
|
|
|
+ if (item.isToday) {
|
|
|
|
|
+ return 'center_calendar_item today_content'
|
|
|
|
|
+ }
|
|
|
|
|
+ return 'center_calendar_item'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (item.right) {
|
|
|
|
|
+ if (item.isToday) {
|
|
|
|
|
+ return 'right_calendar_item today_content'
|
|
|
|
|
+ }
|
|
|
|
|
+ return 'right_calendar_item'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (item.full) {
|
|
|
|
|
+ if (item.isToday) {
|
|
|
|
|
+ return 'full_calendar_item today_content'
|
|
|
|
|
+ }
|
|
|
|
|
+ return 'full_calendar_item'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (item.isToday) {
|
|
|
|
|
+ return 'today1'
|
|
|
|
|
+ }
|
|
|
|
|
+ return 'calendar_item'
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function itemTextClass(item) {
|
|
|
|
|
+ if (item.begin) {
|
|
|
|
|
+ return 'left_day'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (item.center) {
|
|
|
|
|
+ return 'center_day'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (item.right) {
|
|
|
|
|
+ return 'right_day'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (item.full) {
|
|
|
|
|
+ return 'full_day'
|
|
|
|
|
+ }
|
|
|
|
|
+ return 'normal_day'
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function bgColor(item) {
|
|
|
|
|
+ if (item.showStreak && !item.current) {
|
|
|
|
|
+ return '#B2B2B21A'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (itemClass(item) == 'calendar_item') {
|
|
|
|
|
+ return 'transparent'
|
|
|
|
|
+ }
|
|
|
|
|
+ if (itemClass(item) == 'today1') {
|
|
|
|
|
+
|
|
|
|
|
+ return '#000'
|
|
|
|
|
+ }
|
|
|
|
|
+ return getThemeColor(mode) + '33'
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function textColor(item) {
|
|
|
|
|
+ // if (itemTextClass(item) == 'normal_day') {
|
|
|
|
|
+ // return '#000000'
|
|
|
|
|
+ // }
|
|
|
|
|
+ if (item.isToday) {
|
|
|
|
|
+ if (item.begin || item.full || item.right || item.left) {
|
|
|
|
|
+ return '#000'
|
|
|
|
|
+ }
|
|
|
|
|
+ return '#ffffff'
|
|
|
|
|
+ }
|
|
|
|
|
+ return '#000000'
|
|
|
|
|
+ // return getThemeColor(health.mode)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function leftSpace(days) {
|
|
|
|
|
+ if (days < 10) {
|
|
|
|
|
+ return rpxToPx(98)
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (days < 100) {
|
|
|
|
|
+ return rpxToPx(71)
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (days < 1000) {
|
|
|
|
|
+ return rpxToPx(54)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function currentCount(type){
|
|
|
|
|
+ const scenario = getScenario(health.windows,type)
|
|
|
|
|
+ if (scenario.current_streak.days>0) return scenario.current_streak.days
|
|
|
|
|
+ return scenario.current_streak.days
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function content() {
|
|
|
|
|
+ return <View className="calendar_main2">
|
|
|
|
|
+ <View className="calendar_header">
|
|
|
|
|
+
|
|
|
|
|
+ <NewButton type={NewButtonType.img} onClick={() => {
|
|
|
|
|
+ const date = new Date(year, month - 1); // month - 1 因为月份是从 0 开始
|
|
|
|
|
+ date.setMonth(date.getMonth() - 1);
|
|
|
|
|
+ setYear(date.getFullYear())
|
|
|
|
|
+ setMonth(date.getMonth() + 1)
|
|
|
|
|
+ }}>
|
|
|
|
|
+ <Image src={require('@assets/_health/pre.png')} style={{ width: rpxToPx(36), height: rpxToPx(36) }} />
|
|
|
|
|
+ </NewButton>
|
|
|
|
|
+ <Text style={{ width: rpxToPx(236), textAlign: 'center' }}>{`${year}年${month}月`}</Text>
|
|
|
|
|
+
|
|
|
|
|
+ <NewButton type={NewButtonType.img} onClick={() => {
|
|
|
|
|
+ const date = new Date(year, month + 1); // month - 1 因为月份是从 0 开始
|
|
|
|
|
+ date.setMonth(date.getMonth() - 1);
|
|
|
|
|
+ setYear(date.getFullYear())
|
|
|
|
|
+ setMonth(date.getMonth() + 1)
|
|
|
|
|
+ }}>
|
|
|
|
|
+ <Image src={require('@assets/_health/next.png')} style={{ width: rpxToPx(36), height: rpxToPx(36) }} />
|
|
|
|
|
+ </NewButton>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View className="calendar_body">
|
|
|
|
|
+ <View className="calendar_weekly">
|
|
|
|
|
+ {
|
|
|
|
|
+ weeks.map((item, index) => {
|
|
|
|
|
+ return <View className="week_item" key={index}>{item}</View>
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View className="calendar_main3">
|
|
|
|
|
+ {
|
|
|
|
|
+ spaces.map((item, i) => {
|
|
|
|
|
+ return <View className="calendar_item" style={{ width: rpxToPx(90) }} key={i * 10} />
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ days.map((item, index) => {
|
|
|
|
|
+ return <View className={itemClass(item)} style={{ width: rpxToPx(90), backgroundColor: bgColor(item) }} key={index}>
|
|
|
|
|
+ <Text className={itemTextClass(item)} style={{ color: textColor(item) }}>{item.day}</Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View className="calendar_footer">
|
|
|
|
|
+
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ return <View>
|
|
|
|
|
+ <NewHeader type={NewHeaderType.left} title="Calendar" />
|
|
|
|
|
+ <ScrollView style={{ width: rpxToPx(750),flexDirection:'row',display:'flex',height:100 }} scrollX enableFlex showScrollbar={false}>
|
|
|
|
|
+ <View onClick={() => setMode('EAT')}>
|
|
|
|
|
+ <Text>Eat<Text>{currentCount('EAT')}</Text></Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View onClick={() => setMode('ACTIVE')}>
|
|
|
|
|
+ <Text>Active<Text>{currentCount('ACTIVE')}</Text></Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View onClick={() => setMode('FAST')}>
|
|
|
|
|
+ <Text>Fast<Text>{currentCount('FAST')}</Text></Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View onClick={() => setMode('SLEEP')}>
|
|
|
|
|
+ <Text>Sleep<Text>{currentCount('SLEEP')}</Text></Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </ScrollView>
|
|
|
|
|
+ {
|
|
|
|
|
+ content()
|
|
|
|
|
+ }
|
|
|
</View>
|
|
</View>
|
|
|
}
|
|
}
|