| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- import { View, Text, Image } from "@tarojs/components";
- import './calendar.scss'
- import dayjs from "dayjs";
- import { useEffect, useState } from "react";
- import { rpxToPx } from "@/utils/tools";
- import { streaks } from "@/services/health";
- import { useSelector } from "react-redux";
- import { getThemeColor } from "./hooks/health_hooks";
- import NewButton, { NewButtonType } from "@/_health/base/new_button";
- import { MainColorType } from "@/context/themes/color";
- import { useTranslation } from "react-i18next";
- export default function Calendar(props: { year: number, month: number,mode:string }) {
- const weeks = ['日', '一', '二', '三', '四', '五', '六']
- const indexBeginWeek = 0;
- const [spaces, setSpaces] = useState<any>([])
- const [days, setDays] = useState<any>([])
- const health = useSelector((state: any) => state.health);
- const [year, setYear] = useState(props.year)
- const [month, setMonth] = useState(props.month)
- const [current, setCurrent] = useState<any>(null)
- const [loaded, setLoaded] = useState(false)
- const { t } = useTranslation()
- useEffect(() => {
- console.log('------------------')
- console.log(props.mode)
- loadData()
- }, [month,props.mode])
- // useEffect(()=>{
- // setYear(props.year)
- // setMonth(props.month)
- // // loadData(props.year,props.mo)
- // },[props.year,props.month,props.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: props.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) {
- if (item.isToday) {
- return 'normal_day'
- }
- return 'full_day'
- }
- return 'normal_day'
- }
- function bgColor(item) {
- if (item.showStreak && !item.current) {
- return '#B2B2B21A'
- }
- if (itemClass(item) == 'calendar_item') {
- return 'transparent'
- }
- if (item.isToday) {
- if (item.full) {
- return 'transparent'
- }
- }
- // if (item.isToday) {
- // return '#000'
- // }
- return getThemeColor(props.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(props.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 getYearMonth() {
- const date = new Date(year, month - 1);
- if (global.language == 'en') {
- return dayjs(date.getTime()).format('MMMM YYYY')
- }
- return dayjs(date.getTime()).format('YYYY年MMM')
- }
- 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', fontSize: rpxToPx(28) }}>{getYearMonth()}</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(94) }} key={i * 10} />
- })
- }
- {
- days.map((item, index) => {
- if (item.isToday && item.right) {
- return <View key={index} className="calendar_item" style={{ width: rpxToPx(94), position: 'relative' }}>
- <View className="full_right_today" style={{backgroundColor: getThemeColor(props.mode) + '33'}}/>
- <View className="fullToday">
- <View className="today3"/>
- </View>
- <Text >{item.day}</Text>
- </View>
- }
- return <View className={itemClass(item)} style={{ width: rpxToPx(94), backgroundColor: bgColor(item), position: 'relative' }} key={index}>
- {
- !item.full && item.isToday && <View className="today2" />
- }
- {
- item.full && item.isToday && <View className="fullToday" style={{ backgroundColor: getThemeColor(props.mode) + '33' }}>
- <View className="today3" />
- </View>
- }
- <Text className={itemTextClass(item)} style={{ color: textColor(item), zIndex: 1, fontWeight: item.isToday ? 'bold' : 'normal' }}>{item.day}</Text>
- </View>
- })
- }
- </View>
- </View>
- <View className="calendar_footer">
- </View>
- </View>
- }
- function logTitle() {
- switch (props.mode) {
- case 'FAST':
- return t('health.log_fast_streak')
- case 'EAT':
- return t('health.log_eat_streak')
- case 'SLEEP':
- return t('health.log_sleep_streak')
- case 'ACTIVE':
- return t('health.log_active_streak')
- }
- return ''
- }
- function streakTitle() {
- var year = parseInt((current.start_date + '').substring(0, 4))
- var month = parseInt((current.start_date + '').substring(4, 6)) - 1
- var date = parseInt((current.start_date + '').substring(6, 8))
- var dt = new Date(year, month, date)
- var format = global.language == 'en' ? 'MMM D' : 'M月D日'
- return t('health.since_date', { date: dayjs(dt.getTime()).format(format) })
- }
- function todayExpire() {
- if (!current.reset) return false
- var date = new Date(current.reset)
- if (date.getDate() == new Date().getDate()) {
- return true;
- }
- return false;
- }
- function streakDesc() {
- var format = global.language == 'en' ? 'MMM D' : 'M月D日'
- if (current.days == 0) {
- if (current.prev_reset) {
- return t('health.last_expire_date_time', {
- date: dayjs(current.prev_reset).format(format),
- time: dayjs(current.prev_reset).format('HH:mm'),
- })
- }
- }
- else {
- if (todayExpire()) {
- return t('health.expire_date_time', {
- date: dayjs(current.reset).format(format),
- time: dayjs(current.reset).format('HH:mm'),
- })
- }
- else {
- return t('health.until_date_time', {
- date: dayjs(current.reset).format(format),
- time: dayjs(current.reset).format('HH:mm'),
- })
- }
- }
- return ''
- }
- function currentContent() {
- return <View style={{ display: 'flex', flexDirection: 'row', height: rpxToPx(208) }}>
- {
- loaded && <View style={{ display: 'flex', flexDirection: 'row' }}>
- <View className="streak_days" style={{
- color: getThemeColor(props.mode),
- marginLeft: leftSpace(current ? current.days : 0),
- marginRight: rpxToPx(36),
- marginTop: rpxToPx(24)
- }}>{current ? current.days : '0'}</View>
- <View style={{ display: 'flex', flexDirection: 'column', marginTop: rpxToPx(36) }}>
- <View className="h44 bold" style={{ color: getThemeColor(props.mode) }}>{current.days == 1 ? t('health.day') : t('health.days')}</View>
- <View className="h24">{current.days == 0 ? logTitle() : streakTitle()}</View>
- <View className="h20" style={{ color: todayExpire() ? MainColorType.error : MainColorType.g02, marginTop: rpxToPx(12) }}>{streakDesc()}</View>
- </View>
- </View>
- }
- </View>
- }
- return <View className="calendar_main">
- {
- currentContent()
- }
- {
- content()
- }
- </View>
- }
|