123 lines
5.0 KiB
TypeScript
123 lines
5.0 KiB
TypeScript
import CaraouselHome2 from "@/components/home/carouselHome2";
|
|
import ChartDokumenHome from "@/components/home/chartDokumenHome";
|
|
import ChartProgresHome from "@/components/home/chartProgresHome";
|
|
import DisccussionHome from "@/components/home/discussionHome";
|
|
import DivisionHome from "@/components/home/divisionHome";
|
|
import EventHome from "@/components/home/eventHome";
|
|
import { HeaderRightHome } from "@/components/home/headerRightHome";
|
|
import ProjectHome from "@/components/home/projectHome";
|
|
import Text from "@/components/Text";
|
|
import Styles from "@/constants/Styles";
|
|
import { apiGetProfile } from "@/lib/api";
|
|
import { setEntities } from "@/lib/entitiesSlice";
|
|
import { useAuthSession } from "@/providers/AuthProvider";
|
|
import { useTheme } from "@/providers/ThemeProvider";
|
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
import { LinearGradient } from "expo-linear-gradient";
|
|
import { Stack } from "expo-router";
|
|
import { useEffect, useState } from "react";
|
|
import { Dimensions, Platform, RefreshControl, SafeAreaView, ScrollView, View } from "react-native";
|
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
|
|
|
|
export default function Home() {
|
|
const entities = useSelector((state: any) => state.entities)
|
|
const dispatch = useDispatch()
|
|
const queryClient = useQueryClient()
|
|
const { token, decryptToken, signOut } = useAuthSession()
|
|
const { colors } = useTheme();
|
|
const insets = useSafeAreaInsets()
|
|
const [refreshing, setRefreshing] = useState(false)
|
|
|
|
const { data: profile, isError } = useQuery({
|
|
queryKey: ['profile'],
|
|
queryFn: async () => {
|
|
const hasil = await decryptToken(String(token?.current))
|
|
const data = await apiGetProfile({ id: hasil })
|
|
return data.data
|
|
},
|
|
enabled: !!token?.current,
|
|
staleTime: 0, // Ensure it refetches every time the component mounts
|
|
})
|
|
|
|
// Sync to Redux for global usage
|
|
useEffect(() => {
|
|
if (profile) {
|
|
dispatch(setEntities(profile))
|
|
}
|
|
}, [profile, dispatch])
|
|
|
|
// Auto Sign Out if profile fetch fails (e.g. invalid/expired token)
|
|
useEffect(() => {
|
|
if (isError) {
|
|
signOut()
|
|
}
|
|
}, [isError, signOut])
|
|
|
|
const handleRefresh = async () => {
|
|
setRefreshing(true)
|
|
// Invalidate all queries related to the home screen
|
|
await queryClient.invalidateQueries({ queryKey: ['profile'] })
|
|
await queryClient.invalidateQueries({ queryKey: ['banners'] })
|
|
await queryClient.invalidateQueries({ queryKey: ['homeData'] })
|
|
|
|
// Artificial delay to show refresh indicator if sync is too fast
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
setRefreshing(false)
|
|
};
|
|
|
|
return (
|
|
<SafeAreaView style={[Styles.flex1, { backgroundColor: colors.background }]}>
|
|
<Stack.Screen
|
|
options={{
|
|
title: 'Home',
|
|
headerTitle: entities.village,
|
|
header: () => (
|
|
<View style={[Styles.rowItemsCenter, Styles.ph20, Platform.OS === 'ios' ? Styles.pb07 : Styles.pb13, { backgroundColor: colors.header, paddingTop: Platform.OS === 'ios' ? insets.top : 10 }]}>
|
|
<Text style={Styles.textHeaderHome}>{entities.village}</Text>
|
|
<HeaderRightHome />
|
|
</View>
|
|
),
|
|
}}
|
|
/>
|
|
<ScrollView
|
|
refreshControl={
|
|
<RefreshControl
|
|
refreshing={refreshing}
|
|
onRefresh={handleRefresh}
|
|
tintColor={colors.icon}
|
|
/>
|
|
}
|
|
showsVerticalScrollIndicator={false}
|
|
style={[Styles.h100, { backgroundColor: colors.background }]}
|
|
>
|
|
<LinearGradient
|
|
colors={[colors.header, colors.header, colors.header, colors.header, colors.homeGradient]}
|
|
style={[
|
|
Styles.posAbsolute,
|
|
Styles.zIndexMinus1,
|
|
{
|
|
width: Dimensions.get('window').width * 1.5,
|
|
height: Dimensions.get('window').width * 1.5,
|
|
borderRadius: Dimensions.get('window').width * 0.5,
|
|
top: -Dimensions.get('window').width * 1, // Positioned to show the bottom part of the circle as an arc
|
|
left: -Dimensions.get('window').width * 0.25,
|
|
}
|
|
]}
|
|
/>
|
|
{/* <CaraouselHome refreshing={refreshing} /> */}
|
|
<View style={[Styles.ph15]}>
|
|
<CaraouselHome2 refreshing={refreshing} />
|
|
{/* <FiturHome /> */}
|
|
<ProjectHome refreshing={refreshing} />
|
|
<DivisionHome refreshing={refreshing} />
|
|
<ChartProgresHome refreshing={refreshing} />
|
|
<ChartDokumenHome refreshing={refreshing} />
|
|
<EventHome refreshing={refreshing} />
|
|
<DisccussionHome refreshing={refreshing} />
|
|
</View>
|
|
</ScrollView>
|
|
</SafeAreaView>
|
|
)
|
|
} |