Files
2026-04-22 16:42:59 +08:00

143 lines
5.7 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 { Alert, 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])
useEffect(() => {
if (profile && profile.isActive === false) {
Alert.alert(
'Akun Dinonaktifkan',
'Akun kamu telah dinonaktifkan. Silahkan hubungi admin untuk informasi lebih lanjut.',
[{ text: 'OK', onPress: signOut }]
)
}
}, [profile, signOut])
useEffect(() => {
if (profile && profile.villageIsActive === false) {
Alert.alert(
'Desa Dinonaktifkan',
'Desa kamu saat ini telah dinonaktifkan. Silahkan hubungi pengelola sistem untuk informasi lebih lanjut.',
[{ text: 'OK', onPress: signOut }]
)
}
}, [profile, 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>
)
}