feature home

deskripsi:
- tampilan home
This commit is contained in:
2025-06-26 17:43:47 +08:00
parent f0e0ef4b8b
commit 3849e03a1a
17 changed files with 679 additions and 126 deletions

194
screens/Home/UiHome.tsx Normal file
View File

@@ -0,0 +1,194 @@
/* eslint-disable no-unused-expressions */
import Spacing from "@/components/_ShareComponent/Spacing";
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
import { AccentColor, MainColor } from "@/constants/color-palet";
import { Ionicons } from "@expo/vector-icons";
import { Href, router } from "expo-router";
import React from "react";
import {
Dimensions,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native";
import Home_BottomFeatureSection from "./bottomFeatureSection";
import Home_ImageSection from "./imageSection";
import Home_FeatureSection from "./topFeatureSection";
interface Tabs {
id: string;
icon: string;
activeIcon: string;
label: string;
path: Href;
isActive: boolean;
disabled: boolean;
}
const { width } = Dimensions.get("window");
export default function NewHomeView() {
const tabs: Tabs[] = [
{
id: "forum",
icon: "chatbubble-ellipses-outline",
activeIcon: "chatbubble-ellipses",
label: "Forum",
path: "/forum",
isActive: true,
disabled: false,
},
{
id: "marketplace",
icon: "cart-outline",
activeIcon: "cart",
label: "Marketplace",
path: "/market-place",
isActive: false,
disabled: true,
},
{
id: "maps",
icon: "map-outline",
activeIcon: "map",
label: "Maps",
path: "/maps",
isActive: true,
disabled: false,
},
{
id: "profile",
icon: "person-outline",
activeIcon: "person",
label: "Profile",
path: "/profile",
isActive: true,
disabled: false,
},
];
const CustomTab = ({ icon, label, isActive, onPress, disabled }: any) => (
<TouchableOpacity
style={[styles.tabItem, isActive && styles.activeTab]}
onPress={onPress}
activeOpacity={0.7}
>
<View
style={[styles.iconContainer, isActive && styles.activeIconContainer]}
>
<Ionicons name={icon} size={20} color={isActive ? "#fff" : "#666"} />
</View>
<Text style={[styles.tabLabel, isActive && styles.activeTabLabel]}>
{label}
</Text>
{isActive && <View style={styles.activeIndicator} />}
</TouchableOpacity>
);
return (
<>
<ViewWrapper
tabBarComponent={
<View style={styles.tabBar}>
<View style={styles.tabContainer}>
{tabs.map((e) => (
<CustomTab
key={e.id}
icon={e.icon}
label={e.label}
isActive={e.isActive}
onPress={() => {
e.disabled ? console.log("disabled") : router.push(e.path);
}}
/>
))}
</View>
</View>
}
>
<Home_ImageSection />
<Spacing height={10} />
{/* Grid Section */}
<Home_FeatureSection />
<Spacing height={10} />
{/* Job Vacancy Section */}
<Home_BottomFeatureSection />
<Spacing height={20} />
</ViewWrapper>
</>
);
}
const styles = StyleSheet.create({
tabBar: {
backgroundColor: MainColor.darkblue,
borderTopColor: AccentColor.blue,
borderTopWidth: 1,
// borderTopEndRadius: 10,
// borderTopStartRadius: 10,
// tintColor: MainColor.yellow
// paddingBottom: 20,
// paddingTop: 10,
// shadowColor: AccentColor.blue,
// shadowOffset: {
// width: 0,
// height: -2,
// },
// shadowOpacity: 0.9,
// shadowRadius: 3,
// elevation: 5,
},
tabContainer: {
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center",
paddingHorizontal: 0,
},
tabItem: {
alignItems: "center",
justifyContent: "center",
paddingVertical: 8,
paddingHorizontal: 12,
minWidth: width / 5,
position: "relative",
},
activeTab: {
transform: [{ scale: 1.05 }],
},
iconContainer: {
padding: 8,
borderRadius: 20,
// marginBottom: 4,
},
activeIconContainer: {
// backgroundColor: "#007AFF",
// shadowColor: "#007AFF",
// shadowOffset: {
// width: 0,
// height: 2,
// },
// shadowOpacity: 0.3,
// shadowRadius: 4,
// elevation: 4,
},
tabLabel: {
fontSize: 10,
color: "#666",
fontWeight: "500",
},
activeTabLabel: {
color: MainColor.white,
fontWeight: "600",
},
activeIndicator: {
position: "absolute",
bottom: -2,
width: 4,
height: 4,
borderRadius: 2,
backgroundColor: "#007AFF",
},
});

View File

@@ -0,0 +1,60 @@
import Spacing from "@/components/_ShareComponent/Spacing";
import DynamicTruncatedText from "@/components/_ShareComponent/TruncatedText";
import { Text, View } from "react-native";
import Icon from "react-native-vector-icons/FontAwesome";
import { stylesHome } from "./homeViewStyle";
export default function Home_BottomFeatureSection() {
return (
<>
<View style={stylesHome.jobVacancyContainer}>
<View style={stylesHome.jobVacancyHeader}>
<Icon name="briefcase" size={24} color="white" />
<Text style={stylesHome.jobVacancyTitle}>Job Vacancy</Text>
</View>
<View style={stylesHome.vacancyList}>
{/* Vacancy Item 1 */}
<View style={stylesHome.vacancyItem}>
{/* <Icon name="user" size={20} color="#FFD700" /> */}
<View style={stylesHome.vacancyDetails}>
<DynamicTruncatedText
text="Bagas_banuna"
fontSize={14}
fontFamily="System"
style={stylesHome.vacancyName}
/>
<Spacing height={5} />
<DynamicTruncatedText
text="Dicari perawat kucing"
fontSize={12}
fontFamily="System"
style={stylesHome.vacancyDescription}
/>
</View>
</View>
{/* Vacancy Item 2 */}
<View style={stylesHome.vacancyItem}>
{/* <Icon name="user" size={20} color="#FFD700" /> */}
<View style={stylesHome.vacancyDetails}>
<DynamicTruncatedText
text="fibramarcell"
fontSize={14}
fontFamily="System"
style={stylesHome.vacancyName}
/>
<Spacing height={5} />
<DynamicTruncatedText
text="Di Butuhkan Seorang..."
fontSize={12}
fontFamily="System"
style={stylesHome.vacancyDescription}
/>
</View>
</View>
</View>
</View>
</>
);
}

View File

@@ -0,0 +1,26 @@
import { Image } from "expo-image";
import { View } from "react-native";
export default function Home_ImageSection() {
return (
<View
style={{
alignItems: "center",
justifyContent: "center",
backgroundColor: "#fff",
borderRadius: 10,
}}
>
<Image
source={require("@/assets/images/constants/home-hipmi.png")}
contentFit="cover"
transition={1000}
style={{
width: "100%",
height: 120,
borderRadius: 10,
}}
/>
</View>
);
}

View File

@@ -0,0 +1,54 @@
import { Ionicons } from "@expo/vector-icons";
import { router } from "expo-router";
import { Text, TouchableOpacity, View } from "react-native";
import { stylesHome } from "./homeViewStyle";
export default function Home_FeatureSection() {
return (
<>
<View style={stylesHome.gridContainer}>
<TouchableOpacity
style={stylesHome.gridItem}
onPress={() => router.push("/(application)/event")}
>
<Ionicons name="analytics" size={48} color="white" />
<Text style={stylesHome.gridLabel}>Event</Text>
</TouchableOpacity>
<TouchableOpacity style={stylesHome.gridItem}>
<Ionicons name="share" size={48} color="white" />
<Text style={stylesHome.gridLabel}>Collaboration</Text>
</TouchableOpacity>
<TouchableOpacity style={stylesHome.gridItem}>
<Ionicons name="cube" size={48} color="white" />
<Text style={stylesHome.gridLabel}>Voting</Text>
</TouchableOpacity>
<TouchableOpacity style={stylesHome.gridItem}>
<Ionicons name="heart" size={48} color="white" />
<Text style={stylesHome.gridLabel}>Crowdfunding</Text>
</TouchableOpacity>
</View>
<View style={stylesHome.gridContainer}>
<TouchableOpacity
style={stylesHome.gridItem}
onPress={() => router.push("/(application)/event")}
>
<Ionicons name="analytics" size={48} color="white" />
<Text style={stylesHome.gridLabel}>Event</Text>
</TouchableOpacity>
<TouchableOpacity style={stylesHome.gridItem}>
<Ionicons name="share" size={48} color="white" />
<Text style={stylesHome.gridLabel}>Collaboration</Text>
</TouchableOpacity>
<TouchableOpacity style={stylesHome.gridItem}>
<Ionicons name="cube" size={48} color="white" />
<Text style={stylesHome.gridLabel}>Voting</Text>
</TouchableOpacity>
<TouchableOpacity style={stylesHome.gridItem}>
<Ionicons name="heart" size={48} color="white" />
<Text style={stylesHome.gridLabel}>Crowdfunding</Text>
</TouchableOpacity>
</View>
</>
);
}