151 lines
5.2 KiB
TypeScript
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>
|
|
)
|
|
} |