Compare commits

...

7 Commits

Author SHA1 Message Date
16559b94fe feature & fix
deskripsi:
- fix Text input
- feature Box footer & button center
2025-07-09 10:19:02 +08:00
0698e14d36 fix route
deskripsi:
- perbaiki route tujuan pada create profile
2025-07-08 14:18:50 +08:00
3d9672154c fix folder
deskripsi:
- fix folder profile ke (user)
2025-07-08 12:22:15 +08:00
55b4b1fa8d fix folder
deskripsi:
- pindah folder portofolio ke (user)
2025-07-08 12:11:35 +08:00
b80968999e fix
-deskripsi:
- fix folder: map, marketplace, forum ke (user)
2025-07-08 12:04:51 +08:00
6bac89c536 fix folder
deskripsi:
- pindah folder event ke (user)
2025-07-08 11:58:32 +08:00
b9af7e0ca7 fix folder
deksripsi:
- pindah folder user search & notifikasi ke (user)
2025-07-08 11:47:32 +08:00
61 changed files with 1534 additions and 334 deletions

View File

@@ -0,0 +1,117 @@
import { BackButton } from "@/components";
import LeftButtonCustom from "@/components/Button/BackButton";
import { MainColor } from "@/constants/color-palet";
import { HeaderStyles } from "@/styles/header-styles";
import { Ionicons } from "@expo/vector-icons";
import { router, Stack } from "expo-router";
export default function UserLayout() {
return (
<>
<Stack screenOptions={HeaderStyles}>
<Stack.Screen
name="home"
options={{
title: "HIPMI",
headerLeft: () => (
<Ionicons
name="search"
size={20}
color={MainColor.yellow}
onPress={() => router.push("/user-search")}
/>
),
headerRight: () => (
<Ionicons
name="notifications"
size={20}
color={MainColor.yellow}
onPress={() => router.push("/notifications")}
/>
),
}}
/>
{/* Profile */}
<Stack.Screen
name="profile"
options={{
headerShown: false,
}}
/>
{/* Portofolio */}
<Stack.Screen
name="portofolio"
options={{
headerShown: false,
}}
/>
{/* User Search */}
<Stack.Screen
name="user-search/index"
options={{
title: "Pencarian Pengguna",
headerLeft: () => <BackButton />,
}}
/>
{/* Notification */}
<Stack.Screen
name="notifications/index"
options={{
title: "Notifikasi",
headerLeft: () => <BackButton />,
}}
/>
{/* Event */}
<Stack.Screen
name="event/(tabs)"
options={{
title: "Event",
headerLeft: () => (
<LeftButtonCustom path="/(application)/(user)/home" />
),
}}
/>
<Stack.Screen
name="event/detail/[id]"
options={{
title: "Event Detail",
headerLeft: () => <LeftButtonCustom />,
}}
/>
{/* Forum */}
<Stack.Screen
name="forum/index"
options={{
title: "Forum",
headerLeft: () => <BackButton />,
}}
/>
{/* Maps */}
<Stack.Screen
name="maps/index"
options={{
title: "Maps",
headerLeft: () => <BackButton />,
}}
/>
{/* Marketplace */}
<Stack.Screen
name="marketplace/index"
options={{
title: "Market Place",
headerLeft: () => <BackButton />,
}}
/>
</Stack>
</>
);
}

View File

