Fakultas Ilmu Komputer UI

Commit 1b7ff0b6 authored by Ahmad Izzudin Alifyandra's avatar Ahmad Izzudin Alifyandra
Browse files

PBI 13 create ecosystem page

parent 3c8a0c84
...@@ -3,13 +3,11 @@ import React from "react"; ...@@ -3,13 +3,11 @@ import React from "react";
import { SafeAreaProvider } from "react-native-safe-area-context"; import { SafeAreaProvider } from "react-native-safe-area-context";
import { Provider as StoreProvider } from "react-redux"; import { Provider as StoreProvider } from "react-redux";
import useCachedResources from "./src/hooks/useCachedResources"; import useCachedResources from "./src/hooks/useCachedResources";
import useColorScheme from "./src/hooks/useColorScheme";
import Navigation from "./src/navigation"; import Navigation from "./src/navigation";
import store from "./src/redux/store"; import store from "./src/redux/store";
export default function App() { export default function App() {
const isLoadingComplete = useCachedResources(); const isLoadingComplete = useCachedResources();
const colorScheme = useColorScheme();
if (!isLoadingComplete) { if (!isLoadingComplete) {
return null; return null;
} else { } else {
......
...@@ -39,6 +39,7 @@ export default { ...@@ -39,6 +39,7 @@ export default {
appId: process.env.appId, appId: process.env.appId,
measurementId: process.env.measurementId, measurementId: process.env.measurementId,
env: process.env.env, env: process.env.env,
cloudFunctionsUrl: process.env.cloudFunctionsUrl,
}, },
}, },
}; };
...@@ -5,10 +5,14 @@ const FirebaseConfig = { ...@@ -5,10 +5,14 @@ const FirebaseConfig = {
apiKey: Constants.manifest.extra?.apiKey || process.env.apiKey, apiKey: Constants.manifest.extra?.apiKey || process.env.apiKey,
authDomain: Constants.manifest.extra?.authDomain || process.env.authDomain, authDomain: Constants.manifest.extra?.authDomain || process.env.authDomain,
projectId: Constants.manifest.extra?.projectId || process.env.projectid, projectId: Constants.manifest.extra?.projectId || process.env.projectid,
storageBucket: Constants.manifest.extra?.storageBucket || process.env.storageBucket, storageBucket:
messagingSenderId: Constants.manifest.extra?.messagingSenderId || process.env.messagingSenderId, Constants.manifest.extra?.storageBucket || process.env.storageBucket,
appId: Constants.manifest.extra?.appId || process.env.appId, messagingSenderId:
measurementId: Constants.manifest.extra?.measurementId || process.env.measurementId, Constants.manifest.extra?.messagingSenderId ||
process.env.messagingSenderId,
appId: Constants.manifest.extra?.appId || process.env.appId,
measurementId:
Constants.manifest.extra?.measurementId || process.env.measurementId,
}; };
export default FirebaseConfig; export default FirebaseConfig;
import React from "react";
import { View, Text, StyleSheet } from "react-native";
import PlainForm from "../Forms/PlainForm";
import Spacer from "../Spacer/Spacer";
import DropdownForm from "../Forms/DropdownForm";
import Colors from "../../constants/Colors";
type props = {
ecosystemName: string;
setEcosystemName: React.Dispatch<React.SetStateAction<string>>;
ecosystemDetails: string;
setEcosystemDetails: React.Dispatch<React.SetStateAction<string>>;
ecosystemCategory: string;
setEcosystemCategory: React.Dispatch<React.SetStateAction<string>>;
items: any[];
setItems: React.Dispatch<React.SetStateAction<any[]>>;
};
const TopForms = ({
ecosystemName,
setEcosystemName,
ecosystemDetails,
setEcosystemDetails,
ecosystemCategory,
setEcosystemCategory,
items,
setItems,
}: props) => {
return (
<View style={styles.componentWrapper}>
<View style={styles.componentWrapper}>
<Text style={styles.title}>Buat Ekosistem Bisnis</Text>
</View>
<Spacer variant="xl" />
<View style={styles.componentWrapper}>
<Text style={styles.subtitle}>
Silahkan masukkan data berikut untuk membuat ekosistem bisnis
</Text>
</View>
<Spacer variant="xl" />
<View style={styles.componentWrapper}>
<PlainForm
formTitle="Nama Ekosistem Bisnis"
placeholder="Masukkan Nama Ekosistem Bisnis"
text={ecosystemName}
setText={setEcosystemName}
errorMessage="Silahkan masukkan nama ekosistem"
/>
</View>
<Spacer variant="xl" />
<View style={styles.componentWrapper}>
<PlainForm
formTitle="Deskripsi Ekosistem Bisnis"
placeholder="Masukkan Deskripsi Ekosistem Bisnis"
text={ecosystemDetails}
setText={setEcosystemDetails}
errorMessage="Silahkan masukkan deskripsi ekosistem bisnis"
/>
</View>
<Spacer variant="xl" />
<View style={styles.componentWrapper}>
<View style={styles.componentWrapper}>
<Text style={styles.componentTitle}>Kategori Ekosistem Bisnis</Text>
</View>
<Spacer variant="m" />
<DropdownForm
value={ecosystemCategory}
setValue={setEcosystemCategory}
items={items}
setItems={setItems}
formPlaceholder="Pilih Kategori Ekosistem Binis"
searchPlaceholder="Cari Kategori Bisnis"
/>
</View>
<Spacer variant="xl" />
<View style={styles.componentWrapper}>
<Text style={styles.componentTitleBold}>Anggota Supplier</Text>
</View>
<Spacer variant="m" />
</View>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: Colors.background,
padding: 24,
},
componentWrapper: {
width: "100%",
},
title: {
fontSize: 32,
fontWeight: "500",
color: Colors.text.title,
},
subtitle: {
fontSize: 20,
fontWeight: "300",
color: Colors.text.subtitle,
},
listText: {
fontSize: 14,
fontWeight: "300",
color: Colors.text.link,
},
warningText: {
fontSize: 14,
fontWeight: "bold",
color: Colors.button.warning.bg,
},
membersCount: {
fontSize: 14,
fontWeight: "300",
color: Colors.text.body,
},
componentTitle: {
fontSize: 14,
width: "100%",
color: Colors.text.subtitle,
fontWeight: "300",
},
componentTitleBold: {
fontSize: 14,
width: "100%",
color: Colors.text.subtitle,
fontWeight: "bold",
},
});
export default TopForms;
import React from "react"; import React from "react";
import { StyleSheet, Text, View } from "react-native"; import { Alert, StyleSheet, Text, View } from "react-native";
import { AlphabetList } from "react-native-section-alphabet-list"; import { AlphabetList } from "react-native-section-alphabet-list";
import PlainButton from "../button/PlainButton"; import PlainButton from "../button/PlainButton";
import Colors from "../../constants/Colors"; import Colors from "../../constants/Colors";
import { IData, ISectionData } from "../../types/alphabetGroupList"; import { IData, ISectionData } from "../../types/alphabetGroupList";
import { useNavigation } from "@react-navigation/core";
import { ecosystemItem } from "../../types/ListItems";
type props = { type props = {
data: IData[]; data: IData[];
fromScreen?: string;
forGroup?: string;
ecosystemCategories?: ecosystemItem;
}; };
const AlphabetGroupList = ({ data }: props) => { const AlphabetGroupList = ({
data,
fromScreen,
forGroup,
ecosystemCategories,
}: props) => {
const nav = useNavigation();
return ( return (
<View style={styles.container}> <View style={styles.container}>
<AlphabetList <AlphabetList
...@@ -17,7 +29,28 @@ const AlphabetGroupList = ({ data }: props) => { ...@@ -17,7 +29,28 @@ const AlphabetGroupList = ({ data }: props) => {
indexLetterStyle={styles.indexLetter} indexLetterStyle={styles.indexLetter}
renderCustomItem={(item: IData) => ( renderCustomItem={(item: IData) => (
<View style={styles.listItemContainer}> <View style={styles.listItemContainer}>
<PlainButton text={item.value} onPress={() => {}} /> <PlainButton
text={item.value}
onPress={() => {
if (fromScreen === "CreateEcosystem") {
if (ecosystemCategories[item.key] != null) {
Alert.alert(
"Kategori Sudah Ditambahkan",
"Silahkan pilih kategori lain"
);
} else {
nav.navigate("CreateEcosystem", {
screen: "CreateEcosystemScreen",
params: {
id: item.key,
name: item.value,
forGroup: forGroup,
},
});
}
}
}}
/>
</View> </View>
)} )}
renderCustomSectionHeader={(section: ISectionData) => ( renderCustomSectionHeader={(section: ISectionData) => (
......
import Constants from "expo-constants";
export const CLOUD_FUNCTIONS_URL = (Constants.manifest.extra
?.cloudFunctionsUrl || process.env.cloudFunctionsUrl) as string;
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import type { RootState, AppDispatch } from "../redux/store"; import type { RootState, AppDispatch } from "../redux/store";
import { IUser } from "../types/firestore/User";
// Use throughout your app instead of plain `useDispatch` and `useSelector` // Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () => useDispatch<AppDispatch>(); export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector; export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
export const useUser = (): IUser => useAppSelector((state) => state.user);
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import React from "react";
import CreateEcosystemScreen from "../screens/CreateEcosystemScreen";
import { BusinessCategoryScreen } from "../screens/ecosystem";
import { CreateEcosystemStackParamList } from "../types/navigation/CreateEcosystemStack";
const CreateEcosystemStack =
createNativeStackNavigator<CreateEcosystemStackParamList>();
const CreateEcosystemStackNavigator = () => {
return (
<CreateEcosystemStack.Navigator initialRouteName="CreateEcosystemScreen">
<CreateEcosystemStack.Screen
name="CreateEcosystemScreen"
component={CreateEcosystemScreen}
options={{ title: "" }}
/>
<CreateEcosystemStack.Screen
name="BusinessCategory"
component={BusinessCategoryScreen}
options={{ title: "Ekosistem Saya" }}
/>
</CreateEcosystemStack.Navigator>
);
};
export default CreateEcosystemStackNavigator;
...@@ -4,11 +4,11 @@ import BusinessEcosystemScreen from "../screens/ecosystem/BusinessEcosystemScree ...@@ -4,11 +4,11 @@ import BusinessEcosystemScreen from "../screens/ecosystem/BusinessEcosystemScree
import { EcosystemStackParamList } from "../types/navigation/EcosystemStack"; import { EcosystemStackParamList } from "../types/navigation/EcosystemStack";
import { import {
BusinessCategoryScreen, BusinessCategoryScreen,
BusinessListScreen,
EcosystemDetailScreen, EcosystemDetailScreen,
EcosystemListScreen, EcosystemListScreen,
EcosystemMapScreen, EcosystemMapScreen,
RecommendedEcosystemScreen, RecommendedEcosystemScreen,
UserListScreen,
} from "../screens/ecosystem"; } from "../screens/ecosystem";
const EcosystemStack = createNativeStackNavigator<EcosystemStackParamList>(); const EcosystemStack = createNativeStackNavigator<EcosystemStackParamList>();
...@@ -52,8 +52,8 @@ const EcosystemStackNavigator = () => { ...@@ -52,8 +52,8 @@ const EcosystemStackNavigator = () => {
options={{ title: "Peta Ekosistem" }} options={{ title: "Peta Ekosistem" }}
/> />
<EcosystemStack.Screen <EcosystemStack.Screen
name="BusinessList" name="UserList"
component={BusinessListScreen} component={UserListScreen}
initialParams={{ headerTitle: "" }} initialParams={{ headerTitle: "" }}
options={({ route }) => ({ title: route.params.headerTitle })} options={({ route }) => ({ title: route.params.headerTitle })}
/> />
......
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { createNativeStackNavigator } from "@react-navigation/native-stack"; import { createNativeStackNavigator } from "@react-navigation/native-stack";
import BottomTabNavigator from "./BottomTabNavigator"; import BottomTabNavigator from "./BottomTabNavigator";
import CreateEcosystemStackNavigator from "./CreateEcosystemStackNavigator";
import { RootStackParamList } from "../types/navigation"; import { RootStackParamList } from "../types/navigation";
import AuthStackNavigator from "./AuthStackNavigator"; import AuthStackNavigator from "./AuthStackNavigator";
import SuccessChangePasswordScreen from "../screens/SuccessChangePasswordScreen"; import SuccessChangePasswordScreen from "../screens/SuccessChangePasswordScreen";
...@@ -68,11 +69,20 @@ const RootNavigator = () => { ...@@ -68,11 +69,20 @@ const RootNavigator = () => {
options={{ headerShown: false }} options={{ headerShown: false }}
/> />
)} )}
<RootStack.Screen {user.id !== "" && (
name="SuccessChangePassword" <RootStack.Screen
component={SuccessChangePasswordScreen} name="CreateEcosystem"
options={{ headerShown: false }} component={CreateEcosystemStackNavigator}
/> options={{ headerShown: false }}
/>
)}
{user.id !== "" && (
<RootStack.Screen
name="SuccessChangePassword"
component={SuccessChangePasswordScreen}
options={{ headerShown: false }}
/>
)}
</RootStack.Navigator> </RootStack.Navigator>
) : ( ) : (
<RootStack.Navigator> <RootStack.Navigator>
......
This diff is collapsed.
...@@ -6,8 +6,12 @@ import AlphabetGroupList from "../../components/GroupList/AlphabetGroupList"; ...@@ -6,8 +6,12 @@ import AlphabetGroupList from "../../components/GroupList/AlphabetGroupList";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { getCategoriesAsIData } from "../../helpers/alphabetConverter"; import { getCategoriesAsIData } from "../../helpers/alphabetConverter";
import { IData } from "react-native-section-alphabet-list"; import { IData } from "react-native-section-alphabet-list";
import { CreateEcosystemStackScreenProps } from "../../types/navigation";
const BusinessCategoryScreen = () => { const BusinessCategoryScreen = ({
route,
}: CreateEcosystemStackScreenProps<"BusinessCategory">) => {
const { fromScreen, forGroup, ecosystemCategories } = route.params;
const [data, setData] = useState<IData[]>([]); const [data, setData] = useState<IData[]>([]);
useEffect(() => { useEffect(() => {
getCategoriesAsIData().then((res) => setData(res)); getCategoriesAsIData().then((res) => setData(res));
...@@ -15,7 +19,12 @@ const BusinessCategoryScreen = () => { ...@@ -15,7 +19,12 @@ const BusinessCategoryScreen = () => {
return ( return (
<View style={styles.container}> <View style={styles.container}>
<AlphabetGroupList data={data} /> <AlphabetGroupList
data={data}
fromScreen={fromScreen}
forGroup={forGroup}
ecosystemCategories={ecosystemCategories}
/>
</View> </View>
); );
}; };
......
import { useNavigation } from "@react-navigation/core"; import { useNavigation } from "@react-navigation/core";
import * as React from "react"; import React from "react";
import { StyleSheet } from "react-native"; import { StyleSheet } from "react-native";
import { TouchableOpacity } from "react-native-gesture-handler"; import { TouchableOpacity } from "react-native-gesture-handler";
import SmallButton from "../../components/button/SmallButton"; import SmallButton from "../../components/button/SmallButton";
import Spacer from "../../components/Spacer/Spacer"; import Spacer from "../../components/Spacer/Spacer";
import { Text, View } from "../../components/Themed"; import { Text, View } from "../../components/Themed";
import Colors from "../../constants/Colors"; import Colors from "../../constants/Colors";
import { IEcosystem } from "../../types/firestore/ecosystems"; import { useUser } from "../../hooks/reduxHooks";
import ecosystemService from "../../service/firestore/ecosystem";
import { createEcosystem } from "../../service/functions/createEcosystem";
const BusinessEcosystemScreen = () => { const BusinessEcosystemScreen = () => {
const nav = useNavigation(); const nav = useNavigation();
const user = useUser();
return ( return (
<View style={styles.container}> <View style={styles.container}>
...@@ -21,7 +24,9 @@ const BusinessEcosystemScreen = () => { ...@@ -21,7 +24,9 @@ const BusinessEcosystemScreen = () => {
colors="primary" colors="primary"
text="Buat Ekosistem Bisnis" text="Buat Ekosistem Bisnis"
onPress={() => { onPress={() => {
nav.navigate("CreateBusinessEcosystem"); nav.navigate("CreateEcosystem", {
screen: "CreateEcosystem",
});
}} }}
/> />
<Spacer variant="xl" /> <Spacer variant="xl" />
...@@ -32,9 +37,7 @@ const BusinessEcosystemScreen = () => { ...@@ -32,9 +37,7 @@ const BusinessEcosystemScreen = () => {
screen: "Recommended", screen: "Recommended",
params: { params: {
headerTitle: "Ekosistem Saya", headerTitle: "Ekosistem Saya",
toFetch: () => { toFetch: "myEcosystem",
return new Promise<IEcosystem[]>(() => {});
},
}, },
}); });
}} }}
...@@ -72,9 +75,7 @@ const BusinessEcosystemScreen = () => { ...@@ -72,9 +75,7 @@ const BusinessEcosystemScreen = () => {
screen: "Recommended", screen: "Recommended",
params: { params: {
headerTitle: "Paling Populer", headerTitle: "Paling Populer",
toFetch: () => { toFetch: "popular",
return new Promise<IEcosystem[]>(() => {});
},
}, },
}); });
}} }}
...@@ -90,9 +91,7 @@ const BusinessEcosystemScreen = () => { ...@@ -90,9 +91,7 @@ const BusinessEcosystemScreen = () => {
screen: "Recommended", screen: "Recommended",
params: { params: {
headerTitle: "Terbaru Minggu Ini", headerTitle: "Terbaru Minggu Ini",
toFetch: () => { toFetch: "mostRecent",
return new Promise<IEcosystem[]>(() => {});
},
}, },
}); });
}} }}
...@@ -110,6 +109,75 @@ const BusinessEcosystemScreen = () => { ...@@ -110,6 +109,75 @@ const BusinessEcosystemScreen = () => {
<Text style={styles.link}>Peta Ekosistem</Text> <Text style={styles.link}>Peta Ekosistem</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<View>
<TouchableOpacity
onPress={() => {
createEcosystem({
ecosystem: {
creatorId: "abc",
name: "cebetEco",
description: "abc",
categoryId: "A",
pic: "",
rating: 0,
raters: 0,
followerCount: 0,
visibility: "public",
},
ecosystemCategoryMembers: [
{
categoryMember: {
categoryId: "B",
type: "supplier",
},
ecosystemMemberships: [
{
userId: "7n8uc62bS6UGUl29fODxIp7PAdn2",
},
],
},
{
categoryMember: {
categoryId: "D",
type: "supplier",
},
ecosystemMemberships: [
{
userId: "abciuh3789489ho340hdf",