fitnessDashboard

mail@pastecode.io avatar
unknown
plain_text
a month ago
25 kB
1
Indexable
Never
import React, { useEffect, useRef, useState } from "react"
import { Alert, FlatList, Image, ImageBackground, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native"
import LinearGradient from "react-native-linear-gradient"
import moment from "moment"
import { useNavigation } from "@react-navigation/native"
import { useDispatch, useSelector } from "react-redux"

import { BarChartCustom } from "../../component/common/BarChartCustom"
import { BlogRecommendationCard } from "../../component/blogs/BlogRecommendationCard"
import BottomStrip from "../../component/buyplan/BottomStrip"
import ButtonComponent from "../../component/common/ButtonComponent"
import CustomHeader from "../../component/common/CustomHeader"
import DietPlanDashboard from "../DietPlan/DietPlanDashboard"
import FitnessPlanCardComponent from "../../component/buyplan/FitnessPlanCardComponent"
import FoodListPopUp from "../../component/dietplan/FoodListPopUp"
import HeaderCalendarPopup from "../../component/common/HeaderCalendarPopup"
import { ListWithTitle } from "../../component/common/ListWithTitle"
import StickyCallButton from "../../component/buyplan/StickyCallButton"
import { VideoThumbnailComponent } from "../../component/diet-fitness/VideoThumbnailComponent"
import WeekWiseDateComponent from "../../component/common/WeekWiseDaySelect"
import { WorkoutDietAlert } from "../../component/diet-fitness/WorkoutDietAlert"

import CalendarIcon from '../../assets/Icons/commons/calendar.svg'
import InfoIcon from '../../assets/Icons/track-activity/info.svg'
import FIcon from 'react-native-vector-icons/Feather';

import { colors } from "../../theme"
import fonts from "../../assets/fonts"
import { fontSize } from "../../utils/fontUtils"
import { IMAGE_URL } from "../../api/Urls"
import routes from "../../routes/routes"
import { Strings, height, width } from "../../constants/constants"
import { getAllBlogs, getWorkoutCategory } from "../../api"
import { storeBlogsData } from "../../redux/actions/blogs"

interface HistoryDataItem {
    id: number;
    title: string;
    value: number;
}

export const FitnessDashboardScreen = () => {
    const { userData, userType } = useSelector(state => state?.userDetails)
    const { blogsData } = useSelector(store => store.blogs)
    const { buyPlanList } = useSelector(state => state?.buyPlanDetails);

    //states
    const [tabIndex, setTabIndex] = useState(0)
    const [selectedFilterId, setSelectedFilterId] = useState<number | null>(null)
    const flatlistRef = useRef<FlatList<HistoryDataItem> | null>(null);
    const [calenderPopUp, setCalenderPopUp] = useState<boolean>(false);
    const [fitnessData, setFitnessData] = useState()
    const [isYogaPlan, setIsYogaPlan] = useState<boolean>(false);
    const [isGymPlan, setIsGymPlan] = useState<boolean>(false);
    const [searchPopUp, setSearchPopUp] = useState<boolean>(false);
    const navigation = useNavigation()
    const pageSize = 12;
    const pageNo = 1;
    const blogParams = {
        page: pageNo,
        page_size: pageSize,
    }
    const dispatch = useDispatch()

    useEffect(() => {
        getBlogsData(blogParams)
        getWorkoutCategoryData()
    }, [])

    const buttonsData = [
        { title: 'Diet', index: 0 },
        { title: 'Fitness', index: 1 }
    ];
    const barchartData = {
        labels: ["Dec 1", "2", "3", "4", "5", "6", "7"],
        datasets: [
            {
                data: [10200, 4256, 7558, 12000, 9463, 3956, 6000]
            },
        ],
    };
    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 historysDataItems: HistoryDataItem[] = [
        {
            id: 1,
            title: 'Today',
            value: 10200,
        },
        {
            id: 2,
            title: 'Last 7 days',
            value: 9256,
        },
        {
            id: 3,
            title: 'Last 30 days',
            value: 9256,
        },
        {
            id: 4,
            title: 'Till Date',
            value: 13020,
        },
    ]

    //API
    const getBlogsData = (params) => {
        getAllBlogs(params).then(val => dispatch(storeBlogsData(val.data.data)))
            .catch(err => console.log(err?.response))
    };
    const getWorkoutCategoryData = () => {
        getWorkoutCategory().then(val => {
            setFitnessData(val?.data?.data)
            setIsYogaPlan(val?.data?.data?.is_ypr_assigned);
            setIsGymPlan(val?.data?.data?.is_gpr_assigned);
        }).catch(err => console.log(err?.response?.data))
    }

    //handlers
    const handleButtonClick = (index: Object) => {
        setTabIndex(index);
    };
    const handleWorkoutPress = (id: number | string) => {
        navigation.navigate(routes.todaysWorkout, { subcategoryId: id })
    }

    const TitleComponent = React.memo(({ title, icon }: {
        title: string;
        icon: JSX.Element | any;
    }) => (
        <View style={styles.rowCenterApart}>
            <Text style={styles.contentTitle}>{title}</Text>
            {icon}
        </View>
    ))

    //renderers
    const renderGoalOrientedWorkouts = ({ item }) => (<VideoThumbnailComponent
        title={item?.sub_category_id?.name}
        duration={item?.duration}
        totalTime={item?.sub_category_id?.duration}
        thumbnail={item?.sub_category_id?.image}
        id={item?.sub_category_id?.id}
        onpress={handleWorkoutPress}
    />)
    const renderFreeWorkouts = ({ item }) => (
        <VideoThumbnailComponent
            type="free"
            title={item?.name?.split(' ')[0]}
            subTitle={item?.name?.split(' ')[item?.name?.split(' ')?.length - 1]}
            thumbnail={item?.image}
            id={item?.id}
            onpress={handleWorkoutPress}
        />)
    const renderFitnessPlans = ({ item, index }) => (
        <View key={item.id} style={{ backgroundColor: '#F4FFFA' }} >
            <FitnessPlanCardComponent item={item} index={index} />
        </View>)
    const renderHomeWorkouts = ({ item }) => (
        <VideoThumbnailComponent
            type="landscape"
            title={item?.exercise_name}
            duration={item?.exercise_duration}
            thumbnail={item?.exercise_thumbnail}
            id={item?.exercise_id}
            onpress={() => navigation.navigate(routes.exercisePlayerScreen, { videoUrl: item?.template_video?.video_link })}
        />
    )
    const renderTestimonials = ({ item }) => (
        <VideoThumbnailComponent
            type="free"
            title={item?.sub_title}
            thumbnail={item?.thumbnail_image}
            id={item?.id}
            videoUrl={item?.video_link}
            onpress={() => { }}
        />
    )
    const renderTrainers = ({ item }) => {
        let id = item?.id // future use
        return (
            <View style={styles.trainerItemContainer}>
                <Image
                    source={item?.image ? { uri: IMAGE_URL + item?.image } : require('../../assets/Images/commons/trainer2.png')}
                    style={styles.trainerIcon}
                    resizeMode="contain"
                />
                <View style={styles.trainerNameContainer}>
                    <Text style={styles.trainersText}>{item?.name}</Text>
                </View>
                {item?.designition && <Text style={styles.trainersText}>{item?.designition}</Text>}
                <Text style={styles.trainerExpText}>{item?.experience}</Text>
            </View>
        )
    }
    const renderBlogs = ({ item }) => {
        const createDate = moment(item?.create_date).format('DD-MM-YY')
        return (
            <BlogRecommendationCard
                bannerImage={IMAGE_URL + item?.banner_image}
                category={item?.blog_type[0]?.name}
                title={item?.name}
                description={item?.meta_description}
                authorImage={item?.author?.image}
                authorName={item?.author?.name}
                readTime={`${item?.read_duration} mins`}
                uploadDate={createDate}
                onPress={() => navigation.navigate(routes.blogDetailsScreen, { urlSlug: item?.url_slug })}
                cardBackgroundColor={colors.white}
            />
        )
    }

    return (
        <>
            <CustomHeader
                title={
                    <Text style={styles.headerText}>
                        Diet/Fitness{'  '}
                        {userData?.isFromPartner &&
                            <TouchableOpacity
                                onPress={() => navigation.navigate(routes.collaboration)}>
                                <Image
                                    style={styles.partnerImage}
                                    source={{ uri: IMAGE_URL + userData?.partner?.logo }} />
                            </TouchableOpacity>}
                    </Text>
                }
                menuButton
                renderRightIcon={() => (
                    <View style={{ ...styles.rowCenter, gap: 12, }}>
                        {tabIndex === 0 &&
                            <TouchableOpacity
                                onPress={() => setSearchPopUp(true)}
                                style={styles.headerIconsContainer}>
                                <FIcon name='search' size={fontSize.fs24} color={colors.c666666} />
                            </TouchableOpacity>}
                        <TouchableOpacity
                            onPress={() => setCalenderPopUp(true)}
                            style={styles.headerIconsContainer}>
                            <CalendarIcon />
                        </TouchableOpacity>
                    </View>
                )}
            />
            <HeaderCalendarPopup
                visible={calenderPopUp}
                setVisible={setCalenderPopUp}
            />
            <FoodListPopUp
                visible={searchPopUp}
                setVisible={setSearchPopUp}
            />
            <ScrollView style={styles.container}>
                <WeekWiseDateComponent />

                <View style={styles.p16}>
                    <View style={{ ...styles.rowCenterApart, gap: 12 }}>
                        {buttonsData.map((button, index) => (
                            <ButtonComponent
                                key={index}
                                title={button.title}
                                customHeight={44}
                                textStyle={styles.btnTextStyle}
                                isActive={tabIndex === button.index}
                                style={{ flex: 1, borderRadius: 64 }}
                                bgColor={colors.white}
                                onPress={() => handleButtonClick(button.index)}
                            />
                        ))}
                    </View>
                </View>

                {tabIndex === 0 ?
                    <DietPlanDashboard /> :
                    <>
                        {isGymPlan &&
                            <View style={styles.p16}>
                                <View style={styles.rowCenterApart}>
                                    <Text style={styles.contentTitle}>{Strings.TODAYS_WORKOUTS}</Text>
                                    <TouchableOpacity>
                                        <Text style={styles.seeDetailText}>{Strings.SEE_DETAIL}</Text>
                                    </TouchableOpacity>
                                </View>
                            </View>}
                        {isGymPlan &&
                            <WorkoutDietAlert
                                onlyCard
                                hasVideo
                                data={fitnessData?.user_data[0]}
                                onpress={() => navigation.navigate(routes.todaysWorkout)}
                            />}

                        {userType === Strings.FREE || userType === Strings.GUEST ?
                            <View>
                                <View style={[styles.p16, { paddingVertical: 0 }]}>
                                    <TitleComponent
                                        title={Strings.GOAL_ORIENTED_WORKOUTS}
                                        icon={<TouchableOpacity>
                                            <InfoIcon />
                                        </TouchableOpacity>}
                                    />
                                </View>
                                <FlatList
                                    data={fitnessData?.Main_category}
                                    renderItem={renderGoalOrientedWorkouts}
                                    keyExtractor={(_, index) => index?.toString()}
                                    horizontal
                                    style={{ flex: 1 }}
                                    contentContainerStyle={{
                                        gap: 20,
                                        paddingHorizontal: 14
                                    }}
                                    showsHorizontalScrollIndicator={false}
                                />
                            </View>
                            :
                            // <View style={styles.p16}>
                            //     <ListWithTitle
                            //         title={'My progress'}
                            //         data={historysDataItems}
                            //         selectedName={selectedFilterId}
                            //         setSelectedName={setSelectedFilterId}
                            //         key={'my-progress-history-tracker'}
                            //         listRef={flatlistRef}
                            //     />

                            //     <BarChartCustom
                            //         chartConfig={chartConfig}
                            //         data={barchartData}
                            //         key={'custom-bar-chart-fitness-db'}
                            //         showXAxis
                            //         graphWidth={width}
                            //     />
                            // </View>  ------------   commented for now (calories in v2)
                            null}

                        <View style={styles.freeWorkoutsContainer}>
                            <View style={[styles.p16, { paddingVertical: 0 }]}>
                                <TitleComponent
                                    title="Explore free workouts"
                                    icon={<TouchableOpacity>
                                        <InfoIcon />
                                    </TouchableOpacity>}
                                    key={'explore-free-workouts-fitness-db'}
                                />
                            </View>

                            <FlatList
                                data={fitnessData?.sub_category}
                                renderItem={renderFreeWorkouts}
                                horizontal
                                contentContainerStyle={{ gap: 20, paddingHorizontal: 16 }}
                                showsHorizontalScrollIndicator={false}
                                bounces={false}
                            />
                        </View>

                        {userType === Strings.FREE || userType === Strings.GUEST &&
                            <>
                                <ImageBackground
                                    style={{
                                        width: width,
                                        height: width / 1.7,
                                        resizeMode: 'stretch'
                                    }}
                                    source={'48'}>
                                </ImageBackground>
                                <FlatList
                                    data={buyPlanList[0]?.data}
                                    renderItem={renderFitnessPlans}
                                    horizontal
                                />
                            </>}
                        <View>
                            <View style={[styles.p16, { paddingBottom: 0 }]}>
                                <TitleComponent
                                    title="Home workout for you"
                                    icon={<TouchableOpacity>
                                        <InfoIcon />
                                    </TouchableOpacity>}
                                />
                            </View>
                            <FlatList
                                data={fitnessData?.home_workout_videos}
                                renderItem={renderHomeWorkouts}
                                horizontal
                                keyExtractor={(_, index) => index?.toString()}
                                contentContainerStyle={{ gap: 20, paddingHorizontal: 16 }}
                                showsHorizontalScrollIndicator={false}
                                bounces={false}
                            />

                        </View>
                        <View style={styles.p16}>
                            <TitleComponent
                                title="Our Trainers"
                                icon={<InfoIcon />}
                            />
                            <FlatList
                                data={fitnessData?.coaches_data}
                                renderItem={renderTrainers}
                                horizontal
                                contentContainerStyle={{ gap: 24 }}
                                showsHorizontalScrollIndicator={false}
                            />
                        </View>

                        <View style={styles.p16}>
                            <TitleComponent title="Our Testimonials" />
                            <FlatList
                                data={fitnessData?.testimonials}
                                renderItem={renderTestimonials}
                                horizontal
                                contentContainerStyle={{ gap: 16 }}
                            />
                        </View>

                        <View style={styles.p16}>
                            <TitleComponent
                                title="Chat with your trainer"
                            />
                            <View style={styles.chatCardContainer}>
                                <LinearGradient
                                    colors={['rgba(0,0,0,.05)', 'rgba(0,0,0,.08)']}
                                    start={{ x: 0, y: 0 }}
                                    end={{ x: 0, y: 1 }}
                                    style={{ ...styles.gradientContainer, padding: 0 }}>
                                    <View style={{ ...styles.rowCenterApart, paddingHorizontal: 12 }}>
                                        <View style={{ flex: 1 }}>
                                            <View >
                                                <Text style={styles.contentTitle}>Dmitry Medvedev</Text>
                                                <Text style={styles.trainerDesc}>Logging your food is the best way to achieve your goal.</Text>
                                            </View>
                                            <ButtonComponent
                                                title={'Start chat now'}
                                                bgColor={colors.mainBlack}
                                                customWidth={'100%'}
                                                textStyle={[{ color: colors.white }]}
                                                style={{ borderRadius: 47 }}
                                            />

                                        </View>
                                        <View style={{ flex: 1, marginTop: 'auto' }}>
                                            <Image
                                                source={require('../../assets/Images/commons/chat-now-img.png')}
                                                style={styles.trainerImage}
                                                resizeMode="contain"
                                            />
                                        </View>
                                    </View>
                                </LinearGradient>
                            </View>
                        </View>
                        {isGymPlan &&
                            <>
                                <View style={styles.p16}>
                                    <TitleComponent
                                        title="Blogs"
                                    />
                                </View>
                                <FlatList
                                    data={blogsData?.most_read_blogs}
                                    renderItem={renderBlogs}
                                    horizontal
                                    showsHorizontalScrollIndicator={false}
                                    bounces={false}
                                    style={{ marginBottom: 20 }} />
                            </>}
                    </>
                }

            </ScrollView>
            <StickyCallButton onPress={async () => Alert.alert('Button Pressed')} isShowBottomMessage={true} />
            <BottomStrip onPress={async () => { }} isShowBottomMessage={true} />

        </>
    )
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: colors.cf9f9f9,
    },
    contentTitle: {
        fontFamily: fonts.PoppinsSemiBold,
        fontSize: fontSize.fs18,
        color: colors.mainBlack,
        marginVertical: 9,
        marginTop: 16,
    },
    trainerExpText: {
        fontSize: fontSize.fs10,
        fontFamily: fonts.PoppinsRegular,
        color: colors.green,
        textAlign: 'center'
    },
    btnTextStyle: {
        fontSize: fontSize.fs14,
        fontFamily: fonts.PoppinsMedium,
    },
    seeDetailText: {
        fontFamily: fonts.PoppinsMedium,
        fontSize: fontSize.fs14,
        color: colors.green,
    },
    headerIconsContainer: {
        backgroundColor: colors.cf9f9f9,
        width: width * .1222,
        aspectRatio: 1,
        alignItems: 'center',
        justifyContent: 'center',
        borderRadius: 30,
    },
    p16: {
        padding: 16,
    },
    rowCenter: {
        flexDirection: 'row',
        alignItems: 'center',
    },
    rowCenterApart: {
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between'
    },
    headerText: {
        color: colors.BLACK,
        fontFamily: fonts.PoppinsSemiBold,
        fontSize: fontSize.fs20,
    },
    partnerImage: {
        height: height * 0.026,
        resizeMode: 'contain',
        width: width * 0.093,
    },
    freeWorkoutsContainer: {
        backgroundColor: colors.white,
        borderTopLeftRadius: 24,
        borderTopRightRadius: 24,
        marginTop: 32
    },
    gradientContainer: {
        flex: 1,
        padding: 20,
        borderRadius: 12,
        position: 'relative',
    },

    trainerDesc: {
        fontSize: fontSize.fs14,
        fontFamily: fonts.PoppinsRegular,
        color: colors.c999999
    },
    trainerIcon: {
        width: width * .16,
        height: height * .075,
        borderRadius: 100,
        borderWidth: .2,
        borderColor: colors.green
    },
    trainerImage: {
        height: height * .21,
        width: width * .42,
        marginTop: 'auto',
    },
    trainersText: {
        fontSize: fontSize.fs10,
        fontFamily: fonts.PoppinsMedium,
        color: colors.mainBlack,
        textAlign: 'center',
        // width: '80%'
    },
    trainerItemContainer: {
        alignItems: 'center',
        justifyContent: 'center',
        width: width * .23,
    },
    trainerNameContainer: {
        height: 20,
        justifyContent: 'center'
    }
})
Leave a Comment