@@ -8,7 +8,7 @@ export default function EventLayout() {
screenOptions={{
headerShown: false,
tabBarActiveTintColor: MainColor.yellow,
tabBarInactiveTintColor: MainColor.white,
tabBarInactiveTintColor: MainColor.white_gray,
tabBarStyle: {
backgroundColor: MainColor.darkblue,
},

View File

@@ -0,0 +1,11 @@
import { TextCustom, ViewWrapper } from "@/components";
export default function Forum() {
return (
<>
<ViewWrapper>
<TextCustom>Forum</TextCustom>
</ViewWrapper>
</>
);
}

View File

@@ -0,0 +1,9 @@
import { TextCustom, ViewWrapper } from "@/components";
export default function Maps() {
return (
<ViewWrapper>
<TextCustom>Maps</TextCustom>
</ViewWrapper>
)
}

View File

@@ -0,0 +1,9 @@
import { TextCustom, ViewWrapper } from "@/components";
export default function Marketplace() {
return (
<ViewWrapper>
<TextCustom>Marketplace</TextCustom>
</ViewWrapper>
);
}

View File

@@ -0,0 +1,9 @@
import { TextCustom, ViewWrapper } from "@/components";
export default function Notifications() {
return (
<ViewWrapper>
<TextCustom>Notifications</TextCustom>
</ViewWrapper>
);
}

View File

@@ -0,0 +1,170 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import {
ButtonCustom,
Grid,
SelectCustom,
Spacing,
StackCustom,
TextAreaCustom,
TextCustom,
TextInputCustom,
ViewWrapper,
} from "@/components";
import BoxButtonOnFooter from "@/components/Box/BoxButtonOnFooter";
import InformationBox from "@/components/Box/InformationBox";
import ButtonCenteredOnly from "@/components/Button/ButtonCenteredOnly";
import LandscapeFrameUploaded from "@/components/Image/LandscapeFrameUploaded";
import { MainColor } from "@/constants/color-palet";
import dummyMasterBidangBisnis from "@/lib/dummy-data/master-bidang-bisnis";
import dummyMasterSubBidangBisnis from "@/lib/dummy-data/master-sub-bidang-bisnis";
import { Ionicons } from "@expo/vector-icons";
import { useLocalSearchParams } from "expo-router";
import { useState } from "react";
import { Text, TouchableOpacity, View } from "react-native";
import PhoneInput, { ICountry } from "react-native-international-phone-number";
export default function PortofolioCreate() {
const { id } = useLocalSearchParams();
const [selectedCountry, setSelectedCountry] = useState<null | ICountry>(null);
const [inputValue, setInputValue] = useState<string>("");
const [data, setData] = useState({
name: "",
bidang_usaha: "",
sub_bidang_usaha: "",
alamat: "",
nomor_telepon: "",
deskripsi: "",
});
function handleInputValue(phoneNumber: string) {
setInputValue(phoneNumber);
}
function handleSelectedCountry(country: ICountry) {
setSelectedCountry(country);
}
function handleSave() {
console.log("save");
}
const buttonSave = (
<BoxButtonOnFooter>
<ButtonCustom onPress={handleSave}>Selanjutnya</ButtonCustom>
</BoxButtonOnFooter>
);
return (
<ViewWrapper footerComponent={buttonSave}>
{/* <TextCustom>Portofolio Create {id}</TextCustom> */}
<StackCustom>
<InformationBox text="Lengkapi data bisnis anda." />
<TextInputCustom
required
label="Nama Bisnis"
placeholder="Masukkan nama bisnis"
/>
<SelectCustom
label="Bidang Usaha"
required
data={dummyMasterBidangBisnis.map((item) => ({
label: item.name,
value: item.id,
}))}
value=""
onChange={(value) => console.log(value)}
/>
<Grid>
<Grid.Col span={10}>
<SelectCustom
label="Sub Bidang Usaha"
required
data={dummyMasterSubBidangBisnis.map((item) => ({
label: item.name,
value: item.id,
}))}
value=""
onChange={(value) => console.log(value)}
/>
</Grid.Col>
<Grid.Col
span={2}
style={{ alignItems: "center", justifyContent: "center" }}
>
<TouchableOpacity onPress={() => console.log("delete")}>
<Ionicons name="trash" size={24} color={MainColor.red} />
</TouchableOpacity>
</Grid.Col>
</Grid>
<ButtonCenteredOnly onPress={() => console.log("add")}>
Tambah Pilihan
</ButtonCenteredOnly>
<Spacing />
<TextInputCustom
required
label="Alamat Bisnis"
placeholder="Masukkan alamat bisnis"
/>
<View>
<View style={{ flexDirection: "row", alignItems: "center" }}>
<TextCustom semiBold style={{ color: MainColor.white_gray }}>
Nomor Telepon
</TextCustom>
<Text style={{ color: "red" }}> *</Text>
</View>
<Spacing height={5} />
<PhoneInput
value={inputValue}
onChangePhoneNumber={handleInputValue}
selectedCountry={selectedCountry}
onChangeSelectedCountry={handleSelectedCountry}
defaultCountry="ID"
placeholder="xxx-xxx-xxx"
/>
</View>
<Spacing />
<TextAreaCustom
label="Deskripsi Bisnis"
placeholder="Masukkan deskripsi bisnis"
value={data.deskripsi}
onChangeText={(value: any) => setData({ ...data, deskripsi: value })}
autosize
minRows={2}
maxRows={5}
required
showCount
maxLength={100}
/>
<Spacing />
<InformationBox text="Upload logo bisnis anda untuk di tampilaka pada portofolio." />
<LandscapeFrameUploaded />
<ButtonCenteredOnly icon="upload" onPress={() => console.log("upload")}>
Upload
</ButtonCenteredOnly>
<Spacing height={40} />
<InformationBox text="Isi hanya pada sosial media yang anda miliki." />
<TextInputCustom
label="Tiktok"
placeholder="Masukkan username tiktok"
/>
<TextInputCustom
label="Facebook"
placeholder="Masukkan username facebook"
/>
<TextInputCustom
label="Instagram"
placeholder="Masukkan username instagram"
/>
<TextInputCustom
label="Twitter"
placeholder="Masukkan username twitter"
/>
<TextInputCustom
label="Youtube"
placeholder="Masukkan username youtube"
/>
<Spacing />
</StackCustom>
</ViewWrapper>
);
}

View File

@@ -1,4 +1,4 @@
import BackButton from "@/components/Button/BackButton";
import LeftButtonCustom from "@/components/Button/BackButton";
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
import { GStyles } from "@/styles/global-styles";
import { Stack, useLocalSearchParams } from "expo-router";
@@ -12,7 +12,7 @@ export default function Portofolio() {
<Stack.Screen
options={{
title: "Portofolio",
headerLeft: () => <BackButton />,
headerLeft: () => <LeftButtonCustom />,
// headerRight: () => (
// <TouchableOpacity onPress={openDrawer}>
// <Ionicons

View File

@@ -1,5 +1,5 @@
import BackButton from "@/components/Button/BackButton";
import LeftButtonCustom from "@/components/Button/BackButton";
import { GStyles } from "@/styles/global-styles";
import { Stack } from "expo-router";
@@ -12,7 +12,7 @@ export default function PortofolioLayout() {
headerTitleStyle: GStyles.headerTitleStyle,
headerTitleAlign: "center",
headerBackButtonDisplayMode: "minimal",
headerLeft: () => <BackButton />,
headerLeft: () => <LeftButtonCustom />,
}}
>
{/* <Stack.Screen name="[id]/index" options={{ title: "Portofolio" }} /> */}
@@ -20,6 +20,7 @@ export default function PortofolioLayout() {
name="[id]/create"
options={{ title: "Tambah Portofolio" }}
/>
</Stack>
</>
);

View File

@@ -7,14 +7,16 @@ import {
TextInputCustom,
ViewWrapper,
} from "@/components";
import BoxButtonOnFooter from "@/components/Box/BoxButtonOnFooter";
import InformationBox from "@/components/Box/InformationBox";
import ButtonUpload from "@/components/Button/ButtonUpload";
import LandscapeFrameUploaded from "@/components/Image/LandscapeFrameUploaded";
import { GStyles } from "@/styles/global-styles";
import { router, useLocalSearchParams } from "expo-router";
import { useState } from "react";
import { View } from "react-native";
export default function CreateProfile() {
const { id } = useLocalSearchParams();
const [data, setData] = useState({
name: "",
email: "",
@@ -24,20 +26,18 @@ export default function CreateProfile() {
const handlerSave = () => {
console.log("data create profile >>", data);
// router.back();
router.back();
};
const footerComponent = (
<View style={GStyles.bottomBar}>
<View style={GStyles.bottomBarContainer}>
<ButtonCustom
onPress={handlerSave}
disabled={!data.name || !data.email || !data.address || !data.gender}
>
Simpan
</ButtonCustom>
</View>
</View>
<BoxButtonOnFooter>
<ButtonCustom
onPress={handlerSave}
// disabled={!data.name || !data.email || !data.address || !data.gender}
>
Simpan
</ButtonCustom>
</BoxButtonOnFooter>
);
return (
@@ -47,7 +47,9 @@ export default function CreateProfile() {
<View style={{ alignItems: "center" }}>
<AvatarCustom size="xl" />
<Spacing />
<ButtonUpload onPress={() => console.log("pressed")} />
<ButtonUpload
onPress={() => router.navigate(`/take-picture/${id}`)}
/>
</View>
<Spacing />
@@ -56,7 +58,9 @@ export default function CreateProfile() {
<InformationBox text="Upload foto latar belakang anda." />
<LandscapeFrameUploaded />
<Spacing />
<ButtonUpload onPress={() => console.log("pressed")} />
<ButtonUpload
onPress={() => router.navigate(`/take-picture/${id}`)}
/>
</View>
<Spacing />

View File

@@ -6,6 +6,7 @@ import {
TextInputCustom,
ViewWrapper,
} from "@/components";
import BoxButtonOnFooter from "@/components/Box/BoxButtonOnFooter";
import { router, useLocalSearchParams } from "expo-router";
import { useState } from "react";
import { StyleSheet } from "react-native";
@@ -44,15 +45,17 @@ export default function ProfileEdit() {
return (
<ViewWrapper
bottomBarComponent={
<ButtonCustom
disabled={
!data.nama || !data.email || !data.alamat || !data.selectedValue
}
onPress={handleSave}
>
Simpan
</ButtonCustom>
footerComponent={
<BoxButtonOnFooter>
<ButtonCustom
// disabled={
// !data.nama || !data.email || !data.alamat || !data.selectedValue
// }
onPress={handleSave}
>
Simpan
</ButtonCustom>
</BoxButtonOnFooter>
}
>
<StackCustom gap={"xs"}>

View File

@@ -1,7 +1,7 @@
import { IMenuDrawerItem } from "@/components/_Interface/types";
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
import AlertCustom from "@/components/Alert/AlertCustom";
import BackButton from "@/components/Button/BackButton";
import LeftButtonCustom from "@/components/Button/BackButton";
import DrawerCustom from "@/components/Drawer/DrawerCustom";
import { MainColor } from "@/constants/color-palet";
import { DRAWER_HEIGHT } from "@/constants/constans-value";
@@ -89,7 +89,7 @@ export default function Profile() {
<Stack.Screen
options={{
title: "Profile",
headerLeft: () => <BackButton />,
headerLeft: () => <LeftButtonCustom />,
headerRight: () => (
<TouchableOpacity onPress={openDrawer}>
<Ionicons

View File

@@ -0,0 +1,9 @@
import { TextCustom, ViewWrapper } from "@/components";
export default function UserSearch() {
return (
<ViewWrapper>
<TextCustom>User Search</TextCustom>
</ViewWrapper>
);
}

View File

@@ -1,171 +1,13 @@
import { AccentColor, MainColor } from "@/constants/color-palet";
import { GStyles } from "@/styles/global-styles";
import { MainColor } from "@/constants/color-palet";
import { HeaderStyles } from "@/styles/header-styles";
import { Ionicons } from "@expo/vector-icons";
import { router, Stack } from "expo-router";
export default function ApplicationLayout() {
return (
<>
<Stack
screenOptions={{
headerStyle: GStyles.headerStyle,
headerTitleStyle: GStyles.headerTitleStyle,
headerTitleAlign: "center",
contentStyle: {
borderBottomColor: AccentColor.blue,
borderBottomWidth: 2,
},
// headerLargeStyle: {
// backgroundColor: MainColor.darkblue,
// },
}}
>
<Stack.Screen
name="home"
options={{
title: "HIPMI",
headerLeft: () => (
<Ionicons
name="search"
size={20}
color={MainColor.yellow}
onPress={() => router.push("/(application)/user-search")}
/>
),
headerRight: () => (
<Ionicons
name="notifications"
size={20}
color={MainColor.yellow}
onPress={() => router.push("/(application)/notifications")}
/>
),
}}
/>
<Stack.Screen
name="forum/index"
options={{
title: "Forum",
headerLeft: () => (
<Ionicons
name="arrow-back"
size={20}
color={MainColor.yellow}
onPress={() => router.back()}
/>
),
}}
/>
<Stack.Screen
name="maps/index"
options={{
title: "Maps",
headerLeft: () => (
<Ionicons
name="arrow-back"
size={20}
color={MainColor.yellow}
onPress={() => router.back()}
/>
),
}}
/>
<Stack.Screen
name="marketplace/index"
options={{
title: "Market Place",
headerLeft: () => (
<Ionicons
name="arrow-back"
size={20}
color={MainColor.yellow}
onPress={() => router.back()}
/>
),
}}
/>
{/* Profile */}
<Stack.Screen
name="profile"
options={{
headerShown: false,
}}
/>
{/* Portofolio */}
<Stack.Screen
name="portofolio"
options={{
headerShown: false,
}}
/>
{/* Event */}
<Stack.Screen
name="event/(tabs)"
options={{
title: "Event",
headerLeft: () => (
<Ionicons
name="arrow-back"
size={20}
color={MainColor.yellow}
onPress={() => router.push("/(application)/home")}
/>
),
}}
/>
<Stack.Screen
name="event/detail/[id]"
options={{
title: "Detail",
headerLeft: () => (
<Ionicons
name="arrow-back"
size={20}
color={MainColor.yellow}
onPress={() => router.back()}
/>
),
}}
/>
{/* User Search */}
<Stack.Screen
name="user-search/index"
options={{
title: "Pencarian Pengguna",
headerLeft: () => (
<Ionicons
name="arrow-back"
size={20}
color={MainColor.yellow}
onPress={() => router.back()}
/>
),
}}
/>
{/* Notification */}
<Stack.Screen
name="notifications/index"
options={{
title: "Notifikasi",
headerLeft: () => (
<Ionicons
name="arrow-back"
size={20}
color={MainColor.yellow}
onPress={() => router.back()}
/>
),
}}
/>
<Stack screenOptions={HeaderStyles}>
<Stack.Screen name="(user)" options={{ headerShown: false }} />
{/* Take Picture */}
<Stack.Screen

View File

@@ -1,11 +0,0 @@
import { Text, View } from "react-native";
export default function Forum() {
return (
<>
<View>
<Text>Forum</Text>
</View>
</>
);
}

View File

@@ -1,9 +0,0 @@
import { Text, View } from "react-native";
export default function Maps() {
return (
<View>
<Text>Maps</Text>
</View>
)
}

View File

@@ -1,9 +0,0 @@
import { Text, View } from "react-native";
export default function MarketPlace() {
return (
<View>
<Text>Market Place</Text>
</View>
);
}

View File

@@ -1,9 +0,0 @@
import { Text, View } from "react-native";
export default function Notifications() {
return (
<View>
<Text>Notifications</Text>
</View>
);
}

View File

@@ -1,11 +0,0 @@
import { Text, View } from "react-native";
import { useLocalSearchParams } from "expo-router";
export default function PortofolioCreate() {
const { id } = useLocalSearchParams();
return (
<View>
<Text>Portofolio Create {id}</Text>
</View>
);
}

View File

@@ -1,9 +0,0 @@
import { Text, View } from "react-native";
export default function UserSearch() {
return (
<View>
<Text>User Search</Text>
</View>
)
}

View File

@@ -1,9 +1,16 @@
import { Text, View } from "react-native";
import { StackCustom, TextCustom, ViewWrapper } from "@/components";
export default function NotFoundScreen() {
return (
<View>
<Text>Not Found</Text>
</View>
)
<ViewWrapper>
<StackCustom align="center" gap={0} style={{justifyContent: "center", alignItems: "center", flex: 1}}>
<TextCustom size="large" bold style={{fontSize: 100}}>
404
</TextCustom>
<TextCustom size="large" bold>
Sorry, File Not Found
</TextCustom>
</StackCustom>
</ViewWrapper>
);
}

View File

@@ -15,6 +15,7 @@ export default function RootLayout() {
}}
>
<Stack.Screen name="index" options={{ title: "" }} />
<Stack.Screen name="+not-found" options={{ title: "" }} />
<Stack.Screen
name="verification"
options={{ title: "", headerBackVisible: false }}

View File

@@ -95,12 +95,12 @@ const styles = StyleSheet.create({
fontSize: TEXT_SIZE_LARGE,
fontWeight: "bold",
marginBottom: 20,
color: MainColor.white,
color: MainColor.white_gray,
},
alertMessage: {
textAlign: "center",
marginBottom: 20,
color: MainColor.white,
color: MainColor.white_gray,
},
alertButtons: {
flexDirection: "row",

View File

@@ -0,0 +1,16 @@
import { GStyles } from "@/styles/global-styles";
import { StyleProp, View, ViewStyle } from "react-native";
export default function BoxButtonOnFooter({
children,
style,
}: {
children: React.ReactNode;
style?: StyleProp<ViewStyle>;
}) {
return (
<View style={GStyles.bottomBar}>
<View style={[GStyles.bottomBarContainer, style]}>{children}</View>
</View>
);
}

View File

@@ -16,7 +16,7 @@ export default function InformationBox({ text }: { text: string }) {
<Ionicons
name="information-circle-outline"
size={24}
color={MainColor.white}
color={MainColor.white_gray}
/>
</Grid.Col>
<Grid.Col span={10} style={{ justifyContent: "center" }}>

View File

@@ -1,16 +1,22 @@
import { Ionicons } from "@expo/vector-icons";
import { MainColor } from "@/constants/color-palet";
import { router } from "expo-router";
import { Ionicons } from "@expo/vector-icons";
import { Href, router } from "expo-router";
const BackButton = () => {
/**
*
* @param path - path to navigate to ?
* @default router.back()
* @returns if path : router.replace(path) else router.back()
*/
const LeftButtonCustom = ({path}: {path?: Href}) => {
return (
<Ionicons
name="arrow-back"
size={20}
color={MainColor.yellow}
onPress={() => router.back()}
onPress={() => path ? router.replace(path) : router.back()}
/>
);
};
export default BackButton;
export default LeftButtonCustom;

View File

@@ -0,0 +1,29 @@
import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_BUTTON } from "@/constants/constans-value";
import { GStyles } from "@/styles/global-styles";
import { Feather } from "@expo/vector-icons";
import React from "react";
import ButtonCustom from "./ButtonCustom";
interface ButtonCenteredOnlyProps {
children?: React.ReactNode;
icon?: "plus" | "upload";
onPress: () => void;
}
export default function ButtonCenteredOnly({
onPress,
children,
icon = "plus"
}: ButtonCenteredOnlyProps) {
return (
<ButtonCustom
onPress={onPress}
iconLeft={
<Feather name={icon} size={ICON_SIZE_BUTTON} color={MainColor.black} />
}
style={[GStyles.buttonCentered50Percent]}
>
{children}
</ButtonCustom>
);
}

View File

@@ -1,6 +1,7 @@
// components/Button/buttonStyles.js
import { MainColor } from "@/constants/color-palet";
import { TEXT_SIZE_MEDIUM } from "@/constants/constans-value";
import { StyleSheet } from "react-native";
export default function buttonStyles({
@@ -21,7 +22,7 @@ export default function buttonStyles({
},
buttonText: {
color: textColor,
fontSize: 16,
fontSize: TEXT_SIZE_MEDIUM,
fontWeight: "600",
},
disabled: {

View File

@@ -1,10 +1,10 @@
import React, { useRef } from "react";
import {
Animated,
PanResponder,
StyleSheet,
View,
InteractionManager,
Animated,
InteractionManager,
PanResponder,
StyleSheet,
View,
} from "react-native";
import { AccentColor, MainColor } from "@/constants/color-palet";
@@ -86,7 +86,7 @@ DrawerCustomProps) {
{...panResponder.panHandlers}
>
<View
style={[styles.headerBar, { backgroundColor: MainColor.white }]}
style={[styles.headerBar, { backgroundColor: MainColor.white_gray }]}
/>
{children}
@@ -152,7 +152,7 @@ const styles = StyleSheet.create({
headerBar: {
width: 40,
height: 5,
backgroundColor: MainColor.white,
backgroundColor: MainColor.white_gray,
borderRadius: 5,
alignSelf: "center",
marginVertical: 10,

View File

@@ -1,7 +1,7 @@
import { AccentColor, MainColor } from "@/constants/color-palet";
import { ICON_SIZE_MEDIUM, TEXT_SIZE_SMALL } from "@/constants/constans-value";
import { Ionicons } from "@expo/vector-icons";
import { View, TouchableOpacity, Text, StyleSheet } from "react-native";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
const MenuDrawerDynamicGrid = ({ data, columns = 3, onPressItem }: any) => {
const numColumns = columns;
@@ -18,7 +18,7 @@ const MenuDrawerDynamicGrid = ({ data, columns = 3, onPressItem }: any) => {
<Ionicons
name={item.icon}
size={ICON_SIZE_MEDIUM}
color={item.color || MainColor.white}
color={item.color || MainColor.white_gray}
/>
</View>
<Text style={styles.label}>{item.label}</Text>
@@ -52,6 +52,6 @@ const styles = StyleSheet.create({
marginTop: 10,
fontSize: TEXT_SIZE_SMALL,
textAlign: "center",
color: MainColor.white,
color: MainColor.white_gray,
},
});

View File

@@ -109,5 +109,6 @@ const styles = StyleSheet.create({
flexDirection: "row",
flexWrap: "wrap",
justifyContent: "flex-start",
marginInline: 0.1
},
});

View File

@@ -47,7 +47,7 @@ const styles = StyleSheet.create({
overlappingAvatar: {
borderWidth: 2,
borderColor: "#fff",
backgroundColor: MainColor.white,
backgroundColor: MainColor.white_gray,
// shadowColor: "#000",
// shadowOffset: { width: 0, height: 2 },
// shadowOpacity: 0.2,

View File

@@ -3,13 +3,13 @@ import { MainColor } from "@/constants/color-palet";
import { TEXT_SIZE_MEDIUM } from "@/constants/constans-value";
import React, { useState } from "react";
import {
View,
Text,
Pressable,
Modal,
FlatList,
Modal,
Pressable,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native";
type SelectItem = {
@@ -100,7 +100,7 @@ const styles = StyleSheet.create({
label: {
fontSize: TEXT_SIZE_MEDIUM,
marginBottom: 4,
color: MainColor.white,
color: MainColor.white_gray,
fontWeight: "500",
},
requiredIndicator: {
@@ -109,7 +109,7 @@ const styles = StyleSheet.create({
},
input: {
borderWidth: 1,
borderColor: "#ccc",
borderColor: MainColor.white_gray,
padding: 12,
borderRadius: 8,
minHeight: 48,

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
// components/Stack.tsx
import React from "react";
@@ -18,7 +19,7 @@ const StackCustom: React.FC<StackProps> = ({
children,
align = "stretch",
justify = "flex-start",
gap = "md",
gap = "xs",
direction = "column",
style,
}) => {
@@ -57,10 +58,10 @@ const convertToSpacing = (value: GapSizeType): number => {
return sizes[value] || 16; // default md
};
const styles = StyleSheet.create({
stack: {
flex: 1,
},
});
// const styles = StyleSheet.create({
// stack: {
// flex: 1,
// },
// });
export default StackCustom;

View File

@@ -0,0 +1,144 @@
import React, { useEffect, useState } from "react";
import {
TextInput as RNTextInput,
StyleProp,
Text,
View,
ViewStyle,
} from "react-native";
import { textInputStyles } from "../TextInput/textInputStyles";
type IconType = React.ReactNode | string;
type BaseProps = {
iconLeft?: IconType;
iconRight?: IconType;
label?: string;
required?: boolean;
error?: string;
fontColor?: string;
disabled?: boolean;
borderRadius?: number;
autosize?: boolean;
minRows?: number;
maxRows?: number;
showCount?: boolean;
maxLength?: number;
style?: StyleProp<ViewStyle>;
};
type NativeTextInputProps = Omit<
React.ComponentProps<typeof RNTextInput>,
"style"
>;
export type TextAreaCustomProps = BaseProps & NativeTextInputProps;
const TextAreaCustom: React.FC<TextAreaCustomProps> = ({
iconLeft,
iconRight,
label,
required = false,
error = "",
fontColor = "#000",
disabled = false,
borderRadius = 8,
autosize = false,
minRows = 3,
maxRows = 6,
showCount = false,
maxLength,
value,
onChangeText,
style,
...rest
}) => {
const [numberOfLines, setNumberOfLines] = useState(minRows);
// Autosizing logic
useEffect(() => {
if (!autosize || !value) return;
const text = value as string;
const lines = text.split("\n").length;
const newLines = Math.max(minRows, Math.min(maxRows, lines));
setNumberOfLines(newLines);
}, [value, autosize, minRows, maxRows]);
const hasError = Boolean(error);
const renderIcon = (icon: IconType) => {
if (!icon) return null;
return typeof icon === "string" ? (
<Text style={textInputStyles.iconText}>{icon}</Text>
) : (
icon
);
};
return (
<View style={textInputStyles.container}>
{label && (
<Text style={textInputStyles.label}>
{label}
{required && <Text style={textInputStyles.required}> *</Text>}
</Text>
)}
<View
style={[
textInputStyles.inputContainer,
disabled && textInputStyles.disabled,
hasError ? textInputStyles.errorBorder : {},
{ borderRadius },
style,
]}
>
{iconLeft && (
<View style={textInputStyles.icon}>{renderIcon(iconLeft)}</View>
)}
<RNTextInput
maxLength={maxLength}
multiline
numberOfLines={numberOfLines}
style={[
textInputStyles.input,
textInputStyles.textArea,
{ color: fontColor },
]}
editable={!disabled}
value={value as string}
onChangeText={onChangeText}
{...rest}
/>
{iconRight && (
<View style={textInputStyles.icon}>{renderIcon(iconRight)}</View>
)}
</View>
{/* Error Message atau Counter */}
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
marginTop: 4,
minHeight: 16,
}}
>
{hasError ? (
<Text style={textInputStyles.errorMessage}>{error}</Text>
) : null}
{showCount && maxLength ? (
<Text style={textInputStyles.inputLength}>
{(value as string)?.length || 0}/{maxLength}
</Text>
) : null}
</View>
</View>
);
};
export default TextAreaCustom;

View File

@@ -23,6 +23,7 @@ type Props = {
disabled?: boolean;
borderRadius?: number;
style?: StyleProp<ViewStyle>;
maxLength?: number;
} & Omit<React.ComponentProps<typeof RNTextInput>, "style">;
export const TextInputCustom = ({
@@ -38,6 +39,7 @@ export const TextInputCustom = ({
style,
keyboardType,
onChangeText,
maxLength,
...rest
}: Props) => {
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
@@ -96,6 +98,7 @@ export const TextInputCustom = ({
secureTextEntry={secureTextEntry && !isPasswordVisible}
keyboardType={keyboardType}
onChangeText={handleTextChange}
maxLength={maxLength}
{...rest}
/>
{secureTextEntry && (

View File

@@ -1,5 +1,6 @@
// components/text-input.styles.ts
import { AccentColor, MainColor } from "@/constants/color-palet";
import { MainColor } from "@/constants/color-palet";
import { TEXT_SIZE_LARGE, TEXT_SIZE_MEDIUM } from "@/constants/constans-value";
import { StyleSheet } from "react-native";
export const textInputStyles = StyleSheet.create({
@@ -13,7 +14,7 @@ export const textInputStyles = StyleSheet.create({
fontSize: 14,
marginBottom: 6,
fontWeight: "500",
color: MainColor.white,
color: MainColor.white_gray,
},
// Tanda bintang merah untuk required
@@ -28,12 +29,18 @@ export const textInputStyles = StyleSheet.create({
color: MainColor.red,
},
// Input Length
inputLength: {
fontSize: 12,
color: MainColor.white_gray,
},
// Wrapper input (View pembungkus TextInput)
inputContainer: {
flexDirection: "row",
alignItems: "center",
borderWidth: 1,
borderColor: AccentColor.white,
borderColor: MainColor.white_gray,
backgroundColor: MainColor.white,
paddingHorizontal: 12,
height: 50,
@@ -48,7 +55,7 @@ export const textInputStyles = StyleSheet.create({
// Input utama (TextInput)
input: {
flex: 1,
fontSize: 16,
fontSize: TEXT_SIZE_MEDIUM,
paddingVertical: 0,
},
@@ -60,7 +67,7 @@ export const textInputStyles = StyleSheet.create({
// Teks ikon jika berupa string
iconText: {
fontSize: 16,
fontSize: TEXT_SIZE_LARGE,
color: "#000",
},
@@ -68,4 +75,11 @@ export const textInputStyles = StyleSheet.create({
errorBorder: {
borderColor: "red",
},
// Untuk TextArea tambahan
textArea: {
textAlignVertical: "top",
padding: 12,
height: undefined, // biar multiline bebas tinggi
},
});

View File

@@ -28,7 +28,7 @@ const ViewWrapper = ({
<>
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={{ flex: 1 }}
style={{ flex: 1, backgroundColor: MainColor.darkblue }}
>
<ScrollView
contentContainerStyle={{ flexGrow: 1 }}
@@ -57,7 +57,6 @@ const ViewWrapper = ({
<SafeAreaView
edges={["bottom"]}
style={{
flex: 1,
backgroundColor: MainColor.darkblue,
}}
>

View File

@@ -1,24 +1,28 @@
// Alert
import AlertCustom from "./Alert/AlertCustom";
// Button
import BackButton from "./Button/BackButton";
import LeftButtonCustom from "./Button/BackButton";
import ButtonCenteredOnly from "./Button/ButtonCenteredOnly";
import ButtonCustom from "./Button/ButtonCustom";
import ButtonUpload from "./Button/ButtonUpload";
// Drawer
import DrawerCustom from "./Drawer/DrawerCustom";
import MenuDrawerDynamicGrid from "./Drawer/MenuDrawerDynamicGird";
// ShareComponent
import ViewWrapper from "./_ShareComponent/ViewWrapper";
import Spacing from "./_ShareComponent/Spacing";
import ViewWrapper from "./_ShareComponent/ViewWrapper";
// Text
import TextCustom from "./Text/TextCustom";
// TextInput
import { TextInputCustom } from "./TextInput/TextInputCustom";
// TextArea
import TextAreaCustom from "./TextArea/TextAreaCustom";
// Grid
import Grid from "./Grid/GridCustom";
// Box
import BaseBox from "./Box/BaseBox";
// Avatar
import AvatarCustom from "./Image/AvatarCustom"
import AvatarCustom from "./Image/AvatarCustom";
// Stack
import StackCustom from "./Stack/StackCustom";
// Select
@@ -26,27 +30,29 @@ import SelectCustom from "./Select/SelectCustom";
export {
AlertCustom,
// Avatar
AvatarCustom,
// Button
BackButton,
ButtonCustom,
LeftButtonCustom as BackButton,
// Box
BaseBox, ButtonCenteredOnly, ButtonCustom, ButtonUpload,
// Drawer
DrawerCustom,
MenuDrawerDynamicGrid,
// Grid
Grid, MenuDrawerDynamicGrid,
// Select
SelectCustom,
// ShareComponent
Spacing,
ViewWrapper,
// Stack
StackCustom,
// TextArea
TextAreaCustom,
// Text
TextCustom,
// TextInput
TextInputCustom,
// Grid
Grid,
// Box
BaseBox,
// Avatar
AvatarCustom,
// Stack
StackCustom,
// Select
SelectCustom,
// ViewWrapper
ViewWrapper
};

View File

@@ -3,13 +3,14 @@ export const MainColor = {
darkblue: "#001D3D",
soft_darkblue: "#0e3763",
yellow: "#E1B525",
white: "#D4D0D0",
white_gray: "#D4D0D0",
red: "#FF4B4C",
orange: "#FF7043",
green: "#4CAF4F",
text_input: "#EDEBEBFF",
placeholder: "#999",
disabled: "#606360",
white: "#ffffff",
};
export const AccentColor = {

View File

@@ -6,6 +6,7 @@ export {
ICON_SIZE_MEDIUM,
DRAWER_HEIGHT,
RADIUS_BUTTON,
ICON_SIZE_BUTTON,
};
const TEXT_SIZE_SMALL = 12;
@@ -14,4 +15,5 @@ const TEXT_SIZE_LARGE = 16;
const ICON_SIZE_SMALL = 20;
const ICON_SIZE_MEDIUM = 24;
const DRAWER_HEIGHT = 500; // tinggi drawer5
const RADIUS_BUTTON = 50
const RADIUS_BUTTON = 50
const ICON_SIZE_BUTTON = 18

View File

@@ -0,0 +1,100 @@
const dummyMasterBidangBisnis = [
{
id: "1",
name: "Teknologi dan Digital",
slug: "teknologi_dan_digital",
active: true,
createdAt: "2025-06-16T09:57:16.403Z",
updatedAt: "2025-06-16T09:57:16.403Z",
},
{
id: "2",
name: "Kuliner",
slug: "kuliner",
active: true,
createdAt: "2025-06-16T09:57:16.424Z",
updatedAt: "2025-06-16T09:57:16.424Z",
},
{
id: "3",
name: "Fashion dan Kecantikan",
slug: "fashion_dan_kecantikan",
active: true,
createdAt: "2025-06-16T09:57:16.442Z",
updatedAt: "2025-06-16T09:57:16.442Z",
},
{
id: "4",
name: "Otomotif",
slug: "otomotif",
active: true,
createdAt: "2025-06-16T09:57:16.459Z",
updatedAt: "2025-06-16T09:57:16.459Z",
},
{
id: "5",
name: "Industri Kreatif",
slug: "industri_kreatif",
active: true,
createdAt: "2025-06-16T09:57:16.471Z",
updatedAt: "2025-06-16T09:57:16.471Z",
},
{
id: "6",
name: "Konstruksi dan Pertukangan",
slug: "konstruksi_dan_pertukangan",
active: true,
createdAt: "2025-06-16T09:57:16.483Z",
updatedAt: "2025-06-16T09:57:16.483Z",
},
{
id: "7",
name: "Agribisnis dan Pertanian",
slug: "agribisnis_dan_pertanian",
active: true,
createdAt: "2025-06-16T09:57:16.492Z",
updatedAt: "2025-06-16T09:57:16.492Z",
},
{
id: "8",
name: "Jasa Umum",
slug: "jasa_umum",
active: true,
createdAt: "2025-06-16T09:57:16.502Z",
updatedAt: "2025-06-16T09:57:16.502Z",
},
{
id: "9",
name: "Edukasi dan Pelatihan",
slug: "edukasi_dan_pelatihan",
active: true,
createdAt: "2025-06-16T09:57:16.517Z",
updatedAt: "2025-06-16T09:57:16.517Z",
},
{
id: "10",
name: "Keuangan dan Investasi",
slug: "keuangan_dan_investasi",
active: true,
createdAt: "2025-06-16T09:57:16.527Z",
updatedAt: "2025-06-16T09:57:16.527Z",
},
{
id: "11",
name: "Perdagangan Umum",
slug: "perdagangan_umum",
active: true,
createdAt: "2025-06-16T09:57:16.537Z",
updatedAt: "2025-06-16T09:57:16.537Z",
},
{
id: "12",
name: "Pariwisata dan Hospitality",
slug: "pariwisata_dan_hospitality",
active: true,
createdAt: "2025-06-16T09:57:16.547Z",
updatedAt: "2025-06-16T09:57:16.547Z",
},
];
export default dummyMasterBidangBisnis;

View File

@@ -0,0 +1,734 @@
const dummyMasterSubBidangBisnis = [
{
id: "TEK-01",
name: "Software Developer",
slug: "software_developer",
isActive: true,
createdAt: "2025-06-16T09:57:16.406Z",
updatedAt: "2025-06-16T09:57:16.406Z",
masterBidangBisnisId: "1",
},
{
id: "TEK-02",
name: "Web Developer",
slug: "web_developer",
isActive: true,
createdAt: "2025-06-16T09:57:16.408Z",
updatedAt: "2025-06-16T09:57:16.408Z",
masterBidangBisnisId: "1",
},
{
id: "TEK-03",
name: "Mobile App Developer",
slug: "mobile_app_developer",
isActive: true,
createdAt: "2025-06-16T09:57:16.411Z",
updatedAt: "2025-06-16T09:57:16.411Z",
masterBidangBisnisId: "1",
},
{
id: "TEK-04",
name: "Konsultan IT",
slug: "konsultan_it",
isActive: true,
createdAt: "2025-06-16T09:57:16.413Z",
updatedAt: "2025-06-16T09:57:16.413Z",
masterBidangBisnisId: "1",
},
{
id: "TEK-05",
name: "Digital Marketing",
slug: "digital_marketing",
isActive: true,
createdAt: "2025-06-16T09:57:16.415Z",
updatedAt: "2025-06-16T09:57:16.415Z",
masterBidangBisnisId: "1",
},
{
id: "TEK-06",
name: "Cybersecurity",
slug: "cybersecurity",
isActive: true,
createdAt: "2025-06-16T09:57:16.417Z",
updatedAt: "2025-06-16T09:57:16.417Z",
masterBidangBisnisId: "1",
},
{
id: "TEK-07",
name: "AI & Machine Learning Services",
slug: "ai_and_machine_learning_services",
isActive: true,
createdAt: "2025-06-16T09:57:16.419Z",
updatedAt: "2025-06-16T09:57:16.419Z",
masterBidangBisnisId: "1",
},
{
id: "TEK-08",
name: "Data Analyst/Data Scientist",
slug: "data_analyst_data_scientist",
isActive: true,
createdAt: "2025-06-16T09:57:16.421Z",
updatedAt: "2025-06-16T09:57:16.421Z",
masterBidangBisnisId: "1",
},
{
id: "TEK-09",
name: "Blockchain Developer",
slug: "blockchain_developer",
isActive: true,
createdAt: "2025-06-16T09:57:16.423Z",
updatedAt: "2025-06-16T09:57:16.423Z",
masterBidangBisnisId: "1",
},
{
id: "KUL-01",
name: "Restoran",
slug: "restoran",
isActive: true,
createdAt: "2025-06-16T09:57:16.426Z",
updatedAt: "2025-06-16T09:57:16.426Z",
masterBidangBisnisId: "2",
},
{
id: "KUL-02",
name: "Kafe",
slug: "kafe",
isActive: true,
createdAt: "2025-06-16T09:57:16.428Z",
updatedAt: "2025-06-16T09:57:16.428Z",
masterBidangBisnisId: "2",
},
{
id: "KUL-03",
name: "Warung Makan",
slug: "warung_makan",
isActive: true,
createdAt: "2025-06-16T09:57:16.431Z",
updatedAt: "2025-06-16T09:57:16.431Z",
masterBidangBisnisId: "2",
},
{
id: "KUL-04",
name: "Catering",
slug: "catering",
isActive: true,
createdAt: "2025-06-16T09:57:16.433Z",
updatedAt: "2025-06-16T09:57:16.433Z",
masterBidangBisnisId: "2",
},
{
id: "KUL-05",
name: "Food Truck",
slug: "food_truck",
isActive: true,
createdAt: "2025-06-16T09:57:16.435Z",
updatedAt: "2025-06-16T09:57:16.435Z",
masterBidangBisnisId: "2",
},
{
id: "KUL-06",
name: "Minuman Kekinian",
slug: "minuman_kekinian",
isActive: true,
createdAt: "2025-06-16T09:57:16.437Z",
updatedAt: "2025-06-16T09:57:16.437Z",
masterBidangBisnisId: "2",
},
{
id: "KUL-07",
name: "Toko Roti & Kue",
slug: "toko_roti_kue",
isActive: true,
createdAt: "2025-06-16T09:57:16.438Z",
updatedAt: "2025-06-16T09:57:16.438Z",
masterBidangBisnisId: "2",
},
{
id: "KUL-08",
name: "Supplier Bahan Makanan",
slug: "supplier_bahan_makanan",
isActive: true,
createdAt: "2025-06-16T09:57:16.440Z",
updatedAt: "2025-06-16T09:57:16.440Z",
masterBidangBisnisId: "2",
},
{
id: "FAS-01",
name: "Pakaian Dewasa & Anak",
slug: "pakaian_dewasa_anak",
isActive: true,
createdAt: "2025-06-16T09:57:16.444Z",
updatedAt: "2025-06-16T09:57:16.444Z",
masterBidangBisnisId: "3",
},
{
id: "FAS-02",
name: "Butik",
slug: "butik",
isActive: true,
createdAt: "2025-06-16T09:57:16.445Z",
updatedAt: "2025-06-16T09:57:16.445Z",
masterBidangBisnisId: "3",
},
{
id: "FAS-03",
name: "Desainer Fashion",
slug: "desainer_fashion",
isActive: true,
createdAt: "2025-06-16T09:57:16.448Z",
updatedAt: "2025-06-16T09:57:16.448Z",
masterBidangBisnisId: "3",
},
{
id: "FAS-04",
name: "Aksesoris & Perhiasan",
slug: "aksesoris_perhiasan",
isActive: true,
createdAt: "2025-06-16T09:57:16.449Z",
updatedAt: "2025-06-16T09:57:16.449Z",
masterBidangBisnisId: "3",
},
{
id: "FAS-05",
name: "Kosmetik",
slug: "kosmetik",
isActive: true,
createdAt: "2025-06-16T09:57:16.451Z",
updatedAt: "2025-06-16T09:57:16.451Z",
masterBidangBisnisId: "3",
},
{
id: "FAS-06",
name: "Skincare",
slug: "skincare",
isActive: true,
createdAt: "2025-06-16T09:57:16.453Z",
updatedAt: "2025-06-16T09:57:16.453Z",
masterBidangBisnisId: "3",
},
{
id: "FAS-07",
name: "Salon Kecantikan",
slug: "salon_kecantikan",
isActive: true,
createdAt: "2025-06-16T09:57:16.455Z",
updatedAt: "2025-06-16T09:57:16.455Z",
masterBidangBisnisId: "3",
},
{
id: "FAS-08",
name: "Barbershop",
slug: "barbershop",
isActive: true,
createdAt: "2025-06-16T09:57:16.456Z",
updatedAt: "2025-06-16T09:57:16.456Z",
masterBidangBisnisId: "3",
},
{
id: "OTO-01",
name: "Jual Beli Mobil/Motor",
slug: "jual_beli_mobil_motor",
isActive: true,
createdAt: "2025-06-16T09:57:16.461Z",
updatedAt: "2025-06-16T09:57:16.461Z",
masterBidangBisnisId: "4",
},
{
id: "OTO-02",
name: "Bengkel Mobil/Motor",
slug: "bengkel_mobil_motor",
isActive: true,
createdAt: "2025-06-16T09:57:16.463Z",
updatedAt: "2025-06-16T09:57:16.463Z",
masterBidangBisnisId: "4",
},
{
id: "OTO-03",
name: "Aksesori Kendaraan",
slug: "aksesori_kendaraan",
isActive: true,
createdAt: "2025-06-16T09:57:16.465Z",
updatedAt: "2025-06-16T09:57:16.465Z",
masterBidangBisnisId: "4",
},
{
id: "OTO-04",
name: "Rental Kendaraan",
slug: "rental_kendaraan",
isActive: true,
createdAt: "2025-06-16T09:57:16.466Z",
updatedAt: "2025-06-16T09:57:16.466Z",
masterBidangBisnisId: "4",
},
{
id: "OTO-05",
name: "Cuci Mobil/Motor",
slug: "cuci_mobil_motor",
isActive: true,
createdAt: "2025-06-16T09:57:16.468Z",
updatedAt: "2025-06-16T09:57:16.468Z",
masterBidangBisnisId: "4",
},
{
id: "OTO-06",
name: "Spare Part & Mesin Mobil",
slug: "spare_part_mesin_mobil",
isActive: true,
createdAt: "2025-06-16T09:57:16.469Z",
updatedAt: "2025-06-16T09:57:16.469Z",
masterBidangBisnisId: "4",
},
{
id: "INK-01",
name: "Fotografi & Videografi",
slug: "fotografi_videografi",
isActive: true,
createdAt: "2025-06-16T09:57:16.472Z",
updatedAt: "2025-06-16T09:57:16.472Z",
masterBidangBisnisId: "5",
},
{
id: "INK-02",
name: "Event Organizer",
slug: "event_organizer",
isActive: true,
createdAt: "2025-06-16T09:57:16.473Z",
updatedAt: "2025-06-16T09:57:16.473Z",
masterBidangBisnisId: "5",
},
{
id: "INK-03",
name: "Desain Grafis",
slug: "desain_grafis",
isActive: true,
createdAt: "2025-06-16T09:57:16.475Z",
updatedAt: "2025-06-16T09:57:16.475Z",
masterBidangBisnisId: "5",
},
{
id: "INK-04",
name: "Advertising & Branding",
slug: "advertising_branding",
isActive: true,
createdAt: "2025-06-16T09:57:16.476Z",
updatedAt: "2025-06-16T09:57:16.476Z",
masterBidangBisnisId: "5",
},
{
id: "INK-05",
name: "Jasa Percetakan",
slug: "jasa_percetakan",
isActive: true,
createdAt: "2025-06-16T09:57:16.477Z",
updatedAt: "2025-06-16T09:57:16.477Z",
masterBidangBisnisId: "5",
},
{
id: "INK-06",
name: "Dekorasi & Wedding Planner",
slug: "dekorasi_wedding_planner",
isActive: true,
createdAt: "2025-06-16T09:57:16.480Z",
updatedAt: "2025-06-16T09:57:16.480Z",
masterBidangBisnisId: "5",
},
{
id: "INK-07",
name: "Studio Musik & Produksi",
slug: "studio_musik_produksi",
isActive: true,
createdAt: "2025-06-16T09:57:16.481Z",
updatedAt: "2025-06-16T09:57:16.481Z",
masterBidangBisnisId: "5",
},
{
id: "KON-01",
name: "Kontraktor Bangunan",
slug: "kontraktor_bangunan",
isActive: true,
createdAt: "2025-06-16T09:57:16.484Z",
updatedAt: "2025-06-16T09:57:16.484Z",
masterBidangBisnisId: "6",
},
{
id: "KON-02",
name: "Arsitek",
slug: "arsitek",
isActive: true,
createdAt: "2025-06-16T09:57:16.486Z",
updatedAt: "2025-06-16T09:57:16.486Z",
masterBidangBisnisId: "6",
},
{
id: "KON-03",
name: "Desain Interior",
slug: "desain_interior",
isActive: true,
createdAt: "2025-06-16T09:57:16.487Z",
updatedAt: "2025-06-16T09:57:16.487Z",
masterBidangBisnisId: "6",
},
{
id: "KON-04",
name: "Supplier Material Bangunan",
slug: "supplier_material_bangunan",
isActive: true,
createdAt: "2025-06-16T09:57:16.489Z",
updatedAt: "2025-06-16T09:57:16.489Z",
masterBidangBisnisId: "6",
},
{
id: "KON-05",
name: "Tukang & Renovasi Rumah",
slug: "tukang_renovasi_rumah",
isActive: true,
createdAt: "2025-06-16T09:57:16.490Z",
updatedAt: "2025-06-16T09:57:16.490Z",
masterBidangBisnisId: "6",
},
{
id: "AGR-01",
name: "Perkebunan",
slug: "perkebunan",
isActive: true,
createdAt: "2025-06-16T09:57:16.493Z",
updatedAt: "2025-06-16T09:57:16.493Z",
masterBidangBisnisId: "7",
},
{
id: "AGR-02",
name: "Peternakan",
slug: "peternakan",
isActive: true,
createdAt: "2025-06-16T09:57:16.496Z",
updatedAt: "2025-06-16T09:57:16.496Z",
masterBidangBisnisId: "7",
},
{
id: "AGR-03",
name: "Perikanan",
slug: "perikanan",
isActive: true,
createdAt: "2025-06-16T09:57:16.497Z",
updatedAt: "2025-06-16T09:57:16.497Z",
masterBidangBisnisId: "7",
},
{
id: "AGR-04",
name: "Supplier Bibit & Pupuk",
slug: "supplier_bibit_pupuk",
isActive: true,
createdAt: "2025-06-16T09:57:16.498Z",
updatedAt: "2025-06-16T09:57:16.498Z",
masterBidangBisnisId: "7",
},
{
id: "AGR-05",
name: "Hasil Tani Organik",
slug: "hasil_tani_organik",
isActive: true,
createdAt: "2025-06-16T09:57:16.500Z",
updatedAt: "2025-06-16T09:57:16.500Z",
masterBidangBisnisId: "7",
},
{
id: "AGR-06",
name: "Alat & Mesin Pertanian",
slug: "alat_mesin_pertanian",
isActive: true,
createdAt: "2025-06-16T09:57:16.501Z",
updatedAt: "2025-06-16T09:57:16.501Z",
masterBidangBisnisId: "7",
},
{
id: "JAS-01",
name: "Jasa Kebersihan",
slug: "jasa_kebersihan",
isActive: true,
createdAt: "2025-06-16T09:57:16.504Z",
updatedAt: "2025-06-16T09:57:16.504Z",
masterBidangBisnisId: "8",
},
{
id: "JAS-02",
name: "Laundry",
slug: "laundry",
isActive: true,
createdAt: "2025-06-16T09:57:16.505Z",
updatedAt: "2025-06-16T09:57:16.505Z",
masterBidangBisnisId: "8",
},
{
id: "JAS-03",
name: "Penitipan Anak",
slug: "penitipan_anak",
isActive: true,
createdAt: "2025-06-16T09:57:16.506Z",
updatedAt: "2025-06-16T09:57:16.506Z",
masterBidangBisnisId: "8",
},
{
id: "JAS-04",
name: "Jasa Keamanan",
slug: "jasa_keamanan",
isActive: true,
createdAt: "2025-06-16T09:57:16.508Z",
updatedAt: "2025-06-16T09:57:16.508Z",
masterBidangBisnisId: "8",
},
{
id: "JAS-05",
name: "Jasa Pengiriman/Logistik",
slug: "jasa_pengiriman_logistik",
isActive: true,
createdAt: "2025-06-16T09:57:16.511Z",
updatedAt: "2025-06-16T09:57:16.511Z",
masterBidangBisnisId: "8",
},
{
id: "JAS-06",
name: "Jasa Ekspedisi",
slug: "jasa_ekspedisi",
isActive: true,
createdAt: "2025-06-16T09:57:16.513Z",
updatedAt: "2025-06-16T09:57:16.513Z",
masterBidangBisnisId: "8",
},
{
id: "JAS-07",
name: "Konsultan Bisnis",
slug: "konsultan_bisnis",
isActive: true,
createdAt: "2025-06-16T09:57:16.514Z",
updatedAt: "2025-06-16T09:57:16.514Z",
masterBidangBisnisId: "8",
},
{
id: "JAS-08",
name: "Jasa Hukum/Legal",
slug: "jasa_hukum_legal",
isActive: true,
createdAt: "2025-06-16T09:57:16.516Z",
updatedAt: "2025-06-16T09:57:16.516Z",
masterBidangBisnisId: "8",
},
{
id: "EDU-01",
name: "Bimbingan Belajar",
slug: "bimbingan_belajar",
isActive: true,
createdAt: "2025-06-16T09:57:16.518Z",
updatedAt: "2025-06-16T09:57:16.518Z",
masterBidangBisnisId: "9",
},
{
id: "EDU-02",
name: "Kursus Bahasa",
slug: "kursus_bahasa",
isActive: true,
createdAt: "2025-06-16T09:57:16.520Z",
updatedAt: "2025-06-16T09:57:16.520Z",
masterBidangBisnisId: "9",
},
{
id: "EDU-03",
name: "Pelatihan Digital/Skill",
slug: "pelatihan_digital_skill",
isActive: true,
createdAt: "2025-06-16T09:57:16.521Z",
updatedAt: "2025-06-16T09:57:16.521Z",
masterBidangBisnisId: "9",
},
{
id: "EDU-04",
name: "LPK (Lembaga Pelatihan Kerja)",
slug: "lpk_lembaga_pelatihan_kerja",
isActive: true,
createdAt: "2025-06-16T09:57:16.523Z",
updatedAt: "2025-06-16T09:57:16.523Z",
masterBidangBisnisId: "9",
},
{
id: "EDU-05",
name: "Homeschooling",
slug: "homeschooling",
isActive: true,
createdAt: "2025-06-16T09:57:16.525Z",
updatedAt: "2025-06-16T09:57:16.525Z",
masterBidangBisnisId: "9",
},
{
id: "KEU-01",
name: "Koperasi",
slug: "koperasi",
isActive: true,
createdAt: "2025-06-16T09:57:16.529Z",
updatedAt: "2025-06-16T09:57:16.529Z",
masterBidangBisnisId: "10",
},
{
id: "KEU-02",
name: "FinTEKh",
slug: "finTEKh",
isActive: true,
createdAt: "2025-06-16T09:57:16.530Z",
updatedAt: "2025-06-16T09:57:16.530Z",
masterBidangBisnisId: "10",
},
{
id: "KEU-03",
name: "Konsultan Keuangan",
slug: "konsultan_keuangan",
isActive: true,
createdAt: "2025-06-16T09:57:16.531Z",
updatedAt: "2025-06-16T09:57:16.531Z",
masterBidangBisnisId: "10",
},
{
id: "KEU-04",
name: "Investasi & Saham",
slug: "investasi_saham",
isActive: true,
createdAt: "2025-06-16T09:57:16.532Z",
updatedAt: "2025-06-16T09:57:16.532Z",
masterBidangBisnisId: "10",
},
{
id: "KEU-05",
name: "Asuransi",
slug: "asuransi",
isActive: true,
createdAt: "2025-06-16T09:57:16.534Z",
updatedAt: "2025-06-16T09:57:16.534Z",
masterBidangBisnisId: "10",
},
{
id: "KEU-06",
name: "Akuntan Publik",
slug: "akuntan_publik",
isActive: true,
createdAt: "2025-06-16T09:57:16.535Z",
updatedAt: "2025-06-16T09:57:16.535Z",
masterBidangBisnisId: "10",
},
{
id: "PER-01",
name: "Toko Kelontong",
slug: "toko_kelontong",
isActive: true,
createdAt: "2025-06-16T09:57:16.538Z",
updatedAt: "2025-06-16T09:57:16.538Z",
masterBidangBisnisId: "11",
},
{
id: "PER-02",
name: "Minimarket",
slug: "minimarket",
isActive: true,
createdAt: "2025-06-16T09:57:16.540Z",
updatedAt: "2025-06-16T09:57:16.540Z",
masterBidangBisnisId: "11",
},
{
id: "PER-03",
name: "Grosir & Distributor",
slug: "grosir_distributor",
isActive: true,
createdAt: "2025-06-16T09:57:16.541Z",
updatedAt: "2025-06-16T09:57:16.541Z",
masterBidangBisnisId: "11",
},
{
id: "PER-04",
name: "Dropshipper & Reseller",
slug: "dropshipper_reseller",
isActive: true,
createdAt: "2025-06-16T09:57:16.543Z",
updatedAt: "2025-06-16T09:57:16.543Z",
masterBidangBisnisId: "11",
},
{
id: "PER-05",
name: "Marketplace & E-commerce",
slug: "marketplace_e_commerce",
isActive: true,
createdAt: "2025-06-16T09:57:16.544Z",
updatedAt: "2025-06-16T09:57:16.544Z",
masterBidangBisnisId: "11",
},
{
id: "PER-06",
name: "Supplier Produk",
slug: "supplier_produk",
isActive: true,
createdAt: "2025-06-16T09:57:16.546Z",
updatedAt: "2025-06-16T09:57:16.546Z",
masterBidangBisnisId: "11",
},
{
id: "PAR-01",
name: "Agen Travel",
slug: "agen_travel",
isActive: true,
createdAt: "2025-06-16T09:57:16.549Z",
updatedAt: "2025-06-16T09:57:16.549Z",
masterBidangBisnisId: "12",
},
{
id: "PAR-02",
name: "Tour Guide",
slug: "tour_guide",
isActive: true,
createdAt: "2025-06-16T09:57:16.550Z",
updatedAt: "2025-06-16T09:57:16.550Z",
masterBidangBisnisId: "12",
},
{
id: "PAR-03",
name: "Villa & Penginapan",
slug: "villa_penginapan",
isActive: true,
createdAt: "2025-06-16T09:57:16.551Z",
updatedAt: "2025-06-16T09:57:16.551Z",
masterBidangBisnisId: "12",
},
{
id: "PAR-04",
name: "Homestay",
slug: "homestay",
isActive: true,
createdAt: "2025-06-16T09:57:16.552Z",
updatedAt: "2025-06-16T09:57:16.552Z",
masterBidangBisnisId: "12",
},
{
id: "PAR-05",
name: "Hotel",
slug: "hotel",
isActive: true,
createdAt: "2025-06-16T09:57:16.554Z",
updatedAt: "2025-06-16T09:57:16.554Z",
masterBidangBisnisId: "12",
},
{
id: "PAR-06",
name: "Sewa Motor/Travel",
slug: "sewa_motor_travel",
isActive: true,
createdAt: "2025-06-16T09:57:16.555Z",
updatedAt: "2025-06-16T09:57:16.555Z",
masterBidangBisnisId: "12",
},
{
id: "PAR-07",
name: "Sovenir & Oleh-Oleh",
slug: "sovenir_oleh_oleh",
isActive: true,
createdAt: "2025-06-16T09:57:16.557Z",
updatedAt: "2025-06-16T09:57:16.557Z",
masterBidangBisnisId: "12",
},
];
export default dummyMasterSubBidangBisnis;

0
lib/index.ts Normal file
View File

View File

@@ -30,8 +30,8 @@ export default function LoginView() {
const id = randomAlfabet + randomNumber + fixNumber;
console.log("login user id :", id);
router.navigate("/verification");
// router.navigate(`/(application)/profile/${id}`);
// router.navigate("/verification");
router.navigate(`/(application)/(user)/profile/${id}`);
// router.navigate("/(application)/home");
// router.navigate(`/(application)/profile/${id}/edit`);
}
@@ -55,7 +55,7 @@ export default function LoginView() {
fontSize: 10,
fontWeight: "thin",
fontStyle: "italic",
color: MainColor.white,
color: MainColor.white_gray,
}}
>
powered by muku.id

View File

@@ -13,7 +13,7 @@ export default function RegisterView() {
const [username, setUsername] = useState("Bagas Banuna");
const handleRegister = () => {
console.log("Success register", username);
router.push("/(application)/home");
router.push("/(application)/(user)/home");
};
return (
<>

View File

@@ -1,5 +1,5 @@
// import { ITabs } from "@/components/_Interface/types";
import Spacing from "@/components/_ShareComponent/Spacing";
import { StackCustom } from "@/components";
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
import { useNavigation } from "expo-router";
import React, { useEffect } from "react";
@@ -16,21 +16,16 @@ export default function UiHome() {
navigation.setOptions({});
}, [navigation]);
return (
<>
<ViewWrapper footerComponent={<TabSection tabs={tabsHome} />}>
{/* Content Image */}
<Home_ImageSection />
<Spacing height={10} />
<StackCustom>
<Home_ImageSection />
{/* Grid Section */}
<Home_FeatureSection />
<Spacing height={10} />
<Home_FeatureSection />
{/* Job Vacancy Section */}
<Home_BottomFeatureSection />
<Spacing height={20} />
<Home_BottomFeatureSection />
</StackCustom>
</ViewWrapper>
</>
);

View File

@@ -9,7 +9,7 @@ export default function Home_FeatureSection() {
<View style={stylesHome.gridContainer}>
<TouchableOpacity
style={stylesHome.gridItem}
onPress={() => router.push("/(application)/event/(tabs)")}
onPress={() => router.push("/(application)/(user)/event/(tabs)")}
>
<Ionicons name="analytics" size={48} color="white" />
<Text style={stylesHome.gridLabel}>Event</Text>

View File

@@ -1,9 +1,8 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { BaseBox, Grid, Spacing, TextCustom } from "@/components";
import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_SMALL } from "@/constants/constans-value";
import { FontAwesome5, Ionicons } from "@expo/vector-icons";
import { useLocalSearchParams } from "expo-router";
import { router, useLocalSearchParams } from "expo-router";
import { View } from "react-native";
import AvatarAndBackground from "./AvatarAndBackground";
@@ -85,7 +84,10 @@ export default function ProfilSection() {
<BaseBox
key={index}
style={{ backgroundColor: MainColor.darkblue }}
onPress={() => console.log("pressed")}
onPress={() => {
console.log("press to Portofolio");
router.push(`/portofolio/${id}`);
}}
>
<Grid>
<Grid.Col

View File

@@ -44,7 +44,7 @@ export const GStyles = StyleSheet.create({
// TEXT & LABEL
textLabel: {
fontSize: TEXT_SIZE_MEDIUM,
color: MainColor.white,
color: MainColor.white_gray,
fontWeight: "normal",
},
@@ -123,7 +123,7 @@ export const GStyles = StyleSheet.create({
fontWeight: "500",
},
activeTabLabel: {
color: MainColor.white,
color: MainColor.white_gray,
fontWeight: "600",
},
activeIndicator: {

12
styles/header-styles.ts Normal file
View File

@@ -0,0 +1,12 @@
import { AccentColor } from "@/constants/color-palet";
import { NativeStackNavigationOptions } from "@react-navigation/native-stack";
import { GStyles } from "./global-styles";
export const HeaderStyles: NativeStackNavigationOptions = {
headerStyle: GStyles.headerStyle,
headerTitleStyle: GStyles.headerTitleStyle,
headerTitleAlign: "center",
contentStyle: {
borderBottomColor: AccentColor.blue,
},
};