allReportsScreen

mail@pastecode.io avatar
unknown
plain_text
a month ago
20 kB
1
Indexable
Never
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',

    },

})
Leave a Comment