Files
mobile-darmasaba/components/home/carouselHome2.tsx
amaliadwiy ccf8ee1caf upd: caching data
Deskripsi:
- update caching pada fitur utama -yg fitur divisi belom
2026-04-20 14:23:14 +08:00

151 lines
5.2 KiB
TypeScript

import { ConstEnv } from "@/constants/ConstEnv";
import Styles from "@/constants/Styles";
import { apiGetBanner, apiGetProfile } from "@/lib/api";
import { setEntities } from "@/lib/bannerSlice";
import { setEntityUser } from "@/lib/userSlice";
import { useAuthSession } from "@/providers/AuthProvider";
import { useTheme } from "@/providers/ThemeProvider";
import { Feather, Ionicons } from "@expo/vector-icons";
import { useQuery } from "@tanstack/react-query";
import { router } from "expo-router";
import React, { useEffect } from "react";
import { Dimensions, Image, View } from "react-native";
import { useSharedValue } from "react-native-reanimated";
import Carousel, { ICarouselInstance } from "react-native-reanimated-carousel";
import { useDispatch, useSelector } from "react-redux";
import { ButtonFiturMenu } from "../buttonFiturMenu";
import Text from "../Text";
export default function CaraouselHome2({ refreshing }: { refreshing: boolean }) {
const { decryptToken, token } = useAuthSession()
const { colors } = useTheme();
const ref = React.useRef<ICarouselInstance>(null);
const width = Dimensions.get("window").width;
const progress = useSharedValue<number>(0);
const dispatch = useDispatch()
const entities = useSelector((state: any) => state.banner)
// Query for Banners
const { data: banners } = useQuery({
queryKey: ['banners'],
queryFn: async () => {
const hasil = await decryptToken(String(token?.current))
const data = await apiGetBanner({ user: hasil })
return data.data || []
},
enabled: !!token?.current,
staleTime: 0,
})
// Query for Profile (Role Check)
const { data: profile } = useQuery({
queryKey: ['profile'], // Shares same key as Home.tsx
queryFn: async () => {
const hasil = await decryptToken(String(token?.current))
const data = await apiGetProfile({ id: hasil })
return data.data
},
enabled: !!token?.current,
staleTime: 0,
})
// Sync Banners to Redux
useEffect(() => {
if (banners) {
dispatch(setEntities(banners))
}
}, [banners, dispatch])
// Sync User Role to Redux
useEffect(() => {
if (profile) {
dispatch(setEntityUser({ role: profile.idUserRole, admin: false }))
}
}, [profile, dispatch])
return (
<View
style={[
Styles.mv15,
Styles.p15,
Styles.round05,
{ backgroundColor: colors.card },
Styles.wrapHomeCarousel
]}
>
{/* WRAPPER CAROUSEL */}
<View
style={{
justifyContent: 'center', // ⬅️ vertical center
alignItems: 'center',
}}
>
{entities.length > 0 ? (
<Carousel
ref={ref}
width={width - 30} // ⬅️ biar ga nabrak padding hijau
height={width / 2.6}
data={entities}
loop
autoPlay
autoPlayInterval={5000}
onProgressChange={progress}
renderItem={({ index }) => (
<Image
source={{ uri: `${ConstEnv.url_storage}/files/${entities[index].image}` }}
style={[
Styles.caraoselContent,
Styles.round05,
{
backgroundColor: colors.primary
},
]}
resizeMode="stretch"
/>
)}
/>
) : (
<View
style={[
Styles.caraoselContent,
{
height: width / 2.5,
backgroundColor: colors.primary,
justifyContent: 'center',
alignItems: 'center',
},
]}
>
<Text style={[Styles.textDefault, Styles.cWhite]}>BANNER</Text>
</View>
)}
</View>
{/* FITUR */}
<View style={[Styles.mt15]}>
<View style={Styles.rowSpaceBetween}>
<ButtonFiturMenu
icon={<Feather name="users" size={30} color={colors.icon} />}
text="Divisi"
onPress={() => router.push('/division?active=true')}
/>
<ButtonFiturMenu
icon={<Feather name="bar-chart" size={30} color={colors.icon} />}
text="Kegiatan"
onPress={() => router.push('/project?status=0')}
/>
<ButtonFiturMenu
icon={<Ionicons name="megaphone-outline" size={30} color={colors.icon} />}
text="Pengumuman"
onPress={() => router.push('/announcement')}
/>
<ButtonFiturMenu
icon={<Ionicons name="grid-outline" size={30} color={colors.icon} />}
text="Semua"
onPress={() => router.push('/feature')}
/>
</View>
</View>
</View>
)
}