allReportsScreen
unknown
plain_text
a year ago
20 kB
5
Indexable
import React, { useCallback, useEffect, useState } from "react" import { Alert, FlatList, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native" import { AnimatedTrackCard } from "../../../component/common/AnimatedTrackCard" import { BarChartCustom } from "../../../component/common/BarChartCustom" import CustomHeader from "../../../component/common/CustomHeader" import { SheetModal } from "../../../component/common/SheetModal" import { TrackerComponent } from "../../../component/common/TrackerComponent" import DownloadIcon from '../../../assets/Icons/commons/download.svg' import { colors } from "../../../theme" import fonts from "../../../assets/fonts" import { Strings, width } from "../../../constants/constants" import { useDispatch, useSelector } from "react-redux" import { getUserProfile, updateUserProfile } from "../../../api" import { storeUserDetails } from "../../../redux/actions/users" import { ShowErrorMessage } from "../../../component/common/showErrorMessage" import { WeightPickerPopup } from "../../../component/common/WeightPickerPopup" import { TitleButtonComp } from "../../../component/common/TitleButtonComp" import { trackScreenEvent } from "../../../utils/FirebaseTrackEvents" import { useFocusEffect } from "@react-navigation/native" interface TrackerDataItem { id: number; title: string; value: number; bgColor: string; color: string; } interface BodyGoalDataItem { id: number; title: string; animationJson: any; value?: string; unit?: string|null; themeColor?: string; bgColor: string; bottomText?: string|null; idealValue?: number|null; locked?: boolean; description?: string; } interface RenderFilterItemsProps { item: TrackerDataItem; } interface RenderBodyGoalItemsProps { item: BodyGoalDataItem; } interface InfoModalTypes { message: string | null | undefined; value: any | null | undefined; title: string | null | undefined; themeColor: string | null | undefined; description: string | null | undefined; } export const AllReportsScreen = () => { const { user, userType } = useSelector(store => store?.userDetails) const { stats } = useSelector(store => store.stats) const [weightModal, setWeightModal] = useState(false) const dispatch = useDispatch() const isPaidUser = userType !== Strings.FREE && userType !== Strings.GUEST const reportCardData = { title: Strings.YOUR_REPORT_CARD, description: Strings.REPORT_CARD_DESCRIPTION, trackerMain: { name: 'Target Calories', data: stats.calories_intake?.data?.calories_intake_total, totalValue: user?.reach_goal?.target_calories, unit: `${user?.reach_goal?.target_calories} Kcal`, }, } const data = { labels: user?.reach_goal?.weight_chart?.week?.map(item => item.title), datasets: [ { data: user?.reach_goal?.weight_chart?.week?.map(item => item.value?.toFixed(2)) } ] }; const trackersDataItems: TrackerDataItem[] = [ { id: 1, title: 'Current', value: user?.weight ?? 0, bgColor: colors.lightGreenBg, color: colors.green }, { id: 2, title: 'Target', value: user?.target_weight ?? 0, bgColor: colors.lightBlueBg, color: colors.purple }, { id: 3, title: 'Ideal Body', value: user?.reach_goal?.ibw ?? 0, bgColor: colors.lightYellowBg, color: colors.mangoYellow }, ] const myBodyGoalsData: BodyGoalDataItem[] = [ { id: 1, title: 'Body Mass Index', animationJson: require('../../../assets/jsons/wave-animation-purple.json'), description: Strings.BMI_DESCRIPTION, value: user?.reach_goal?.bmi ?? '0', unit: 'Kg/m2', themeColor: colors.purple1, bgColor: colors.lightPurpleBg, bottomText: 'Your Ideal water percentage should be ', idealValue: 66, }, { id: 2, title: 'Resting Metabolic Rate', animationJson: require('../../../assets/jsons/wave-animation-yellow.json'), description: Strings.RMR_DESCRIPTION, value: user?.reach_goal?.rmr ?? '0', unit: 'Kg/m2', bgColor: colors.lightYellowBg, themeColor: colors.mangoYellow, bottomText: 'Your Ideal water consumption should be ', idealValue: 10, }, { id: 3, title: 'Fat-Free Mass ', themeColor: colors.cEC6E6E, animationJson: require('../../../assets/jsons/wave-animation-red.json'), description: Strings.FAT_FREE_MASS_DESCRIPTION, value: isPaidUser ? user?.reach_goal?.muscle ?? 0 : null, unit: isPaidUser ? 'Kg' : null, bgColor: colors.lightRedBg, locked: isPaidUser ? false : true, bottomText: isPaidUser ? 'Your Ideal water consumption should be ' : null, idealValue: isPaidUser ? 10 : null, }, { id: 4, title: 'Fat Mass (FM)%', themeColor: colors.purple, bgColor: colors.lightBlueBg, description: Strings.FAT_MASS_DESCRIPTION, animationJson: require('../../../assets/jsons/wave-animation.json'), value: isPaidUser ? user?.reach_goal?.fat_mass ?? '0' : null, unit: isPaidUser ? 'Kg' : null, locked: isPaidUser ? false : true, bottomText: isPaidUser ? 'Your Ideal water consumption should be ' : null, idealValue: isPaidUser ? 10 : null, }, ] const chartConfig = { backgroundGradientFrom: "#fff", backgroundGradientFromOpacity: 0, backgroundGradientTo: "#fff", backgroundGradientToOpacity: 1, color: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`, labelColor: (opacity = 1) => `rgba(153, 153, 153, ${opacity})`, strokeWidth: 2, barPercentage: .75, barRadius: 20, useShadowColorFromDataset: false, fillShadowGradientFrom: colors.GREY_F4F4F4, fillShadowGradientTo: '#f0f0f0', fillShadowGradientFromOpacity: 1, fillShadowGradientToOpacity: 1, propsForBackgroundLines: { strokeWidth: 2, stroke: colors.green }, }; const [infoModal, setInfoModal] = useState<InfoModalTypes>({ message: null, value: null, title: null, themeColor: null, description: null }) const [weight, setWeight] = useState(user?.weight) const getUserProfileData = () => { getUserProfile().then(val => { if (val.data) { dispatch(storeUserDetails(val.data.data)) } else { ShowErrorMessage('something went wrong'); } }).catch(err => console.log(err)) } const updateUserProfileData = (data) => { const formData = new FormData(); if (data.you_active) { formData.append('you_active', data.you_active) } if (data.username) { formData.append('username', data?.username); } if (data.age) { formData.append('age', data.age); } if (data.gender) { formData.append('gender', data.gender) } if (data.height) { formData.append('height', data.height) } if (data.weight) { formData.append('weight', data.weight) } if (data.target_weight) { formData.append('target_weight', data.target_weight) } if (data.bmi) { formData.append('bmi', data.bmi) } if (data.email_address) { formData.append('email_address', data.email_address) } updateUserProfile(formData).then(val => { if (val.data) { if (val.data?.status) { setWeightModal(false) Alert.alert('Toneop v2 Alert', 'Data set successfully!', [ { text: 'OK', style: 'cancel', }, ]); } } else { ShowErrorMessage('something went wrong'); } getUserProfileData() }).catch(err => console.log(err)) }; const handleWeightUpdate = (val) => { if (val) { let dataObj = { username: user?.username, age: user?.age, gender: user?.gender, height: user?.height, weight: weight, you_active: user?.you_active, target_weight: user?.target_weight, bmi: user?.reach_goal?.bmi, email_address: user?.email_address } updateUserProfileData(dataObj) } } useEffect(() => { getUserProfileData() }, []) useFocusEffect( useCallback(() => { const params = { user_id: user.user_id, screen_name: 'AllReports_Screen', is_event: 0, }; trackScreenEvent(params); }, []) ) const renderFilterItems: React.FC<RenderFilterItemsProps> = ({ item }) => ( <TouchableOpacity style={{ ...styles.weightTrackerIndicator, backgroundColor: item?.bgColor }}> <View style={{ ...styles.indicatorDot, backgroundColor: item?.color }} /> <Text style={{ ...styles.graphFilterTextStyles, color: item?.color }}>{item?.title}: <Text style={styles.graphFilterTextStyles}>{item?.value}</Text></Text> </TouchableOpacity> ) const renderGoalItems: React.FC<RenderBodyGoalItemsProps> = ({ item }) => ( <AnimatedTrackCard bgColor={item?.bgColor} onPressInfo={() => setInfoModal({ message: item?.bottomText, value: item?.value, title: item?.title, themeColor: item?.themeColor, description: item?.description })} style={{ marginRight: item?.id % 2 !== 0 ? 12 : null }} themeColor={item?.themeColor} renderTopContent={() => ( <Text style={{ ...styles.bodyGoalCardValue, color: item?.themeColor }}>{item?.value}<Text style={styles.bodyGoalCardUnit}> {item?.unit}</Text></Text> )} lottieJson={item?.animationJson} renderBottomContent={() => ( <View style={{ ...styles.p12, paddingBottom: 18 }}> <Text style={styles.bodyIntakeGoalCardTitle}>{item?.title}</Text> <Text style={styles.cardInfoText}>{item?.bottomText} <Text style={{ ...styles.fs10ppSbPrimary, color: item?.themeColor }}>{item?.idealValue}</Text></Text> {item?.locked && <Text style={{ ...styles.cardInfoText, color: item?.themeColor }}>Buy Plan to Unlock</Text>} </View> )} locked={item?.locked} /> ) return ( <> <CustomHeader title={'All Reports'} renderRightIcon={() => <TouchableOpacity><DownloadIcon /></TouchableOpacity>} /> <ScrollView style={styles.container} showsVerticalScrollIndicator={false}> <TrackerComponent title={reportCardData.title} description={reportCardData.description} trackerMain={reportCardData.trackerMain} /> <View style={styles.p16}> <Text style={styles.commonTitleStyles}>Water Intake Goal</Text> <View style={styles.waterIntakeCardsContainer}> <AnimatedTrackCard bgColor={colors.lightBlueBg} themeColor={colors.purple} lottieJson={require('../../../assets/jsons/wave-animation.json')} renderBottomContent={() => ( <View style={{ ...styles.p12, paddingBottom: 18 }}> <Text style={styles.bodyIntakeGoalCardTitle}>Body Water Percentage</Text> <Text style={styles.cardInfoText}>Your Ideal water percentage should be <Text style={{ ...styles.fs10ppSbPrimary, color: colors.purple }}>{user?.reach_goal?.ideal_water_percentage}%</Text></Text> </View> )} renderTopContent={() => ( <Text style={{ ...styles.bodyGoalCardValue, color: colors.purple }}>{user?.reach_goal?.body_water_percentage}<Text style={styles.bodyGoalCardUnit}> %</Text></Text> )} /> <AnimatedTrackCard bgColor={colors.lightGreenBg} themeColor={colors.green} lottieJson={require('../../../assets/jsons/wave-animation-green.json')} renderTopContent={() => ( <Text style={{ ...styles.bodyGoalCardValue, color: colors.green, }}>{user?.water_intake_goal?.intake_number_of_glass}<Text style={styles.bodyGoalCardUnit}> out of 10</Text></Text> )} renderBottomContent={() => ( <View style={{ ...styles.p12, paddingBottom: 18 }}> <Text style={styles.bodyIntakeGoalCardTitle}>Daily Water Consumption</Text> <Text style={styles.cardInfoText}>Your Ideal water consumption should be <Text style={{ ...styles.fs10ppSbPrimary, color: colors.green }}>{user?.water_intake_goal?.set_glass_of_water} glasses</Text> per day</Text> </View> )} /> </View> <View style={styles.weightTrackerContainer}> <TitleButtonComp title="Weight Tracker" btnText="Update weight" onBtnPress={() => setWeightModal(true)} /> </View> <FlatList data={trackersDataItems} renderItem={renderFilterItems} keyExtractor={item => item?.id.toString()} horizontal contentContainerStyle={{ gap: 12 }} showsHorizontalScrollIndicator={false} /> <BarChartCustom chartConfig={chartConfig} key={'barchart-allreports'} data={data} graphWidth={width} showXAxis showYAxis showAverage maxDataValue={100} /> <Text style={{ ...styles.contentTitle, marginTop: 12 }}>My Body Goals</Text> <FlatList data={myBodyGoalsData} renderItem={renderGoalItems} numColumns={2} contentContainerStyle={{ gap: 12, marginVertical: 12 }} keyExtractor={item => item?.id.toString()} /> </View> <SheetModal visible={infoModal && infoModal?.title} setVisible={setInfoModal} style={{ justifyContent: 'flex-end', margin: 0 }}> <View style={styles.modalView}> <Text style={styles.commonTitleStyles}>{infoModal?.title}</Text> <Text style={{ ...styles.fs14ppMedGreen, color: colors.mainBlack }}>{infoModal?.message} <Text style={{ ...styles.fs14ppMedGreen, color: infoModal?.themeColor }}>{infoModal?.value}%</Text></Text> <Text style={{ ...styles.fs12ppReg75, marginVertical: 8 }}>{infoModal?.description}</Text> </View> </SheetModal> {weightModal && <WeightPickerPopup visible={weightModal} setVisible={setWeightModal} onUpdate={handleWeightUpdate} />} </ScrollView> </> ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: colors.white, }, contentTitle: { fontFamily: fonts.PoppinsSemiBold, fontSize: 18, fontWeight: '600', color: colors.mainBlack, }, dashedLineStyles: { position: 'absolute', left: 0, right: 0, }, cardInfoText: { fontSize: 10, fontFamily: fonts.PoppinsRegular, fontWeight: '400', color: colors.c666666, marginTop: 8 }, fs10ppSbPrimary: { fontSize: 10, fontFamily: fonts.PoppinsSemiBold, fontWeight: '600', color: colors.purple }, graphFilterTextStyles: { fontSize: 12, fontFamily: fonts.PoppinsMedium, fontWeight: '500', color: colors.mainBlack, }, fs12ppReg75: { fontSize: 12, fontFamily: fonts.PoppinsRegular, fontWeight: '400', color: colors.mutedGrey }, fs14ppMedGreen: { fontFamily: fonts.PoppinsMedium, fontSize: 14, fontWeight: '500', color: colors.green, }, bodyGoalCardUnit: { fontSize: 14, fontFamily: fonts.PoppinsRegular, fontWeight: '400', color: colors.c666666 }, commonTitleStyles: { fontSize: 18, fontFamily: fonts.PoppinsSemiBold, fontWeight: '600', color: colors.mainBlack, marginBottom: 32 }, bodyIntakeGoalCardTitle: { fontSize: 16, fontFamily: fonts.PoppinsMedium, fontWeight: '500', color: colors.black, }, bodyGoalCardValue: { fontSize: 42, fontFamily: fonts.PoppinsBold, fontWeight: '800', color: colors.purple, textAlign: 'center', marginTop: 20, }, graphContainer: { width: '100%', marginVertical: 36, position: 'relative', }, indicatorDot: { width: 4, height: 4, marginRight: 4 }, modalView: { backgroundColor: colors.white, padding: 16, borderTopLeftRadius: 24, borderTopRightRadius: 24, }, p12: { padding: width * .03333 }, p16: { padding: width * .0444, }, rowCenterApart: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }, waterIntakeCardsContainer: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginTop: 22 }, weightTrackerContainer: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginVertical: 22, paddingRight: 12 }, weightTrackerIndicator: { padding: 12, paddingHorizontal: 16, borderRadius: 64, flexDirection: 'row', alignItems: 'center', }, })
Editor is loading...
Leave a Comment