allReportsScreen
unknown
plain_text
2 years ago
20 kB
14
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