Initial commit
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Expo
|
||||||
|
.expo/
|
||||||
|
dist/
|
||||||
|
web-build/
|
||||||
|
expo-env.d.ts
|
||||||
|
|
||||||
|
# Native
|
||||||
|
*.orig.*
|
||||||
|
*.jks
|
||||||
|
*.p8
|
||||||
|
*.p12
|
||||||
|
*.key
|
||||||
|
*.mobileprovision
|
||||||
|
|
||||||
|
# Metro
|
||||||
|
.metro-health-check*
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.*
|
||||||
|
yarn-debug.*
|
||||||
|
yarn-error.*
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
app-example
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
import "react-native-gesture-handler";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { NavigationContainer } from "@react-navigation/native";
|
||||||
|
import { createStackNavigator } from "@react-navigation/stack";
|
||||||
|
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
||||||
|
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
|
||||||
|
|
||||||
|
// Screens
|
||||||
|
import SplashScreen from "./screens/SplashScreen";
|
||||||
|
import Onboarding from "./screens/Onboarding";
|
||||||
|
import AksesAkun from "./screens/AksesAkun"; // Pastikan ini sudah diimport dengan benar
|
||||||
|
// import masuk from "./screens/masuk";
|
||||||
|
// import Home from "./screens/AksesWarga/Home";
|
||||||
|
import Home from "./screens/AksesWarga/Home";
|
||||||
|
import EcoMapCoinExchangeScreen from "./screens/AksesWarga/EcoMapCoinExchangeScreen";
|
||||||
|
import NotifikasiScreen from "./screens/AksesWarga/NotifikasiScreen";
|
||||||
|
import ProfilScreen from "./screens/AksesWarga/ProfilScreen";
|
||||||
|
import AksesWargaNavigator from "./Navigation/AksesWargaNavigator";
|
||||||
|
import AksesAdminNavigator from "./Navigation/AksesAdminNavigator";
|
||||||
|
import BottomTab from "./Navigation/BottomTab";
|
||||||
|
import AdminScreen from "./screens/AksesAdmin/AdminScreen";
|
||||||
|
import masuk from "./screens/masuk";
|
||||||
|
import BottomNav from "./Navigation/BottomNav";
|
||||||
|
|
||||||
|
const Stack = createStackNavigator();
|
||||||
|
const Tab = createBottomTabNavigator();
|
||||||
|
|
||||||
|
// --- Bottom Tab Navigator ---
|
||||||
|
function MyTabs() {
|
||||||
|
return (
|
||||||
|
<Tab.Navigator
|
||||||
|
initialRouteName="Home"
|
||||||
|
screenOptions={({ route }) => ({
|
||||||
|
headerShown: false,
|
||||||
|
tabBarActiveTintColor: "#1B5E20",
|
||||||
|
tabBarInactiveTintColor: "#A5D6A7",
|
||||||
|
tabBarStyle: {
|
||||||
|
backgroundColor: "#2E7D32",
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
height: 60,
|
||||||
|
paddingBottom: 5,
|
||||||
|
},
|
||||||
|
tabBarLabelStyle: {
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: "600",
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
tabBarIcon: ({ focused, color, size }) => {
|
||||||
|
size = 24;
|
||||||
|
if (route.name === "Home") {
|
||||||
|
return (
|
||||||
|
<Ionicons
|
||||||
|
name={focused ? "home" : "home-outline"}
|
||||||
|
size={size}
|
||||||
|
color={color}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else if (route.name === "EcoMapCoinExchangeScreen") {
|
||||||
|
return <FontAwesome5 name="coins" size={size} color={color} />;
|
||||||
|
} else if (route.name === "NotifikasiScreen") {
|
||||||
|
return (
|
||||||
|
<Ionicons
|
||||||
|
name={focused ? "notifications" : "notifications-outline"}
|
||||||
|
size={size}
|
||||||
|
color={color}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else if (route.name === "ProfilScreen") {
|
||||||
|
return (
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name={focused ? "account" : "account-outline"}
|
||||||
|
size={size}
|
||||||
|
color={color}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Tab.Screen name="Home" component={Home} />
|
||||||
|
<Tab.Screen name="TukarKoin" component={EcoMapCoinExchangeScreen} />
|
||||||
|
<Tab.Screen name="Notifikasi" component={NotifikasiScreen} />
|
||||||
|
<Tab.Screen name="Profil" component={ProfilScreen} />
|
||||||
|
</Tab.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
// // State untuk menyimpan role yang dipilih
|
||||||
|
// const [selectedRole, setSelectedRole] = useState(null);
|
||||||
|
// // State login user
|
||||||
|
// const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
||||||
|
<NavigationContainer>
|
||||||
|
<Stack.Navigator
|
||||||
|
initialRouteName="Splash"
|
||||||
|
screenOptions={{ headerShown: false }}
|
||||||
|
>
|
||||||
|
{/* Splash Screen */}
|
||||||
|
<Stack.Screen name="Splash" component={SplashScreen} />
|
||||||
|
|
||||||
|
{/* Onboarding Screen */}
|
||||||
|
<Stack.Screen name="Onboarding" component={Onboarding} />
|
||||||
|
<Stack.Screen name="AksesAkun" component={AksesAkun} />
|
||||||
|
{/* <Stack.Screen name="masuk" component={masuk} /> */}
|
||||||
|
{/* <Stack.Screen name="Home" component={Home} /> */}
|
||||||
|
{/* <Stack.Screen
|
||||||
|
name="Home"
|
||||||
|
component={BottomTab} // Menampilkan BottomTabNavigator di sini
|
||||||
|
options={{ headerShown: false }} // Menyembunyikan header jika perlu
|
||||||
|
/> */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="AksesAdminNavigator"
|
||||||
|
component={AksesAdminNavigator}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="AksesWargaNavigator"
|
||||||
|
component={AksesWargaNavigator}
|
||||||
|
/>
|
||||||
|
</Stack.Navigator>
|
||||||
|
</NavigationContainer>
|
||||||
|
</GestureHandlerRootView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
import React from "react";
|
||||||
|
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
|
||||||
|
import { NavigationContainer } from "@react-navigation/native";
|
||||||
|
import HomeNavigator from "./HomeNavigator"; // Import HomeNavigator
|
||||||
|
import ProfilScreenNavigator from "./ProfilScreenNavigator"; // Import ProfileNavigator
|
||||||
|
import NotifikasiScreen from "./screens/AksesWarga/NotifikasiScreen";
|
||||||
|
import EcoMapCoinExchangeScreen from "./screens/AksesWarga/EcoMapCoinExchangeScreen";
|
||||||
|
|
||||||
|
const Tab = createBottomTabNavigator();
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return (
|
||||||
|
<NavigationContainer>
|
||||||
|
<Tab.Navigator initialRouteName="Home">
|
||||||
|
{/* Tab Home yang akan menggunakan HomeNavigator */}
|
||||||
|
<Tab.Screen
|
||||||
|
name="HomeNavigator"
|
||||||
|
component={HomeNavigator} // Gunakan HomeNavigator di sini
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Tab Profile yang menggunakan ProfileNavigator */}
|
||||||
|
<Tab.Screen
|
||||||
|
name="ProfilNavigator"
|
||||||
|
component={ProfilScreenNavigator}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Tab Notifikasi */}
|
||||||
|
<Tab.Screen
|
||||||
|
name="Notifikasi"
|
||||||
|
component={NotifikasiScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Tab EcoMap Coin Exchange */}
|
||||||
|
<Tab.Screen
|
||||||
|
name="EcoMapCoinExchange"
|
||||||
|
component={EcoMapCoinExchangeScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
</Tab.Navigator>
|
||||||
|
</NavigationContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
import { createStackNavigator } from "@react-navigation/stack";
|
||||||
|
import AdminScreen from "../screens/AksesAdmin/AdminScreen";
|
||||||
|
import MasukAdmin from "../screens/MasukAdmin";
|
||||||
|
import BottomTabAdmin from "../Navigation/BottomTabAdmin";
|
||||||
|
import PosterEdukasiScreen from "../screens/AksesAdmin/PosterEdukasiScreen";
|
||||||
|
import PengaduanSampahScreenAdmin from "../screens/AksesAdmin/PengaduanSampahScreenAdmin";
|
||||||
|
import BerandaPengaduanAdmin from "../screens/AksesAdmin/BerandaPengaduanAdmin";
|
||||||
|
import DaftarTPSAdmin from "../screens/AksesAdmin/DaftarTPSAdmin";
|
||||||
|
import TambahTPS from "../screens/AksesAdmin/TambahTPS";
|
||||||
|
import EditTPS from "../screens/AksesAdmin/EditTPS";
|
||||||
|
import KontribusiAdmin from "../screens/AksesAdmin/KontribusiAdmin";
|
||||||
|
import KontribusiBerhasilAdmin from "../screens/AksesAdmin/KontribusiBerhasilAdmin";
|
||||||
|
import RiwayatDonasiAdmin from "../screens/AksesAdmin/RiwayatDonasiAdmin";
|
||||||
|
import DetailDalamProses from "../screens/AksesAdmin/DetailDalamProses";
|
||||||
|
import DetailVerifikasi from "../screens/AksesAdmin/DetailVerifikasi";
|
||||||
|
import DetailDitolak from "../screens/AksesAdmin/DetailDitolak";
|
||||||
|
import Laporan from "../screens/AksesAdmin/Laporan";
|
||||||
|
import TukarKoin from "../screens/AksesAdmin/TukarKoin";
|
||||||
|
import NotifikasiAdminScreen from "../screens/AksesAdmin/NotifikasiAdminScreen";
|
||||||
|
import ProfilAdminScreen from "../screens/AksesAdmin/ProfilAdminScreen";
|
||||||
|
import EditProfilScreen from "../screens/AksesAdmin/EditProfilScreen";
|
||||||
|
import DetailPengirimanAdmin from "../screens/AksesAdmin/DetailPengirimanAdmin";
|
||||||
|
import AksesAkun from "../screens/AksesAkun";
|
||||||
|
import DaftarBarang from "../screens/AksesAdmin/DaftarBarang";
|
||||||
|
|
||||||
|
const Stack = createStackNavigator();
|
||||||
|
|
||||||
|
export default function AksesAdminNavigator() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator>
|
||||||
|
<Stack.Screen
|
||||||
|
name="admin"
|
||||||
|
component={AksesAkun}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="AdminScreen"
|
||||||
|
component={AdminScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="BottomTabAdmin"
|
||||||
|
component={BottomTabAdmin}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Stack.Screen
|
||||||
|
name="PosterEdukasiScreen"
|
||||||
|
component={PosterEdukasiScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="PengaduanSampahScreenAdmin"
|
||||||
|
component={PengaduanSampahScreenAdmin}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DetailDalamProses"
|
||||||
|
component={DetailDalamProses}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DetailVerifikasi"
|
||||||
|
component={DetailVerifikasi}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DetailDitolak"
|
||||||
|
component={DetailDitolak}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="BerandaPengaduanAdmin"
|
||||||
|
component={BerandaPengaduanAdmin}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Laporan"
|
||||||
|
component={Laporan}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="TukarKoin"
|
||||||
|
component={TukarKoin}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DaftarBarang"
|
||||||
|
component={DaftarBarang}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DetailPengirimanAdmin"
|
||||||
|
component={DetailPengirimanAdmin}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="NotifikasiAdminScreen"
|
||||||
|
component={NotifikasiAdminScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="ProfilAdminScreen"
|
||||||
|
component={ProfilAdminScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="EditProfilScreen"
|
||||||
|
component={EditProfilScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Stack.Screen
|
||||||
|
name="KontribusiAdmin"
|
||||||
|
component={KontribusiAdmin}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="KontribusiBerhasilAdmin"
|
||||||
|
component={KontribusiBerhasilAdmin}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DaftarTPSAdmin"
|
||||||
|
component={DaftarTPSAdmin}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="TambahTPS"
|
||||||
|
component={TambahTPS}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="EditTPS"
|
||||||
|
component={EditTPS}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="RiwayatDonasiAdmin"
|
||||||
|
component={RiwayatDonasiAdmin}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,222 @@
|
||||||
|
import { createStackNavigator } from "@react-navigation/stack";
|
||||||
|
import Home from "../screens/AksesWarga/Home";
|
||||||
|
// import AksesAkun from "../screens/AksesAkun";
|
||||||
|
import masuk from "../screens/masuk";
|
||||||
|
import BottomNav from "./BottomNav";
|
||||||
|
import LokasiTerdekat from "../screens/AksesWarga/LokasiTerdekat";
|
||||||
|
import daftarTPS from "../screens/daftarTPS";
|
||||||
|
import RiwayatCoinScreen from "../screens/AksesWarga/RiwayatCoinScreen";
|
||||||
|
import pengaduansampah from "../screens/PengaduanWarga/pengaduansampah";
|
||||||
|
// import PengaduanSampahScreenAdmin from "../screens/AksesAdmin/PengaduanSampahScreenAdmin";
|
||||||
|
import misimingguan from "../screens/AksesWarga/misimingguan";
|
||||||
|
import BerandaPengaduan from "../screens/AksesWarga/BerandaPengaduan";
|
||||||
|
import KontribusiScreen from "../screens/PengaduanWarga/KontribusiScreen";
|
||||||
|
import EcoMapCoinExchangeScreen from "../screens/AksesWarga/EcoMapCoinExchangeScreen";
|
||||||
|
// import NotifikasiScreen from "../screens/AksesAdmin/NotifikasiAdminScreen";
|
||||||
|
import ProfilScreen from "../screens/AksesWarga/ProfilScreen";
|
||||||
|
import ProfilNavigation from "../Navigation/ProfilNavigation";
|
||||||
|
import NotifikasiScreen from "../screens/AksesWarga/NotifikasiScreen";
|
||||||
|
// import DonasiNavigator from "./DonasiNavigator";
|
||||||
|
import Donasiberhasil from "../screens/ProfilWarga/DonasiWarga/Donasiberhasil";
|
||||||
|
import Donasi from "../screens/ProfilWarga/DonasiWarga/Donasi";
|
||||||
|
import MetodeDonasi from "../screens/ProfilWarga/DonasiWarga/MetodeDonasi";
|
||||||
|
import KonfirmasiPembayaran from "../screens/ProfilWarga/DonasiWarga/KonfirmasiPembayaran";
|
||||||
|
import DonasiVerifikasi from "../screens/ProfilWarga/DonasiWarga/DonasiVerifikasi";
|
||||||
|
// import LoadingScreen from "../screens/PengaduanWarga/LoadingScreen";
|
||||||
|
import PengaduanBerhasil from "../screens/PengaduanWarga/PengaduanBerhasil";
|
||||||
|
import KontribusiBerhasil from "../screens/PengaduanWarga/KontribusiBerhasil";
|
||||||
|
// import BerandaPengaduan from "../screens/AksesWarga/BerandaPengaduan";
|
||||||
|
// import PengaduanWargaNavigator from "../Navigation/AksesWargaNavigator";
|
||||||
|
import AksesAkun from "../screens/AksesAkun";
|
||||||
|
import DaftarNavigation from "../Navigation/DaftarNavigation";
|
||||||
|
import DaftarBerhasil from "../screens/DaftarBerhasil";
|
||||||
|
import daftar from "../screens/daftar";
|
||||||
|
import lupasandi from "../screens/password/lupasandi"; // Halaman lupa sandi
|
||||||
|
import resetsandi from "../screens/password/InputContact"; // Halaman reset sandi
|
||||||
|
import notifikasisukses from "../screens/password/notifikasisukses"; // Halaman notifikasi sukses
|
||||||
|
import InputContact from "../screens/password/InputContact";
|
||||||
|
import VerifyCode from "../screens/password/VerifyCode";
|
||||||
|
// import LokasiTerdekat from "../screens/AksesWarga/LokasiTerdekat";
|
||||||
|
// import daftarTPS from "../screens/daftarTPS";
|
||||||
|
// import RiwayatCoinScreen from "../screens/AksesWarga/RiwayatCoinScreen";
|
||||||
|
const Stack = createStackNavigator();
|
||||||
|
const AkeswargaNavigator = createStackNavigator();
|
||||||
|
|
||||||
|
function AkeswargaStack() {
|
||||||
|
return (
|
||||||
|
<AkeswargaNavigator.Navigator>
|
||||||
|
<AkeswargaNavigator.Screen
|
||||||
|
name="ProfilNavigation"
|
||||||
|
component={ProfilStack}
|
||||||
|
/>
|
||||||
|
</AkeswargaNavigator.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default function AksesWargaNavigator() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator>
|
||||||
|
{/* <Stack.Screen
|
||||||
|
name="AksesAkun"
|
||||||
|
component={AksesAkun}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/> */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="warga"
|
||||||
|
component={AksesAkun}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DaftarNavigation"
|
||||||
|
component={DaftarNavigation}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="daftar"
|
||||||
|
component={daftar}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DaftarBerhasil"
|
||||||
|
component={DaftarBerhasil}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="lupasandi"
|
||||||
|
component={lupasandi}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="InputContact"
|
||||||
|
component={InputContact}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="VerifyCode"
|
||||||
|
component={VerifyCode}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="notifikasisukses"
|
||||||
|
component={notifikasisukses}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Home"
|
||||||
|
component={Home}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="BottomNav"
|
||||||
|
component={BottomNav}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="LokasiTerdekat"
|
||||||
|
component={LokasiTerdekat}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="daftarTPS"
|
||||||
|
component={daftarTPS}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="RiwayatCoinScreen"
|
||||||
|
component={RiwayatCoinScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="pengaduansampah"
|
||||||
|
component={pengaduansampah}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
{/* <Stack.Screen
|
||||||
|
name="pengaduansampahNavigator"
|
||||||
|
component={PengaduanWargaNavigator}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/> */}
|
||||||
|
{/* <Stack.Screen
|
||||||
|
name="pengaduansampah"
|
||||||
|
component={pengaduansampah}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/> */}
|
||||||
|
{/* <Stack.Screen
|
||||||
|
name="LoadingScreen"
|
||||||
|
component={LoadingScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/> */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="PengaduanBerhasil"
|
||||||
|
component={PengaduanBerhasil}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Stack.Screen
|
||||||
|
name="misimingguan"
|
||||||
|
component={misimingguan}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="BerandaPengaduan"
|
||||||
|
component={BerandaPengaduan}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="KontribusiScreen"
|
||||||
|
component={KontribusiScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="KontribusiBerhasil"
|
||||||
|
component={KontribusiBerhasil}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="EcoMapCoinExchangeScreen"
|
||||||
|
component={EcoMapCoinExchangeScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="NotifikasiScreen"
|
||||||
|
component={NotifikasiScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="ProfilScreen"
|
||||||
|
component={ProfilScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="ProfilNavigation"
|
||||||
|
component={ProfilNavigation}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Donasi"
|
||||||
|
component={Donasi}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="MetodeDonasi"
|
||||||
|
component={MetodeDonasi}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="KonfirmasiPembayaran"
|
||||||
|
component={KonfirmasiPembayaran}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DonasiVerifikasi"
|
||||||
|
component={DonasiVerifikasi}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Donasiberhasil"
|
||||||
|
component={Donasiberhasil}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
{/* <Stack.Screen name="Home" component={Home}options={{ headerShown: false }} /> */}
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
// import { createStackNavigator } from "@react-navigation/stack";
|
||||||
|
// import Home from "../screens/AksesWarga/Home";
|
||||||
|
// import pengaduansampah from "../screens/PengaduanWarga/pengaduansampah";
|
||||||
|
// import masuk from "../screens/masuk";
|
||||||
|
// import BerandaPengaduan from "../screens/AksesWarga/BerandaPengaduan";
|
||||||
|
// import KontribusiScreen from "../screens/PengaduanWarga/KontribusiScreen";
|
||||||
|
|
||||||
|
// const Stack = createStackNavigator();
|
||||||
|
|
||||||
|
// export default function BerandaPengaduanNav() {
|
||||||
|
// return (
|
||||||
|
// <Stack.Navigator>
|
||||||
|
// <Stack.Screen
|
||||||
|
// name="Home"
|
||||||
|
// component={Home}
|
||||||
|
// options={{ headerShown: false }}
|
||||||
|
// />
|
||||||
|
// <Stack.Screen
|
||||||
|
// name="BerandaPengaduan"
|
||||||
|
// component={BerandaPengaduan}
|
||||||
|
// options={{ headerShown: false }}
|
||||||
|
// />
|
||||||
|
// <Stack.Screen
|
||||||
|
// name="KontribusiScreen"
|
||||||
|
// component={KontribusiScreen}
|
||||||
|
// options={{ headerShown: false }}
|
||||||
|
// />
|
||||||
|
// </Stack.Navigator>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, TouchableOpacity, Text, StyleSheet } from "react-native";
|
||||||
|
import { Ionicons, FontAwesome5 } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const BottomNav = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.bottomNav}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("Home")}
|
||||||
|
>
|
||||||
|
<Ionicons name="home" size={30} color="#2C6B2F" />
|
||||||
|
<Text style={styles.navText}>UTAMA</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("EcoMapCoinExchangeScreen")}
|
||||||
|
>
|
||||||
|
<FontAwesome5 name="exchange-alt" size={24} color="#2C6B2F" />
|
||||||
|
<Text style={styles.navText}>TUKAR KOIN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("NotifikasiScreen")}
|
||||||
|
>
|
||||||
|
<View style={styles.notifIconContainer}>
|
||||||
|
<Ionicons name="notifications-outline" size={24} color="#2C6B2F" />
|
||||||
|
{/* Ensure the badge text is wrapped in Text component */}
|
||||||
|
<View style={styles.badge}>
|
||||||
|
<Text style={styles.badgeText}>1</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.navText}>NOTIFIKASI</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("ProfilNavigation")}
|
||||||
|
>
|
||||||
|
<Ionicons name="person-circle-outline" size={24} color="#2C6B2F" />
|
||||||
|
<Text style={styles.navText}>PROFIL</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
bottomNav: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
width: "100%",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: -2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 6,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
navItem: {
|
||||||
|
flex: 1, // Membuat tiap tombol punya lebar yang sama
|
||||||
|
alignItems: "center",
|
||||||
|
padding: 6,
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
paddingVertical: 5,
|
||||||
|
marginHorizontal: 5,
|
||||||
|
},
|
||||||
|
navText: { color: "#2C6B2F", fontSize: 12, marginTop: 5 },
|
||||||
|
notifIconContainer: { position: "relative" },
|
||||||
|
badge: {
|
||||||
|
position: "absolute",
|
||||||
|
right: -5,
|
||||||
|
top: -5,
|
||||||
|
backgroundColor: "#E74C3C",
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 6,
|
||||||
|
paddingVertical: 2,
|
||||||
|
},
|
||||||
|
badgeText: { color: "#fff", fontSize: 10, fontWeight: "bold" },
|
||||||
|
});
|
||||||
|
|
||||||
|
export default BottomNav;
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
import React from "react";
|
||||||
|
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { Text, StyleSheet } from "react-native";
|
||||||
|
|
||||||
|
// Import screens
|
||||||
|
import Home from "../screens/AksesWarga/Home";
|
||||||
|
import EcoMapCoinExchangeScreen from "../screens/AksesWarga/EcoMapCoinExchangeScreen";
|
||||||
|
import NotifikasiScreen from "../screens/AksesWarga/NotifikasiScreen";
|
||||||
|
import ProfilScreen from "../screens/AksesWarga/ProfilScreen";
|
||||||
|
|
||||||
|
const Tab = createBottomTabNavigator();
|
||||||
|
|
||||||
|
export default function bottomtab() {
|
||||||
|
return (
|
||||||
|
<Tab.Navigator
|
||||||
|
initialRouteName="Home"
|
||||||
|
screenOptions={({ route }) => ({
|
||||||
|
headerShown: false,
|
||||||
|
tabBarStyle: {
|
||||||
|
backgroundColor: "#fff", // White background for the tab bar
|
||||||
|
borderTopWidth: 1,
|
||||||
|
borderTopColor: "#2C6B2F",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
tabBarIcon: ({ focused, color, size }) => {
|
||||||
|
// Set color to green explicitly
|
||||||
|
const iconColor = "#2C6B2F"; // Green color for icons
|
||||||
|
let iconName;
|
||||||
|
|
||||||
|
if (route.name === "Home") {
|
||||||
|
iconName = "home";
|
||||||
|
} else if (route.name === "EcoMapCoin") {
|
||||||
|
iconName = "swap-horizontal";
|
||||||
|
} else if (route.name === "Notifikasi") {
|
||||||
|
iconName = "notifications-outline";
|
||||||
|
} else if (route.name === "Profil") {
|
||||||
|
iconName = "person-circle-outline";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return an icon component with the green color
|
||||||
|
return <Ionicons name={iconName} size={size} color={iconColor} />;
|
||||||
|
},
|
||||||
|
tabBarLabel: ({ focused, color }) => {
|
||||||
|
let label;
|
||||||
|
if (route.name === "Home") {
|
||||||
|
label = "UTAMA";
|
||||||
|
} else if (route.name === "EcoMapCoin") {
|
||||||
|
label = "TUKAR KOIN";
|
||||||
|
} else if (route.name === "Notifikasi") {
|
||||||
|
label = "NOTIFIKASI";
|
||||||
|
} else if (route.name === "Profil") {
|
||||||
|
label = "PROFIL";
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Text style={{ color: "#2C6B2F", fontSize: 12 }}>{label}</Text>
|
||||||
|
); // Green text color
|
||||||
|
},
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Tab.Screen name="Home" component={Home} />
|
||||||
|
<Tab.Screen
|
||||||
|
name="EcoMapCoin"
|
||||||
|
component={EcoMapCoinExchangeScreen}
|
||||||
|
options={{ title: "Tukar Koin" }}
|
||||||
|
/>
|
||||||
|
<Tab.Screen
|
||||||
|
name="Notifikasi"
|
||||||
|
component={NotifikasiScreen}
|
||||||
|
options={{ title: "Notifikasi" }}
|
||||||
|
/>
|
||||||
|
<Tab.Screen
|
||||||
|
name="Profil"
|
||||||
|
component={ProfilScreen}
|
||||||
|
options={{ title: "Profil" }}
|
||||||
|
/>
|
||||||
|
</Tab.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
bottomNav: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
paddingVertical: 10,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderTopWidth: 1,
|
||||||
|
borderTopColor: "#2C6B2F",
|
||||||
|
marginBottom: 0, // Green border
|
||||||
|
},
|
||||||
|
navItem: {
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
navText: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#2C6B2F", // Green text color
|
||||||
|
},
|
||||||
|
notifIconContainer: {
|
||||||
|
position: "relative",
|
||||||
|
},
|
||||||
|
badge: {
|
||||||
|
position: "absolute",
|
||||||
|
top: -5,
|
||||||
|
right: -5,
|
||||||
|
backgroundColor: "red",
|
||||||
|
borderRadius: 8,
|
||||||
|
paddingHorizontal: 5,
|
||||||
|
paddingVertical: 2,
|
||||||
|
},
|
||||||
|
badgeText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 10,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, TouchableOpacity, Text, StyleSheet } from "react-native";
|
||||||
|
import { Ionicons, FontAwesome5 } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const BottomTabAdmin = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.bottomNav}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("AdminScreen")}
|
||||||
|
>
|
||||||
|
<Ionicons name="home" size={30} color="#2C6B2F" />
|
||||||
|
<Text style={styles.navText}>UTAMA</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("TukarKoin")}
|
||||||
|
>
|
||||||
|
<FontAwesome5 name="exchange-alt" size={24} color="#2C6B2F" />
|
||||||
|
<Text style={styles.navText}>TUKAR KOIN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("NotifikasiAdminScreen")}
|
||||||
|
>
|
||||||
|
<View style={styles.notifIconContainer}>
|
||||||
|
<Ionicons name="notifications-outline" size={24} color="#2C6B2F" />
|
||||||
|
{/* Ensure the badge text is wrapped in Text component */}
|
||||||
|
<View style={styles.badge}>
|
||||||
|
<Text style={styles.badgeText}>1</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.navText}>NOTIFIKASI</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("ProfilAdminScreen")}
|
||||||
|
>
|
||||||
|
<Ionicons name="person-circle-outline" size={24} color="#2C6B2F" />
|
||||||
|
<Text style={styles.navText}>PROFIL</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
bottomNav: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
width: "100%",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: -2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 6,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
navItem: {
|
||||||
|
flex: 1, // Membuat tiap tombol punya lebar yang sama
|
||||||
|
alignItems: "center",
|
||||||
|
padding: 6,
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
paddingVertical: 5,
|
||||||
|
marginHorizontal: 5,
|
||||||
|
},
|
||||||
|
navText: { color: "#2C6B2F", fontSize: 12, marginTop: 5 },
|
||||||
|
notifIconContainer: { position: "relative" },
|
||||||
|
badge: {
|
||||||
|
position: "absolute",
|
||||||
|
right: -5,
|
||||||
|
top: -5,
|
||||||
|
backgroundColor: "#E74C3C",
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 6,
|
||||||
|
paddingVertical: 2,
|
||||||
|
},
|
||||||
|
badgeText: { color: "#fff", fontSize: 10, fontWeight: "bold" },
|
||||||
|
});
|
||||||
|
|
||||||
|
export default BottomTabAdmin;
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
import React from "react";
|
||||||
|
import { createStackNavigator } from "@react-navigation/stack";
|
||||||
|
import { NavigationContainer } from "@react-navigation/native";
|
||||||
|
import Masuk from "../screens/masuk"; // Halaman login
|
||||||
|
import Daftar from "../screens/daftar"; // Halaman daftar
|
||||||
|
import DaftarBerhasil from "../screens/DaftarBerhasil"; // Halaman pendaftaran berhasil
|
||||||
|
import LupaSandi from "../screens/password/lupasandi"; // Halaman lupa sandi
|
||||||
|
import ResetSandi from "../screens/password/InputContact"; // Halaman reset sandi
|
||||||
|
import NotifikasiSukses from "../screens/password/notifikasisukses"; // Halaman notifikasi sukses
|
||||||
|
|
||||||
|
// Membuat Stack Navigators
|
||||||
|
const Stack = createStackNavigator();
|
||||||
|
const DaftarStack = createStackNavigator(); // Untuk halaman Daftar
|
||||||
|
const LupaSandiStack = createStackNavigator(); // Untuk halaman Lupa Sandi
|
||||||
|
|
||||||
|
// DaftarSekarangStackScreen: Mengatur navigasi untuk pendaftaran
|
||||||
|
function DaftarSekarangStackScreen() {
|
||||||
|
return (
|
||||||
|
<DaftarStack.Navigator>
|
||||||
|
<DaftarStack.Screen
|
||||||
|
name="Daftar"
|
||||||
|
component={Daftar}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<DaftarStack.Screen
|
||||||
|
name="DaftarBerhasil"
|
||||||
|
component={DaftarBerhasil}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
</DaftarStack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LupaKataSandiStackScreen: Mengatur navigasi untuk lupa kata sandi
|
||||||
|
function LupaKataSandiStackScreen() {
|
||||||
|
return (
|
||||||
|
<LupaSandiStack.Navigator>
|
||||||
|
<LupaSandiStack.Screen
|
||||||
|
name="LupaSandi"
|
||||||
|
component={LupaSandi}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<LupaSandiStack.Screen
|
||||||
|
name="ResetSandi"
|
||||||
|
component={ResetSandi}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<LupaSandiStack.Screen
|
||||||
|
name="NotifikasiSukses"
|
||||||
|
component={NotifikasiSukses}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
</LupaSandiStack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigasi utama untuk Akses Warga
|
||||||
|
export default function DaftarNavigation() {
|
||||||
|
return (
|
||||||
|
<NavigationContainer>
|
||||||
|
<Stack.Navigator>
|
||||||
|
{/* Halaman Masuk */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="Masuk"
|
||||||
|
component={Masuk}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Nested Navigators */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="DaftarSekarangStackScreen"
|
||||||
|
component={DaftarSekarangStackScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="LupaKataSandiStackScreen"
|
||||||
|
component={LupaKataSandiStackScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
</Stack.Navigator>
|
||||||
|
</NavigationContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
Image,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
ScrollView,
|
||||||
|
Alert,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
|
||||||
|
const EditProfileScreen = () => {
|
||||||
|
// State for profile fields
|
||||||
|
const [profile, setProfile] = useState({
|
||||||
|
name: "Okta",
|
||||||
|
email: "okta@example.com",
|
||||||
|
phone: "08123456789",
|
||||||
|
address: "Jl. Raya No. 123, Jakarta",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Function to handle input changes
|
||||||
|
const handleInputChange = (field, value) => {
|
||||||
|
setProfile({
|
||||||
|
...profile,
|
||||||
|
[field]: value,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to handle save button click with confirmation
|
||||||
|
const handleSave = () => {
|
||||||
|
Alert.alert(
|
||||||
|
"Konfirmasi Edit Data",
|
||||||
|
"Apakah Anda yakin ingin mengedit data pribadi?",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: "Tidak",
|
||||||
|
onPress: () => console.log("Edit cancelled"),
|
||||||
|
style: "cancel",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Yakin",
|
||||||
|
onPress: () => {
|
||||||
|
console.log("Data pribadi berhasil disimpan!");
|
||||||
|
// Implement save logic here (e.g., save to API or local storage)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{ cancelable: false }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView style={styles.container}>
|
||||||
|
{/* Header with Back Button */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => console.log("Go back")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#333" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>Informasi Pribadi</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Profile Picture Section */}
|
||||||
|
<View style={styles.profileImageContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://imgv3.fotor.com/images/gallery/a-woman-linkedin-picture-with-grey-background-made-by-LinkedIn-Profile-Picture-Maker.jpg",
|
||||||
|
}} // Placeholder, replace with real profile picture
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
<TouchableOpacity style={styles.changeImageButton}>
|
||||||
|
<Text style={styles.changeImageText}>Ubah Foto Profil</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Input Fields for Profile Information */}
|
||||||
|
<View style={styles.formSection}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.inputField}
|
||||||
|
value={profile.name}
|
||||||
|
placeholder="Nama"
|
||||||
|
onChangeText={(text) => handleInputChange("name", text)}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.inputField}
|
||||||
|
value={profile.email}
|
||||||
|
placeholder="Email"
|
||||||
|
onChangeText={(text) => handleInputChange("email", text)}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.inputField}
|
||||||
|
value={profile.phone}
|
||||||
|
placeholder="No. HP"
|
||||||
|
onChangeText={(text) => handleInputChange("phone", text)}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.inputField}
|
||||||
|
value={profile.address}
|
||||||
|
placeholder="Alamat"
|
||||||
|
onChangeText={(text) => handleInputChange("address", text)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Save Button */}
|
||||||
|
<TouchableOpacity style={styles.saveButton} onPress={handleSave}>
|
||||||
|
<Text style={styles.saveButtonText}>Simpan</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#f9f9f9",
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
paddingTop: 30,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row", // Align back button and title in one row
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
profileImageContainer: {
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 30,
|
||||||
|
},
|
||||||
|
profileImage: {
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
borderRadius: 50,
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
changeImageButton: {
|
||||||
|
backgroundColor: "#dcdcdc",
|
||||||
|
paddingVertical: 5,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 5,
|
||||||
|
},
|
||||||
|
changeImageText: {
|
||||||
|
color: "#333",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
formSection: {
|
||||||
|
marginBottom: 30,
|
||||||
|
},
|
||||||
|
inputField: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 15,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 15,
|
||||||
|
fontSize: 16,
|
||||||
|
borderColor: "#ddd",
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
saveButton: {
|
||||||
|
backgroundColor: "#2D572C", // Green color
|
||||||
|
paddingVertical: 12,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
saveButtonText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
|
||||||
|
logoutButtonText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default EditProfileScreen;
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import React, { Component } from "react";
|
||||||
|
import { Text } from "react-native";
|
||||||
|
|
||||||
|
class ErrorBoundary extends Component {
|
||||||
|
state = { hasError: false };
|
||||||
|
|
||||||
|
static getDerivedStateFromError() {
|
||||||
|
return { hasError: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidCatch(error, info) {
|
||||||
|
console.error("Error caught by Error Boundary:", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (this.state.hasError) {
|
||||||
|
return <Text>Error Occurred!</Text>;
|
||||||
|
}
|
||||||
|
return this.props.children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ErrorBoundary;
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { createStackNavigator } from "@react-navigation/stack";
|
||||||
|
import Home from "../screens/AksesWarga/Home";
|
||||||
|
import pengaduansampah from "../screens/PengaduanWarga/pengaduansampah";
|
||||||
|
import masuk from "../screens/masuk";
|
||||||
|
import LoadingScreen from "../screens/PengaduanWarga/LoadingScreen";
|
||||||
|
import PengaduanBerhasil from "../screens/PengaduanWarga/PengaduanBerhasil";
|
||||||
|
import BerandaPengaduan from "../screens/AksesWarga/BerandaPengaduan";
|
||||||
|
|
||||||
|
const Stack = createStackNavigator();
|
||||||
|
|
||||||
|
// Navigator untuk Pengaduan Warga
|
||||||
|
function PengaduanWargaStackScreen() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator>
|
||||||
|
<Stack.Screen
|
||||||
|
name="pengaduansampah"
|
||||||
|
component={pengaduansampah}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
{/* <Stack.Screen
|
||||||
|
name="LoadingScreen"
|
||||||
|
component={LoadingScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/> */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="PengaduanBerhasil"
|
||||||
|
component={PengaduanBerhasil}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="BerandaPengaduan"
|
||||||
|
component={BerandaPengaduan}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigator utama untuk Akses Warga
|
||||||
|
export default function AksesWargaNavigator() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Home"
|
||||||
|
component={Home}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
{/* Di sini kita bisa menambahkan PengaduanWargaStack sebagai nested navigator */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="PengaduanWargaNavigator"
|
||||||
|
component={PengaduanWargaStackScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,133 @@
|
||||||
|
import { createStackNavigator } from "@react-navigation/stack";
|
||||||
|
import { NavigationContainer } from "@react-navigation/native";
|
||||||
|
import Home from "../screens/AksesWarga/Home";
|
||||||
|
// import AksesAkun from "../screens/AksesAkun";
|
||||||
|
import masuk from "../screens/masuk";
|
||||||
|
// import bottomtab from "./BottomTab";
|
||||||
|
import LokasiTerdekat from "../screens/AksesWarga/LokasiTerdekat";
|
||||||
|
import daftarTPS from "../screens/daftarTPS";
|
||||||
|
import RiwayatCoinScreen from "../screens/AksesWarga/RiwayatCoinScreen";
|
||||||
|
import pengaduansampah from "../screens/PengaduanWarga/pengaduansampah";
|
||||||
|
import PengaduanSampahScreenAdmin from "../screens/AksesAdmin/PengaduanSampahScreenAdmin";
|
||||||
|
import misimingguan from "../screens/AksesWarga/misimingguan";
|
||||||
|
import BerandaPengaduan from "../screens/AksesWarga/BerandaPengaduan";
|
||||||
|
import KontribusiScreen from "../screens/PengaduanWarga/KontribusiScreen";
|
||||||
|
import EcoMapCoinExchangeScreen from "../screens/AksesWarga/EcoMapCoinExchangeScreen";
|
||||||
|
import NotifikasiScreen from "../screens/AksesAdmin/NotifikasiAdminScreen";
|
||||||
|
import ProfilScreen from "../screens/AksesWarga/ProfilScreen";
|
||||||
|
import DetailPengaduan from "../screens/PengaduanWarga/DetailPengaduan";
|
||||||
|
import StatusPengirimanScreen from "../screens/ProfilWarga/StatusPengiriman/StatusPengirimanScreen";
|
||||||
|
import Donasi from "../screens/ProfilWarga/DonasiWarga/Donasi";
|
||||||
|
import InformasiPribadi from "../screens/ProfilWarga/InformasiPribadi/InformasiPribadi";
|
||||||
|
import EditInformasiPribadi from "../screens/ProfilWarga/InformasiPribadi/EditInformasiPribadi";
|
||||||
|
import DetailPengiriman from "../screens/ProfilWarga/StatusPengiriman/DetailPengiriman";
|
||||||
|
import Donasiberhasil from "../screens/ProfilWarga/DonasiWarga/Donasiberhasil";
|
||||||
|
import StatusPengaduan from "../screens/ProfilWarga/StatusPengaduan/StatusPengaduan";
|
||||||
|
// import Donasi from "../screens/ProfilWarga/DonasiWarga/Donasi";
|
||||||
|
import MetodeDonasi from "../screens/ProfilWarga/DonasiWarga/MetodeDonasi";
|
||||||
|
import KonfirmasiPembayaran from "../screens/ProfilWarga/DonasiWarga/KonfirmasiPembayaran";
|
||||||
|
import DonasiVerifikasi from "../screens/ProfilWarga/DonasiWarga/DonasiVerifikasi";
|
||||||
|
|
||||||
|
// import LokasiTerdekat from "../screens/AksesWarga/LokasiTerdekat";
|
||||||
|
// import daftarTPS from "../screens/daftarTPS";
|
||||||
|
// import RiwayatCoinScreen from "../screens/AksesWarga/RiwayatCoinScreen";
|
||||||
|
const Stack = createStackNavigator();
|
||||||
|
const ProfilNavigator = createStackNavigator();
|
||||||
|
|
||||||
|
function StatusPengaduanStack() {
|
||||||
|
return (
|
||||||
|
<ProfilNavigator.Navigator>
|
||||||
|
<ProfilNavigator.Screen
|
||||||
|
name="StatusPengaduan"
|
||||||
|
component={StatusPengaduan}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
</ProfilNavigator.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function InformasiPribadiStackScreen() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator>
|
||||||
|
<Stack.Screen
|
||||||
|
name="InformasiPribadi"
|
||||||
|
component={InformasiPribadi}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="EditInformasiPribadi"
|
||||||
|
component={EditInformasiPribadi}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function StatusPenukaranKoinStackScreen() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator>
|
||||||
|
<Stack.Screen
|
||||||
|
name="StatusPengirimanScreen"
|
||||||
|
component={StatusPengirimanScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DetailPengiriman"
|
||||||
|
component={DetailPengiriman}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function DonasiStackScreen() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator screenOptions={{ headerShown: false }}>
|
||||||
|
<Stack.Screen name="Donasi" component={Donasi} />
|
||||||
|
<Stack.Screen name="MetodeDonasi" component={MetodeDonasi} />
|
||||||
|
<Stack.Screen
|
||||||
|
name="KonfirmasiPembayaran"
|
||||||
|
component={KonfirmasiPembayaran}
|
||||||
|
/>
|
||||||
|
<Stack.Screen name="DonasiVerifikasi" component={DonasiVerifikasi} />
|
||||||
|
<Stack.Screen name="Donasiberhasil" component={Donasiberhasil} />
|
||||||
|
<Stack.Screen name="Home" component={Home} />
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigator utama untuk Akses Warga
|
||||||
|
export default function ProfilNavigation() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator>
|
||||||
|
{/* <Stack.Screen
|
||||||
|
name="Home"
|
||||||
|
component={Home}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/> */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="ProfilScreen"
|
||||||
|
component={ProfilScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
{/* Di sini kita bisa menambahkan PengaduanWargaStack sebagai nested navigator */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="InformasiPribadiStackScreen"
|
||||||
|
component={InformasiPribadiStackScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="StatusPenukaranKoinStackScreen"
|
||||||
|
component={StatusPenukaranKoinStackScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="DonasiStackScreen"
|
||||||
|
component={DonasiStackScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="StatusPengaduanStack"
|
||||||
|
component={StatusPengaduanStack}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import React from "react";
|
||||||
|
import { createStackNavigator } from "@react-navigation/stack";
|
||||||
|
import ProfilScreen from "./screens/AksesWarga/ProfilScreen";
|
||||||
|
// Pastikan StatusPengirimanScreen sudah diimpor jika kamu ingin menggunakannya
|
||||||
|
import StatusPengirimanScreen from "./screens/ProfilWarga/StatusPengiriman/StatusPengirimanScreen";
|
||||||
|
import Donasi from "./screens/ProfilWarga/DonasiWarga/Donasi";
|
||||||
|
|
||||||
|
const Stack = createStackNavigator();
|
||||||
|
|
||||||
|
function ProfilScreenNavigator() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator>
|
||||||
|
{/* Layar Utama Profile */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="ProfilScreen"
|
||||||
|
component={ProfilScreen}
|
||||||
|
options={{ headerShown: false }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Layar-Layar Detail di dalam Profile */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="StatusPengirimanScreen"
|
||||||
|
component={StatusPengirimanScreen}
|
||||||
|
options={{ title: "Status Penukaran Koin" }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Donasi"
|
||||||
|
component={Donasi}
|
||||||
|
options={{ title: "Donasi" }}
|
||||||
|
/>
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProfilScreenNavigator;
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Welcome to your Expo app 👋
|
||||||
|
|
||||||
|
This is an [Expo](https://expo.dev) project created with [`create-expo-app`](https://www.npmjs.com/package/create-expo-app).
|
||||||
|
|
||||||
|
## Get started
|
||||||
|
|
||||||
|
1. Install dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Start the app
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx expo start
|
||||||
|
```
|
||||||
|
|
||||||
|
In the output, you'll find options to open the app in a
|
||||||
|
|
||||||
|
- [development build](https://docs.expo.dev/develop/development-builds/introduction/)
|
||||||
|
- [Android emulator](https://docs.expo.dev/workflow/android-studio-emulator/)
|
||||||
|
- [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/)
|
||||||
|
- [Expo Go](https://expo.dev/go), a limited sandbox for trying out app development with Expo
|
||||||
|
|
||||||
|
You can start developing by editing the files inside the **app** directory. This project uses [file-based routing](https://docs.expo.dev/router/introduction).
|
||||||
|
|
||||||
|
## Get a fresh project
|
||||||
|
|
||||||
|
When you're ready, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run reset-project
|
||||||
|
```
|
||||||
|
|
||||||
|
This command will move the starter code to the **app-example** directory and create a blank **app** directory where you can start developing.
|
||||||
|
|
||||||
|
## Learn more
|
||||||
|
|
||||||
|
To learn more about developing your project with Expo, look at the following resources:
|
||||||
|
|
||||||
|
- [Expo documentation](https://docs.expo.dev/): Learn fundamentals, or go into advanced topics with our [guides](https://docs.expo.dev/guides).
|
||||||
|
- [Learn Expo tutorial](https://docs.expo.dev/tutorial/introduction/): Follow a step-by-step tutorial where you'll create a project that runs on Android, iOS, and the web.
|
||||||
|
|
||||||
|
## Join the community
|
||||||
|
|
||||||
|
Join our community of developers creating universal apps.
|
||||||
|
|
||||||
|
- [Expo on GitHub](https://github.com/expo/expo): View our open source platform and contribute.
|
||||||
|
- [Discord community](https://chat.expo.dev): Chat with Expo users and ask questions.
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
{
|
||||||
|
"expo": {
|
||||||
|
"doctor": {
|
||||||
|
"reactNativeDirectoryCheck": {
|
||||||
|
"listUnknownPackages": false,
|
||||||
|
"name": "yakinbisa",
|
||||||
|
"slug": "yakinbisa",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"orientation": "portrait",
|
||||||
|
"icon": "./assets/images/icon.png",
|
||||||
|
"scheme": "myapp",
|
||||||
|
"platforms": [
|
||||||
|
"ios",
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"android": {
|
||||||
|
"jsEngine": "hermes",
|
||||||
|
"adaptiveIcon": {
|
||||||
|
"foregroundImage": "./assets/images/adaptive-icon.png",
|
||||||
|
"backgroundColor": "#ffffff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"userInterfaceStyle": "automatic",
|
||||||
|
"newArchEnabled": true,
|
||||||
|
"ios": {
|
||||||
|
"supportsTablet": true
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"bundler": "metro",
|
||||||
|
"output": "static",
|
||||||
|
"favicon": "./assets/images/favicon.png"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
[
|
||||||
|
"expo-splash-screen",
|
||||||
|
{
|
||||||
|
"image": "./assets/images/splash-icon.png",
|
||||||
|
"imageWidth": 200,
|
||||||
|
"resizeMode": "contain",
|
||||||
|
"backgroundColor": "#ffffff"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"expo-font",
|
||||||
|
"expo-router"
|
||||||
|
],
|
||||||
|
"experiments": {
|
||||||
|
"typedRoutes": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 951 B |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -0,0 +1,65 @@
|
||||||
|
{
|
||||||
|
"name": "yakinbisa",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"start": "expo start",
|
||||||
|
"reset-project": "node ./scripts/reset-project.js",
|
||||||
|
"android": "expo start --android",
|
||||||
|
"ios": "expo start --ios",
|
||||||
|
"web": "expo start --web",
|
||||||
|
"test": "jest --watchAll",
|
||||||
|
"lint": "expo lint"
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"preset": "jest-expo"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@expo/vector-icons": "^14.1.0",
|
||||||
|
"@react-native-picker/picker": "2.11.0",
|
||||||
|
"@react-navigation/bottom-tabs": "^7.3.13",
|
||||||
|
"@react-navigation/native": "^7.1.9",
|
||||||
|
"@react-navigation/stack": "^7.3.2",
|
||||||
|
"expo": "^53.0.11",
|
||||||
|
"expo-blur": "~14.1.5",
|
||||||
|
"expo-camera": "~16.1.7",
|
||||||
|
"expo-checkbox": "~4.1.4",
|
||||||
|
"expo-constants": "~17.1.6",
|
||||||
|
"expo-font": "~13.3.1",
|
||||||
|
"expo-haptics": "~14.1.4",
|
||||||
|
"expo-image-picker": "~16.1.4",
|
||||||
|
"expo-linear-gradient": "~14.1.5",
|
||||||
|
"expo-linking": "~7.1.5",
|
||||||
|
"expo-location": "~18.1.5",
|
||||||
|
"expo-media-library": "~17.1.7",
|
||||||
|
"expo-print": "~14.1.4",
|
||||||
|
"expo-router": "~5.0.7",
|
||||||
|
"expo-splash-screen": "^0.30.9",
|
||||||
|
"expo-status-bar": "~2.2.3",
|
||||||
|
"expo-symbols": "^0.4.5",
|
||||||
|
"expo-system-ui": "~5.0.8",
|
||||||
|
"expo-web-browser": "~14.1.6",
|
||||||
|
"react": "19.0.0",
|
||||||
|
"react-dom": "19.0.0",
|
||||||
|
"react-native": "^0.79.3",
|
||||||
|
"react-native-calendars": "^1.1312.0",
|
||||||
|
"react-native-chart-kit": "^6.12.0",
|
||||||
|
"react-native-gesture-handler": "~2.24.0",
|
||||||
|
"react-native-google-places-autocomplete": "^2.5.7",
|
||||||
|
"react-native-maps": "1.20.1",
|
||||||
|
"react-native-reanimated": "~3.17.4",
|
||||||
|
"react-native-reanimated-carousel": "^4.0.2",
|
||||||
|
"react-native-safe-area-context": "5.4.0",
|
||||||
|
"react-native-screens": "~4.11.1",
|
||||||
|
"react-native-svg": "15.11.2",
|
||||||
|
"react-native-vector-icons": "^10.2.0",
|
||||||
|
"react-native-web": "^0.20.0",
|
||||||
|
"expo-av": "~15.1.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.26.0",
|
||||||
|
"jest": "~29.7.0",
|
||||||
|
"jest-expo": "~53.0.7",
|
||||||
|
"react-test-renderer": "18.3.1"
|
||||||
|
},
|
||||||
|
"private": true
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,473 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
TouchableOpacity,
|
||||||
|
ImageBackground,
|
||||||
|
Dimensions,
|
||||||
|
Image,
|
||||||
|
ScrollView,
|
||||||
|
} from "react-native";
|
||||||
|
import {
|
||||||
|
Ionicons,
|
||||||
|
FontAwesome5,
|
||||||
|
MaterialCommunityIcons,
|
||||||
|
} from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import BottomTabAdmin from "../../Navigation/BottomTabAdmin";
|
||||||
|
import { LineChart } from "react-native-chart-kit";
|
||||||
|
|
||||||
|
const { width, height } = Dimensions.get("window");
|
||||||
|
|
||||||
|
const AdminScreen = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [activeSlide, setActiveSlide] = useState(0);
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
labels: ["Jan", "Feb", "Mar", "Apr", "May"], // Label untuk bulan
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
data: [5000000, 7000000, 4000000, 8000000, 6000000], // Data donasi per bulan
|
||||||
|
strokeWidth: 1, // Lebar garis
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNext = () => {
|
||||||
|
navigation.navigate(""); // Add the name of the screen to navigate
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<ImageBackground
|
||||||
|
source={require("../../assets/images/bg.png")}
|
||||||
|
style={styles.backgroundImage}
|
||||||
|
>
|
||||||
|
{/* <Text style={styles.date}>05 Mei 2025</Text> */}
|
||||||
|
{/* Profile Section */}
|
||||||
|
|
||||||
|
<ScrollView contentContainerStyle={styles.scrollContainer}>
|
||||||
|
<View style={styles.profileContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://shanibacreative.com/wp-content/uploads/2022/10/SCI-0801220002_7-1280x1920.jpeg",
|
||||||
|
}} // Replace with your image URL
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text style={styles.greetingnama}>
|
||||||
|
Halooo Dina {"\n"}
|
||||||
|
<Text style={styles.subtitle}>
|
||||||
|
Kebersihan Lingkungan Wajib Terjaga!
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.subtitle}></Text>
|
||||||
|
{/* <Text style={styles.greetingnama}>
|
||||||
|
Dinas Lingkungan Hidup{" "}
|
||||||
|
<Ionicons name="checkmark-circle" size={18} color="green" />
|
||||||
|
</Text> */}
|
||||||
|
</View>
|
||||||
|
{/* <View style={styles.header}> */}
|
||||||
|
|
||||||
|
<Text style={styles.subtitle}></Text>
|
||||||
|
<View style={styles.coinRow}>
|
||||||
|
<View style={styles.coinInfo}>
|
||||||
|
<View style={styles.coinBox}>
|
||||||
|
<Text style={styles.coinLabel}>JUMLAH DONASI</Text>
|
||||||
|
<View style={styles.coinValueRow}>
|
||||||
|
<Text style={styles.coinText}>Rp. 5.870.000</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.noCoinText}>Donasi dalam satu tahun</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.historyButton}
|
||||||
|
onPress={() => navigation.navigate("RiwayatDonasiAdmin")}
|
||||||
|
>
|
||||||
|
<Text style={styles.historyButtonText}>RIWAYAT DONASI</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={styles.coinInfo}>
|
||||||
|
<View style={styles.coinBox}>
|
||||||
|
<Text style={styles.coinLabel}>PENGELUARAN</Text>
|
||||||
|
<View style={styles.coinValueRow}>
|
||||||
|
<Text style={styles.coinText}>Rp. 3.270.000</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.noCoinText}>
|
||||||
|
Pengeluaran dalam satu bulan
|
||||||
|
</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.historyButton}
|
||||||
|
onPress={() => navigation.navigate("RiwayatDonasiAdmin")}
|
||||||
|
>
|
||||||
|
<Text style={styles.historyButtonText}>
|
||||||
|
RIWAYAT PENGELUARAN
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.statsContainer}>
|
||||||
|
<View style={styles.statBox}>
|
||||||
|
<Text style={styles.statLabel}>Pengaduan</Text>
|
||||||
|
<Text style={styles.statValue}>102</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.statBox}>
|
||||||
|
<Text style={styles.statLabel}>TPS di Nganjuk</Text>
|
||||||
|
<Text style={styles.statValue}>52</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.reportButton}
|
||||||
|
onPress={() => navigation.navigate("BerandaPengaduanAdmin")}
|
||||||
|
>
|
||||||
|
<Text style={styles.reportButtonText}>BERANDA PENGADUAN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<View style={styles.menuContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.menuItem}
|
||||||
|
onPress={() => navigation.navigate("DaftarTPSAdmin")}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name="bookmarks"
|
||||||
|
size={40}
|
||||||
|
color="#2C6B2F"
|
||||||
|
style={styles.menuImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.menuText}>TPS di Nganjuk</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.menuItem}
|
||||||
|
onPress={() => navigation.navigate("Laporan")}
|
||||||
|
>
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name="file-document"
|
||||||
|
size={50}
|
||||||
|
color="#2C6B2F"
|
||||||
|
style={styles.menuImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.menuText}>Laporan</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.menuItem}
|
||||||
|
onPress={() => navigation.navigate("PosterEdukasiScreen")}
|
||||||
|
>
|
||||||
|
<FontAwesome5
|
||||||
|
name="chalkboard-teacher"
|
||||||
|
size={38}
|
||||||
|
color="#2C6B2F"
|
||||||
|
style={styles.menuImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.menuText}>Poster Edukasi</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.menuItem}
|
||||||
|
onPress={() => navigation.navigate("PengaduanSampahScreenAdmin")}
|
||||||
|
>
|
||||||
|
<FontAwesome5
|
||||||
|
name="exclamation-triangle"
|
||||||
|
size={40}
|
||||||
|
color="#2C6B2F"
|
||||||
|
style={styles.menuImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.menuText}>Pengaduan Sampah</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.chartContainer}>
|
||||||
|
<Text style={styles.chartTitle}>Grafik Donasi Bulanan</Text>
|
||||||
|
<LineChart
|
||||||
|
data={data}
|
||||||
|
width={width - 40} // Mengatur lebar grafik
|
||||||
|
height={220} // Mengatur tinggi grafik
|
||||||
|
chartConfig={{
|
||||||
|
backgroundColor: "#000",
|
||||||
|
backgroundGradientFrom: "#2C6B2F",
|
||||||
|
backgroundGradientTo: "#000",
|
||||||
|
decimalPlaces: 0, // Tidak ada angka desimal pada grafik
|
||||||
|
color: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
|
||||||
|
labelColor: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
|
||||||
|
style: {
|
||||||
|
borderRadius: 16,
|
||||||
|
marginBottom: 40,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
style={styles.chartStyle}
|
||||||
|
/>
|
||||||
|
<Text style={styles.chartTitlebawah}>Grafik Donasi Bulanan</Text>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
</ImageBackground>
|
||||||
|
<BottomTabAdmin />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: { flex: 1, backgroundColor: "#2C6B2F", paddingTop: 20 },
|
||||||
|
scrollContainer: {
|
||||||
|
flexGrow: 1, // This ensures the ScrollView can expand to take up the remaining space
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
// alignItems: "center",
|
||||||
|
borderBottomLeftRadius: 30,
|
||||||
|
borderTopStartRadius: 50,
|
||||||
|
borderBottomRightRadius: 30,
|
||||||
|
borderTopRightRadius: 50,
|
||||||
|
paddingBottom: 10,
|
||||||
|
marginTop: 170,
|
||||||
|
marginBottom: 150,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#cdcdcd", // Reduce this padding for better scrolling
|
||||||
|
},
|
||||||
|
chartContainer: {
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
marginVertical: 20,
|
||||||
|
marginBottom: 20, // Reduced to avoid pushing the content down
|
||||||
|
},
|
||||||
|
profileContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
marginBottom: 20,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
},
|
||||||
|
profileImage: {
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
borderRadius: 50,
|
||||||
|
marginRight: 10,
|
||||||
|
marginTop: 30,
|
||||||
|
},
|
||||||
|
chartTitle: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
chartTitlebawah: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
chartStyle: {
|
||||||
|
borderRadius: 16,
|
||||||
|
marginBottom: 200,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
alignItems: "center",
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderBottomLeftRadius: 30,
|
||||||
|
borderTopStartRadius: 50,
|
||||||
|
borderBottomRightRadius: 30,
|
||||||
|
borderTopRightRadius: 50,
|
||||||
|
paddingBottom: 50,
|
||||||
|
marginBottom: 50,
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
date: {
|
||||||
|
fontSize: 18,
|
||||||
|
color: "#fff",
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
marginBottom: 5,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
greeting: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginTop: 20,
|
||||||
|
color: "#000",
|
||||||
|
paddingHorizontal: 90,
|
||||||
|
// alignItems: "center",
|
||||||
|
// justifyContent: "center",
|
||||||
|
},
|
||||||
|
greetingnama: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginTop: 30,
|
||||||
|
marginLeft: -10,
|
||||||
|
color: "#000",
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
flexDirection: "column",
|
||||||
|
},
|
||||||
|
subtitle: {
|
||||||
|
fontSize: 15,
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: "500",
|
||||||
|
paddingHorizontal: 70,
|
||||||
|
marginBottom: -30,
|
||||||
|
marginTop: 5,
|
||||||
|
marginLeft: 20,
|
||||||
|
// justifyContent: "center",
|
||||||
|
},
|
||||||
|
coinRow: {
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
alignItems: "center",
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
coinInfo: { alignItems: "flex-start" },
|
||||||
|
coinLabel: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "700",
|
||||||
|
color: "#333",
|
||||||
|
marginBottom: 0,
|
||||||
|
marginLeft: -100,
|
||||||
|
},
|
||||||
|
coinBox: {
|
||||||
|
marginVertical: 10,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingHorizontal: 130,
|
||||||
|
paddingVertical: 15,
|
||||||
|
borderRadius: 20,
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
elevation: 1,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#aaa",
|
||||||
|
position: "relative",
|
||||||
|
marginLeft: -5,
|
||||||
|
},
|
||||||
|
coinValueRow: { flexDirection: "row", alignItems: "center", marginTop: 0 },
|
||||||
|
coinText: {
|
||||||
|
fontSize: 30,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
textAlign: "left",
|
||||||
|
marginLeft: -100,
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
noCoinText: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#aaa",
|
||||||
|
marginTop: 0,
|
||||||
|
marginBottom: -5,
|
||||||
|
textAlign: "left",
|
||||||
|
marginLeft: -100,
|
||||||
|
},
|
||||||
|
statsContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginVertical: 0,
|
||||||
|
alignContent: "space-between",
|
||||||
|
padding: 0,
|
||||||
|
},
|
||||||
|
statBox: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 15,
|
||||||
|
borderRadius: 15,
|
||||||
|
width: "30%",
|
||||||
|
alignItems: "center",
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 8,
|
||||||
|
borderWidth: 0.5,
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginRight: 12,
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
statLabel: {
|
||||||
|
fontSize: 12,
|
||||||
|
justifyContent: "center",
|
||||||
|
color: "black",
|
||||||
|
alignItems: "center",
|
||||||
|
fontWeight: "600",
|
||||||
|
},
|
||||||
|
statValue: {
|
||||||
|
fontSize: 25,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
historyButton: {
|
||||||
|
position: "absolute",
|
||||||
|
backgroundColor: "#2C6B2F",
|
||||||
|
borderColor: "#000",
|
||||||
|
paddingVertical: 12,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
borderRadius: 20,
|
||||||
|
top: -6,
|
||||||
|
right: 10,
|
||||||
|
marginTop: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
width: "110%",
|
||||||
|
elevation: 1,
|
||||||
|
},
|
||||||
|
historyButtonText: {
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#fff",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
|
||||||
|
reportButton: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
borderRadius: 20,
|
||||||
|
// alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
borderColor: "#000",
|
||||||
|
width: "80%",
|
||||||
|
marginTop: 15,
|
||||||
|
paddingLeft: 5,
|
||||||
|
padding: 15,
|
||||||
|
elevation: 2,
|
||||||
|
marginLeft: 40,
|
||||||
|
},
|
||||||
|
reportButtonText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "center",
|
||||||
|
padding: 5,
|
||||||
|
},
|
||||||
|
menuImage: {
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
marginLeft: 3,
|
||||||
|
marginBottom: 5,
|
||||||
|
marginTop: 10,
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
menuContainer: {
|
||||||
|
marginTop: 5,
|
||||||
|
marginRight: 5,
|
||||||
|
marginLeft: 12,
|
||||||
|
flexDirection: "row",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
justifyContent: "space-evenly",
|
||||||
|
paddingRight: 15,
|
||||||
|
},
|
||||||
|
menuItem: {
|
||||||
|
width: "20%",
|
||||||
|
|
||||||
|
alignItems: "center",
|
||||||
|
marginVertical: 5,
|
||||||
|
padding: 10,
|
||||||
|
borderWidth: 0,
|
||||||
|
borderColor: "#fff",
|
||||||
|
borderRadius: 25,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
elevation: 2,
|
||||||
|
},
|
||||||
|
menuText: {
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: "500",
|
||||||
|
color: "#333",
|
||||||
|
marginTop: 0,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default AdminScreen;
|
||||||
|
|
@ -0,0 +1,217 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, Text, StyleSheet, TouchableOpacity, Image } from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const BerandaPengaduanAdmin = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.navigate("AdminScreen")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.headerTitle}>BERANDA PENGADUAN</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* First Report */}
|
||||||
|
<View style={styles.reportContainer}>
|
||||||
|
<View style={styles.reportHeader}>
|
||||||
|
<View style={styles.profileContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://www.w3schools.com/howto/img_avatar.png", // Replace with actual profile picture URI
|
||||||
|
}}
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.reporterName}>Johan Okta Pangestu</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.time}>03/01/2025 10.12 WIB</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity style={styles.statusButton}>
|
||||||
|
<Text style={styles.reportStatus}>Sedang diverifikasi</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.reportDescription}>
|
||||||
|
Sampah numpuk di depan masjid - JI Letjen Sparman
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.reportNote}>
|
||||||
|
Catatan: Mohon segera ditindaklanjuti karena sangat mengganggu
|
||||||
|
masyarakat sekitar.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Images */}
|
||||||
|
<View style={styles.imageContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.arenalte.com/uploads/2019/07/sampah.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://www.storypick.com/wp-content/uploads/2019/06/waste.png",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Second Report */}
|
||||||
|
<View style={styles.reportContainer}>
|
||||||
|
<View style={styles.reportHeader}>
|
||||||
|
<View style={styles.profileContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://www.w3schools.com/howto/img_avatar2.png", // Replace with actual profile picture URI
|
||||||
|
}}
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.reporterName}>Jihan Pangesti</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.time}>03/01/2025 10.12 WIB</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity style={styles.statusButton}>
|
||||||
|
<Text style={styles.reportStatus}>Dalam Proses</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.reportDescription}>
|
||||||
|
Sampah berserakan di Pasar Lama - JI. Sukarno, Nganjuk
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.reportNote}>
|
||||||
|
Catatan: Mohon segera ditindaklanjuti karena sangat mengganggu
|
||||||
|
masyarakat sekitar.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Images */}
|
||||||
|
<View style={styles.imageContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.toiimg.com/thumb/msid-97714168,imgsize-1547670,width-400,resizemode-4/97714168.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.toiimg.com/thumb/msid-87155572,imgsize-1511223,width-400,resizemode-4/87155572.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 16,
|
||||||
|
marginTop: 40,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
headerTitle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
reportContainer: {
|
||||||
|
marginBottom: 20,
|
||||||
|
padding: 12,
|
||||||
|
borderRadius: 15,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
borderColor: "#000",
|
||||||
|
},
|
||||||
|
reportHeader: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
paddingBottom: 10,
|
||||||
|
},
|
||||||
|
profileContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
profileImage: {
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
borderRadius: 20,
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
reporterName: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
statusButton: {
|
||||||
|
backgroundColor: "#DDD",
|
||||||
|
borderRadius: 8,
|
||||||
|
paddingVertical: 5,
|
||||||
|
paddingHorizontal: 5,
|
||||||
|
marginVertical: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "32%",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
reportStatus: {
|
||||||
|
color: "#000",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
reportDescription: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
reportNote: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#000",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
imageContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
reportImage: {
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginRight: 5,
|
||||||
|
marginLeft: 5,
|
||||||
|
},
|
||||||
|
contributeButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "50%",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginLeft: 90,
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
contributeText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
coinText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default BerandaPengaduanAdmin;
|
||||||
|
|
@ -0,0 +1,352 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
Image,
|
||||||
|
ScrollView,
|
||||||
|
StyleSheet,
|
||||||
|
Alert,
|
||||||
|
} from "react-native";
|
||||||
|
import * as ImagePicker from "expo-image-picker"; // import image picker
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
const DaftarBarang = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [items, setItems] = useState([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Botol Minum",
|
||||||
|
coin: 300,
|
||||||
|
image: require("../../assets/images/botol1.png"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Botol Minum Anak",
|
||||||
|
coin: 350,
|
||||||
|
image: require("../../assets/images/botol2.png"),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const [isEditing, setIsEditing] = useState(false);
|
||||||
|
const [formItem, setFormItem] = useState({
|
||||||
|
id: null,
|
||||||
|
name: "",
|
||||||
|
coin: "",
|
||||||
|
image: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const pickImage = async () => {
|
||||||
|
// Minta izin akses galeri
|
||||||
|
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
|
||||||
|
if (status !== "granted") {
|
||||||
|
Alert.alert(
|
||||||
|
"Izin Ditolak",
|
||||||
|
"Izin akses galeri dibutuhkan untuk memilih foto"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await ImagePicker.launchImageLibraryAsync({
|
||||||
|
mediaTypes: ImagePicker.MediaTypeOptions.Images,
|
||||||
|
quality: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.canceled) {
|
||||||
|
setFormItem({ ...formItem, image: { uri: result.assets[0].uri } });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEdit = (item) => {
|
||||||
|
setFormItem(item);
|
||||||
|
setIsEditing(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddItem = () => {
|
||||||
|
setFormItem({ id: null, name: "", coin: "", image: null });
|
||||||
|
setIsEditing(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (formItem.name === "" || formItem.coin === "") {
|
||||||
|
Alert.alert("Error", "Nama dan koin wajib diisi");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formItem.id) {
|
||||||
|
// Edit
|
||||||
|
setItems(items.map((i) => (i.id === formItem.id ? { ...formItem } : i)));
|
||||||
|
} else {
|
||||||
|
// Tambah
|
||||||
|
setItems([
|
||||||
|
...items,
|
||||||
|
{
|
||||||
|
...formItem,
|
||||||
|
id: Date.now(),
|
||||||
|
image: formItem.image
|
||||||
|
? formItem.image
|
||||||
|
: require("../../assets/images/botol1.png"),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
setIsEditing(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDelete = (id) => {
|
||||||
|
Alert.alert("Konfirmasi", "Apakah Anda yakin ingin menghapus item ini?", [
|
||||||
|
{
|
||||||
|
text: "Batal",
|
||||||
|
style: "cancel",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Hapus",
|
||||||
|
style: "destructive",
|
||||||
|
onPress: () => {
|
||||||
|
setItems(items.filter((item) => item.id !== id));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.headerRow}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.navigate("TukarKoin")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>DAFTAR BARANG</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity style={styles.addButton} onPress={handleAddItem}>
|
||||||
|
<Text style={styles.addButtonText}>+ Tambah Item</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{isEditing && (
|
||||||
|
<View style={styles.form}>
|
||||||
|
<TextInput
|
||||||
|
placeholder="Nama Barang"
|
||||||
|
value={formItem.name}
|
||||||
|
onChangeText={(text) => setFormItem({ ...formItem, name: text })}
|
||||||
|
style={styles.input}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
placeholder="Jumlah Koin"
|
||||||
|
keyboardType="numeric"
|
||||||
|
value={formItem.coin.toString()}
|
||||||
|
onChangeText={(text) => setFormItem({ ...formItem, coin: text })}
|
||||||
|
style={styles.input}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Tombol pilih foto */}
|
||||||
|
<TouchableOpacity style={styles.imagePickerBtn} onPress={pickImage}>
|
||||||
|
<Text style={styles.imagePickerText}>
|
||||||
|
{formItem.image ? "Ganti Foto" : "Pilih Foto"}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* Preview foto yang dipilih */}
|
||||||
|
{formItem.image && (
|
||||||
|
<Image source={formItem.image} style={styles.previewImage} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.submitBtn} onPress={handleSubmit}>
|
||||||
|
<Text style={styles.submitText}>
|
||||||
|
{formItem.id ? "Simpan Perubahan" : "Tambah"}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<ScrollView showsVerticalScrollIndicator={false}>
|
||||||
|
<View style={styles.itemGrid}>
|
||||||
|
{items.map((item) => (
|
||||||
|
<View key={item.id} style={styles.itemCard}>
|
||||||
|
<Image source={item.image} style={styles.itemImage} />
|
||||||
|
<Text style={styles.itemName}>{item.name}</Text>
|
||||||
|
<View style={styles.coinBoxItem}>
|
||||||
|
<Text style={styles.itemCoin}>{item.coin} Koin</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.actionRow}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.editBtn}
|
||||||
|
onPress={() => handleEdit(item)}
|
||||||
|
>
|
||||||
|
<Text style={styles.actionText}>Edit</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.deleteBtn}
|
||||||
|
onPress={() => handleDelete(item.id)}
|
||||||
|
>
|
||||||
|
<Text style={styles.actionText}>Hapus</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: { flex: 1, padding: 20, backgroundColor: "#fff" },
|
||||||
|
backButton: { marginBottom: 10 },
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
textAlign: "left",
|
||||||
|
marginBottom: 12,
|
||||||
|
marginLeft: 20,
|
||||||
|
marginRight: 50,
|
||||||
|
},
|
||||||
|
headerRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 16,
|
||||||
|
marginTop: 30,
|
||||||
|
},
|
||||||
|
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
|
||||||
|
// title: {
|
||||||
|
// fontSize: 26,
|
||||||
|
// fontWeight: "bold",
|
||||||
|
// color: "#000",
|
||||||
|
// marginBottom: 20,
|
||||||
|
// textAlign: "center",
|
||||||
|
// marginTop: 30,
|
||||||
|
// },
|
||||||
|
addButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 12,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 10,
|
||||||
|
alignSelf: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
addButtonText: { color: "white", fontWeight: "bold", fontSize: 16 },
|
||||||
|
form: {
|
||||||
|
backgroundColor: "#f9f9f9",
|
||||||
|
padding: 20,
|
||||||
|
borderRadius: 12,
|
||||||
|
marginBottom: 25,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#d1d1d1",
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 14,
|
||||||
|
borderRadius: 8,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ccc",
|
||||||
|
marginBottom: 15,
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
imagePickerBtn: {
|
||||||
|
backgroundColor: "#DDD",
|
||||||
|
paddingVertical: 12,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 10,
|
||||||
|
padding: 10,
|
||||||
|
width: "40%",
|
||||||
|
},
|
||||||
|
imagePickerText: {
|
||||||
|
color: "BLACK",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
previewImage: {
|
||||||
|
width: 100,
|
||||||
|
height: 140,
|
||||||
|
alignSelf: "center",
|
||||||
|
marginBottom: 15,
|
||||||
|
resizeMode: "contain",
|
||||||
|
borderRadius: 10,
|
||||||
|
},
|
||||||
|
submitBtn: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 14,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
submitText: { color: "white", fontWeight: "bold", fontSize: 16 },
|
||||||
|
itemGrid: {
|
||||||
|
flexDirection: "row",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
},
|
||||||
|
itemCard: {
|
||||||
|
width: "48%",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderRadius: 12,
|
||||||
|
padding: 15,
|
||||||
|
marginBottom: 20,
|
||||||
|
elevation: 4,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 6,
|
||||||
|
shadowOffset: { width: 0, height: 3 },
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
itemImage: {
|
||||||
|
width: 80,
|
||||||
|
height: 110,
|
||||||
|
resizeMode: "contain",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
itemName: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#2D572C",
|
||||||
|
marginBottom: 8,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
coinBoxItem: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 6,
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
itemCoin: {
|
||||||
|
color: "white",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
actionRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
width: "100%",
|
||||||
|
},
|
||||||
|
editBtn: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#4CAF50",
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
marginRight: 8,
|
||||||
|
},
|
||||||
|
deleteBtn: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#E53935",
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
actionText: { color: "white", fontWeight: "bold", fontSize: 14 },
|
||||||
|
});
|
||||||
|
|
||||||
|
export default DaftarBarang;
|
||||||
|
|
@ -0,0 +1,413 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
ScrollView,
|
||||||
|
Linking,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const tpsData = [
|
||||||
|
{
|
||||||
|
nama: "TPS SENGKUT",
|
||||||
|
kecamatan: "BERBEK",
|
||||||
|
alamat: "Desa Werungotok, Kec. Nganjuk",
|
||||||
|
jenis: "Depo Kecil",
|
||||||
|
luas: "1,5 x 1,5",
|
||||||
|
volume: "3.375 m3",
|
||||||
|
latitude: -7.6141,
|
||||||
|
longitude: 111.5177,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nama: "TPS NGRONGGOT",
|
||||||
|
kecamatan: "BERBEK",
|
||||||
|
alamat: "Desa Werungotok, Kec. Nganjuk",
|
||||||
|
jenis: "Depo Kecil",
|
||||||
|
luas: "1,5 x 1,5",
|
||||||
|
volume: "3.375 m3",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
nama: "TPS 3R MASTRIP",
|
||||||
|
kecamatan: "NGANJUK",
|
||||||
|
alamat: "Desa Mangundikaran, Kec. Nganjuk",
|
||||||
|
jenis: "TPS 3R",
|
||||||
|
luas: "2 x 2",
|
||||||
|
volume: "5 m3",
|
||||||
|
latitude: -6.6,
|
||||||
|
longitude: 106.8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nama: "TPS 3R KARTOHARJO",
|
||||||
|
kecamatan: "NGANJUK",
|
||||||
|
alamat: "Desa Kartoharjo, Kec. Nganjuk",
|
||||||
|
jenis: "TPS 3R",
|
||||||
|
luas: "2 x 2",
|
||||||
|
volume: "5 m3",
|
||||||
|
latitude: -7.25,
|
||||||
|
longitude: 112.75,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nama: "TPS 3R KSM GANUNGKIDUL",
|
||||||
|
kecamatan: "NGANJUK",
|
||||||
|
alamat: "Desa Ganungkidul, Kec. Nganjuk",
|
||||||
|
jenis: "TPS 3R KSM",
|
||||||
|
luas: "3 x 3",
|
||||||
|
volume: "7.5 m3",
|
||||||
|
latitude: -6.175,
|
||||||
|
longitude: 106.8272,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nama: "TPS 3R KSM PAYAMAN",
|
||||||
|
kecamatan: "NGANJUK",
|
||||||
|
alamat: "Desa Payaman, Kec. Nganjuk",
|
||||||
|
jenis: "TPS 3R KSM",
|
||||||
|
luas: "3 x 3",
|
||||||
|
volume: "7.5 m3",
|
||||||
|
latitude: -6.175,
|
||||||
|
longitude: 106.8272,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nama: "TPS 3R KSM JATIREJO",
|
||||||
|
kecamatan: "NGANJUK",
|
||||||
|
alamat: "Desa Jatirejo, Kec. Nganjuk",
|
||||||
|
jenis: "TPS 3R KSM",
|
||||||
|
luas: "3 x 3",
|
||||||
|
volume: "7.5 m3",
|
||||||
|
latitude: -6.175,
|
||||||
|
longitude: 106.8272,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const DaftarTPS = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [search, setSearch] = useState("");
|
||||||
|
const [activeCategory, setActiveCategory] = useState("TPS");
|
||||||
|
|
||||||
|
const filteredTPS = tpsData.filter(
|
||||||
|
(tps) =>
|
||||||
|
tps.nama.toLowerCase().includes(search.toLowerCase()) &&
|
||||||
|
(activeCategory === "TPS" || tps.jenis === activeCategory)
|
||||||
|
);
|
||||||
|
|
||||||
|
const openInMaps = (latitude, longitude) => {
|
||||||
|
const url = `https://www.google.com/maps/search/?api=1&query=${latitude},${longitude}`;
|
||||||
|
Linking.openURL(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEdit = (tps) => {
|
||||||
|
console.log("Edit TPS: ", tps); // Implement the edit functionality here
|
||||||
|
// You can navigate to another screen for editing if needed
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDelete = (id) => {
|
||||||
|
console.log("Delete TPS with ID: ", id); // Implement the delete functionality here
|
||||||
|
// Handle the deletion logic, e.g., updating state or making an API call
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.navigate("Home")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>DAFTAR TPS DI NGANJUK</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Button for categories */}
|
||||||
|
<View style={styles.categoryButtonsContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.categoryButton,
|
||||||
|
activeCategory === "TPS" && styles.activeButton,
|
||||||
|
]}
|
||||||
|
onPress={() => setActiveCategory("TPS")}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.buttonTexts,
|
||||||
|
activeCategory === "TPS" && styles.activeButtonText,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
TPS
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.categoryButton,
|
||||||
|
activeCategory === "TPS 3R" && styles.activeButton,
|
||||||
|
]}
|
||||||
|
onPress={() => setActiveCategory("TPS 3R")}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.buttonTexts,
|
||||||
|
activeCategory === "TPS 3R" && styles.activeButtonText,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
TPS 3R
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.categoryButton,
|
||||||
|
activeCategory === "TPS 3R KSM" && styles.activeButton,
|
||||||
|
]}
|
||||||
|
onPress={() => setActiveCategory("TPS 3R KSM")}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.buttonTexts,
|
||||||
|
activeCategory === "TPS 3R KSM" && styles.activeButtonText,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
TPS 3R KSM
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.searchContainer}>
|
||||||
|
<TextInput
|
||||||
|
placeholder="Cari Lokasi"
|
||||||
|
style={styles.input}
|
||||||
|
value={search}
|
||||||
|
onChangeText={setSearch}
|
||||||
|
/>
|
||||||
|
<TouchableOpacity style={styles.searchButton}>
|
||||||
|
<Ionicons name="search" size={20} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<ScrollView>
|
||||||
|
{filteredTPS.map((tps, index) => (
|
||||||
|
<View key={index} style={styles.card}>
|
||||||
|
<View style={styles.cardHeader}>
|
||||||
|
<View style={{ flex: 1 }}>
|
||||||
|
<Text style={styles.label}>LUAS TPS</Text>
|
||||||
|
<Text style={styles.value}>{tps.luas}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={{ flex: 2 }}>
|
||||||
|
<Text style={styles.tpsName}>{tps.nama}</Text>
|
||||||
|
<Text style={styles.kecamatan}>KECAMATAN {tps.kecamatan}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={{ flex: 1, alignItems: "flex-end" }}>
|
||||||
|
<Text style={styles.labelSmall}>VOLUME MAKSIMAL</Text>
|
||||||
|
<Text style={styles.volume}>{tps.volume}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.cardContent}>
|
||||||
|
<View style={styles.infoRow}>
|
||||||
|
<Ionicons name="location-outline" size={16} />
|
||||||
|
<Text style={styles.infoText}>Alamat</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.lokasiButton}
|
||||||
|
onPress={() => openInMaps(tps.latitude, tps.longitude)}
|
||||||
|
>
|
||||||
|
<Text style={{ fontWeight: "bold" }}>LOKASI</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.subInfo}>{tps.alamat}</Text>
|
||||||
|
|
||||||
|
<View style={[styles.infoRow, { marginTop: 8 }]}>
|
||||||
|
<Ionicons name="trash-outline" size={16} />
|
||||||
|
<Text style={styles.infoText}>Jenis</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.subInfo}>{tps.jenis}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Edit and Delete Buttons */}
|
||||||
|
<View style={styles.actionButtons}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.editButton}
|
||||||
|
onPress={() => handleEdit(tps)} // Pass the tps object here
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>Edit</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.deleteButton}
|
||||||
|
onPress={() => handleDelete(tps.id)} // You can pass the id if available
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>Hapus</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
{/* Tambah TPS Button */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.tambahButton}
|
||||||
|
onPress={() => navigation.navigate("TambahTPS")}
|
||||||
|
>
|
||||||
|
<Text style={styles.tambahButtonText}>TAMBAH TPS</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 16,
|
||||||
|
marginBottom: 0,
|
||||||
|
marginTop: -40,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginBottom: 10,
|
||||||
|
marginTop: 70,
|
||||||
|
},
|
||||||
|
backButton: { marginBottom: 10 },
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
textAlign: "left",
|
||||||
|
marginBottom: 12,
|
||||||
|
marginLeft: 20,
|
||||||
|
marginRight: 230,
|
||||||
|
},
|
||||||
|
categoryButtonsContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
categoryButton: {
|
||||||
|
flex: 1,
|
||||||
|
paddingVertical: 10,
|
||||||
|
marginRight: 8,
|
||||||
|
borderRadius: 15,
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#2D572C",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
activeButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
color: "#2D572C",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
actionButtons: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
padding: 10,
|
||||||
|
marginTop: 12,
|
||||||
|
},
|
||||||
|
editButton: {
|
||||||
|
backgroundColor: "#4CAF50",
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
deleteButton: {
|
||||||
|
backgroundColor: "#F44336",
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
buttonTexts: {
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
tambahButton: {
|
||||||
|
backgroundColor: "#f0F0F0",
|
||||||
|
paddingVertical: 12,
|
||||||
|
borderRadius: 25,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginTop: 20,
|
||||||
|
marginHorizontal: 50,
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
tambahButtonText: {
|
||||||
|
color: "#000",
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
activeButtonText: {
|
||||||
|
color: "white", // Change text color to white when the button is active
|
||||||
|
},
|
||||||
|
searchContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
flex: 1,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#999",
|
||||||
|
borderRadius: 10,
|
||||||
|
padding: 10,
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
searchButton: {
|
||||||
|
backgroundColor: "#E0E0E0",
|
||||||
|
padding: 10,
|
||||||
|
marginLeft: 8,
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
borderRadius: 12,
|
||||||
|
marginBottom: 20,
|
||||||
|
borderColor: "#000",
|
||||||
|
borderWidth: 1,
|
||||||
|
overflow: "hidden",
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 5,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
elevation: 3,
|
||||||
|
},
|
||||||
|
cardHeader: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
padding: 10,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
label: { color: "white", fontSize: 11 },
|
||||||
|
value: { color: "white", fontWeight: "bold" },
|
||||||
|
tpsName: {
|
||||||
|
color: "white",
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginLeft: 40,
|
||||||
|
},
|
||||||
|
kecamatan: { color: "white", fontSize: 12, marginLeft: 40 },
|
||||||
|
labelSmall: { fontSize: 10, color: "white", textAlign: "right" },
|
||||||
|
volume: { fontSize: 14, color: "white", fontWeight: "bold" },
|
||||||
|
cardContent: { padding: 12 },
|
||||||
|
infoRow: { flexDirection: "row", alignItems: "center", gap: 4 },
|
||||||
|
infoText: { fontWeight: "bold", marginLeft: 8 },
|
||||||
|
subInfo: { marginLeft: 30, fontSize: 13 },
|
||||||
|
lokasiButton: {
|
||||||
|
backgroundColor: "#F0F0F0",
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 14,
|
||||||
|
borderRadius: 8,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
elevation: 2,
|
||||||
|
marginLeft: 220,
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default DaftarTPS;
|
||||||
|
|
@ -0,0 +1,186 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, Text, StyleSheet, TouchableOpacity, Image } from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const DetailDalamProses = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.navigate("PengaduanSampahScreenAdmin")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.headerTitle}>DALAM PROSES</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* First Report */}
|
||||||
|
|
||||||
|
{/* Second Report */}
|
||||||
|
<View style={styles.reportContainer}>
|
||||||
|
<View style={styles.reportHeader}>
|
||||||
|
<View style={styles.profileContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://www.w3schools.com/howto/img_avatar2.png", // Replace with actual profile picture URI
|
||||||
|
}}
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.reporterName}>Jihan Pangesti</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.time}>10/04/2025 13.00 WIB</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity style={styles.statusButton}>
|
||||||
|
<Text style={styles.reportStatus}>Dalam Proses</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.reportDescription}>
|
||||||
|
Sampah berserakan di Pasar Lama - JI. Sukarno, Nganjuk
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.reportNote}>
|
||||||
|
Catatan: Mohon segera ditindaklanjuti karena sangat mengganggu
|
||||||
|
masyarakat sekitar.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Images */}
|
||||||
|
<View style={styles.imageContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.toiimg.com/thumb/msid-97714168,imgsize-1547670,width-400,resizemode-4/97714168.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.toiimg.com/thumb/msid-87155572,imgsize-1511223,width-400,resizemode-4/87155572.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Button to contribute */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.contributeButton}
|
||||||
|
onPress={() => navigation.navigate("KontribusiAdmin")}
|
||||||
|
>
|
||||||
|
<Text style={styles.contributeText}>Kontribusi Sekarang</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 16,
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
marginTop: 40,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
headerTitle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
reportContainer: {
|
||||||
|
marginBottom: 20,
|
||||||
|
padding: 12,
|
||||||
|
borderRadius: 15,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
borderColor: "#000",
|
||||||
|
},
|
||||||
|
reportHeader: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
paddingBottom: 10,
|
||||||
|
},
|
||||||
|
profileContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
profileImage: {
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
borderRadius: 20,
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
reporterName: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
statusButton: {
|
||||||
|
backgroundColor: "#DDD",
|
||||||
|
borderRadius: 8,
|
||||||
|
paddingVertical: 5,
|
||||||
|
paddingHorizontal: 5,
|
||||||
|
marginVertical: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "32%",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
reportStatus: {
|
||||||
|
color: "#000",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
reportDescription: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
reportNote: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#000",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
imageContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
reportImage: {
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginRight: 5,
|
||||||
|
marginLeft: 5,
|
||||||
|
},
|
||||||
|
contributeButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "50%",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginLeft: 90,
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
contributeText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
coinText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default DetailDalamProses;
|
||||||
|
|
@ -0,0 +1,188 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, Text, StyleSheet, TouchableOpacity, Image } from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const DetailDitolak = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.navigate("PengaduanSampahScreenAdmin")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.headerTitle}>DETAIL DITOLAK</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Report Section */}
|
||||||
|
<View style={styles.reportContainer}>
|
||||||
|
<View style={styles.reportHeader}>
|
||||||
|
<View style={styles.profileContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://www.w3schools.com/howto/img_avatar2.png", // Ganti dengan foto profil asli
|
||||||
|
}}
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.reporterName}>Jihan Pangesti</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.time}>10/04/2025 13:00 WIB</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.statusButton}>
|
||||||
|
<Text style={styles.reportStatus}>Ditolak</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<Text style={styles.reportDescription}>
|
||||||
|
Sampah berserakan di Pasar Lama - JI. Sukarno, Nganjuk
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text style={styles.reportNote}>
|
||||||
|
Catatan: Mohon segera ditindaklanjuti karena sangat mengganggu
|
||||||
|
masyarakat sekitar.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Alasan Ditolak */}
|
||||||
|
<View style={styles.alasanContainer}>
|
||||||
|
<Text style={styles.alasanTitle}>Alasan Ditolak:</Text>
|
||||||
|
<Text style={styles.alasanText}>
|
||||||
|
Pengaduan ini ditolak karena lokasi yang dilaporkan tidak sesuai
|
||||||
|
pada foto backButtonContainer yang dikirim.
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Images */}
|
||||||
|
<View style={styles.imageContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.toiimg.com/thumb/msid-97714168,imgsize-1547670,width-400,resizemode-4/97714168.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.toiimg.com/thumb/msid-87155572,imgsize-1511223,width-400,resizemode-4/87155572.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 16,
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
marginTop: 40,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
headerTitle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
reportContainer: {
|
||||||
|
marginBottom: 20,
|
||||||
|
padding: 12,
|
||||||
|
borderRadius: 15,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
borderColor: "#000",
|
||||||
|
},
|
||||||
|
reportHeader: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
paddingBottom: 10,
|
||||||
|
},
|
||||||
|
profileContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
profileImage: {
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
borderRadius: 20,
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
reporterName: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
statusButton: {
|
||||||
|
backgroundColor: "#ddd",
|
||||||
|
borderRadius: 8,
|
||||||
|
paddingVertical: 5,
|
||||||
|
paddingHorizontal: 5,
|
||||||
|
marginVertical: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "32%",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
reportStatus: {
|
||||||
|
color: "#000",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
reportDescription: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
reportNote: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#000",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
alasanContainer: {
|
||||||
|
marginTop: 20,
|
||||||
|
padding: 12,
|
||||||
|
borderRadius: 8,
|
||||||
|
backgroundColor: "#FFF3F3",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#F5B7B1",
|
||||||
|
},
|
||||||
|
alasanTitle: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#D9534F",
|
||||||
|
},
|
||||||
|
alasanText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#721c24",
|
||||||
|
marginTop: 8,
|
||||||
|
},
|
||||||
|
imageContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
marginBottom: 12,
|
||||||
|
marginTop: 12,
|
||||||
|
},
|
||||||
|
reportImage: {
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginRight: 5,
|
||||||
|
marginLeft: 5,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default DetailDitolak;
|
||||||
|
|
@ -0,0 +1,319 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
Image,
|
||||||
|
StyleSheet,
|
||||||
|
TouchableOpacity,
|
||||||
|
Linking,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons"; // Import Ionicons untuk ikon panah
|
||||||
|
|
||||||
|
export default function DetailPengirimanAdmin({ route, navigation }) {
|
||||||
|
const { item } = route.params; // Mendapatkan data item dari navigation params
|
||||||
|
const [status, setStatus] = useState(item.status); // Menentukan status awal sesuai item
|
||||||
|
|
||||||
|
// Fungsi untuk menangani perubahan status
|
||||||
|
const handleUpdateStatus = (newStatus) => {
|
||||||
|
setStatus(newStatus); // Mengubah status pengiriman
|
||||||
|
};
|
||||||
|
|
||||||
|
// Timeline status pengiriman
|
||||||
|
const statusTimeline = {
|
||||||
|
diproses: {
|
||||||
|
title: "Diproses",
|
||||||
|
time: "23 Januari 2025, 15:12 WIB",
|
||||||
|
},
|
||||||
|
dikirim: {
|
||||||
|
title: "Dikirim",
|
||||||
|
time: "24 Januari 2025, 10:00 WIB",
|
||||||
|
},
|
||||||
|
diterima: {
|
||||||
|
title: "Diterima",
|
||||||
|
time: "25 Januari 2025, 13:00 WIB",
|
||||||
|
},
|
||||||
|
selesai: {
|
||||||
|
title: "Selesai",
|
||||||
|
time: "26 Januari 2025, 17:00 WIB",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fungsi untuk menghubungi penerima via WhatsApp
|
||||||
|
const handleContactRecipient = () => {
|
||||||
|
const phoneNumber = "628123456789"; // Ganti dengan nomor penerima yang terdaftar
|
||||||
|
const message = "Halo, ada update tentang pengiriman barang Anda."; // Pesan default yang ingin dikirim
|
||||||
|
|
||||||
|
const url = `whatsapp://send?phone=${phoneNumber}&text=${encodeURIComponent(
|
||||||
|
message
|
||||||
|
)}`;
|
||||||
|
|
||||||
|
// Mengecek apakah WhatsApp dapat dibuka
|
||||||
|
Linking.openURL(url).catch((err) => {
|
||||||
|
console.error("Error opening WhatsApp:", err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const currentItem = {
|
||||||
|
...item,
|
||||||
|
statusDetails:
|
||||||
|
status === "diproses"
|
||||||
|
? "Barang sedang diproses oleh tim Dinas Lingkungan Hidup."
|
||||||
|
: status === "dikirim"
|
||||||
|
? "Barang telah dikirimkan kepada penerima."
|
||||||
|
: status === "diterima"
|
||||||
|
? "Barang telah diterima oleh penerima."
|
||||||
|
: "Pengiriman selesai.",
|
||||||
|
estimatedDate:
|
||||||
|
status === "diterima"
|
||||||
|
? "Pengiriman selesai, tidak ada tanggal estimasi lebih lanjut."
|
||||||
|
: "Diperkirakan tiba pada 30 Januari 2025.",
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#333" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>DETAIL PENGIRIMAN BARANG</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Hubungi Penerima Button */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.contactButton}
|
||||||
|
onPress={handleContactRecipient}
|
||||||
|
>
|
||||||
|
<Text style={styles.contactText}>Hubungi Penerima</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* Image */}
|
||||||
|
<Image source={currentItem.imageUri} style={styles.image} />
|
||||||
|
|
||||||
|
{/* Product Details */}
|
||||||
|
<View style={styles.productInfo}>
|
||||||
|
<Text style={styles.productName}>{currentItem.name}</Text>
|
||||||
|
<Text style={styles.productPoints}>{currentItem.points}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Foto Profil Penerima */}
|
||||||
|
<View style={styles.recipientInfo}></View>
|
||||||
|
|
||||||
|
{/* Informasi Profil Penerima */}
|
||||||
|
<View style={styles.profileInfo}>
|
||||||
|
<Text style={styles.profileText}>
|
||||||
|
Alamat: Jl. Sudirman No.5, Bandung
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.profileText}>Email: siti@example.com</Text>
|
||||||
|
<Text style={styles.profileText}>No. Telepon: 082123456789</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Status Progress */}
|
||||||
|
<View style={styles.statusContainer}>
|
||||||
|
<Text style={styles.statusTitle}>Proses Pengiriman</Text>
|
||||||
|
<View style={styles.statusTimeline}>
|
||||||
|
{Object.keys(statusTimeline).map((step, index) => (
|
||||||
|
<View
|
||||||
|
key={index}
|
||||||
|
style={status === step ? styles.activeStep : styles.step}
|
||||||
|
>
|
||||||
|
<Text style={styles.stepText}>{statusTimeline[step].title}</Text>
|
||||||
|
<Text style={styles.time}>{statusTimeline[step].time}</Text>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Status Detail */}
|
||||||
|
<View style={styles.statusDetail}>
|
||||||
|
<Text style={styles.statusDetails}>{currentItem.statusDetails}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Estimated Delivery */}
|
||||||
|
<View style={styles.estimatedDelivery}>
|
||||||
|
<Text style={styles.estimatedText}>{currentItem.estimatedDate}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Shipping Information */}
|
||||||
|
<View style={styles.shippingInfo}>
|
||||||
|
<Text style={styles.shippingDetails}>
|
||||||
|
{currentItem.shippingAddress}
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.shippingTitle}>Jasa Pengiriman</Text>
|
||||||
|
<Text style={styles.shippingDetails}>JNE</Text>
|
||||||
|
<Text style={styles.shippingTitle}>No Resi</Text>
|
||||||
|
<Text style={styles.shippingDetails}>5679032190775</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Buttons to update the status */}
|
||||||
|
{status === "diproses" && (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() => handleUpdateStatus("dikirim")}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>UPDATE STATUS: DIKIRIM</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{status === "diterima" && (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() => handleUpdateStatus("selesai")}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>UPDATE STATUS: SELESAI</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 16,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
marginTop: 40,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 30,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
contactButton: {
|
||||||
|
backgroundColor: "#4CAF50",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginBottom: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
borderRadius: 20,
|
||||||
|
marginLeft: 120,
|
||||||
|
marginRight: 120,
|
||||||
|
},
|
||||||
|
contactText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
alignSelf: "center",
|
||||||
|
marginBottom: 16,
|
||||||
|
},
|
||||||
|
productInfo: {
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 16,
|
||||||
|
},
|
||||||
|
productName: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
},
|
||||||
|
productPoints: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#777",
|
||||||
|
},
|
||||||
|
recipientInfo: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 16,
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
recipientImage: {
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
borderRadius: 25,
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
recipientName: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
profileInfo: {
|
||||||
|
marginBottom: 10,
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
},
|
||||||
|
profileText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#777",
|
||||||
|
alignItems: "center",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
statusContainer: {
|
||||||
|
marginBottom: 16,
|
||||||
|
},
|
||||||
|
statusTitle: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
statusTimeline: {
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
},
|
||||||
|
step: {
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
activeStep: {
|
||||||
|
marginBottom: 12,
|
||||||
|
borderLeftWidth: 4,
|
||||||
|
borderColor: "#4CAF50",
|
||||||
|
paddingLeft: 12,
|
||||||
|
},
|
||||||
|
stepText: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#777",
|
||||||
|
},
|
||||||
|
statusDetail: {
|
||||||
|
marginBottom: 16,
|
||||||
|
},
|
||||||
|
statusDetails: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#777",
|
||||||
|
},
|
||||||
|
estimatedDelivery: {
|
||||||
|
marginBottom: 16,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
estimatedText: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontStyle: "italic",
|
||||||
|
},
|
||||||
|
shippingInfo: {
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
shippingTitle: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
shippingDetails: {
|
||||||
|
fontSize: 14,
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
marginTop: 20,
|
||||||
|
backgroundColor: "#2f4f2f",
|
||||||
|
padding: 15,
|
||||||
|
borderRadius: 10,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,317 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
TouchableOpacity,
|
||||||
|
Image,
|
||||||
|
TextInput,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native"; // Import useNavigation untuk navigasi
|
||||||
|
|
||||||
|
const DetailVerifikasi = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
// State untuk mengatur status tombol
|
||||||
|
const [isVerified, setIsVerified] = useState(false); // Menyimpan status verifikasi
|
||||||
|
const [showTolakForm, setShowTolakForm] = useState(false); // Menyimpan status tampilkan form alasan tolak
|
||||||
|
const [alasanTolak, setAlasanTolak] = useState(""); // Menyimpan alasan tolak pengaduan
|
||||||
|
const [isTolakClicked, setIsTolakClicked] = useState(false); // Status tombol tolak pengaduan sudah diklik
|
||||||
|
|
||||||
|
// Fungsi untuk menangani klik tombol verifikasi
|
||||||
|
const handleVerifikasi = () => {
|
||||||
|
setIsVerified(true); // Mengubah status menjadi diverifikasi
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fungsi untuk mengirim alasan tolak pengaduan
|
||||||
|
const handleKirimTolak = () => {
|
||||||
|
setIsTolakClicked(true); // Mengubah status tombol tolak menjadi sudah diklik
|
||||||
|
setShowTolakForm(false); // Menutup form setelah alasan dikirim
|
||||||
|
|
||||||
|
// Navigasi ke halaman DitolakScreen dan mengirim alasan penolakan
|
||||||
|
navigation.navigate("DitolakScreen");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.navigate("PengaduanSampahScreenAdmin")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.headerTitle}>VERIFIKASI</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* First Report */}
|
||||||
|
|
||||||
|
{/* Second Report */}
|
||||||
|
<View style={styles.reportContainer}>
|
||||||
|
<View style={styles.reportHeader}>
|
||||||
|
<View style={styles.profileContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://www.w3schools.com/howto/img_avatar2.png", // Replace with actual profile picture URI
|
||||||
|
}}
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.reporterName}>Jihan Pangesti</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.time}>10/04/2025 13.00 WIB</Text>
|
||||||
|
</View>
|
||||||
|
{/* Status */}
|
||||||
|
<TouchableOpacity style={styles.statusButton}>
|
||||||
|
<Text style={styles.reportStatus}>Dalam Proses</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.reportDescription}>
|
||||||
|
Sampah berserakan di Pasar Lama - JI. Sukarno, Nganjuk
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.reportNote}>
|
||||||
|
Catatan: Mohon segera ditindaklanjuti karena sangat mengganggu
|
||||||
|
masyarakat sekitar.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Images */}
|
||||||
|
<View style={styles.imageContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.toiimg.com/thumb/msid-97714168,imgsize-1547670,width-400,resizemode-4/97714168.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.toiimg.com/thumb/msid-87155572,imgsize-1511223,width-400,resizemode-4/87155572.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Button to contribute (Verifikasi) */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={isVerified ? styles.verifiedButton : styles.contributeButton}
|
||||||
|
onPress={handleVerifikasi}
|
||||||
|
disabled={isVerified} // Menonaktifkan tombol jika sudah diverifikasi
|
||||||
|
>
|
||||||
|
<Text style={styles.contributeTextSudah}>
|
||||||
|
{isVerified ? "Sudah Diverifikasi" : "Verifikasi"}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* Button to reject the report, will hide if verified */}
|
||||||
|
{!isVerified && (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={
|
||||||
|
isTolakClicked
|
||||||
|
? styles.tolakButtonDisabled
|
||||||
|
: styles.contributeButtonTolak
|
||||||
|
}
|
||||||
|
onPress={() => setShowTolakForm(true)}
|
||||||
|
disabled={isTolakClicked} // Menonaktifkan tombol jika sudah diklik
|
||||||
|
>
|
||||||
|
<Text style={styles.contributeText}>
|
||||||
|
{isTolakClicked ? "Tolak Pengaduan" : "Tolak Pengaduan"}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Form Alasan Tolak Pengaduan */}
|
||||||
|
{showTolakForm && (
|
||||||
|
<View style={styles.formContainer}>
|
||||||
|
<Text style={styles.formTitle}>Alasan Tolak Pengaduan</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.textInput}
|
||||||
|
multiline
|
||||||
|
numberOfLines={4}
|
||||||
|
placeholder="Tulis alasan penolakan..."
|
||||||
|
value={alasanTolak}
|
||||||
|
onChangeText={setAlasanTolak}
|
||||||
|
/>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.submitButton}
|
||||||
|
onPress={handleKirimTolak}
|
||||||
|
>
|
||||||
|
<Text style={styles.submitText}>Kirim</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 16,
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
marginTop: 40,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
headerTitle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
reportContainer: {
|
||||||
|
marginBottom: 20,
|
||||||
|
padding: 12,
|
||||||
|
borderRadius: 15,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
borderColor: "#000",
|
||||||
|
},
|
||||||
|
reportHeader: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
paddingBottom: 10,
|
||||||
|
},
|
||||||
|
profileContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
profileImage: {
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
borderRadius: 20,
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
reporterName: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
statusButton: {
|
||||||
|
backgroundColor: "#DDD",
|
||||||
|
borderRadius: 8,
|
||||||
|
paddingVertical: 5,
|
||||||
|
paddingHorizontal: 5,
|
||||||
|
marginVertical: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "32%",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
reportStatus: {
|
||||||
|
color: "#000",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
reportDescription: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
reportNote: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#000",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
imageContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
reportImage: {
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginRight: 5,
|
||||||
|
marginLeft: 5,
|
||||||
|
},
|
||||||
|
contributeButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "50%",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginLeft: 90,
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
contributeButtonTolak: {
|
||||||
|
backgroundColor: "#8b0000",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "50%",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginLeft: 90,
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
tolakButtonDisabled: {
|
||||||
|
backgroundColor: "#A9A9A9", // Disabled gray
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "50%",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginLeft: 90,
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
verifiedButton: {
|
||||||
|
backgroundColor: "#777b7e",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "50%",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginLeft: 90,
|
||||||
|
marginTop: 20,
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
contributeTextSudah: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
contributeText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
formContainer: {
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
formTitle: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
textInput: {
|
||||||
|
height: 100,
|
||||||
|
borderColor: "#ddd",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 8,
|
||||||
|
padding: 10,
|
||||||
|
fontSize: 16,
|
||||||
|
textAlignVertical: "top",
|
||||||
|
},
|
||||||
|
submitButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginTop: 10,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
submitText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default DetailVerifikasi;
|
||||||
|
|
@ -0,0 +1,256 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
Image,
|
||||||
|
StyleSheet,
|
||||||
|
Alert,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import * as ImagePicker from "expo-image-picker"; // Mengimpor expo-image-picker
|
||||||
|
|
||||||
|
const EditProfilScreen = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
// State untuk data profil
|
||||||
|
const [userProfile, setUserProfile] = useState({
|
||||||
|
name: "Johan Okta Pangestu",
|
||||||
|
email: "okta@gmail.com",
|
||||||
|
phone: "08123456789",
|
||||||
|
address: "Jl. Raya No. 123, Nganjuk",
|
||||||
|
photo:
|
||||||
|
"https://i.ytimg.com/vi/b1XXKeq5ccQ/oar2.jpg?sqp=-oaymwEkCJUDENAFSFqQAgHyq4qpAxMIARUAAAAAJQAAyEI9AICiQ3gB&rs=AOn4CLBxYjkvH5GuWS8_SYMNsg5aIGYIRA", // Default photo
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fungsi untuk memilih foto
|
||||||
|
const handleChoosePhoto = async () => {
|
||||||
|
// Meminta izin untuk mengakses galeri
|
||||||
|
const permissionResult =
|
||||||
|
await ImagePicker.requestMediaLibraryPermissionsAsync();
|
||||||
|
|
||||||
|
if (permissionResult.granted === false) {
|
||||||
|
alert("Izin akses galeri ditolak!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Meluncurkan galeri untuk memilih gambar
|
||||||
|
const result = await ImagePicker.launchImageLibraryAsync({
|
||||||
|
mediaTypes: ImagePicker.MediaTypeOptions.Images, // Hanya gambar
|
||||||
|
quality: 0.5, // Kualitas gambar
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.canceled) {
|
||||||
|
// Update foto profil dengan gambar yang dipilih
|
||||||
|
setUserProfile({ ...userProfile, photo: result.uri });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fungsi untuk menghapus foto
|
||||||
|
const handleRemovePhoto = () => {
|
||||||
|
Alert.alert(
|
||||||
|
"Konfirmasi",
|
||||||
|
"Apakah Anda yakin ingin menghapus foto profil?",
|
||||||
|
[
|
||||||
|
{ text: "Batal", style: "cancel" },
|
||||||
|
{
|
||||||
|
text: "Hapus",
|
||||||
|
onPress: () => setUserProfile({ ...userProfile, photo: "" }), // Hapus foto profil
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fungsi untuk menyimpan perubahan profil
|
||||||
|
const handleSaveChanges = () => {
|
||||||
|
// Tampilkan alert sebagai konfirmasi
|
||||||
|
Alert.alert("Profil Diperbarui", "Perubahan profil berhasil disimpan.");
|
||||||
|
// Logika untuk menyimpan perubahan, misalnya API request, bisa ditambahkan di sini.
|
||||||
|
console.log(userProfile);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity onPress={() => navigation.goBack()}>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.headerText}>EDIT PROFIL</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Foto Profil */}
|
||||||
|
<View style={styles.profileImageContainer}>
|
||||||
|
{userProfile.photo ? (
|
||||||
|
<Image
|
||||||
|
source={{ uri: userProfile.photo }}
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<View style={styles.defaultImage}>
|
||||||
|
<Ionicons name="person-circle-outline" size={100} color="#2C6B2F" />
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.changePhotoButton}
|
||||||
|
onPress={handleChoosePhoto}
|
||||||
|
>
|
||||||
|
<Text style={styles.changePhotoButtonText}>Ubah Foto Profil</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{userProfile.photo && (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.removePhotoButton}
|
||||||
|
onPress={handleRemovePhoto}
|
||||||
|
>
|
||||||
|
<Text style={styles.removePhotoButtonText}>Hapus Foto Profil</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Form Edit Profil */}
|
||||||
|
<View style={styles.form}>
|
||||||
|
<Text style={styles.label}>Nama:</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
value={userProfile.name}
|
||||||
|
onChangeText={(text) =>
|
||||||
|
setUserProfile({ ...userProfile, name: text })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text style={styles.label}>Email:</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
value={userProfile.email}
|
||||||
|
onChangeText={(text) =>
|
||||||
|
setUserProfile({ ...userProfile, email: text })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text style={styles.label}>No. HP:</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
value={userProfile.phone}
|
||||||
|
onChangeText={(text) =>
|
||||||
|
setUserProfile({ ...userProfile, phone: text })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text style={styles.label}>Alamat:</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
value={userProfile.address}
|
||||||
|
onChangeText={(text) =>
|
||||||
|
setUserProfile({ ...userProfile, address: text })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Tombol Simpan */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.saveButton}
|
||||||
|
onPress={() => navigation.navigate("ProfilAdminScreen")}
|
||||||
|
>
|
||||||
|
<Text style={styles.saveButtonText}>Simpan</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
marginTop: 40,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
headerText: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
marginLeft: 10,
|
||||||
|
},
|
||||||
|
profileImageContainer: {
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
profileImage: {
|
||||||
|
width: 150,
|
||||||
|
height: 150,
|
||||||
|
borderRadius: 75,
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
defaultImage: {
|
||||||
|
width: 150,
|
||||||
|
height: 150,
|
||||||
|
borderRadius: 75,
|
||||||
|
backgroundColor: "#ddd",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
changePhotoButton: {
|
||||||
|
backgroundColor: "#ddd",
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 10,
|
||||||
|
width: "30%",
|
||||||
|
alignItems: "center",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
changePhotoButtonText: {
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
removePhotoButton: {
|
||||||
|
backgroundColor: "#E74C3C",
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderRadius: 8,
|
||||||
|
width: "30%",
|
||||||
|
alignItems: "center",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
removePhotoButtonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#555",
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ccc",
|
||||||
|
borderRadius: 5,
|
||||||
|
padding: 10,
|
||||||
|
marginBottom: 20,
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
saveButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 12,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
saveButtonText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default EditProfilScreen;
|
||||||
|
|
@ -0,0 +1,238 @@
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
Alert,
|
||||||
|
ScrollView,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation, useRoute } from "@react-navigation/native";
|
||||||
|
import MapView, { Marker } from "react-native-maps";
|
||||||
|
import { Picker } from "@react-native-picker/picker";
|
||||||
|
|
||||||
|
const EditTPS = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const route = useRoute();
|
||||||
|
const { tps } = route.params || {}; // Handle missing tps object gracefully
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (tps) {
|
||||||
|
console.log("Received tps data:", tps);
|
||||||
|
} else {
|
||||||
|
console.log("No tps data received");
|
||||||
|
}
|
||||||
|
}, [tps]);
|
||||||
|
|
||||||
|
const [nama, setNama] = useState(tps?.nama || "");
|
||||||
|
const [kecamatan, setKecamatan] = useState(tps?.kecamatan || "");
|
||||||
|
const [alamat, setAlamat] = useState(tps?.alamat || "");
|
||||||
|
const [jenis, setJenis] = useState(tps?.jenis || "");
|
||||||
|
const [luas, setLuas] = useState(tps?.luas || "");
|
||||||
|
const [volume, setVolume] = useState(tps?.volume || "");
|
||||||
|
const [latitude, setLatitude] = useState(tps?.latitude?.toString() || "");
|
||||||
|
const [longitude, setLongitude] = useState(tps?.longitude?.toString() || "");
|
||||||
|
|
||||||
|
const handleSave = () => {
|
||||||
|
if (
|
||||||
|
!nama ||
|
||||||
|
!kecamatan ||
|
||||||
|
!alamat ||
|
||||||
|
!jenis ||
|
||||||
|
!luas ||
|
||||||
|
!volume ||
|
||||||
|
!latitude ||
|
||||||
|
!longitude
|
||||||
|
) {
|
||||||
|
Alert.alert("Error", "Semua field harus diisi!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedTPS = {
|
||||||
|
...tps,
|
||||||
|
nama,
|
||||||
|
kecamatan,
|
||||||
|
alamat,
|
||||||
|
jenis,
|
||||||
|
luas,
|
||||||
|
volume,
|
||||||
|
latitude: parseFloat(latitude),
|
||||||
|
longitude: parseFloat(longitude),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Here you can update your database or state with the updated data.
|
||||||
|
navigation.goBack();
|
||||||
|
Alert.alert("Sukses", "TPS berhasil diperbarui!");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>EDIT LOKASI TPS</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<ScrollView style={styles.formContainer}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Nama TPS"
|
||||||
|
value={nama}
|
||||||
|
onChangeText={setNama}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Luas TPS (m2)"
|
||||||
|
value={luas}
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={setLuas}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Volume (m³)"
|
||||||
|
value={volume}
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={setVolume}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text style={styles.label}>Pilih Jenis TPS</Text>
|
||||||
|
<Picker
|
||||||
|
selectedValue={jenis}
|
||||||
|
style={styles.picker}
|
||||||
|
onValueChange={(itemValue) => setJenis(itemValue)}
|
||||||
|
>
|
||||||
|
<Picker.Item label="Container" value="Container" />
|
||||||
|
<Picker.Item label="Depo Kecil" value="Depo Kecil" />
|
||||||
|
</Picker>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Alamat"
|
||||||
|
value={alamat}
|
||||||
|
onChangeText={setAlamat}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text style={styles.label}>Pilih Kecamatan</Text>
|
||||||
|
<Picker
|
||||||
|
selectedValue={kecamatan}
|
||||||
|
style={styles.picker}
|
||||||
|
onValueChange={(itemValue) => setKecamatan(itemValue)}
|
||||||
|
>
|
||||||
|
<Picker.Item label="Nganjuk" value="Nganjuk" />
|
||||||
|
<Picker.Item label="Bagor" value="Bagor" />
|
||||||
|
<Picker.Item label="Wilangan" value="Wilangan" />
|
||||||
|
<Picker.Item label="Baron" value="Baron" />
|
||||||
|
</Picker>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Latitude"
|
||||||
|
value={latitude}
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={setLatitude}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Longitude"
|
||||||
|
value={longitude}
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={setLongitude}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* MapView to show location */}
|
||||||
|
{latitude && longitude ? (
|
||||||
|
<MapView
|
||||||
|
style={styles.map}
|
||||||
|
initialRegion={{
|
||||||
|
latitude: parseFloat(latitude),
|
||||||
|
longitude: parseFloat(longitude),
|
||||||
|
latitudeDelta: 0.0922,
|
||||||
|
longitudeDelta: 0.0421,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Marker
|
||||||
|
coordinate={{
|
||||||
|
latitude: parseFloat(latitude),
|
||||||
|
longitude: parseFloat(longitude),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</MapView>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.saveButton} onPress={handleSave}>
|
||||||
|
<Text style={styles.saveButtonText}>SIMPAN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 16,
|
||||||
|
marginTop: 30,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 20,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
formContainer: {
|
||||||
|
marginTop: -15,
|
||||||
|
padding: 15,
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ccc",
|
||||||
|
borderRadius: 8,
|
||||||
|
padding: 15,
|
||||||
|
marginBottom: 12,
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
picker: {
|
||||||
|
height: 50,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ccc",
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
map: {
|
||||||
|
height: 200,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
saveButton: {
|
||||||
|
width: "100%",
|
||||||
|
padding: 15,
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
alignItems: "center",
|
||||||
|
borderRadius: 15,
|
||||||
|
},
|
||||||
|
saveButtonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default EditTPS;
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
// ExpensePage.js
|
||||||
|
import React from 'react';
|
||||||
|
import { View, Text, StyleSheet, ScrollView } from 'react-native';
|
||||||
|
|
||||||
|
const ExpensePage = () => {
|
||||||
|
// Data pengeluaran untuk pengelolaan sampah, bisa diganti dengan data dari API atau state global
|
||||||
|
const expenses = [
|
||||||
|
{ id: 1, description: 'Biaya Transportasi Pengangkutan Sampah', amount: 3000000 },
|
||||||
|
{ id: 2, description: 'Biaya Pemeliharaan TPS', amount: 1200000 },
|
||||||
|
{ id: 3, description: 'Gaji Petugas Pengelola Sampah', amount: 1500000 },
|
||||||
|
{ id: 4, description: 'Biaya Pengadaan Alat Pengelolaan Sampah', amount: 800000 },
|
||||||
|
{ id: 5, description: 'Biaya Sosialisasi Pengelolaan Sampah', amount: 500000 },
|
||||||
|
];
|
||||||
|
|
||||||
|
const totalExpense = expenses.reduce((total, expense) => total + expense.amount, 0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView style={styles.container}>
|
||||||
|
<Text style={styles.header}>Halaman Pengeluaran Pengelolaan Sampah</Text>
|
||||||
|
<View style={styles.expensesList}>
|
||||||
|
{expenses.map((expense) => (
|
||||||
|
<View key={expense.id} style={styles.expenseItem}>
|
||||||
|
<Text style={styles.description}>{expense.description}</Text>
|
||||||
|
<Text style={styles.amount}>Rp {expense.amount.toLocaleString()}</Text>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
<View style={styles.totalContainer}>
|
||||||
|
<Text style={styles.totalText}>Total Pengeluaran Pengelolaan Sampah:</Text>
|
||||||
|
<Text style={styles.totalAmount}>Rp {totalExpense.toLocaleString()}</Text>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
padding: 20,
|
||||||
|
backgroundColor: '#f8f8f8',
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
textAlign: 'center',
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
expensesList: {
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
expenseItem: {
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
padding: 15,
|
||||||
|
marginBottom: 10,
|
||||||
|
borderRadius: 5,
|
||||||
|
shadowColor: '#000',
|
||||||
|
shadowOffset: { width: 0, height: 2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 5,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: '600',
|
||||||
|
},
|
||||||
|
amount: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: '#888',
|
||||||
|
},
|
||||||
|
totalContainer: {
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
padding: 15,
|
||||||
|
borderRadius: 5,
|
||||||
|
shadowColor: '#000',
|
||||||
|
shadowOffset: { width: 0, height: 2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 5,
|
||||||
|
},
|
||||||
|
totalText: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
totalAmount: {
|
||||||
|
fontSize: 18,
|
||||||
|
color: '#f00',
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ExpensePage;
|
||||||
|
|
@ -0,0 +1,195 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
ScrollView,
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons"; // Icon library for the media buttons
|
||||||
|
|
||||||
|
const KontribusiAdmin = ({ navigation, route }) => {
|
||||||
|
// Destructuring safely with fallback values if route.params is undefined
|
||||||
|
const {
|
||||||
|
judulPengaduan = "Sampah berantakan",
|
||||||
|
tempatPengaduan = "Jl Raya Madiun Nganjuk",
|
||||||
|
} = route?.params || {};
|
||||||
|
|
||||||
|
const [catatan, setCatatan] = useState("");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView style={styles.container}>
|
||||||
|
{/* Title and Back Button */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>KONTRIBUSI SEKARANG</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Contribution Info Container */}
|
||||||
|
<View style={styles.contributionContainer}>
|
||||||
|
<View style={styles.infoBox}>
|
||||||
|
<Text style={styles.infoText1}>{judulPengaduan}</Text>
|
||||||
|
<Text style={styles.infoText2}>{tempatPengaduan}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Add Media Row (Foto & Video) */}
|
||||||
|
<View style={styles.mediaRow}>
|
||||||
|
<TouchableOpacity style={styles.mediaButton}>
|
||||||
|
<Ionicons name="image-outline" size={30} color="#2D572C" />
|
||||||
|
<Text style={styles.mediaButtonText}>Tambah Foto</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity style={styles.mediaButton}>
|
||||||
|
<Ionicons name="videocam-outline" size={30} color="#2D572C" />
|
||||||
|
<Text style={styles.mediaButtonText}>Tambah Video</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Catatan (Note Input) */}
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Catatan"
|
||||||
|
multiline
|
||||||
|
value={catatan}
|
||||||
|
onChangeText={setCatatan}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Koin Message */}
|
||||||
|
<Text style={styles.koinText}>Dapatkan +520 Koin</Text>
|
||||||
|
|
||||||
|
{/* Post Button at Bottom */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.postButton}
|
||||||
|
onPress={() => navigation.navigate("KontribusiBerhasilAdmin")}
|
||||||
|
>
|
||||||
|
<Text style={styles.postButtonText}>Posting</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
// marginTop: 30,
|
||||||
|
backgroundColor: "#f9f9f9",
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
marginTop: 40,
|
||||||
|
flexDirection: "row", // Aligns items horizontally
|
||||||
|
alignItems: "center", // Vertically centers items
|
||||||
|
padding: 15,
|
||||||
|
backgroundColor: "#fff", // Dark green background
|
||||||
|
borderBottomLeftRadius: 20,
|
||||||
|
borderBottomRightRadius: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 15, // Adds spacing between the back button and the title
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
flex: 1, // Ensures title takes up remaining space
|
||||||
|
textAlign: "left",
|
||||||
|
},
|
||||||
|
contributionContainer: {
|
||||||
|
padding: 20,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
marginBottom: 20,
|
||||||
|
borderRadius: 12,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowOffset: { width: 0, height: 4 },
|
||||||
|
shadowRadius: 4,
|
||||||
|
// elevation: 5, // For Android shadow
|
||||||
|
},
|
||||||
|
infoBox: {
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
infoText1: {
|
||||||
|
fontSize: 22,
|
||||||
|
color: "#333",
|
||||||
|
fontWeight: "700",
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
infoText2: {
|
||||||
|
fontSize: 18,
|
||||||
|
color: "#777",
|
||||||
|
fontWeight: "400",
|
||||||
|
},
|
||||||
|
mediaRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginBottom: 25,
|
||||||
|
},
|
||||||
|
mediaButton: {
|
||||||
|
alignItems: "center",
|
||||||
|
flex: 1,
|
||||||
|
padding: 15,
|
||||||
|
backgroundColor: "#E8F5E9", // Light green background
|
||||||
|
borderRadius: 10,
|
||||||
|
marginHorizontal: 10,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#2D572C",
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowOffset: { width: 0, height: 3 },
|
||||||
|
shadowRadius: 5,
|
||||||
|
elevation: 3,
|
||||||
|
},
|
||||||
|
mediaButtonText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#2D572C",
|
||||||
|
marginTop: 5,
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
height: 100,
|
||||||
|
borderColor: "#2D572C",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 8,
|
||||||
|
padding: 12,
|
||||||
|
fontSize: 16,
|
||||||
|
marginBottom: 15,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowOffset: { width: 0, height: 2 },
|
||||||
|
shadowRadius: 5,
|
||||||
|
elevation: 2,
|
||||||
|
},
|
||||||
|
koinText: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "center",
|
||||||
|
color: "#2D572C",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
postButton: {
|
||||||
|
backgroundColor: "#2D572C", // Dark Green
|
||||||
|
paddingVertical: 15,
|
||||||
|
borderRadius: 10,
|
||||||
|
marginBottom: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "90%",
|
||||||
|
alignSelf: "center",
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowOffset: { width: 0, height: 5 },
|
||||||
|
shadowRadius: 8,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
postButtonText: {
|
||||||
|
fontSize: 18,
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default KontribusiAdmin;
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, Text, Button, StyleSheet, TouchableOpacity } from "react-native";
|
||||||
|
import { MaterialCommunityIcons } from "@expo/vector-icons"; // Menggunakan ikon ceklis
|
||||||
|
|
||||||
|
const KontribusiBerhasilAdmin = ({ navigation }) => {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.content}>
|
||||||
|
<MaterialCommunityIcons name="cloud-check" size={140} color="white" />
|
||||||
|
<Text style={styles.title}>Kontribusi Berhasil !</Text>
|
||||||
|
{/* <Text style={styles.message}>
|
||||||
|
Mohon pastikan informasi yang diberikan sudah sesuai, agar kami dapat
|
||||||
|
segera menindaklanjuti.
|
||||||
|
</Text> */}
|
||||||
|
<Text style={styles.subMessage}>
|
||||||
|
Terima kasih telah berkontribusi untuk lingkungan!
|
||||||
|
</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
// onPress={() => console.log("Daftar Submit")}
|
||||||
|
onPress={() => navigation.navigate("BerandaPengaduanAdmin")}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>LIHAT KONTRIBUSI</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Warna hijau gelap
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Transparansi gelap untuk efek overlay
|
||||||
|
padding: 30,
|
||||||
|
borderRadius: 15,
|
||||||
|
width: "80%",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#ffea00",
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#fff",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
subMessage: {
|
||||||
|
fontSize: 15,
|
||||||
|
color: "#ffea00",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
padding: 3,
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 40,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginTop: 20,
|
||||||
|
borderRadius: 25,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 15,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default KontribusiBerhasilAdmin;
|
||||||
|
|
@ -0,0 +1,347 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { Ionicons, MaterialIcons } from "@expo/vector-icons"; // I
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
Button,
|
||||||
|
Modal,
|
||||||
|
TouchableOpacity,
|
||||||
|
FlatList,
|
||||||
|
} from "react-native";
|
||||||
|
import * as Print from "expo-print";
|
||||||
|
import * as FileSystem from "expo-file-system";
|
||||||
|
import { useNavigation } from "@react-navigation/native"; // Import useNavigation untuk navigasi
|
||||||
|
|
||||||
|
const Laporan = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [bulan, setBulan] = useState("Januari");
|
||||||
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
|
const [selectedReport, setSelectedReport] = useState(null);
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
tpsData: [
|
||||||
|
{ tps: "TPS 1", jumlah: 150 },
|
||||||
|
{ tps: "TPS 2", jumlah: 200 },
|
||||||
|
{ tps: "TPS 3", jumlah: 180 },
|
||||||
|
],
|
||||||
|
pengaduanData: [
|
||||||
|
{ bulan: "Januari", jumlah: 25 },
|
||||||
|
{ bulan: "Februari", jumlah: 30 },
|
||||||
|
{ bulan: "Maret", jumlah: 18 },
|
||||||
|
],
|
||||||
|
penukaranKoinData: [
|
||||||
|
{ bulan: "Januari", jumlah: 1500 },
|
||||||
|
{ bulan: "Februari", jumlah: 2000 },
|
||||||
|
{ bulan: "Maret", jumlah: 1200 },
|
||||||
|
],
|
||||||
|
donasiData: [
|
||||||
|
{ bulan: "Januari", jumlah: 100000 },
|
||||||
|
{ bulan: "Februari", jumlah: 120000 },
|
||||||
|
{ bulan: "Maret", jumlah: 80000 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const filterDataByMonth = (month) => {
|
||||||
|
const filteredData = {
|
||||||
|
tpsData: data.tpsData,
|
||||||
|
pengaduanData: data.pengaduanData.filter((item) => item.bulan === month),
|
||||||
|
penukaranKoinData: data.penukaranKoinData.filter(
|
||||||
|
(item) => item.bulan === month
|
||||||
|
),
|
||||||
|
donasiData: data.donasiData.filter((item) => item.bulan === month),
|
||||||
|
};
|
||||||
|
return filteredData;
|
||||||
|
};
|
||||||
|
|
||||||
|
const generatePDF = async (reportType) => {
|
||||||
|
const filteredData = filterDataByMonth(bulan);
|
||||||
|
|
||||||
|
let htmlContent = "";
|
||||||
|
|
||||||
|
if (reportType === "tps") {
|
||||||
|
htmlContent = `
|
||||||
|
<h1 style="text-align:center;">Laporan TPS di Nganjuk</h1>
|
||||||
|
<table border="1" style="width:100%; text-align:left;">
|
||||||
|
<tr>
|
||||||
|
<th>TPS</th>
|
||||||
|
<th>Jumlah</th>
|
||||||
|
</tr>
|
||||||
|
${filteredData.tpsData
|
||||||
|
.map(
|
||||||
|
(item) => `
|
||||||
|
<tr>
|
||||||
|
<td>${item.tps}</td>
|
||||||
|
<td>${item.jumlah}</td>
|
||||||
|
</tr>`
|
||||||
|
)
|
||||||
|
.join("")}
|
||||||
|
</table>
|
||||||
|
`;
|
||||||
|
} else if (reportType === "pengaduan") {
|
||||||
|
htmlContent = `
|
||||||
|
<h1 style="text-align:center;">Laporan Pengaduan Sampah - ${bulan}</h1>
|
||||||
|
<table border="1" style="width:100%; text-align:left;">
|
||||||
|
<tr>
|
||||||
|
<th>Bulan</th>
|
||||||
|
<th>Jumlah Pengaduan</th>
|
||||||
|
</tr>
|
||||||
|
${filteredData.pengaduanData
|
||||||
|
.map(
|
||||||
|
(item) => `
|
||||||
|
<tr>
|
||||||
|
<td>${item.bulan}</td>
|
||||||
|
<td>${item.jumlah}</td>
|
||||||
|
</tr>`
|
||||||
|
)
|
||||||
|
.join("")}
|
||||||
|
</table>
|
||||||
|
`;
|
||||||
|
} else if (reportType === "penukaran") {
|
||||||
|
htmlContent = `
|
||||||
|
<h1 style="text-align:center;">Laporan Penukaran Koin - ${bulan}</h1>
|
||||||
|
<table border="1" style="width:100%; text-align:left;">
|
||||||
|
<tr>
|
||||||
|
<th>Bulan</th>
|
||||||
|
<th>Jumlah Koin</th>
|
||||||
|
</tr>
|
||||||
|
${filteredData.penukaranKoinData
|
||||||
|
.map(
|
||||||
|
(item) => `
|
||||||
|
<tr>
|
||||||
|
<td>${item.bulan}</td>
|
||||||
|
<td>${item.jumlah}</td>
|
||||||
|
</tr>`
|
||||||
|
)
|
||||||
|
.join("")}
|
||||||
|
</table>
|
||||||
|
`;
|
||||||
|
} else if (reportType === "donasi") {
|
||||||
|
htmlContent = `
|
||||||
|
<h1 style="text-align:center;">Laporan Donasi - ${bulan}</h1>
|
||||||
|
<table border="1" style="width:100%; text-align:left;">
|
||||||
|
<tr>
|
||||||
|
<th>Bulan</th>
|
||||||
|
<th>Jumlah Donasi</th>
|
||||||
|
</tr>
|
||||||
|
${filteredData.donasiData
|
||||||
|
.map(
|
||||||
|
(item) => `
|
||||||
|
<tr>
|
||||||
|
<td>${item.bulan}</td>
|
||||||
|
<td>Rp ${item.jumlah.toLocaleString()}</td>
|
||||||
|
</tr>`
|
||||||
|
)
|
||||||
|
.join("")}
|
||||||
|
</table>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { uri } = await Print.printToFileAsync({ html: htmlContent });
|
||||||
|
console.log("PDF berhasil dibuat di:", uri);
|
||||||
|
alert(`PDF berhasil dibuat! File disimpan di: ${uri}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error saat membuat PDF:", error);
|
||||||
|
alert("Gagal membuat PDF.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const months = [
|
||||||
|
"Januari",
|
||||||
|
"Februari",
|
||||||
|
"Maret",
|
||||||
|
"April",
|
||||||
|
"Mei",
|
||||||
|
"Juni",
|
||||||
|
"Juli",
|
||||||
|
"Agustus",
|
||||||
|
"September",
|
||||||
|
"Oktober",
|
||||||
|
"November",
|
||||||
|
"Desember",
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* <Text style={styles.headerTitle}>Laporan Data</Text> */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.navigate("AdminScreen")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>LAPORAN</Text>
|
||||||
|
</View>
|
||||||
|
{/* Tombol untuk Memilih Laporan */}
|
||||||
|
<View style={styles.buttonContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.reportButton}
|
||||||
|
onPress={() => {
|
||||||
|
setSelectedReport("tps");
|
||||||
|
setModalVisible(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>TPS di Nganjuk</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.reportButton}
|
||||||
|
onPress={() => {
|
||||||
|
setSelectedReport("pengaduan");
|
||||||
|
setModalVisible(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>Pengaduan Sampah</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.reportButton}
|
||||||
|
onPress={() => {
|
||||||
|
setSelectedReport("penukaran");
|
||||||
|
setModalVisible(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>Penukaran Koin</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.reportButton}
|
||||||
|
onPress={() => {
|
||||||
|
setSelectedReport("donasi");
|
||||||
|
setModalVisible(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>Donasi</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Modal untuk memilih bulan */}
|
||||||
|
<Modal
|
||||||
|
visible={modalVisible}
|
||||||
|
transparent={true}
|
||||||
|
animationType="slide"
|
||||||
|
onRequestClose={() => setModalVisible(false)}
|
||||||
|
>
|
||||||
|
<View style={styles.modalContainer}>
|
||||||
|
<View style={styles.modalContent}>
|
||||||
|
<Text style={styles.modalTitle}>Pilih Bulan</Text>
|
||||||
|
<FlatList
|
||||||
|
data={months}
|
||||||
|
numColumns={3}
|
||||||
|
keyExtractor={(item) => item}
|
||||||
|
renderItem={({ item }) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.monthButton}
|
||||||
|
onPress={() => {
|
||||||
|
setBulan(item);
|
||||||
|
generatePDF(selectedReport);
|
||||||
|
setModalVisible(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={styles.monthButtonText}>{item}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.closeButton}
|
||||||
|
onPress={() => setModalVisible(false)}
|
||||||
|
>
|
||||||
|
<Text style={styles.closeButtonText}>Tutup</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 16,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
marginTop: 40,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 12,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
headerTitle: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 20,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
buttonContainer: {
|
||||||
|
marginBottom: 20,
|
||||||
|
flexDirection: "row",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
},
|
||||||
|
reportButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
padding: 20,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 10,
|
||||||
|
width: "100%",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 20,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
modalContainer: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
||||||
|
},
|
||||||
|
modalContent: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 20,
|
||||||
|
borderRadius: 10,
|
||||||
|
width: 300,
|
||||||
|
},
|
||||||
|
modalTitle: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 10,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
monthButton: {
|
||||||
|
backgroundColor: "#4CAF50",
|
||||||
|
margin: 5,
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 5,
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
monthButtonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
closeButton: {
|
||||||
|
backgroundColor: "#ddd",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginTop: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
closeButtonText: {
|
||||||
|
color: "#000",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Laporan;
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, Text, StyleSheet, ScrollView } from "react-native";
|
||||||
|
import { Ionicons, MaterialIcons } from "@expo/vector-icons"; // Importing icons
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import BottomTabAdmin from "../../Navigation/BottomTabAdmin";
|
||||||
|
|
||||||
|
const NotifikasiAdminScreen = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
// Get current date and time
|
||||||
|
const currentDate = new Date();
|
||||||
|
const formattedDate = `${currentDate.toLocaleDateString()} ${currentDate.toLocaleTimeString()}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<ScrollView style={styles.scrollContainer}>
|
||||||
|
{/* Header */}
|
||||||
|
<View>
|
||||||
|
<Text style={styles.title}>NOTIFIKASI ADMIN</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Notification 1: New User Report */}
|
||||||
|
<View style={styles.notification}>
|
||||||
|
<MaterialIcons name="report-problem" size={24} color="#e74c3c" />
|
||||||
|
<View style={styles.notificationText}>
|
||||||
|
<Text style={styles.notificationTitle}>Laporan pengguna baru!</Text>
|
||||||
|
<Text style={styles.notificationDescription}>
|
||||||
|
Pengguna baru melaporkan masalah terkait sistem. Harap tinjau
|
||||||
|
segera.
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDate}>{formattedDate}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Notification 2: Task Assigned to You */}
|
||||||
|
<View style={styles.notification}>
|
||||||
|
<Ionicons name="clipboard" size={24} color="#3498db" />
|
||||||
|
<View style={styles.notificationText}>
|
||||||
|
<Text style={styles.notificationTitle}>
|
||||||
|
Tugas baru telah ditugaskan!
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDescription}>
|
||||||
|
Anda telah ditugaskan untuk meninjau laporan terbaru yang masuk.
|
||||||
|
Silakan cek sekarang.
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDate}>{formattedDate}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Notification 3: System Maintenance Update */}
|
||||||
|
<View style={styles.notification}>
|
||||||
|
<Ionicons name="construct" size={24} color="#f39c12" />
|
||||||
|
<View style={styles.notificationText}>
|
||||||
|
<Text style={styles.notificationTitle}>
|
||||||
|
Pembaruan sistem sedang berjalan.
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDescription}>
|
||||||
|
Pembaruan sistem akan memengaruhi akses beberapa fitur. Harap
|
||||||
|
bersabar.
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDate}>{formattedDate}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Notification 4: New Trash Pickup Location */}
|
||||||
|
<View style={styles.notification}>
|
||||||
|
<Ionicons name="location-sharp" size={24} color="#27ae60" />
|
||||||
|
<View style={styles.notificationText}>
|
||||||
|
<Text style={styles.notificationTitle}>
|
||||||
|
TPS baru telah ditambahkan!
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDescription}>
|
||||||
|
Lokasi pembuangan sampah terbaru sudah tersedia di sistem. Cek
|
||||||
|
peta untuk detailnya.
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDate}>{formattedDate}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
{/* Bottom Navigation */}
|
||||||
|
<View style={styles.bottomNavigationContainer}>
|
||||||
|
<BottomTabAdmin />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1, // Flex untuk menutupi seluruh layar
|
||||||
|
backgroundColor: "#f9f9f9",
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
paddingTop: 10,
|
||||||
|
},
|
||||||
|
scrollContainer: {
|
||||||
|
flex: 1, // Agar ScrollView mengisi ruang yang tersisa
|
||||||
|
paddingBottom: 80, // Menambahkan ruang untuk bottom navigation
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
marginLeft: 10,
|
||||||
|
marginBottom: 20,
|
||||||
|
marginTop: 40,
|
||||||
|
},
|
||||||
|
notification: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 15,
|
||||||
|
marginBottom: 15,
|
||||||
|
borderRadius: 8,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ddd",
|
||||||
|
},
|
||||||
|
notificationText: {
|
||||||
|
marginLeft: 15,
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
notificationTitle: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
notificationDescription: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
notificationDate: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#888", // Lighter color for date
|
||||||
|
marginTop: 5,
|
||||||
|
},
|
||||||
|
bottomNavigationContainer: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 0,
|
||||||
|
left: 0, // Memberikan ruang kiri sedikit
|
||||||
|
right: 0, // Memberikan ruang kanan sedikit
|
||||||
|
height: 60,
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: -2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 6,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default NotifikasiAdminScreen;
|
||||||
|
|
@ -0,0 +1,231 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
ScrollView,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons, MaterialIcons } from "@expo/vector-icons"; // Importing icons
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const PengaduanSampahScreenAdmin = () => {
|
||||||
|
const [filter, setFilter] = useState("all"); // State to manage the active filter
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
// Function to navigate to the details page
|
||||||
|
const goToDetailPage = (status) => {
|
||||||
|
navigation.navigate(`Detail${status}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sample data for reports
|
||||||
|
const reports = [
|
||||||
|
{
|
||||||
|
title: "Sampah Berantakan",
|
||||||
|
location: "Pasar Nganjuk - Jl. Sukomoro Nganjuk",
|
||||||
|
status: "Selesai",
|
||||||
|
date: "10 April 2025 - 14:30",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Sampah Pinggir Jalan",
|
||||||
|
location: "Pasar Madiun - Jl. Raya Madiun",
|
||||||
|
status: "Dalam Proses",
|
||||||
|
date: "10 April 2025 - 13:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "TPS Liar",
|
||||||
|
location: "Pasar Kediri - Jl. Raya Kediri",
|
||||||
|
status: "Verifikasi",
|
||||||
|
date: "9 April 2025 - 15:20",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Sampah Depan SMA 1",
|
||||||
|
location: "Pasar Surabaya - Jl. Raya Surabaya",
|
||||||
|
status: "Ditolak",
|
||||||
|
date: "8 April 2025 - 10:45",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// Filter reports based on the active filter
|
||||||
|
const filteredReports = reports.filter(
|
||||||
|
(report) => filter === "all" || report.status === filter
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView style={styles.container}>
|
||||||
|
{/* Header with Title and Back Button */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.navigate("AdminScreen")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#333" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>PENGADUAN SAMPAH</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Filter Buttons */}
|
||||||
|
<View style={styles.filterContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[styles.filterButton, filter === "all" && styles.activeFilter]}
|
||||||
|
onPress={() => setFilter("all")}
|
||||||
|
>
|
||||||
|
<Text style={styles.filterButtonText}>Semua</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.filterButton,
|
||||||
|
filter === "Verifikasi" && styles.activeFilter,
|
||||||
|
]}
|
||||||
|
onPress={() => setFilter("Verifikasi")}
|
||||||
|
>
|
||||||
|
<Text style={styles.filterButtonText}>Verifikasi</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.filterButton,
|
||||||
|
filter === "Dalam Proses" && styles.activeFilter,
|
||||||
|
]}
|
||||||
|
onPress={() => setFilter("Dalam Proses")}
|
||||||
|
>
|
||||||
|
<Text style={styles.filterButtonText}>Dalam Proses</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.filterButton,
|
||||||
|
filter === "Selesai" && styles.activeFilter,
|
||||||
|
]}
|
||||||
|
onPress={() => setFilter("Selesai")}
|
||||||
|
>
|
||||||
|
<Text style={styles.filterButtonText}>Selesai</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.filterButton,
|
||||||
|
filter === "Ditolak" && styles.activeFilter,
|
||||||
|
]}
|
||||||
|
onPress={() => setFilter("Ditolak")}
|
||||||
|
>
|
||||||
|
<Text style={styles.filterButtonText}>Ditolak</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Report Content */}
|
||||||
|
{filteredReports.map((report, index) => (
|
||||||
|
<View style={styles.reportContainer} key={index}>
|
||||||
|
<Text style={styles.reportTitle}>{report.title}</Text>
|
||||||
|
<Text style={styles.reportLocation}>{report.location}</Text>
|
||||||
|
|
||||||
|
<View style={styles.statusContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.statusBox,
|
||||||
|
report.status === "Selesai" && styles.statusDone,
|
||||||
|
report.status === "Dalam Proses" && styles.statusInProgress,
|
||||||
|
report.status === "Verifikasi" && styles.statusOnProcess,
|
||||||
|
report.status === "Ditolak" && styles.statusRejected,
|
||||||
|
]}
|
||||||
|
onPress={() => goToDetailPage(report.status)}
|
||||||
|
>
|
||||||
|
<Text style={styles.statusText}>{report.status}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.dateTimeText}>{report.date}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#f9f9f9",
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
marginTop: 40,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
filterContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
filterButton: {
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
borderRadius: 15,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
filterButtonText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
activeFilter: {
|
||||||
|
backgroundColor: "#dcdcdc", // Green color for active filter
|
||||||
|
},
|
||||||
|
reportContainer: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 15,
|
||||||
|
marginBottom: 15,
|
||||||
|
borderRadius: 8,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ddd",
|
||||||
|
},
|
||||||
|
reportTitle: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
reportLocation: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
statusContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
statusBox: {
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
borderRadius: 8,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
statusDone: {
|
||||||
|
backgroundColor: "#d1f0d1", // Light Green
|
||||||
|
},
|
||||||
|
statusInProgress: {
|
||||||
|
backgroundColor: "#d1e3f0", // Light Blue
|
||||||
|
},
|
||||||
|
statusOnProcess: {
|
||||||
|
backgroundColor: "#f0e0a1", // Light Yellow
|
||||||
|
},
|
||||||
|
statusRejected: {
|
||||||
|
backgroundColor: "#f0c1c1", // Light Red
|
||||||
|
},
|
||||||
|
statusText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
dateTimeText: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default PengaduanSampahScreenAdmin;
|
||||||
|
|
@ -0,0 +1,159 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
TouchableOpacity,
|
||||||
|
Image,
|
||||||
|
ScrollView,
|
||||||
|
Alert,
|
||||||
|
ToastAndroid,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const PosterEdukasiScreen = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
// State untuk menyimpan daftar poster
|
||||||
|
const [posters, setPosters] = useState([
|
||||||
|
{ id: 1, image: require("../../assets/images/poster1.png") },
|
||||||
|
{ id: 2, image: require("../../assets/images/poster2.png") }, // Tambah poster kedua
|
||||||
|
{ id: 2, image: require("../../assets/images/poster3.png") }, // Tambah poster kedua
|
||||||
|
// Tambahkan poster lainnya sesuai kebutuhan
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Handle add poster action
|
||||||
|
const handleAddPoster = () => {
|
||||||
|
navigation.navigate("AddPosterScreen");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fungsi untuk menghapus poster
|
||||||
|
const handleDeletePoster = (posterId) => {
|
||||||
|
Alert.alert(
|
||||||
|
"Hapus Poster",
|
||||||
|
"Apakah Anda yakin ingin menghapus poster ini?",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: "Batal",
|
||||||
|
style: "cancel",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Hapus",
|
||||||
|
onPress: () => {
|
||||||
|
// Hapus poster berdasarkan ID
|
||||||
|
const updatedPosters = posters.filter(
|
||||||
|
(poster) => poster.id !== posterId
|
||||||
|
);
|
||||||
|
setPosters(updatedPosters);
|
||||||
|
ToastAndroid.show("Poster telah dihapus", ToastAndroid.SHORT);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView style={styles.container}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>POSTER EDUKASI</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Daftar Poster */}
|
||||||
|
<View style={styles.posterList}>
|
||||||
|
{posters.map((poster) => (
|
||||||
|
<View key={poster.id} style={styles.posterItem}>
|
||||||
|
<TouchableOpacity onPress={() => handleDeletePoster(poster.id)}>
|
||||||
|
<Image source={poster.image} style={styles.posterImage} />
|
||||||
|
{/* Tombol Hapus Poster */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.deleteIcon}
|
||||||
|
onPress={() => handleDeletePoster(poster.id)}
|
||||||
|
>
|
||||||
|
<Ionicons name="trash" size={24} color="white" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Add Poster Button */}
|
||||||
|
<View style={styles.addPosterContainer}>
|
||||||
|
<TouchableOpacity style={styles.addButton} onPress={handleAddPoster}>
|
||||||
|
<Ionicons name="add-circle" size={24} color="#FFF" />
|
||||||
|
<Text style={styles.addButtonText}>Tambah Poster</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#FFF",
|
||||||
|
padding: 16,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
marginTop: 40,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 12,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
posterList: {
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
posterItem: {
|
||||||
|
position: "relative",
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
posterImage: {
|
||||||
|
width: "100%",
|
||||||
|
height: 250,
|
||||||
|
resizeMode: "contain",
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
deleteIcon: {
|
||||||
|
position: "absolute",
|
||||||
|
top: 10,
|
||||||
|
right: 10,
|
||||||
|
backgroundColor: "red",
|
||||||
|
padding: 6,
|
||||||
|
borderRadius: 16,
|
||||||
|
},
|
||||||
|
addPosterContainer: {
|
||||||
|
marginTop: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 50,
|
||||||
|
},
|
||||||
|
addButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 12,
|
||||||
|
paddingHorizontal: 32,
|
||||||
|
borderRadius: 8,
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
addButtonText: {
|
||||||
|
color: "#FFF",
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginLeft: 8,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default PosterEdukasiScreen;
|
||||||
|
|
@ -0,0 +1,265 @@
|
||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
Image,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
Alert,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import BottomTabAdmin from "../../Navigation/BottomTabAdmin";
|
||||||
|
|
||||||
|
const ProfilAdminScreen = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
const userProfile = {
|
||||||
|
name: "Johan Okta Pangestu",
|
||||||
|
email: "okta@gmail.com",
|
||||||
|
phone: "08123456789",
|
||||||
|
address: "Jl. Raya No. 123, Nganjuk",
|
||||||
|
joinDate: "January 15, 2023",
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLogout = () => {
|
||||||
|
Alert.alert(
|
||||||
|
"Konfirmasi Keluar",
|
||||||
|
"Apakah Anda yakin ingin keluar dari aplikasi?",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: "Tidak",
|
||||||
|
onPress: () => console.log("Logout cancelled"),
|
||||||
|
style: "cancel",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Yakin",
|
||||||
|
onPress: () => {
|
||||||
|
console.log("User logged out");
|
||||||
|
navigation.navigate("AksesAkun"); // Navigasi ke halaman masuk admin
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{ cancelable: false }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Profile Section */}
|
||||||
|
<View style={styles.profileSection}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://i.ytimg.com/vi/b1XXKeq5ccQ/oar2.jpg?sqp=-oaymwEkCJUDENAFSFqQAgHyq4qpAxMIARUAAAAAJQAAyEI9AICiQ3gB&rs=AOn4CLBxYjkvH5GuWS8_SYMNsg5aIGYIRA",
|
||||||
|
}}
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
<View style={styles.profileTextContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.editButton}
|
||||||
|
onPress={() => navigation.navigate("EditProfilScreen")}
|
||||||
|
>
|
||||||
|
<Text style={styles.editButtonText}>Edit Profil</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.greetingText}>Hi, {userProfile.name}</Text>
|
||||||
|
<Text style={styles.envMessageText}>
|
||||||
|
Keberihan lingkungan sekitar anda wajib terjaga
|
||||||
|
</Text>
|
||||||
|
<View style={styles.dinasBox}>
|
||||||
|
<Text style={styles.dinasText}>DINAS LINGKUNGAN HIDUP</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Profile Information Section */}
|
||||||
|
<View style={styles.infoSection}>
|
||||||
|
<Text style={styles.infoLabel}>Nama:</Text>
|
||||||
|
<Text style={styles.infoText}>{userProfile.name}</Text>
|
||||||
|
|
||||||
|
<Text style={styles.infoLabel}>Email:</Text>
|
||||||
|
<Text style={styles.infoText}>{userProfile.email}</Text>
|
||||||
|
|
||||||
|
<Text style={styles.infoLabel}>No. HP:</Text>
|
||||||
|
<Text style={styles.infoText}>{userProfile.phone}</Text>
|
||||||
|
|
||||||
|
<Text style={styles.infoLabel}>Alamat:</Text>
|
||||||
|
<Text style={styles.infoText}>{userProfile.address}</Text>
|
||||||
|
|
||||||
|
<Text style={styles.infoLabel}>Tanggal Bergabung:</Text>
|
||||||
|
<Text style={styles.infoText}>{userProfile.joinDate}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Logout Button */}
|
||||||
|
<TouchableOpacity style={styles.logoutButton} onPress={handleLogout}>
|
||||||
|
<Text style={styles.logoutButtonText}>KELUAR AKUN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* Bottom Navigation */}
|
||||||
|
<View style={styles.bottomNav}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("AksesAkun")}
|
||||||
|
>
|
||||||
|
<Ionicons name="home" size={30} color="#2C6B2F" />
|
||||||
|
<Text style={styles.navText}>UTAMA</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("NotifikasiAdminScreen")}
|
||||||
|
>
|
||||||
|
<View style={styles.notifIconContainer}>
|
||||||
|
<Ionicons name="notifications-outline" size={24} color="#2C6B2F" />
|
||||||
|
<View style={styles.badge}>
|
||||||
|
<Text style={styles.badgeText}>1</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.navText}>NOTIFIKASI</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("ProfilAdminScreen")}
|
||||||
|
>
|
||||||
|
<Ionicons name="person-circle-outline" size={24} color="#2C6B2F" />
|
||||||
|
<Text style={styles.navText}>PROFIL</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<BottomTabAdmin />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
},
|
||||||
|
profileSection: {
|
||||||
|
alignItems: "center",
|
||||||
|
padding: 20,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: "#ddd",
|
||||||
|
marginTop: 30,
|
||||||
|
},
|
||||||
|
profileImage: {
|
||||||
|
width: 150,
|
||||||
|
height: 150,
|
||||||
|
borderRadius: 75,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
profileTextContainer: {
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
greetingText: {
|
||||||
|
fontSize: 30,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
envMessageText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
marginVertical: 5,
|
||||||
|
},
|
||||||
|
dinasBox: {
|
||||||
|
backgroundColor: "#ddd",
|
||||||
|
paddingVertical: 3,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
marginTop: 1,
|
||||||
|
borderRadius: 8,
|
||||||
|
borderColor: "#000",
|
||||||
|
alignItems: "center",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
dinasText: {
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
editButton: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 5,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
paddingHorizontal: 30,
|
||||||
|
marginBottom: 5,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#000",
|
||||||
|
},
|
||||||
|
editButtonText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
infoSection: {
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
infoLabel: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#555",
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
infoText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#777",
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
logoutButton: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 12,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
marginHorizontal: 20,
|
||||||
|
marginBottom: 20,
|
||||||
|
borderWidth: 0.5,
|
||||||
|
elevation: 1,
|
||||||
|
},
|
||||||
|
logoutButtonText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
bottomNav: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 0,
|
||||||
|
width: "100%",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-evenly",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: -2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 6,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
navItem: {
|
||||||
|
alignItems: "center",
|
||||||
|
padding: 6,
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
paddingVertical: 5,
|
||||||
|
marginHorizontal: 5,
|
||||||
|
},
|
||||||
|
navText: { color: "#2C6B2F", fontSize: 12, marginTop: 5 },
|
||||||
|
notifIconContainer: { position: "relative" },
|
||||||
|
badge: {
|
||||||
|
position: "absolute",
|
||||||
|
right: -5,
|
||||||
|
top: -5,
|
||||||
|
backgroundColor: "#E74C3C",
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 6,
|
||||||
|
paddingVertical: 2,
|
||||||
|
},
|
||||||
|
badgeText: { color: "#fff", fontSize: 10, fontWeight: "bold" },
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ProfilAdminScreen;
|
||||||
|
|
@ -0,0 +1,158 @@
|
||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
ScrollView,
|
||||||
|
StyleSheet,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons"; // Import Ionicons for back icon
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
// Sample data for donation history
|
||||||
|
const donations = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "John Doe",
|
||||||
|
tujuan: "Edukasi Lingkungan",
|
||||||
|
catatan: "-",
|
||||||
|
tanggal: "2025-05-19",
|
||||||
|
waktu: "14:30",
|
||||||
|
nominal: "Rp 500.000",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Jane Smith",
|
||||||
|
tujuan: "Pengelolaan Sampah",
|
||||||
|
catatan: "Donasi untuk pengadaan tempat sampah",
|
||||||
|
tanggal: "2025-06-01",
|
||||||
|
waktu: "10:00",
|
||||||
|
nominal: "Rp 150.000",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Mark Wilson",
|
||||||
|
tujuan: "Program Pelatihan",
|
||||||
|
catatan: "Untuk program pelatihan masyarakat",
|
||||||
|
tanggal: "2025-04-15",
|
||||||
|
waktu: "16:45",
|
||||||
|
nominal: "Rp 300.000",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function RiwayatDonasiAdmin() {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView contentContainerStyle={styles.container}>
|
||||||
|
{/* Back Button */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()} // Go back to previous screen
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={30} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* Title */}
|
||||||
|
<Text style={styles.title}>RIWAYAT DONASI</Text>
|
||||||
|
|
||||||
|
{/* Donation History List */}
|
||||||
|
<View style={styles.historyBox}>
|
||||||
|
{donations.map((donation) => (
|
||||||
|
<View key={donation.id} style={styles.donationView}>
|
||||||
|
<View style={styles.donationContent}>
|
||||||
|
{/* Donation Info */}
|
||||||
|
<View style={styles.leftColumn}>
|
||||||
|
<Text style={styles.donationName}>{donation.name}</Text>
|
||||||
|
<Text style={styles.donationDetail}>
|
||||||
|
Tujuan: {donation.tujuan}
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.donationDetail}>
|
||||||
|
Catatan: {donation.catatan}
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.donationDetail}>
|
||||||
|
Tanggal: {donation.tanggal}
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.donationDetail}>
|
||||||
|
Waktu: {donation.waktu}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Donation Amount */}
|
||||||
|
<View style={styles.rightColumn}>
|
||||||
|
<Text style={styles.donationAmount}>{donation.nominal}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
marginTop: 20,
|
||||||
|
padding: 20,
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
position: "absolute",
|
||||||
|
top: 20,
|
||||||
|
left: 10,
|
||||||
|
zIndex: 1,
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
marginBottom: 5,
|
||||||
|
marginLeft: 30,
|
||||||
|
marginTop: 15,
|
||||||
|
},
|
||||||
|
historyBox: {
|
||||||
|
marginTop: 10,
|
||||||
|
paddingBottom: 5,
|
||||||
|
},
|
||||||
|
donationView: {
|
||||||
|
backgroundColor: "#fff", // Background color for each donation box
|
||||||
|
borderRadius: 20,
|
||||||
|
marginVertical: 10,
|
||||||
|
padding: 15,
|
||||||
|
flexDirection: "row", // Layout of elements horizontally
|
||||||
|
justifyContent: "space-between", // Space out left and right columns
|
||||||
|
alignItems: "center",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#000",
|
||||||
|
},
|
||||||
|
donationContent: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
width: "100%",
|
||||||
|
},
|
||||||
|
leftColumn: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
rightColumn: {
|
||||||
|
alignItems: "flex-end", // Align right side for donation amount
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
donationName: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
donationDetail: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
donationAmount: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#4F772D", // Green color for donation amount
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,284 @@
|
||||||
|
import React, { useState, useEffect } from "react"; // Tambahkan useEffect
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
Image,
|
||||||
|
ScrollView,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const StatusPengirimanAdmin = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [selectedButton, setSelectedButton] = useState("diproses"); // Default to 'diproses'
|
||||||
|
const [selectedStatus, setSelectedStatus] = useState("diproses"); // Default to 'diproses'
|
||||||
|
|
||||||
|
// Data barang
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Tas Kertas",
|
||||||
|
time: "10 April 2025 - 14:30",
|
||||||
|
status: "diproses",
|
||||||
|
imageUri: require("../../../assets/images/tas2.png"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Botol",
|
||||||
|
time: "11 April 2025 - 15:00",
|
||||||
|
status: "dikirim",
|
||||||
|
imageUri: require("../../../assets/images/botol1.png"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Botol Anak",
|
||||||
|
time: "12 April 2025 - 16:30",
|
||||||
|
status: "diterima",
|
||||||
|
imageUri: require("../../../assets/images/botol2.png"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// Effect untuk men-set status saat pertama kali halaman dibuka
|
||||||
|
useEffect(() => {
|
||||||
|
setSelectedButton("diproses");
|
||||||
|
setSelectedStatus("diproses");
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleButtonClick = (status) => {
|
||||||
|
setSelectedStatus(status);
|
||||||
|
setSelectedButton(status);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Filter items berdasarkan selected status
|
||||||
|
const filteredItems = items.filter((item) => item.status === selectedStatus);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#333" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>STATUS PENGIRIMAN</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Status Buttons */}
|
||||||
|
<View style={styles.buttonRow}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.statusButton,
|
||||||
|
selectedButton === "diproses" && styles.selectedButton,
|
||||||
|
]}
|
||||||
|
onPress={() => handleButtonClick("diproses")}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name="sync"
|
||||||
|
size={20}
|
||||||
|
color={selectedButton === "diproses" ? "#fff" : "#000"}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.buttonText,
|
||||||
|
selectedButton === "diproses" && { color: "#fff" },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
Diproses
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.statusButton,
|
||||||
|
selectedButton === "dikirim" && styles.selectedButton,
|
||||||
|
]}
|
||||||
|
onPress={() => handleButtonClick("dikirim")}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name="paper-plane"
|
||||||
|
size={20}
|
||||||
|
color={selectedButton === "dikirim" ? "#fff" : "#000"}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.buttonText,
|
||||||
|
selectedButton === "dikirim" && { color: "#fff" },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
Dikirim
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.statusButton,
|
||||||
|
selectedButton === "diterima" && styles.selectedButton,
|
||||||
|
]}
|
||||||
|
onPress={() => handleButtonClick("diterima")}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name="checkmark"
|
||||||
|
size={20}
|
||||||
|
color={selectedButton === "diterima" ? "#fff" : "#000"}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.buttonText,
|
||||||
|
selectedButton === "diterima" && { color: "#fff" },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
Diterima
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Filtered List of Items Based on Selected Status */}
|
||||||
|
<ScrollView style={styles.itemList}>
|
||||||
|
{filteredItems.length > 0 ? (
|
||||||
|
filteredItems.map((item) => (
|
||||||
|
<View key={item.id} style={styles.itemRow}>
|
||||||
|
<Image source={item.imageUri} style={styles.itemImage} />
|
||||||
|
<View style={styles.itemDetails}>
|
||||||
|
<Text style={styles.itemName}>{item.name}</Text>
|
||||||
|
<Text style={styles.itemTime}>{item.time}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.itemActions}>
|
||||||
|
<View style={styles.coinButton}>
|
||||||
|
<Text style={styles.coinButtonText}>500 Koin</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.detailButton}
|
||||||
|
onPress={() =>
|
||||||
|
navigation.navigate("DetailPengiriman", { item: item })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text style={styles.detailButtonText}>Lihat Detail</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<Text style={styles.noItemsText}>
|
||||||
|
Tidak ada barang dalam status ini.
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#f9f9f9",
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 30,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
buttonRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
statusButton: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#333",
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 15,
|
||||||
|
borderRadius: 20,
|
||||||
|
width: "30%",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
selectedButton: {
|
||||||
|
backgroundColor: "#2D572C", // Green color for selected button
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
marginLeft: 5,
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
itemList: {
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
itemRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 15,
|
||||||
|
marginBottom: 15,
|
||||||
|
borderRadius: 8,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ddd",
|
||||||
|
},
|
||||||
|
itemImage: {
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderRadius: 5,
|
||||||
|
},
|
||||||
|
itemDetails: {
|
||||||
|
flex: 1,
|
||||||
|
marginLeft: 10,
|
||||||
|
},
|
||||||
|
itemName: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
itemTime: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#555",
|
||||||
|
marginTop: 5,
|
||||||
|
},
|
||||||
|
itemActions: {
|
||||||
|
alignItems: "flex-end",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
coinButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 15,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
coinButtonText: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#fff",
|
||||||
|
},
|
||||||
|
detailButton: {
|
||||||
|
backgroundColor: "#ddd",
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 15,
|
||||||
|
borderRadius: 25,
|
||||||
|
},
|
||||||
|
detailButtonText: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
noItemsText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#888",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default StatusPengirimanAdmin;
|
||||||
|
|
@ -0,0 +1,221 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
Alert,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons"; // Pastikan menggunakan Ionicons yang benar
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import MapView, { Marker } from "react-native-maps"; // Import MapView
|
||||||
|
import { Picker } from "@react-native-picker/picker"; // Hanya gunakan ini saja
|
||||||
|
|
||||||
|
const TambahTPS = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
// State untuk form input
|
||||||
|
const [namaTPS, setNamaTPS] = useState("");
|
||||||
|
const [luasTPS, setLuasTPS] = useState("");
|
||||||
|
const [dayaTampung, setDayaTampung] = useState("");
|
||||||
|
const [jenisTPS, setJenisTPS] = useState("Container");
|
||||||
|
const [alamat, setAlamat] = useState("");
|
||||||
|
const [kecamatan, setKecamatan] = useState("Nganjuk");
|
||||||
|
const [latitude, setLatitude] = useState(null);
|
||||||
|
const [longitude, setLongitude] = useState(null);
|
||||||
|
|
||||||
|
// Fungsi untuk menangani penyimpanan TPS baru
|
||||||
|
const handleTambahTPS = () => {
|
||||||
|
if (
|
||||||
|
!namaTPS ||
|
||||||
|
!luasTPS ||
|
||||||
|
!dayaTampung ||
|
||||||
|
!alamat ||
|
||||||
|
!latitude ||
|
||||||
|
!longitude
|
||||||
|
) {
|
||||||
|
Alert.alert("Form belum lengkap", "Mohon lengkapi semua data TPS.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aksi penyimpanan TPS baru (misalnya kirim ke backend atau state global)
|
||||||
|
Alert.alert("Berhasil", "TPS baru berhasil ditambahkan!");
|
||||||
|
|
||||||
|
// Kembali ke halaman daftar TPS
|
||||||
|
navigation.goBack();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>TAMBAH LOKASI TPS</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Form Input TPS */}
|
||||||
|
<View style={styles.formContainer}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Nama TPS"
|
||||||
|
value={namaTPS}
|
||||||
|
onChangeText={setNamaTPS}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Luas TPS (m2)"
|
||||||
|
value={luasTPS}
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={setLuasTPS}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Daya Tampung"
|
||||||
|
value={dayaTampung}
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={setDayaTampung}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text style={styles.label}>Pilih Jenis TPS</Text>
|
||||||
|
<Picker
|
||||||
|
selectedValue={jenisTPS}
|
||||||
|
style={styles.picker}
|
||||||
|
onValueChange={(itemValue) => setJenisTPS(itemValue)}
|
||||||
|
>
|
||||||
|
<Picker.Item label="Container" value="Container" />
|
||||||
|
<Picker.Item label="Depo Kecil" value="Depo Kecil" />
|
||||||
|
</Picker>
|
||||||
|
|
||||||
|
{/* Form Detail Lokasi */}
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Alamat"
|
||||||
|
value={alamat}
|
||||||
|
onChangeText={setAlamat}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text style={styles.label}>Pilih Kecamatan</Text>
|
||||||
|
<Picker
|
||||||
|
selectedValue={kecamatan}
|
||||||
|
style={styles.picker}
|
||||||
|
onValueChange={(itemValue) => setKecamatan(itemValue)}
|
||||||
|
>
|
||||||
|
<Picker.Item label="Nganjuk" value="Nganjuk" />
|
||||||
|
<Picker.Item label="Bagor" value="Bagor" />
|
||||||
|
<Picker.Item label="Wilangan" value="Wilangan" />
|
||||||
|
<Picker.Item label="Baron" value="Baron" />
|
||||||
|
</Picker>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Latitude"
|
||||||
|
value={latitude}
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={setLatitude}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Longitude"
|
||||||
|
value={longitude}
|
||||||
|
keyboardType="numeric"
|
||||||
|
onChangeText={setLongitude}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Peta */}
|
||||||
|
{latitude && longitude ? (
|
||||||
|
<MapView
|
||||||
|
style={styles.map}
|
||||||
|
initialRegion={{
|
||||||
|
latitude: parseFloat(latitude),
|
||||||
|
longitude: parseFloat(longitude),
|
||||||
|
latitudeDelta: 0.0922,
|
||||||
|
longitudeDelta: 0.0421,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Marker
|
||||||
|
coordinate={{
|
||||||
|
latitude: parseFloat(latitude),
|
||||||
|
longitude: parseFloat(longitude),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</MapView>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{/* Tombol Simpan */}
|
||||||
|
<TouchableOpacity style={styles.saveButton} onPress={handleTambahTPS}>
|
||||||
|
<Text style={styles.saveButtonText}>SIMPAN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 16,
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
marginTop: 40,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 20,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
formContainer: {
|
||||||
|
marginTop: -15,
|
||||||
|
padding: 15,
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ccc",
|
||||||
|
borderRadius: 8,
|
||||||
|
padding: 15,
|
||||||
|
marginBottom: 12,
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
picker: {
|
||||||
|
height: 50,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ccc",
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
map: {
|
||||||
|
height: 200,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
saveButton: {
|
||||||
|
width: "100%",
|
||||||
|
padding: 15,
|
||||||
|
backgroundColor: "#2D572C", // Warna hijau untuk tombol kirim
|
||||||
|
alignItems: "center",
|
||||||
|
borderRadius: 15,
|
||||||
|
},
|
||||||
|
saveButtonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default TambahTPS;
|
||||||
|
|
@ -0,0 +1,348 @@
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
Image,
|
||||||
|
ScrollView,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import BottomTabAdmin from "../../Navigation/BottomTabAdmin";
|
||||||
|
|
||||||
|
const TukarKoin = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [selectedButton, setSelectedButton] = useState("diproses");
|
||||||
|
const [selectedStatus, setSelectedStatus] = useState("diproses");
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Tas Kertas",
|
||||||
|
time: "10 April 2025 - 14:30",
|
||||||
|
status: "diproses",
|
||||||
|
imageUri: require("../../assets/images/tas2.png"),
|
||||||
|
user: {
|
||||||
|
profileImage: require("../../assets/images/fotoprofil.jpeg"),
|
||||||
|
fullName: "Budi Santoso",
|
||||||
|
address: "Jl. Merdeka No.10, Jakarta",
|
||||||
|
email: "budi@example.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Botol",
|
||||||
|
time: "11 April 2025 - 15:00",
|
||||||
|
status: "dikirim",
|
||||||
|
imageUri: require("../../assets/images/botol1.png"),
|
||||||
|
user: {
|
||||||
|
profileImage: require("../../assets/images/fotoprofil.jpeg"),
|
||||||
|
fullName: "Siti Rahma",
|
||||||
|
address: "Jl. Sudirman No.5, Bandung",
|
||||||
|
email: "siti@example.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Botol Anak",
|
||||||
|
time: "12 April 2025 - 16:30",
|
||||||
|
status: "diterima",
|
||||||
|
imageUri: require("../../assets/images/botol2.png"),
|
||||||
|
user: {
|
||||||
|
profileImage: require("../../assets/images/fotoprofil.jpeg"),
|
||||||
|
fullName: "Ahmad Rizki",
|
||||||
|
address: "Jl. Raya No.7, Surabaya",
|
||||||
|
email: "ahmad@example.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setSelectedButton("diproses");
|
||||||
|
setSelectedStatus("diproses");
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleButtonClick = (status) => {
|
||||||
|
setSelectedStatus(status);
|
||||||
|
setSelectedButton(status);
|
||||||
|
};
|
||||||
|
|
||||||
|
const filteredItems = items.filter((item) => item.status === selectedStatus);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<Text style={styles.title}>PENUKARAN KOIN</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Status Buttons */}
|
||||||
|
<View style={styles.buttonRow}>
|
||||||
|
{["diproses", "dikirim", "diterima"].map((status) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
key={status}
|
||||||
|
style={[
|
||||||
|
styles.statusButton,
|
||||||
|
selectedButton === status && styles.selectedButton,
|
||||||
|
]}
|
||||||
|
onPress={() => handleButtonClick(status)}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name={
|
||||||
|
status === "diproses"
|
||||||
|
? "sync"
|
||||||
|
: status === "dikirim"
|
||||||
|
? "paper-plane"
|
||||||
|
: "checkmark"
|
||||||
|
}
|
||||||
|
size={20}
|
||||||
|
color={selectedButton === status ? "#fff" : "#000"}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.buttonText,
|
||||||
|
selectedButton === status && { color: "#fff" },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{status.charAt(0).toUpperCase() + status.slice(1)}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Filtered List of Items */}
|
||||||
|
<ScrollView contentContainerStyle={styles.itemList}>
|
||||||
|
{filteredItems.length > 0 ? (
|
||||||
|
filteredItems.map((item) => (
|
||||||
|
<View key={item.id} style={styles.itemRow}>
|
||||||
|
<View style={styles.itemInfo}>
|
||||||
|
<Image source={item.imageUri} style={styles.itemImage} />
|
||||||
|
<View style={styles.itemDetails}>
|
||||||
|
<Text style={styles.itemName}>{item.name}</Text>
|
||||||
|
<Text style={styles.itemTime}>{item.time}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.itemActions}>
|
||||||
|
<View style={styles.coinButton}>
|
||||||
|
<Text style={styles.coinButtonText}>500 Koin</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.detailButton}
|
||||||
|
onPress={() =>
|
||||||
|
navigation.navigate("DetailPengirimanAdmin", { item })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text style={styles.detailButtonText}>Lihat Detail</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.userInfo}>
|
||||||
|
<Image
|
||||||
|
source={item.user.profileImage}
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
<View style={styles.userDetails}>
|
||||||
|
<Text style={styles.userName}>{item.user.fullName}</Text>
|
||||||
|
<Text style={styles.userAddress}>{item.user.address}</Text>
|
||||||
|
<Text style={styles.userEmail}>{item.user.email}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<Text style={styles.noItemsText}>
|
||||||
|
Tidak ada barang dalam status ini.
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
{/* Floating Daftar Barang Button */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.floatingButton}
|
||||||
|
onPress={() => navigation.navigate("DaftarBarang")}
|
||||||
|
>
|
||||||
|
<Ionicons name="add-circle-outline" size={24} color="#fff" />
|
||||||
|
<Text style={styles.floatingButtonText}>Daftar Barang</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* Bottom Navigation */}
|
||||||
|
<View style={styles.bottomNavigation}>
|
||||||
|
<BottomTabAdmin />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#f9f9f9",
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
paddingTop: 20,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
marginTop: 30,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
buttonRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
marginBottom: 25,
|
||||||
|
},
|
||||||
|
statusButton: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#2D572C",
|
||||||
|
paddingVertical: 12,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 25,
|
||||||
|
justifyContent: "center",
|
||||||
|
width: "30%",
|
||||||
|
},
|
||||||
|
selectedButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
marginLeft: 10,
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
itemList: {
|
||||||
|
paddingBottom: 120,
|
||||||
|
},
|
||||||
|
itemRow: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 20,
|
||||||
|
marginBottom: 20,
|
||||||
|
borderRadius: 15,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: 2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 5,
|
||||||
|
elevation: 3,
|
||||||
|
},
|
||||||
|
itemInfo: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
itemImage: {
|
||||||
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderRadius: 10,
|
||||||
|
},
|
||||||
|
itemDetails: {
|
||||||
|
flex: 1,
|
||||||
|
marginLeft: 15,
|
||||||
|
},
|
||||||
|
itemName: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
itemTime: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#777",
|
||||||
|
marginTop: 5,
|
||||||
|
},
|
||||||
|
itemActions: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
coinButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 5,
|
||||||
|
},
|
||||||
|
coinButtonText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#fff",
|
||||||
|
},
|
||||||
|
detailButton: {
|
||||||
|
backgroundColor: "#ddd",
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 25,
|
||||||
|
},
|
||||||
|
detailButtonText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
userInfo: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
borderTopWidth: 1,
|
||||||
|
borderTopColor: "#ddd",
|
||||||
|
paddingTop: 10,
|
||||||
|
},
|
||||||
|
profileImage: {
|
||||||
|
width: 45,
|
||||||
|
height: 45,
|
||||||
|
borderRadius: 25,
|
||||||
|
},
|
||||||
|
userDetails: {
|
||||||
|
marginLeft: 12,
|
||||||
|
},
|
||||||
|
userName: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
userAddress: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
userEmail: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
noItemsText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#888",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 30,
|
||||||
|
},
|
||||||
|
floatingButton: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 100,
|
||||||
|
right: 20,
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
paddingVertical: 12,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 30,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
floatingButtonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginLeft: 6,
|
||||||
|
},
|
||||||
|
bottomNavigation: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderTopWidth: 1,
|
||||||
|
borderTopColor: "#ddd",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default TukarKoin;
|
||||||
|
|
@ -0,0 +1,334 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
TextInput,
|
||||||
|
StyleSheet,
|
||||||
|
Image,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons, FontAwesome } from "@expo/vector-icons";
|
||||||
|
|
||||||
|
const AksesAkun = ({ navigation }) => {
|
||||||
|
const [role, setRole] = useState(null);
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [password, setPassword] = useState("");
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
const [errorMessage, setErrorMessage] = useState("");
|
||||||
|
|
||||||
|
const handleLogin = () => {
|
||||||
|
if (!role) {
|
||||||
|
setErrorMessage("Pilih dulu role Anda (Admin atau Warga)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!email || !password) {
|
||||||
|
setErrorMessage("Masukkan email dan kata sandi dengan benar");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
role === "admin" &&
|
||||||
|
email === "admin@gmail.com" &&
|
||||||
|
password === "1234"
|
||||||
|
) {
|
||||||
|
setErrorMessage("");
|
||||||
|
navigation.navigate("AksesAdminNavigator", { screen: "AdminScreen" });
|
||||||
|
} else if (
|
||||||
|
role === "warga" &&
|
||||||
|
email === "warga@gmail.com" &&
|
||||||
|
password === "1234"
|
||||||
|
) {
|
||||||
|
setErrorMessage("");
|
||||||
|
navigation.navigate("AksesWargaNavigator", { screen: "Home" });
|
||||||
|
} else {
|
||||||
|
setErrorMessage("Email atau kata sandi salah");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.navigate("Onboarding")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={30} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Image
|
||||||
|
style={styles.image}
|
||||||
|
source={require("../assets/images/sampah.png")}
|
||||||
|
resizeMode="contain"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text style={styles.welcomeText}>Selamat Datang kembali,</Text>
|
||||||
|
<Text style={styles.ecoMapperText}>EcoMapper !</Text>
|
||||||
|
|
||||||
|
<Text style={styles.label}>Pilih Akses</Text>
|
||||||
|
<View style={styles.buttonContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.roleButton,
|
||||||
|
role === "admin" && styles.roleButtonSelected,
|
||||||
|
]}
|
||||||
|
onPress={() => setRole("admin")}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name="person"
|
||||||
|
size={24}
|
||||||
|
color={role === "admin" ? "#fff" : "#000"}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.roleButtonText,
|
||||||
|
role === "admin" && styles.roleButtonTextSelected,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
ADMIN
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.roleButton,
|
||||||
|
role === "warga" && styles.roleButtonSelected,
|
||||||
|
]}
|
||||||
|
onPress={() => setRole("warga")}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name="people"
|
||||||
|
size={24}
|
||||||
|
color={role === "warga" ? "#fff" : "#000"}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.roleButtonText,
|
||||||
|
role === "warga" && styles.roleButtonTextSelected,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
WARGA
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Text style={styles.label}>Email</Text>
|
||||||
|
<View style={styles.inputContainer}>
|
||||||
|
<Ionicons name="mail" size={24} color="gray" style={styles.icon} />
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Masukkan email"
|
||||||
|
value={email}
|
||||||
|
onChangeText={setEmail}
|
||||||
|
keyboardType="email-address"
|
||||||
|
autoCapitalize="none"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Text style={styles.label}>Kata Sandi</Text>
|
||||||
|
<View style={styles.passwordContainer}>
|
||||||
|
<FontAwesome name="lock" size={24} color="gray" style={styles.icon} />
|
||||||
|
<TextInput
|
||||||
|
style={styles.passwordInput}
|
||||||
|
placeholder="Masukkan kata sandi"
|
||||||
|
secureTextEntry={!showPassword}
|
||||||
|
value={password}
|
||||||
|
onChangeText={setPassword}
|
||||||
|
autoCapitalize="none"
|
||||||
|
/>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.eyeIcon}
|
||||||
|
onPress={() => setShowPassword(!showPassword)}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name={showPassword ? "eye-off" : "eye"}
|
||||||
|
size={24}
|
||||||
|
color="gray"
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{errorMessage ? (
|
||||||
|
<Text style={styles.errorText}>{errorMessage}</Text>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.loginButton} onPress={handleLogin}>
|
||||||
|
<Text style={styles.loginButtonText}>Masuk</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* "Daftar Sekarang" Text */}
|
||||||
|
<View style={styles.registerContainer}>
|
||||||
|
<Text style={styles.registerText}>
|
||||||
|
Belum punya akun?{" "}
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() =>
|
||||||
|
navigation.navigate("AksesWargaNavigator", { screen: "daftar" })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text style={styles.registerLink}>Daftar Sekarang</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* "Lupa Kata Sandi?" Text */}
|
||||||
|
<View style={styles.forgotPasswordContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() =>
|
||||||
|
navigation.navigate("AksesWargaNavigator", { screen: "lupasandi" })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text style={styles.forgotPasswordText}>Lupa Kata Sandi?</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AksesAkun;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
position: "absolute",
|
||||||
|
top: 60, // sesuaikan dengan tinggi status bar dan padding
|
||||||
|
left: 20,
|
||||||
|
zIndex: 10,
|
||||||
|
padding: 6,
|
||||||
|
borderRadius: 6,
|
||||||
|
backgroundColor: "#fff", // warna soft supaya tombol terlihat
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: 2 },
|
||||||
|
shadowOpacity: 0.2,
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
width: 300,
|
||||||
|
height: 200,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
welcomeText: {
|
||||||
|
fontSize: 28,
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
ecoMapperText: {
|
||||||
|
fontSize: 34,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
marginBottom: 30,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
fontSize: 18,
|
||||||
|
alignSelf: "flex-start",
|
||||||
|
marginLeft: 10,
|
||||||
|
marginBottom: 10,
|
||||||
|
fontWeight: "600",
|
||||||
|
},
|
||||||
|
buttonContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
marginBottom: 30,
|
||||||
|
justifyContent: "center",
|
||||||
|
gap: 15,
|
||||||
|
},
|
||||||
|
roleButton: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#000",
|
||||||
|
borderRadius: 12,
|
||||||
|
paddingVertical: 15,
|
||||||
|
paddingHorizontal: 25,
|
||||||
|
marginHorizontal: 5,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
},
|
||||||
|
roleButtonSelected: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
borderColor: "#2D572C",
|
||||||
|
},
|
||||||
|
roleButtonText: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginLeft: 8,
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
roleButtonTextSelected: {
|
||||||
|
color: "#fff",
|
||||||
|
},
|
||||||
|
inputContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
borderColor: "#ddd",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 20,
|
||||||
|
paddingLeft: 10,
|
||||||
|
height: 50,
|
||||||
|
width: "100%",
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
flex: 1,
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
passwordContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
borderColor: "#ddd",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 40,
|
||||||
|
paddingLeft: 10,
|
||||||
|
height: 50,
|
||||||
|
width: "100%",
|
||||||
|
},
|
||||||
|
passwordInput: {
|
||||||
|
flex: 1,
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
eyeIcon: {
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
},
|
||||||
|
loginButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 15,
|
||||||
|
paddingHorizontal: 160,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
loginButtonText: {
|
||||||
|
color: "#fff",
|
||||||
|
textAlign: "center",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 20,
|
||||||
|
},
|
||||||
|
registerContainer: {
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
registerText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
registerLink: {
|
||||||
|
color: "#2D572C",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
forgotPasswordContainer: {
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
forgotPasswordText: {
|
||||||
|
color: "#2D572C",
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "center",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
errorText: {
|
||||||
|
color: "red",
|
||||||
|
fontSize: 15,
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,225 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, Text, StyleSheet, TouchableOpacity, Image } from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const BerandaPengaduan = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.navigate("Home")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.headerTitle}>BERANDA PENGADUAN</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* First Report */}
|
||||||
|
<View style={styles.reportContainer}>
|
||||||
|
<View style={styles.reportHeader}>
|
||||||
|
<View style={styles.profileContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://www.w3schools.com/howto/img_avatar.png", // Replace with actual profile picture URI
|
||||||
|
}}
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.reporterName}>Johan Okta Pangestu</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.time}>03/01/2025 10.12 WIB</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity style={styles.statusButton}>
|
||||||
|
<Text style={styles.reportStatus}>Sedang diverifikasi</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.reportDescription}>
|
||||||
|
Sampah numpuk di depan masjid - JI Letjen Sparman
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.reportNote}>
|
||||||
|
Catatan: Mohon segera ditindaklanjuti karena sangat mengganggu
|
||||||
|
masyarakat sekitar.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Images */}
|
||||||
|
<View style={styles.imageContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.arenalte.com/uploads/2019/07/sampah.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://www.storypick.com/wp-content/uploads/2019/06/waste.png",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Second Report */}
|
||||||
|
<View style={styles.reportContainer}>
|
||||||
|
<View style={styles.reportHeader}>
|
||||||
|
<View style={styles.profileContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://www.w3schools.com/howto/img_avatar2.png", // Replace with actual profile picture URI
|
||||||
|
}}
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.reporterName}>Jihan Pangesti</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.time}>03/01/2025 10.12 WIB</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity style={styles.statusButton}>
|
||||||
|
<Text style={styles.reportStatus}>Dalam Proses</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.reportDescription}>
|
||||||
|
Sampah berserakan di Pasar Lama - JI. Sukarno, Nganjuk
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.reportNote}>
|
||||||
|
Catatan: Mohon segera ditindaklanjuti karena sangat mengganggu
|
||||||
|
masyarakat sekitar.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Images */}
|
||||||
|
<View style={styles.imageContainer}>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.toiimg.com/thumb/msid-97714168,imgsize-1547670,width-400,resizemode-4/97714168.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
source={{
|
||||||
|
uri: "https://static.toiimg.com/thumb/msid-87155572,imgsize-1511223,width-400,resizemode-4/87155572.jpg",
|
||||||
|
}}
|
||||||
|
style={styles.reportImage}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Button to contribute */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.contributeButton}
|
||||||
|
onPress={() => navigation.navigate("KontribusiScreen")}
|
||||||
|
>
|
||||||
|
<Text style={styles.contributeText}>Kontribusi Sekarang</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 16,
|
||||||
|
marginTop: 40,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
headerTitle: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
reportContainer: {
|
||||||
|
marginBottom: 20,
|
||||||
|
padding: 12,
|
||||||
|
borderRadius: 15,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
borderColor: "#000",
|
||||||
|
},
|
||||||
|
reportHeader: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
paddingBottom: 10,
|
||||||
|
},
|
||||||
|
profileContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
profileImage: {
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
borderRadius: 20,
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
reporterName: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
statusButton: {
|
||||||
|
backgroundColor: "#DDD",
|
||||||
|
borderRadius: 8,
|
||||||
|
paddingVertical: 5,
|
||||||
|
paddingHorizontal: 5,
|
||||||
|
marginVertical: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "32%",
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
reportStatus: {
|
||||||
|
color: "#000",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
reportDescription: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
reportNote: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#000",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
imageContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
reportImage: {
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginRight: 5,
|
||||||
|
marginLeft: 5,
|
||||||
|
},
|
||||||
|
contributeButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "50%",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginLeft: 90,
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
contributeText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
coinText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default BerandaPengaduan;
|
||||||
|
|
@ -0,0 +1,236 @@
|
||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
Image,
|
||||||
|
ScrollView,
|
||||||
|
StyleSheet,
|
||||||
|
Alert,
|
||||||
|
} from "react-native";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import BottomNav from "../../Navigation/BottomNav";
|
||||||
|
|
||||||
|
const EcoMapCoinExchangeScreen = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const userCoin = 1350;
|
||||||
|
const expiredDate = "30 Mei 2025";
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Botol Minum",
|
||||||
|
coin: 300,
|
||||||
|
image: require("../../assets/images/botol1.png"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Botol Minum Anak",
|
||||||
|
coin: 350,
|
||||||
|
image: require("../../assets/images/botol2.png"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Tas Belanja",
|
||||||
|
coin: 250,
|
||||||
|
image: require("../../assets/images/tas2.png"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: "Peralatan Makan",
|
||||||
|
coin: 400,
|
||||||
|
image: require("../../assets/images/alatmakan.png"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleExchange = (item) => {
|
||||||
|
if (userCoin >= item.coin) {
|
||||||
|
Alert.alert(
|
||||||
|
"Konfirmasi Penukaran",
|
||||||
|
`Anda yakin ingin menukar ${item.coin} koin untuk mendapatkan ${item.name}?`,
|
||||||
|
[
|
||||||
|
{ text: "Batal", style: "cancel" },
|
||||||
|
{
|
||||||
|
text: "Ya",
|
||||||
|
onPress: () => {
|
||||||
|
Alert.alert(
|
||||||
|
"Berhasil",
|
||||||
|
`Kamu telah menukar ${item.name} dengan ${item.coin} Koin.`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Alert.alert(
|
||||||
|
"Koin Tidak Cukup",
|
||||||
|
"Silakan kumpulkan koin terlebih dahulu."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={{ flex: 1, backgroundColor: "#fff" }}>
|
||||||
|
<ScrollView contentContainerStyle={styles.container}>
|
||||||
|
<Text style={styles.title}>TUKAR KOIN</Text>
|
||||||
|
|
||||||
|
<View style={styles.coinBox}>
|
||||||
|
<View style={styles.coinInfoColumn}>
|
||||||
|
<Text style={styles.coinAmount}>
|
||||||
|
<Text style={styles.coinIcon}></Text> {userCoin}{" "}
|
||||||
|
<Text style={styles.coinText}>Koin EcoMap</Text>
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.expiryText}>
|
||||||
|
{userCoin} Koin EcoMap kadaluwarsa pada {expiredDate}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.coinInfoRow}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.getCoinBtn}
|
||||||
|
onPress={() => navigation.navigate("misimingguan")}
|
||||||
|
>
|
||||||
|
<Text style={styles.getCoinText}>Dapatkan Koin</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.itemGrid}>
|
||||||
|
{items.map((item) => (
|
||||||
|
<View key={item.id} style={styles.itemCard}>
|
||||||
|
<Image source={item.image} style={styles.itemImage} />
|
||||||
|
<Text style={styles.itemName}>{item.name}</Text>
|
||||||
|
<View style={styles.coinBoxItem}>
|
||||||
|
<Text style={styles.itemCoin}>{item.coin} Koin</Text>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.exchangeBtn}
|
||||||
|
onPress={() => handleExchange(item)}
|
||||||
|
>
|
||||||
|
<Text style={styles.exchangeText}>Tukar Koin</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
{/* BottomNav harus di luar ScrollView supaya fixed */}
|
||||||
|
<BottomNav />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
padding: 20,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
width: "100%",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
marginBottom: 20,
|
||||||
|
textAlign: "left",
|
||||||
|
marginLeft: 10,
|
||||||
|
marginTop: 40,
|
||||||
|
},
|
||||||
|
coinBox: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ccc",
|
||||||
|
padding: 15,
|
||||||
|
borderRadius: 10,
|
||||||
|
marginBottom: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
},
|
||||||
|
coinInfoColumn: {
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
},
|
||||||
|
coinAmount: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#d4af37",
|
||||||
|
},
|
||||||
|
coinIcon: {
|
||||||
|
fontSize: 22,
|
||||||
|
},
|
||||||
|
coinText: {
|
||||||
|
color: "#2f4f2f",
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
expiryText: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#888",
|
||||||
|
marginTop: 5,
|
||||||
|
},
|
||||||
|
coinInfoRow: {
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
getCoinBtn: {
|
||||||
|
backgroundColor: "#d4af37",
|
||||||
|
paddingVertical: 6,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 8,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#000",
|
||||||
|
},
|
||||||
|
getCoinText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
itemGrid: {
|
||||||
|
flexDirection: "row",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
},
|
||||||
|
itemCard: {
|
||||||
|
width: "48%",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ccc",
|
||||||
|
borderRadius: 12,
|
||||||
|
padding: 8,
|
||||||
|
marginBottom: 15,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
itemImage: {
|
||||||
|
width: 70,
|
||||||
|
height: 100,
|
||||||
|
resizeMode: "contain",
|
||||||
|
},
|
||||||
|
itemName: {
|
||||||
|
marginTop: 10,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
coinBoxItem: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 6,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginVertical: 6,
|
||||||
|
},
|
||||||
|
itemCoin: {
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 18,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
exchangeBtn: {
|
||||||
|
backgroundColor: "#e2e2e2",
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
paddingVertical: 6,
|
||||||
|
borderRadius: 6,
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
exchangeText: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default EcoMapCoinExchangeScreen;
|
||||||
|
|
@ -0,0 +1,415 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
Image,
|
||||||
|
TouchableOpacity,
|
||||||
|
ImageBackground,
|
||||||
|
Dimensions,
|
||||||
|
} from "react-native";
|
||||||
|
import {
|
||||||
|
Ionicons,
|
||||||
|
FontAwesome5,
|
||||||
|
MaterialCommunityIcons,
|
||||||
|
} from "@expo/vector-icons";
|
||||||
|
|
||||||
|
import Carousel from "react-native-reanimated-carousel";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import BottomNav from "../../Navigation/BottomNav";
|
||||||
|
|
||||||
|
const { width } = Dimensions.get("window"); // Get the screen width
|
||||||
|
|
||||||
|
const Home = () => {
|
||||||
|
// const navigate = (route) => navigation.navigate(route);
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [activeSlide, setActiveSlide] = useState(0);
|
||||||
|
|
||||||
|
const sliderData = [
|
||||||
|
{ id: "1", image: require("../../assets/images/poster1.png") },
|
||||||
|
{ id: "2", image: require("../../assets/images/poster2.png") },
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleNext = () => {
|
||||||
|
navigation.navigate(""); // Add the name of the screen to navigate
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<ImageBackground
|
||||||
|
source={require("../../assets/images/bg.png")}
|
||||||
|
style={styles.backgroundImage}
|
||||||
|
>
|
||||||
|
<View style={styles.header}>
|
||||||
|
<Text style={styles.date}>05 Mei 2024</Text>
|
||||||
|
<Text style={styles.greeting}>
|
||||||
|
HI, PENGGUNA ECOMAP{" "}
|
||||||
|
<Ionicons name="checkmark-circle" size={18} color="green" />
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.subtitle}>
|
||||||
|
KEBERSIHAN LINGKUNGAN SEKITAR ANDA WAJIB TERJAGA!
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.coinRow}>
|
||||||
|
<View style={styles.coinInfo}>
|
||||||
|
<View style={styles.coinBox}>
|
||||||
|
<Text style={styles.coinLabel}>KOIN SAYA</Text>
|
||||||
|
<View style={styles.coinValueRow}>
|
||||||
|
<Text style={styles.coinText}>0</Text>
|
||||||
|
<Image
|
||||||
|
source={require("../../assets/images/koin.png")}
|
||||||
|
style={styles.coinImage}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.noCoinText}>
|
||||||
|
Belum ada koin yang terkumpul
|
||||||
|
</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.historyButton}
|
||||||
|
onPress={() => navigation.navigate("RiwayatCoinScreen")} // Ganti dengan nama layar yang sesuai
|
||||||
|
>
|
||||||
|
<Text style={styles.historyButtonText}>RIWAYAT KOIN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.reportButton}
|
||||||
|
onPress={() => navigation.navigate("BerandaPengaduan")}
|
||||||
|
>
|
||||||
|
<Text style={styles.reportButtonText}>BERANDA PENGADUAN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.menuContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.menuItem}
|
||||||
|
onPress={() => navigation.navigate("LokasiTerdekat")}
|
||||||
|
// onPress={() =>
|
||||||
|
// navigation.navigate("MainTabs", { screen: "LokasiTerdekat" })
|
||||||
|
// } // Buka MainTabs, lalu LokasiTerdekat
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name="location"
|
||||||
|
size={45}
|
||||||
|
color="#2C6B2F"
|
||||||
|
style={styles.menuImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.menuText}>LOKASI TERDEKAT</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.menuItem}
|
||||||
|
onPress={() => navigation.navigate("daftarTPS")}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name="bookmarks"
|
||||||
|
size={45}
|
||||||
|
color="#2C6B2F"
|
||||||
|
style={styles.menuImage}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text style={styles.menuText}>DAFTAR TPS DI NGANJUK</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.menuItem}
|
||||||
|
onPress={() => navigation.navigate("pengaduansampah")}
|
||||||
|
>
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name="trash-can"
|
||||||
|
size={50}
|
||||||
|
color="#2C6B2F"
|
||||||
|
style={styles.menuImage}
|
||||||
|
/>
|
||||||
|
{/* <View style={styles.badge}>
|
||||||
|
<FontAwesome5
|
||||||
|
name="lock"
|
||||||
|
size={12}
|
||||||
|
color="#fff"
|
||||||
|
style={styles.lock}
|
||||||
|
/>
|
||||||
|
</View> */}
|
||||||
|
<Text style={styles.menuText}>PENGADUAN SAMPAH</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.menuItem}
|
||||||
|
onPress={() => navigation.navigate("misimingguan")}
|
||||||
|
>
|
||||||
|
<FontAwesome5
|
||||||
|
name="gift"
|
||||||
|
size={45}
|
||||||
|
color="#2C6B2F"
|
||||||
|
style={styles.menuImage}
|
||||||
|
/>
|
||||||
|
{/* <View style={styles.badge}>
|
||||||
|
<FontAwesome5
|
||||||
|
name="lock"
|
||||||
|
size={12}
|
||||||
|
color="#fff"
|
||||||
|
style={styles.lock}
|
||||||
|
/>
|
||||||
|
</View> */}
|
||||||
|
<Text style={styles.menuText}>DAPATKAN KOIN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={{ marginTop: 20 }}>
|
||||||
|
<Carousel
|
||||||
|
loop
|
||||||
|
autoPlay={true}
|
||||||
|
autoPlayInterval={3000}
|
||||||
|
width={width} // Use screen width here
|
||||||
|
height={180}
|
||||||
|
data={sliderData}
|
||||||
|
scrollAnimationDuration={1000}
|
||||||
|
onSnapToItem={(index) => setActiveSlide(index)}
|
||||||
|
renderItem={({ item }) => (
|
||||||
|
<Image
|
||||||
|
source={item.image}
|
||||||
|
style={styles.sliderImage}
|
||||||
|
resizeMode="cover"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</ImageBackground>
|
||||||
|
<BottomNav />
|
||||||
|
{/* <View style={styles.bottomNav}>
|
||||||
|
<TouchableOpacity style={styles.navItem}>
|
||||||
|
<Ionicons name="home" size={30} color="#2C6B2F" />
|
||||||
|
<Text style={styles.navText}>UTAMA</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.navItem}
|
||||||
|
onPress={() => navigation.navigate("EcoMapCoinExchangeScreen")}
|
||||||
|
>
|
||||||
|
<FontAwesome5 name="exchange-alt" size={24} color="#2C6B2F" />
|
||||||
|
<Text style={styles.navText}>TUKAR KOIN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.navItem}>
|
||||||
|
<View style={styles.notifIconContainer}>
|
||||||
|
<Ionicons name="notifications-outline" size={24} color="#2C6B2F" />
|
||||||
|
<View style={styles.badge}>
|
||||||
|
<Text style={styles.badgeText}>1</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.navText}>NOTIFIKASI</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.navItem}>
|
||||||
|
<Ionicons name="person-circle-outline" size={24} color="#2C6B2F" />
|
||||||
|
<Text style={styles.navText}>PROFIL</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View> */}
|
||||||
|
</View>
|
||||||
|
// </View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: { flex: 1, backgroundColor: "#f9f9f9" },
|
||||||
|
backgroundImage: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
paddingLeft: 10,
|
||||||
|
paddingRight: 10,
|
||||||
|
paddingTop: 0,
|
||||||
|
},
|
||||||
|
header: { marginTop: 10, alignItems: "flex-start", paddingBottom: 5 },
|
||||||
|
date: { fontSize: 20, color: "#000", paddingLeft: 20, marginTop: 20 },
|
||||||
|
greeting: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginTop: 0,
|
||||||
|
color: "#333",
|
||||||
|
paddingLeft: 20,
|
||||||
|
},
|
||||||
|
subtitle: {
|
||||||
|
fontSize: 15,
|
||||||
|
color: "#27AE60",
|
||||||
|
fontWeight: "600",
|
||||||
|
paddingLeft: 20,
|
||||||
|
},
|
||||||
|
coinRow: {
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
alignItems: "center",
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
|
||||||
|
coinInfo: { alignItems: "flex-start" },
|
||||||
|
coinLabel: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "700",
|
||||||
|
color: "#333",
|
||||||
|
marginBottom: 0,
|
||||||
|
marginLeft: -100,
|
||||||
|
},
|
||||||
|
coinBox: {
|
||||||
|
marginVertical: 10,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingHorizontal: 130,
|
||||||
|
paddingVertical: 15,
|
||||||
|
borderRadius: 20,
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
elevation: 1,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#aaa",
|
||||||
|
position: "relative",
|
||||||
|
},
|
||||||
|
coinValueRow: { flexDirection: "row", alignItems: "center", marginTop: 10 },
|
||||||
|
coinText: {
|
||||||
|
fontSize: 30,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
textAlign: "left",
|
||||||
|
marginLeft: -100,
|
||||||
|
},
|
||||||
|
coinImage: { width: 24, height: 24, marginLeft: 6 },
|
||||||
|
|
||||||
|
noCoinText: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#aaa",
|
||||||
|
marginTop: 5,
|
||||||
|
textAlign: "left",
|
||||||
|
marginLeft: -100,
|
||||||
|
},
|
||||||
|
historyButton: {
|
||||||
|
position: "absolute",
|
||||||
|
backgroundColor: "#27AE60", // Sesuaikan dengan warna yang diinginkan
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
borderRadius: 20,
|
||||||
|
top: -6,
|
||||||
|
right: 10,
|
||||||
|
marginTop: 15, // Spasi antara tombol dan teks
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
width: "100%", // Lebar penuh box
|
||||||
|
elevation: 1, // Tambahkan sedikit bayangan
|
||||||
|
},
|
||||||
|
historyButtonText: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#fff",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
|
||||||
|
reportButton: {
|
||||||
|
backgroundColor: "#DCDCDC",
|
||||||
|
paddingVertical: 15, // Adjust padding for a more rectangular shape
|
||||||
|
paddingHorizontal: 10, // Increase horizontal padding to make it look like a rectangle
|
||||||
|
borderRadius: 20, // Keep the border radius low for a rectangular shape
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#999",
|
||||||
|
width: "80%", // Take up full width inside the box
|
||||||
|
marginTop: 10,
|
||||||
|
paddingLeft: 5, // Add some spacing between the content
|
||||||
|
},
|
||||||
|
reportButtonText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
menuImage: {
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
marginLeft: 3,
|
||||||
|
marginBottom: 5,
|
||||||
|
marginTop: 7,
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
menuContainer: {
|
||||||
|
marginTop: 5,
|
||||||
|
marginRight: 5,
|
||||||
|
marginLeft: 12,
|
||||||
|
flexDirection: "row",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
paddingRight: 15,
|
||||||
|
},
|
||||||
|
menuItem: {
|
||||||
|
width: "23%",
|
||||||
|
alignItems: "center",
|
||||||
|
marginVertical: 10,
|
||||||
|
padding: 10,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ddd",
|
||||||
|
borderRadius: 25,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
elevation: 2,
|
||||||
|
},
|
||||||
|
menuText: {
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: "500",
|
||||||
|
color: "#333",
|
||||||
|
marginTop: 8,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
sliderImage: {
|
||||||
|
height: 160,
|
||||||
|
borderRadius: 19,
|
||||||
|
width: "80%",
|
||||||
|
alignSelf: "center",
|
||||||
|
marginRight: 25,
|
||||||
|
},
|
||||||
|
bottomNav: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: -10,
|
||||||
|
|
||||||
|
width: "100%",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: -2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 6,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
navItem: {
|
||||||
|
alignItems: "center",
|
||||||
|
padding: 6,
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
paddingVertical: 5,
|
||||||
|
marginHorizontal: 5,
|
||||||
|
},
|
||||||
|
navText: { color: "#2C6B2F", fontSize: 12, marginTop: 5 },
|
||||||
|
notifIconContainer: { position: "relative" },
|
||||||
|
badge: {
|
||||||
|
position: "absolute",
|
||||||
|
right: -5,
|
||||||
|
top: -5,
|
||||||
|
backgroundColor: "#E74C3C",
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 6,
|
||||||
|
paddingVertical: 2,
|
||||||
|
},
|
||||||
|
lock: {
|
||||||
|
position: "absolute",
|
||||||
|
right: -5,
|
||||||
|
top: -5,
|
||||||
|
backgroundColor: "#2C6B2F",
|
||||||
|
borderRadius: 40,
|
||||||
|
paddingHorizontal: 8,
|
||||||
|
paddingVertical: 5,
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
badgeText: { color: "#fff", fontSize: 10, fontWeight: "bold" },
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Home;
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
Dimensions,
|
||||||
|
TouchableOpacity,
|
||||||
|
} from "react-native";
|
||||||
|
import MapView, { Marker } from "react-native-maps";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
// Koordinat awal Nganjuk (misal: Alun-Alun Nganjuk)
|
||||||
|
const initialRegion = {
|
||||||
|
latitude: -7.6079,
|
||||||
|
longitude: 111.903,
|
||||||
|
latitudeDelta: 0.05,
|
||||||
|
longitudeDelta: 0.05,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Contoh lokasi TPS di Nganjuk
|
||||||
|
const locations = [
|
||||||
|
{ id: 1, name: "TPS Alun-Alun", latitude: -7.6085, longitude: 111.9012 },
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "TPS Jl. Gatot Subroto",
|
||||||
|
latitude: -7.6102,
|
||||||
|
longitude: 111.9051,
|
||||||
|
},
|
||||||
|
{ id: 3, name: "TPS Pasar Wage", latitude: -7.6055, longitude: 111.9083 },
|
||||||
|
];
|
||||||
|
|
||||||
|
const LokasiTerdekat = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [region, setRegion] = useState(initialRegion);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.navigate("Home")}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>LOKASI TERDEKAT</Text>
|
||||||
|
<View style={{ width: 28 }} /> {/* Spacer untuk keseimbangan header */}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* MapView */}
|
||||||
|
<MapView
|
||||||
|
style={styles.map}
|
||||||
|
region={region}
|
||||||
|
onRegionChangeComplete={(newRegion) => setRegion(newRegion)}
|
||||||
|
>
|
||||||
|
{locations.map((location) => (
|
||||||
|
<Marker
|
||||||
|
key={location.id}
|
||||||
|
coordinate={{
|
||||||
|
latitude: location.latitude,
|
||||||
|
longitude: location.longitude,
|
||||||
|
}}
|
||||||
|
title={location.name}
|
||||||
|
description={`Lat: ${location.latitude}, Lng: ${location.longitude}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</MapView>
|
||||||
|
|
||||||
|
{/* Deskripsi */}
|
||||||
|
<Text style={styles.description}>
|
||||||
|
Menampilkan lokasi TPS terdekat di wilayah Nganjuk.
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingTop: 40,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
padding: 8,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "left",
|
||||||
|
marginRight: 160,
|
||||||
|
},
|
||||||
|
map: {
|
||||||
|
width: Dimensions.get("window").width,
|
||||||
|
height: 800,
|
||||||
|
// width: 500,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#555",
|
||||||
|
marginTop: 16,
|
||||||
|
textAlign: "center",
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default LokasiTerdekat;
|
||||||
|
|
@ -0,0 +1,164 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, Text, StyleSheet, ScrollView } from "react-native";
|
||||||
|
import { Ionicons, MaterialIcons } from "@expo/vector-icons"; // Importing icons
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import BottomNav from "../../Navigation/BottomNav";
|
||||||
|
|
||||||
|
const NotifikasiScreen = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
const currentDate = new Date();
|
||||||
|
const formattedDate = `${currentDate.toLocaleDateString()} ${currentDate.toLocaleTimeString()}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<ScrollView style={styles.scrollContainer}>
|
||||||
|
{/* Back Button */}
|
||||||
|
<View>
|
||||||
|
<Text style={styles.title}>NOTIFIKASI</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Notification 1: New Report */}
|
||||||
|
<View style={styles.notification}>
|
||||||
|
<MaterialIcons name="notifications" size={24} color="#ff9f00" />
|
||||||
|
<View style={styles.notificationText}>
|
||||||
|
<Text style={styles.notificationTitle}>Ada laporan baru!</Text>
|
||||||
|
<Text style={styles.notificationDescription}>
|
||||||
|
Tim kami sedang meninjau pengaduan sampah terbaru. Terima kasih
|
||||||
|
atas partisipasi Anda!
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDate}>{formattedDate}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Notification 2: New Trash Pickup Location */}
|
||||||
|
<View style={styles.notification}>
|
||||||
|
<Ionicons name="location-sharp" size={24} color="#27ae60" />
|
||||||
|
<View style={styles.notificationText}>
|
||||||
|
<Text style={styles.notificationTitle}>
|
||||||
|
TPS baru telah ditambahkan!
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDescription}>
|
||||||
|
Sekarang Anda bisa menemukan lebih banyak lokasi pembuangan sampah
|
||||||
|
terdekat di EcoMap.
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDate}>{formattedDate}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Notification 3: Duplicate Example */}
|
||||||
|
<View style={styles.notification}>
|
||||||
|
<Ionicons name="location-sharp" size={24} color="#27ae60" />
|
||||||
|
<View style={styles.notificationText}>
|
||||||
|
<Text style={styles.notificationTitle}>
|
||||||
|
TPS baru telah ditambahkan!
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDescription}>
|
||||||
|
Sekarang Anda bisa menemukan lebih banyak lokasi pembuangan sampah
|
||||||
|
terdekat di EcoMap.
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDate}>{formattedDate}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Notification 4: Another Example */}
|
||||||
|
<View style={styles.notification}>
|
||||||
|
<Ionicons name="location-sharp" size={24} color="#27ae60" />
|
||||||
|
<View style={styles.notificationText}>
|
||||||
|
<Text style={styles.notificationTitle}>
|
||||||
|
TPS baru telah ditambahkan!
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDescription}>
|
||||||
|
Sekarang Anda bisa menemukan lebih banyak lokasi pembuangan sampah
|
||||||
|
terdekat di EcoMap.
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.notificationDate}>{formattedDate}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
{/* Bottom Navigation */}
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 0,
|
||||||
|
left: 0, // kasih sedikit ruang kiri supaya agak geser ke kanan
|
||||||
|
right: 0, // beri ruang kanan biar tidak penuh
|
||||||
|
height: 60,
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: -2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 6,
|
||||||
|
elevation: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BottomNav />
|
||||||
|
</View>{" "}
|
||||||
|
{/* Pastikan tag View ditutup dengan benar */}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1, // Flex untuk menutupi seluruh layar
|
||||||
|
backgroundColor: "#f9f9f9",
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
paddingTop: 20,
|
||||||
|
},
|
||||||
|
scrollContainer: {
|
||||||
|
flex: 1, // Agar ScrollView mengisi ruang yang tersisa
|
||||||
|
},
|
||||||
|
backButtonContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
marginLeft: 10,
|
||||||
|
marginBottom: 20,
|
||||||
|
marginTop: 40,
|
||||||
|
},
|
||||||
|
notification: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 15,
|
||||||
|
marginBottom: 15,
|
||||||
|
borderRadius: 8,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ddd",
|
||||||
|
},
|
||||||
|
notificationText: {
|
||||||
|
marginLeft: 15,
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
notificationTitle: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
notificationDescription: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
notificationDate: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#888", // Lighter color for date
|
||||||
|
marginTop: 5,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default NotifikasiScreen;
|
||||||
|
|
@ -0,0 +1,206 @@
|
||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
TouchableOpacity,
|
||||||
|
Image,
|
||||||
|
Alert,
|
||||||
|
Share,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import BottomNav from "../../Navigation/BottomNav";
|
||||||
|
|
||||||
|
const ProfilScreen = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
const handleLogout = () => {
|
||||||
|
Alert.alert("Konfirmasi", "Anda yakin ingin keluar?", [
|
||||||
|
{ text: "Batal" },
|
||||||
|
{ text: "Keluar", onPress: () => navigation.replace("AksesAkun") },
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleShare = async () => {
|
||||||
|
try {
|
||||||
|
await Share.share({
|
||||||
|
message: "Lihat aplikasi lingkungan ini!",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error sharing: ", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Header dengan Foto Profil */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<View style={styles.profileInfo}>
|
||||||
|
<Image
|
||||||
|
source={require("../../assets/images/fotoprofil.jpeg")}
|
||||||
|
style={styles.profileImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.profileName}>Hi Dina 👋</Text>
|
||||||
|
<Text style={styles.environmentStatus}>
|
||||||
|
Terus jaga lingkungan sekitar agar tetap hijau dan asri! 🌱
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Info dan Motivasi */}
|
||||||
|
<View style={styles.motivationSection}>
|
||||||
|
<Text style={styles.motivationText}>PAHLAWAN LINGKUNGAN</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Tombol dan Informasi */}
|
||||||
|
<View style={styles.buttonContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate("InformasiPribadiStackScreen", {
|
||||||
|
screen: "InformasiPribadi",
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons name="person-outline" size={24} color="black" />
|
||||||
|
<Text style={styles.buttonText}>Informasi Pribadi</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate("StatusPenukaranKoinStackScreen", {
|
||||||
|
screen: "StatusPengirimanScreen",
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons name="cash-outline" size={24} color="black" />
|
||||||
|
<Text style={styles.buttonText}>Status Penukaran Koin</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.navigate("StatusPengaduanStack", {
|
||||||
|
screen: "StatusPengaduanStack",
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons name="alert-circle-outline" size={24} color="black" />
|
||||||
|
<Text style={styles.buttonText}>Status Pengaduan</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() => {
|
||||||
|
navigation.replace("DonasiStackScreen");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons name="heart-outline" size={24} color="black" />
|
||||||
|
<Text style={styles.buttonText}>Donasi</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.button} onPress={handleShare}>
|
||||||
|
<Ionicons name="share-social-outline" size={24} color="black" />
|
||||||
|
<Text style={styles.buttonText}>Bagikan ke Media Sosial</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity style={styles.button} onPress={handleLogout}>
|
||||||
|
<Ionicons name="log-out-outline" size={24} color="black" />
|
||||||
|
<Text style={styles.buttonText}>Keluar Akun</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Bottom Navigation */}
|
||||||
|
<View style={styles.bottomNavContainer}>
|
||||||
|
<BottomNav />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
profileImage: {
|
||||||
|
width: 150,
|
||||||
|
height: 150,
|
||||||
|
borderRadius: 100,
|
||||||
|
borderWidth: 5,
|
||||||
|
borderColor: "#388e3c",
|
||||||
|
marginBottom: 10,
|
||||||
|
marginTop: 50,
|
||||||
|
},
|
||||||
|
profileInfo: {
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
profileName: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
environmentStatus: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#2e7d32",
|
||||||
|
marginTop: 5,
|
||||||
|
fontStyle: "italic",
|
||||||
|
},
|
||||||
|
motivationSection: {
|
||||||
|
marginTop: 10,
|
||||||
|
backgroundColor: "#f0f0f0",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 12,
|
||||||
|
marginBottom: 10,
|
||||||
|
marginRight: 100,
|
||||||
|
marginLeft: 100,
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
motivationText: {
|
||||||
|
fontSize: 15,
|
||||||
|
color: "#000",
|
||||||
|
textAlign: "center",
|
||||||
|
fontWeight: "600",
|
||||||
|
},
|
||||||
|
buttonContainer: {
|
||||||
|
marginTop: 20,
|
||||||
|
marginLeft: 10,
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
paddingVertical: 12,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: "#ddd",
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
marginLeft: 10,
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
bottomNavContainer: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
height: 60,
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: -2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 6,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ProfilScreen;
|
||||||
|
|
@ -0,0 +1,148 @@
|
||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
ScrollView,
|
||||||
|
StyleSheet,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons"; // Import Ionicons untuk icon kembali
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
const transactions = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
type: "Penukaran Koin",
|
||||||
|
amount: -250,
|
||||||
|
date: "2025-04-25 10:30",
|
||||||
|
description: "Tukar dengan Tas Belanja",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
type: "Penukaran Koin",
|
||||||
|
amount: -150,
|
||||||
|
date: "2025-04-26 14:00",
|
||||||
|
description: "Tukar dengan Botol Minum",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
type: "Penukaran Koin",
|
||||||
|
amount: -350,
|
||||||
|
date: "2025-04-27 08:15",
|
||||||
|
description: "Tukar dengan Peralatan Makan",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function RiwayatCoinScreen() {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
return (
|
||||||
|
<ScrollView contentContainerStyle={styles.container}>
|
||||||
|
{/* Tombol Kembali */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()} // Kembali ke halaman sebelumnya
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={30} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* Judul */}
|
||||||
|
<Text style={styles.title}>RIWAYAT KOIN</Text>
|
||||||
|
|
||||||
|
{/* Kolom Riwayat Transaksi */}
|
||||||
|
<View style={styles.historyBox}>
|
||||||
|
{transactions.map((transaction) => (
|
||||||
|
<View key={transaction.id} style={styles.transactionView}>
|
||||||
|
<View style={styles.transactionContent}>
|
||||||
|
{/* Deskripsi Transaksi */}
|
||||||
|
<View style={styles.leftColumn}>
|
||||||
|
<Text style={styles.transactionType}>{transaction.type}</Text>
|
||||||
|
<Text style={styles.transactionDescription}>
|
||||||
|
{transaction.description}
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.transactionDate}>{transaction.date}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Jumlah Koin */}
|
||||||
|
<View style={styles.rightColumn}>
|
||||||
|
<Text style={styles.transactionAmount}>
|
||||||
|
{transaction.amount} Koin
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
padding: 20,
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
position: "absolute",
|
||||||
|
top: 20,
|
||||||
|
left: 10,
|
||||||
|
zIndex: 1,
|
||||||
|
marginTop: 30,
|
||||||
|
// Menempatkan tombol di atas komponen lainnya
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
marginBottom: 5,
|
||||||
|
textAlign: "center",
|
||||||
|
marginRight: 200,
|
||||||
|
marginTop: 30,
|
||||||
|
},
|
||||||
|
historyBox: {
|
||||||
|
marginTop: 10,
|
||||||
|
paddingBottom: 5,
|
||||||
|
},
|
||||||
|
transactionView: {
|
||||||
|
backgroundColor: "#fff", // Warna latar belakang kotak
|
||||||
|
borderRadius: 20,
|
||||||
|
marginVertical: 10,
|
||||||
|
padding: 15,
|
||||||
|
flexDirection: "row", // Menyusun elemen secara horizontal
|
||||||
|
justifyContent: "space-between", // Membuat kedua kolom terpisah
|
||||||
|
alignItems: "center",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#000",
|
||||||
|
},
|
||||||
|
transactionContent: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
width: "100%",
|
||||||
|
},
|
||||||
|
leftColumn: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
rightColumn: {
|
||||||
|
alignItems: "flex-end", // Memposisikan kanan
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
transactionType: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
transactionDescription: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
transactionDate: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#888",
|
||||||
|
},
|
||||||
|
transactionAmount: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#4F772D", // Warna merah untuk pengurangan koin
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,305 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
TouchableOpacity,
|
||||||
|
ScrollView,
|
||||||
|
Image,
|
||||||
|
} from "react-native";
|
||||||
|
import Icon from "react-native-vector-icons/Ionicons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const users = [
|
||||||
|
{ name: "Diana Fitri Nur Aini", coins: 5000, rank: 1, color: "#A30000" },
|
||||||
|
{ name: "Revan Ilyas Fatoni", coins: 4800, rank: 2, color: "#FFD700" },
|
||||||
|
{ name: "Alena Syahwa", coins: 4350, rank: 3, color: "#228B22" },
|
||||||
|
{ name: "Dina Dwi Anisa", coins: 0, rank: "-", color: "#aaa" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const misimingguan = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [completedDays, setCompletedDays] = useState([]);
|
||||||
|
const [totalCoins, setTotalCoins] = useState(0);
|
||||||
|
|
||||||
|
// Function to mark a day as completed
|
||||||
|
const handleDayClick = (day, points) => {
|
||||||
|
if (!completedDays.includes(day)) {
|
||||||
|
setCompletedDays([...completedDays, day]);
|
||||||
|
setTotalCoins(totalCoins + points);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if the day is completed once
|
||||||
|
const isCompleted = (day) => completedDays.includes(day);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView contentContainerStyle={styles.container}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => navigation.navigate("Home")}
|
||||||
|
style={styles.backButton}
|
||||||
|
>
|
||||||
|
<Icon name="arrow-back" size={24} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<View style={styles.headerTitle}>
|
||||||
|
<Text style={styles.titleText}>DAPATKAN KOIN</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Subtitle */}
|
||||||
|
<Text style={styles.subTitle}>
|
||||||
|
Dapatkan Koin <Text style={{ color: "red" }}>LEBIH BANYAK</Text>
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.koinText}>
|
||||||
|
Koin Terkumpul{" "}
|
||||||
|
<Text style={{ fontWeight: "bold" }}>{totalCoins} / 2600</Text>
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Daily Check-in */}
|
||||||
|
<Text style={styles.dailyCheckinLabel}>KUNJUNGI TIAP HARI</Text>
|
||||||
|
<View style={styles.checkinRow}>
|
||||||
|
{[
|
||||||
|
{ day: "Hari-1", point: 10 },
|
||||||
|
{ day: "Hari-2", point: 15 },
|
||||||
|
{ day: "Hari-3", point: 20 },
|
||||||
|
{ day: "Hari-4", point: 25 },
|
||||||
|
{ day: "Hari-5", point: 30 },
|
||||||
|
{ day: "Hari-6", point: 35 },
|
||||||
|
{ day: "Hari-7", point: 50 },
|
||||||
|
].map((item, index) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
key={index}
|
||||||
|
style={styles.checkinItem}
|
||||||
|
onPress={() => handleDayClick(item.day, item.point)}
|
||||||
|
disabled={isCompleted(item.day)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.flameIcon,
|
||||||
|
isCompleted(item.day) && styles.completedItem,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
styles.pointText,
|
||||||
|
isCompleted(item.day) && styles.completedPointText,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{item.point}
|
||||||
|
</Text>
|
||||||
|
<Icon
|
||||||
|
name="flame"
|
||||||
|
size={20}
|
||||||
|
color={isCompleted(item.day) ? "gray" : "red"}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.dayText}>{item.day}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Missions as buttons */}
|
||||||
|
<View style={styles.missionContainer}>
|
||||||
|
<MissionButton
|
||||||
|
point="1000"
|
||||||
|
label="KONTRIBUSI PENGADUAN SAMPAH"
|
||||||
|
icon="person"
|
||||||
|
/>
|
||||||
|
<MissionButton point="800" label="DONASI" icon="cash" />
|
||||||
|
<MissionButton point="750" label="PENGADUAN SAMPAH" icon="trash" />
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Top 3 Users */}
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text style={styles.title}>TOP 3 KOIN TERBANYAK</Text>
|
||||||
|
{users.map((user, index) => (
|
||||||
|
<View key={index} style={styles.userCard}>
|
||||||
|
<Icon name="person-circle" size={40} color="#ccc" />
|
||||||
|
<View style={styles.userInfo}>
|
||||||
|
<Text style={styles.name}>{user.name}</Text>
|
||||||
|
<View style={styles.coinRow}>
|
||||||
|
<Icon name="cash-outline" size={16} color="#FFC107" />
|
||||||
|
<Text style={styles.coinText}>{user.coins}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={styles.rankBox}>
|
||||||
|
<Text style={styles.rankNumber}>{user.rank}</Text>
|
||||||
|
<Icon name="ribbon" size={20} color={user.color} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
<Text style={styles.footerText}>
|
||||||
|
"Ayo kumpulkan lebih banyak koin dengan berkontribusi aktif!{"\n"}
|
||||||
|
Semakin banyak kamu membantu, semakin besar dampaknya{"\n"}
|
||||||
|
untuk lingkungan kita!"
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const MissionButton = ({ point, label, icon }) => (
|
||||||
|
<TouchableOpacity style={styles.missionButton}>
|
||||||
|
<Text style={styles.koinBox}>{point}</Text>
|
||||||
|
<Icon name={icon} size={32} color="#333" />
|
||||||
|
<Text style={styles.missionText}>{label}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
padding: 16,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
marginTop: 40,
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
headerTitle: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginLeft: 12,
|
||||||
|
},
|
||||||
|
titleText: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginLeft: 6,
|
||||||
|
},
|
||||||
|
subTitle: {
|
||||||
|
fontSize: 16,
|
||||||
|
marginVertical: 6,
|
||||||
|
},
|
||||||
|
koinText: {
|
||||||
|
textAlign: "right",
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
dailyCheckinLabel: {
|
||||||
|
textAlign: "center",
|
||||||
|
marginVertical: 15,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
},
|
||||||
|
checkinRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-evenly",
|
||||||
|
marginBottom: 28,
|
||||||
|
},
|
||||||
|
checkinItem: {
|
||||||
|
alignItems: "center",
|
||||||
|
width: 50,
|
||||||
|
},
|
||||||
|
flameIcon: {
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#fff0f0",
|
||||||
|
borderRadius: 10,
|
||||||
|
padding: 9,
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
completedItem: {
|
||||||
|
opacity: 0.5, // Lower opacity for completed item
|
||||||
|
},
|
||||||
|
pointText: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#2D572C",
|
||||||
|
fontSize: 12,
|
||||||
|
},
|
||||||
|
completedPointText: {
|
||||||
|
color: "gray", // Change point color to gray when completed
|
||||||
|
},
|
||||||
|
dayText: {
|
||||||
|
fontSize: 10,
|
||||||
|
color: "#444",
|
||||||
|
marginTop: 4,
|
||||||
|
},
|
||||||
|
missionContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-evenly",
|
||||||
|
marginBottom: 10,
|
||||||
|
flexWrap: "wrap",
|
||||||
|
},
|
||||||
|
missionButton: {
|
||||||
|
width: "30%",
|
||||||
|
backgroundColor: "#fFF",
|
||||||
|
borderRadius: 12,
|
||||||
|
padding: 12,
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 12,
|
||||||
|
justifyContent: "center",
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
koinBox: {
|
||||||
|
backgroundColor: "#ffeb3b",
|
||||||
|
justifyContent: "space-evenly",
|
||||||
|
paddingHorizontal: 6,
|
||||||
|
paddingVertical: 2,
|
||||||
|
borderRadius: 10,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 6,
|
||||||
|
borderWidth: 0.5,
|
||||||
|
},
|
||||||
|
missionText: {
|
||||||
|
textAlign: "center",
|
||||||
|
fontSize: 11,
|
||||||
|
marginTop: 6,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
textAlign: "center",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 18,
|
||||||
|
color: "#2D572C",
|
||||||
|
marginBottom: 10,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderTopWidth: 1,
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderColor: "#ccc",
|
||||||
|
},
|
||||||
|
userCard: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ddd",
|
||||||
|
borderRadius: 12,
|
||||||
|
padding: 10,
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
userInfo: {
|
||||||
|
flex: 1,
|
||||||
|
marginLeft: 12,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
coinRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginTop: 4,
|
||||||
|
},
|
||||||
|
coinText: {
|
||||||
|
marginLeft: 4,
|
||||||
|
fontSize: 13,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
rankBox: {
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
rankNumber: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 14,
|
||||||
|
marginBottom: 2,
|
||||||
|
},
|
||||||
|
footerText: {
|
||||||
|
marginTop: 10,
|
||||||
|
textAlign: "center",
|
||||||
|
fontSize: 13,
|
||||||
|
color: "#444",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default misimingguan;
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, Text, Button, StyleSheet, TouchableOpacity } from "react-native";
|
||||||
|
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
||||||
|
|
||||||
|
const KontribusiBerhasil = ({ navigation }) => {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.content}>
|
||||||
|
<MaterialCommunityIcons name="cloud-check" size={140} color="white" />
|
||||||
|
<Text style={styles.title}>Daftar Berhasil !</Text>
|
||||||
|
|
||||||
|
<Text style={styles.subMessage}>
|
||||||
|
Silahkan masuk untuk mencoba fitur yang ada di EcoMap!
|
||||||
|
</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
// onPress={() => console.log("Daftar Submit")}
|
||||||
|
onPress={() => navigation.navigate("AksesAkun")}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>MASUK</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Warna hijau gelap
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Transparansi gelap untuk efek overlay
|
||||||
|
padding: 30,
|
||||||
|
borderRadius: 15,
|
||||||
|
width: "100%",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#fff",
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#fff",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
subMessage: {
|
||||||
|
fontSize: 15,
|
||||||
|
color: "#fff",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
padding: 3,
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 40,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginTop: 20,
|
||||||
|
borderRadius: 25,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 15,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default KontribusiBerhasil;
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
// import React from "react";
|
||||||
|
// import { createStackNavigator } from "@react-navigation/stack";
|
||||||
|
|
||||||
|
// import Home from "./screens/AksesWarga/Home";
|
||||||
|
// import pengaduansampah from "./screens/PengaduanWarga/pengaduansampah";
|
||||||
|
// import DetailPengaduan from "./screens/PengaduanWarga/DetailPengaduan";
|
||||||
|
|
||||||
|
// const Stack = createStackNavigator();
|
||||||
|
|
||||||
|
// export default function HomeStackNavigator() {
|
||||||
|
// return (
|
||||||
|
// <Stack.Navigator initialRouteName="Home">
|
||||||
|
// <Stack.Screen
|
||||||
|
// name="Home"
|
||||||
|
// component={Home}
|
||||||
|
// options={{ headerShown: false }}
|
||||||
|
// />
|
||||||
|
// <Stack.Screen
|
||||||
|
// name="pengaduansampah"
|
||||||
|
// component={pengaduansampah}
|
||||||
|
// options={{ headerShown: false }}
|
||||||
|
// />
|
||||||
|
// <Stack.Screen
|
||||||
|
// name="DetailPengaduan"
|
||||||
|
// component={DetailPengaduan}
|
||||||
|
// options={{ headerShown: false }}
|
||||||
|
// />
|
||||||
|
// </Stack.Navigator>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
@ -0,0 +1,227 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
ScrollView,
|
||||||
|
StatusBar,
|
||||||
|
Image,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons, FontAwesome } from "@expo/vector-icons"; // Import FontAwesome untuk ikon surat
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
// import AksesWargaNavigator from "../Navigation/AksesWargaNavigator";
|
||||||
|
|
||||||
|
const MasukAdmin = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [password, setPassword] = useState("");
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView style={{ flex: 1, backgroundColor: "#fff" }}>
|
||||||
|
<StatusBar backgroundColor={"#fff"} barStyle={"dark-content"} />
|
||||||
|
|
||||||
|
<View style={{ flex: 1, backgroundColor: "#fff" }}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 20,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Tombol Kembali */}
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => navigation.navigate("AksesAkun")}
|
||||||
|
style={{ width: 45, height: 45, marginRight: 13 }}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={30} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={{ justifyContent: "center", alignItems: "center" }}>
|
||||||
|
<Image
|
||||||
|
source={require("../assets/images/sampah.png")}
|
||||||
|
style={{
|
||||||
|
width: 250,
|
||||||
|
height: 300,
|
||||||
|
marginTop: 10,
|
||||||
|
marginBottom: 10,
|
||||||
|
marginLeft: 10,
|
||||||
|
marginRight: 10,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 40,
|
||||||
|
textAlign: "left",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Selamat Datang
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 40,
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Ecomapper!
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.formContainer}>
|
||||||
|
<Text style={styles.label}>Email</Text>
|
||||||
|
<View style={styles.inputContainer}>
|
||||||
|
<Ionicons name="mail" size={24} color="gray" style={styles.icon} />
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
value={email}
|
||||||
|
onChangeText={setEmail}
|
||||||
|
placeholder="Masukkan email"
|
||||||
|
keyboardType="email-address"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Text style={styles.label}>Kata Sandi</Text>
|
||||||
|
<View style={styles.passwordContainer}>
|
||||||
|
<FontAwesome name="lock" size={24} color="gray" style={styles.icon} />
|
||||||
|
<TextInput
|
||||||
|
style={styles.passwordInput}
|
||||||
|
value={password}
|
||||||
|
onChangeText={setPassword}
|
||||||
|
placeholder="Masukkan Kata Sandi"
|
||||||
|
secureTextEntry={!showPassword}
|
||||||
|
/>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => setShowPassword(!showPassword)}
|
||||||
|
style={styles.eyeIcon}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name={showPassword ? "eye-off" : "eye"}
|
||||||
|
size={24}
|
||||||
|
color="gray"
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() =>
|
||||||
|
navigation.navigate("AksesAdminNavigator", {
|
||||||
|
screen: "AdminScreen",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>Masuk</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* "Daftar Sekarang" Text */}
|
||||||
|
<View style={styles.registerContainer}>
|
||||||
|
<Text style={styles.registerText}>
|
||||||
|
Belum punya akun?{" "}
|
||||||
|
<TouchableOpacity onPress={() => navigation.navigate("daftar")}>
|
||||||
|
<Text style={styles.registerLink}>Daftar Sekarang</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* "Lupa Kata Sandi?" Text */}
|
||||||
|
<View style={styles.forgotPasswordContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => navigation.navigate("lupakatasandi")}
|
||||||
|
>
|
||||||
|
<Text style={styles.forgotPasswordText}>Lupa Kata Sandi?</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
formContainer: {
|
||||||
|
paddingHorizontal: 30,
|
||||||
|
marginTop: 20,
|
||||||
|
marginBottom: 30,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
fontSize: 16,
|
||||||
|
marginBottom: 10,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
inputContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
borderColor: "#ddd",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
flex: 1,
|
||||||
|
height: 45,
|
||||||
|
paddingLeft: 10,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
paddingLeft: 10,
|
||||||
|
},
|
||||||
|
passwordContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
borderColor: "#ddd",
|
||||||
|
height: 45,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
passwordInput: {
|
||||||
|
flex: 1,
|
||||||
|
height: 45,
|
||||||
|
paddingLeft: 10,
|
||||||
|
},
|
||||||
|
eyeIcon: {
|
||||||
|
paddingRight: 10,
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 15,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
textAlign: "center",
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
registerContainer: {
|
||||||
|
marginTop: 15,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
registerText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
registerLink: {
|
||||||
|
color: "#2D572C",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
forgotPasswordContainer: {
|
||||||
|
marginTop: 15,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
forgotPasswordText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#2D572C",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default MasukAdmin;
|
||||||
|
|
@ -0,0 +1,139 @@
|
||||||
|
import React, { useRef, useEffect, useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
Image,
|
||||||
|
FlatList,
|
||||||
|
Dimensions,
|
||||||
|
StyleSheet,
|
||||||
|
TouchableOpacity,
|
||||||
|
} from "react-native";
|
||||||
|
import { useNavigation } from "@react-navigation/native"; // Mengimpor useNavigation
|
||||||
|
|
||||||
|
const { width } = Dimensions.get("window");
|
||||||
|
|
||||||
|
const slides = [
|
||||||
|
{
|
||||||
|
id: "1",
|
||||||
|
image: require("../assets/images/onboarding1.png"),
|
||||||
|
text: "Temukan lokasi tempat pembuangan sampah terdekat.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2",
|
||||||
|
image: require("../assets/images/onboarding2.png"),
|
||||||
|
text: "Laporkan sampah dan bantu lingkungan jadi lebih bersih.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "3",
|
||||||
|
image: require("../assets/images/onboarding3.png"),
|
||||||
|
text: "Tukar poinmu dengan barang bermanfaat untuk sehari-hari.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const Onboarding = () => {
|
||||||
|
const flatListRef = useRef(null);
|
||||||
|
const [currentIndex, setCurrentIndex] = useState(0);
|
||||||
|
const navigation = useNavigation(); // Mendapatkan objek navigasi
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (currentIndex < slides.length - 1) {
|
||||||
|
flatListRef.current?.scrollToIndex({
|
||||||
|
index: currentIndex + 1,
|
||||||
|
animated: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [currentIndex]);
|
||||||
|
|
||||||
|
const handleNext = () => {
|
||||||
|
navigation.navigate("AksesAkun"); // Mengarahkan ke layar "AksesAkun"
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderItem = ({ item }) => (
|
||||||
|
<View style={styles.slide}>
|
||||||
|
<Image source={item.image} style={styles.image} resizeMode="contain" />
|
||||||
|
<Text style={styles.text}>{item.text}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
const onViewableItemsChanged = useRef(({ viewableItems }) => {
|
||||||
|
if (viewableItems.length > 0) {
|
||||||
|
setCurrentIndex(viewableItems[0].index);
|
||||||
|
}
|
||||||
|
}).current;
|
||||||
|
|
||||||
|
const viewConfigRef = useRef({ viewAreaCoveragePercentThreshold: 50 });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<FlatList
|
||||||
|
ref={flatListRef}
|
||||||
|
data={slides}
|
||||||
|
horizontal
|
||||||
|
pagingEnabled
|
||||||
|
showsHorizontalScrollIndicator={false}
|
||||||
|
renderItem={renderItem}
|
||||||
|
keyExtractor={(item) => item.id}
|
||||||
|
onViewableItemsChanged={onViewableItemsChanged}
|
||||||
|
viewabilityConfig={viewConfigRef.current}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<View style={styles.dotsContainer}>
|
||||||
|
{slides.map((_, index) => (
|
||||||
|
<View
|
||||||
|
key={index}
|
||||||
|
style={[styles.dot, index === currentIndex && styles.activeDot]}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{currentIndex === slides.length - 1 && (
|
||||||
|
<TouchableOpacity style={styles.nextButton} onPress={handleNext}>
|
||||||
|
<Text style={styles.nextText}>LANJUT</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: { flex: 1, backgroundColor: "#fff", marginBottom: 0 },
|
||||||
|
slide: { width, alignItems: "center", justifyContent: "center", padding: 20 },
|
||||||
|
image: { width: 250, height: 250, marginBottom: 30 },
|
||||||
|
text: {
|
||||||
|
fontSize: 18,
|
||||||
|
color: "#000",
|
||||||
|
textAlign: "center",
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
},
|
||||||
|
dotsContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginBottom: 40,
|
||||||
|
},
|
||||||
|
dot: {
|
||||||
|
width: 10,
|
||||||
|
height: 10,
|
||||||
|
borderRadius: 5,
|
||||||
|
backgroundColor: "#aaa",
|
||||||
|
marginHorizontal: 5,
|
||||||
|
},
|
||||||
|
activeDot: { backgroundColor: "#435739" },
|
||||||
|
nextButton: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: 50,
|
||||||
|
alignSelf: "flex-end",
|
||||||
|
backgroundColor: "#435739",
|
||||||
|
paddingHorizontal: 26,
|
||||||
|
paddingVertical: 16,
|
||||||
|
elevation: 3,
|
||||||
|
borderRadius: 10,
|
||||||
|
marginHorizontal: 20,
|
||||||
|
},
|
||||||
|
nextText: { color: "#fff", fontSize: 18, fontWeight: "bold" },
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Onboarding;
|
||||||
|
|
@ -0,0 +1,184 @@
|
||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
TouchableOpacity,
|
||||||
|
Image,
|
||||||
|
ScrollView,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
|
||||||
|
const pengaduanData = {
|
||||||
|
id: 1,
|
||||||
|
judul: "Sampah Menumpuk di Jalan Raya",
|
||||||
|
alamat: "Jl. Raya No. 25, Desa Suka Maju, Nganjuk",
|
||||||
|
catatan: "Mohon segera dibersihkan, sudah terlalu lama menumpuk.",
|
||||||
|
tanggal: "2025-04-28",
|
||||||
|
gambar: "https://via.placeholder.com/150", // Ganti dengan gambar yang sesuai
|
||||||
|
status: "Sedang Diproses", // Bisa diganti dengan 'Sedang Diverifikasi', 'Ditolak', dll.
|
||||||
|
pelapor: {
|
||||||
|
nama: "Dina",
|
||||||
|
profilGambar: "https://via.placeholder.com/50", // Gambar profil pelapor
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const PengaduanScreen = ({ navigation }) => {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Tombol Kembali */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#2D572C" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* Judul */}
|
||||||
|
<Text style={styles.title}>PENGADUAN</Text>
|
||||||
|
|
||||||
|
{/* Container Pengaduan */}
|
||||||
|
<ScrollView style={styles.pengaduanContainer}>
|
||||||
|
<View style={styles.pengaduanBox}>
|
||||||
|
<Text style={styles.pengaduanJudul}>{pengaduanData.judul}</Text>
|
||||||
|
<Text style={styles.pengaduanAlamat}>{pengaduanData.alamat}</Text>
|
||||||
|
<Text style={styles.pengaduanCatatan}>{pengaduanData.catatan}</Text>
|
||||||
|
<Text style={styles.pengaduanTanggal}>
|
||||||
|
Tanggal: {pengaduanData.tanggal}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Image
|
||||||
|
source={{ uri: pengaduanData.gambar }}
|
||||||
|
style={styles.buktiImage}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Profil Pelapor */}
|
||||||
|
<View style={styles.pelaporContainer}>
|
||||||
|
<Image
|
||||||
|
source={{ uri: pengaduanData.pelapor.profilGambar }}
|
||||||
|
style={styles.pelaporImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.pelaporNama}>{pengaduanData.pelapor.nama}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Status Pengaduan */}
|
||||||
|
<View style={styles.statusContainer}>
|
||||||
|
<Text style={styles.statusText}>{pengaduanData.status}</Text>
|
||||||
|
|
||||||
|
{/* Jika Status Sedang Diproses */}
|
||||||
|
{pengaduanData.status === "Sedang Diproses" && (
|
||||||
|
<TouchableOpacity style={styles.kontribusiButton}>
|
||||||
|
<Text style={styles.kontribusiText}>Kontribusi</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Jika Status Sedang Diproses */}
|
||||||
|
{pengaduanData.status === "Sedang Diproses" && (
|
||||||
|
<Text style={styles.koinText}>Dapatkan Koin 300</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 16,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginBottom: 16,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#2D572C",
|
||||||
|
marginBottom: 20,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
pengaduanContainer: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
pengaduanBox: {
|
||||||
|
padding: 16,
|
||||||
|
backgroundColor: "#F8F8F8",
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 20,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 5,
|
||||||
|
elevation: 3,
|
||||||
|
},
|
||||||
|
pengaduanJudul: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
pengaduanAlamat: {
|
||||||
|
marginTop: 8,
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
pengaduanCatatan: {
|
||||||
|
marginTop: 8,
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
pengaduanTanggal: {
|
||||||
|
marginTop: 8,
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#777",
|
||||||
|
},
|
||||||
|
buktiImage: {
|
||||||
|
marginTop: 16,
|
||||||
|
width: "100%",
|
||||||
|
height: 150,
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
pelaporContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginTop: 16,
|
||||||
|
},
|
||||||
|
pelaporImage: {
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
borderRadius: 20,
|
||||||
|
},
|
||||||
|
pelaporNama: {
|
||||||
|
marginLeft: 12,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
statusContainer: {
|
||||||
|
marginTop: 16,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
statusText: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#FF6F61", // Bisa diganti dengan warna yang sesuai status
|
||||||
|
},
|
||||||
|
kontribusiButton: {
|
||||||
|
marginTop: 12,
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
kontribusiText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
koinText: {
|
||||||
|
marginTop: 8,
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default PengaduanScreen;
|
||||||
|
|
@ -0,0 +1,215 @@
|
||||||
|
import React from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
StyleSheet,
|
||||||
|
TouchableOpacity,
|
||||||
|
Image,
|
||||||
|
ScrollView,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
|
||||||
|
const pengaduanData = {
|
||||||
|
id: 1,
|
||||||
|
judul: "Sampah Menumpuk di Jalan Raya",
|
||||||
|
alamat: "Jl. Raya No. 25, Desa Suka Maju, Nganjuk",
|
||||||
|
catatan: "Mohon segera dibersihkan, sudah terlalu lama menumpuk.",
|
||||||
|
tanggal: "2025-04-28",
|
||||||
|
status: "Sedang Diproses", // Bisa diganti dengan 'Sedang Diverifikasi', 'Ditolak', dll.
|
||||||
|
pelapor: {
|
||||||
|
nama: "Dina",
|
||||||
|
profilGambar:
|
||||||
|
"https://imgv3.fotor.com/images/gallery/a-woman-linkedin-picture-with-grey-background-made-by-LinkedIn-Profile-Picture-Maker.jpg", // Gambar profil pelapor
|
||||||
|
},
|
||||||
|
gambarSampah: [
|
||||||
|
"https://majanews.com/wp-content/uploads/2022/07/0_20220718_193954.jpg", // Image 1
|
||||||
|
"https://newvision-media.s3.amazonaws.com/cms/d2d008c8-1703-4c3e-8b34-3181fc5eda5d.jpg", // Image 2// Image 3
|
||||||
|
// "https://newvision-media.s3.amazonaws.com/cms/d2d008c8-1703-4c3e-8b34-3181fc5eda5d.jpg", // Image 2// Image 3
|
||||||
|
// "https://newvision-media.s3.amazonaws.com/cms/d2d008c8-1703-4c3e-8b34-3181fc5eda5d.jpg", // Image 2// Image 3
|
||||||
|
"https://newvision-media.s3.amazonaws.com/cms/d2d008c8-1703-4c3e-8b34-3181fc5eda5d.jpg", // Image 2// Image 3
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const PengaduanScreen = ({ navigation }) => {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{/* Judul Pengaduan */}
|
||||||
|
<Text style={styles.title}>PENGADUAN</Text>
|
||||||
|
|
||||||
|
{/* Tombol Kembali */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={28} color="#2D572C" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{/* Container Pengaduan */}
|
||||||
|
<ScrollView style={styles.pengaduanContainer}>
|
||||||
|
<View style={styles.pelaporContainer}>
|
||||||
|
<Image
|
||||||
|
source={{ uri: pengaduanData.pelapor.profilGambar }}
|
||||||
|
style={styles.pelaporImage}
|
||||||
|
/>
|
||||||
|
<Text style={styles.pelaporNama}>{pengaduanData.pelapor.nama}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.pengaduanBox}>
|
||||||
|
<Text style={styles.pengaduanJudul}>{pengaduanData.judul}</Text>
|
||||||
|
<Text style={styles.pengaduanAlamat}>{pengaduanData.alamat}</Text>
|
||||||
|
<Text style={styles.pengaduanCatatan}>{pengaduanData.catatan}</Text>
|
||||||
|
<Text style={styles.pengaduanTanggal}>
|
||||||
|
Tanggal: {pengaduanData.tanggal}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{/* Gambar Sampah - Row Layout */}
|
||||||
|
<View style={styles.rowContainer}>
|
||||||
|
{pengaduanData.gambarSampah.map((image, index) => (
|
||||||
|
<Image
|
||||||
|
key={index}
|
||||||
|
source={{ uri: image }}
|
||||||
|
style={styles.sampahImage}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Profil Pelapor */}
|
||||||
|
|
||||||
|
{/* Status Pengaduan */}
|
||||||
|
<View style={styles.statusContainer}>
|
||||||
|
<TouchableOpacity style={styles.kontribusiButton}>
|
||||||
|
<Text style={styles.kontribusiText}>Kontribusi</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
{/* Jika Status Sedang Diproses */}
|
||||||
|
{pengaduanData.status === "Sedang Diproses" && (
|
||||||
|
<Text style={styles.koinText}>Dapatkan Koin 300</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 16,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#000",
|
||||||
|
marginBottom: 16,
|
||||||
|
marginTop: 16, // Reduced margin to bring title closer
|
||||||
|
textAlign: "left",
|
||||||
|
marginLeft: 35,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginBottom: 20,
|
||||||
|
marginTop: 10, // Space between back button and title
|
||||||
|
position: "absolute", // Positioning it at the top-left
|
||||||
|
top: 20,
|
||||||
|
left: 10,
|
||||||
|
zIndex: 1,
|
||||||
|
},
|
||||||
|
pengaduanContainer: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
pengaduanBox: {
|
||||||
|
padding: 16,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 20,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 5,
|
||||||
|
elevation: 3,
|
||||||
|
marginTop: 20,
|
||||||
|
},
|
||||||
|
pengaduanJudul: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
pengaduanAlamat: {
|
||||||
|
marginTop: 8,
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
pengaduanCatatan: {
|
||||||
|
marginTop: 8,
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
pengaduanTanggal: {
|
||||||
|
marginTop: 8,
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#777",
|
||||||
|
},
|
||||||
|
buktiImage: {
|
||||||
|
marginTop: 16,
|
||||||
|
width: "100%",
|
||||||
|
height: 150,
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
rowContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginTop: 26,
|
||||||
|
marginTop: 16,
|
||||||
|
width: "70%",
|
||||||
|
height: 80,
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
sampahImage: {
|
||||||
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
pelaporContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginTop: 16,
|
||||||
|
marginLeft: 20,
|
||||||
|
},
|
||||||
|
pelaporImage: {
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
borderRadius: 20,
|
||||||
|
},
|
||||||
|
pelaporNama: {
|
||||||
|
marginLeft: 12,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
statusContainer: {
|
||||||
|
marginTop: 16,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
statusText: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#FF6F61", // Bisa diganti dengan warna yang sesuai status
|
||||||
|
},
|
||||||
|
kontribusiButton: {
|
||||||
|
marginTop: 12,
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
kontribusiText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
koinText: {
|
||||||
|
marginTop: 8,
|
||||||
|
fontSize: 12,
|
||||||
|
color: "#555",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default PengaduanScreen;
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, Text, Button, StyleSheet, TouchableOpacity } from "react-native";
|
||||||
|
import { MaterialCommunityIcons } from "@expo/vector-icons"; // Menggunakan ikon ceklis
|
||||||
|
|
||||||
|
const KontribusiBerhasil = ({ navigation }) => {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.content}>
|
||||||
|
<MaterialCommunityIcons name="cloud-check" size={140} color="white" />
|
||||||
|
<Text style={styles.title}>Kontribusi Berhasil !</Text>
|
||||||
|
{/* <Text style={styles.message}>
|
||||||
|
Mohon pastikan informasi yang diberikan sudah sesuai, agar kami dapat
|
||||||
|
segera menindaklanjuti.
|
||||||
|
</Text> */}
|
||||||
|
<Text style={styles.subMessage}>
|
||||||
|
Terima kasih telah berkontribusi untuk lingkungan!
|
||||||
|
</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
// onPress={() => console.log("Daftar Submit")}
|
||||||
|
onPress={() => navigation.navigate("BerandaPengaduan")}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>LIHAT KONTRIBUSI</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Warna hijau gelap
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Transparansi gelap untuk efek overlay
|
||||||
|
padding: 30,
|
||||||
|
borderRadius: 15,
|
||||||
|
width: "80%",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#ffea00",
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#fff",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
subMessage: {
|
||||||
|
fontSize: 15,
|
||||||
|
color: "#ffea00",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
padding: 3,
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 40,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginTop: 20,
|
||||||
|
borderRadius: 25,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 15,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default KontribusiBerhasil;
|
||||||
|
|
@ -0,0 +1,280 @@
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import {
|
||||||
|
ScrollView,
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
Alert,
|
||||||
|
Image,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons"; // Icon library for the media buttons
|
||||||
|
import * as ImagePicker from "expo-image-picker"; // For picking images
|
||||||
|
import * as MediaLibrary from "expo-media-library"; // For accessing media library
|
||||||
|
import { Video } from "expo-av"; // For displaying videos
|
||||||
|
|
||||||
|
const KontribusiScreen = ({ navigation, route }) => {
|
||||||
|
const {
|
||||||
|
judulPengaduan = "Sampah berantakan",
|
||||||
|
tempatPengaduan = "Jl Raya Madiun Nganjuk",
|
||||||
|
} = route?.params || {};
|
||||||
|
|
||||||
|
const [catatan, setCatatan] = useState("");
|
||||||
|
const [photo, setPhoto] = useState(null);
|
||||||
|
const [video, setVideo] = useState(null);
|
||||||
|
|
||||||
|
// Request permissions for camera and media library
|
||||||
|
useEffect(() => {
|
||||||
|
const requestPermissions = async () => {
|
||||||
|
// Request permission for media library (Images and Videos)
|
||||||
|
const { status: mediaStatus } =
|
||||||
|
await ImagePicker.requestMediaLibraryPermissionsAsync();
|
||||||
|
if (mediaStatus !== "granted") {
|
||||||
|
Alert.alert(
|
||||||
|
"Permission required",
|
||||||
|
"You need to grant permission to access your media library."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally, you can also request permission for camera
|
||||||
|
const { status: cameraStatus } =
|
||||||
|
await ImagePicker.requestCameraPermissionsAsync();
|
||||||
|
if (cameraStatus !== "granted") {
|
||||||
|
Alert.alert(
|
||||||
|
"Permission required",
|
||||||
|
"You need to grant permission to use the camera."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
requestPermissions();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Function to pick image
|
||||||
|
const pickImage = async () => {
|
||||||
|
let result = await ImagePicker.launchImageLibraryAsync({
|
||||||
|
mediaTypes: ImagePicker.MediaTypeOptions.Images,
|
||||||
|
allowsEditing: true,
|
||||||
|
aspect: [4, 3],
|
||||||
|
quality: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.canceled) {
|
||||||
|
setPhoto(result.assets[0].uri); // Set the selected photo URI
|
||||||
|
} else {
|
||||||
|
Alert.alert("Tambah foto dibatalkan.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to pick video
|
||||||
|
const pickVideo = async () => {
|
||||||
|
let result = await ImagePicker.launchImageLibraryAsync({
|
||||||
|
mediaTypes: ImagePicker.MediaTypeOptions.Videos,
|
||||||
|
allowsEditing: true,
|
||||||
|
quality: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.canceled) {
|
||||||
|
setVideo(result.assets[0].uri); // Set the selected video URI
|
||||||
|
} else {
|
||||||
|
Alert.alert("Pemilihan video dibatalkan.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView style={styles.container}>
|
||||||
|
{/* Title and Back Button */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>KONTRIBUSI SEKARANG</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Contribution Info Container */}
|
||||||
|
<View style={styles.contributionContainer}>
|
||||||
|
<View style={styles.infoBox}>
|
||||||
|
<Text style={styles.infoText1}>{judulPengaduan}</Text>
|
||||||
|
<Text style={styles.infoText2}>{tempatPengaduan}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Add Media Row (Foto & Video) */}
|
||||||
|
<View style={styles.mediaRow}>
|
||||||
|
<TouchableOpacity style={styles.mediaButton} onPress={pickImage}>
|
||||||
|
<Ionicons name="image-outline" size={30} color="#2D572C" />
|
||||||
|
<Text style={styles.mediaButtonText}>Tambah Foto</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity style={styles.mediaButton} onPress={pickVideo}>
|
||||||
|
<Ionicons name="videocam-outline" size={30} color="#2D572C" />
|
||||||
|
<Text style={styles.mediaButtonText}>Tambah Video</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Display selected photo */}
|
||||||
|
{photo && (
|
||||||
|
<Image source={{ uri: photo }} style={styles.mediaThumbnail} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Display selected video */}
|
||||||
|
{video && (
|
||||||
|
<Video
|
||||||
|
source={{ uri: video }}
|
||||||
|
style={styles.mediaThumbnail}
|
||||||
|
useNativeControls
|
||||||
|
resizeMode="contain"
|
||||||
|
isLooping
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Catatan (Note Input) */}
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Catatan"
|
||||||
|
multiline
|
||||||
|
value={catatan}
|
||||||
|
onChangeText={setCatatan}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Koin Message */}
|
||||||
|
<Text style={styles.koinText}>Dapatkan +520 Koin</Text>
|
||||||
|
|
||||||
|
{/* Post Button at Bottom */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.postButton}
|
||||||
|
onPress={() => navigation.navigate("KontribusiBerhasil")}
|
||||||
|
>
|
||||||
|
<Text style={styles.postButtonText}>Posting</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#f9f9f9",
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
padding: 15,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderBottomLeftRadius: 20,
|
||||||
|
borderBottomRightRadius: 20,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 15,
|
||||||
|
marginTop: 40,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: "bold",
|
||||||
|
flex: 1,
|
||||||
|
textAlign: "left",
|
||||||
|
marginTop: 40,
|
||||||
|
},
|
||||||
|
contributionContainer: {
|
||||||
|
padding: 20,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
marginBottom: 20,
|
||||||
|
borderRadius: 12,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowOffset: { width: 0, height: 4 },
|
||||||
|
shadowRadius: 4,
|
||||||
|
},
|
||||||
|
infoBox: {
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
infoText1: {
|
||||||
|
fontSize: 22,
|
||||||
|
color: "#333",
|
||||||
|
fontWeight: "700",
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
infoText2: {
|
||||||
|
fontSize: 18,
|
||||||
|
color: "#777",
|
||||||
|
fontWeight: "400",
|
||||||
|
},
|
||||||
|
mediaRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginBottom: 25,
|
||||||
|
},
|
||||||
|
mediaButton: {
|
||||||
|
alignItems: "center",
|
||||||
|
flex: 1,
|
||||||
|
padding: 15,
|
||||||
|
backgroundColor: "#E8F5E9",
|
||||||
|
borderRadius: 10,
|
||||||
|
marginHorizontal: 10,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#2D572C",
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowOffset: { width: 0, height: 3 },
|
||||||
|
shadowRadius: 5,
|
||||||
|
elevation: 3,
|
||||||
|
},
|
||||||
|
mediaButtonText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#2D572C",
|
||||||
|
marginTop: 5,
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
height: 100,
|
||||||
|
borderColor: "#2D572C",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 8,
|
||||||
|
padding: 12,
|
||||||
|
fontSize: 16,
|
||||||
|
marginBottom: 15,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowOffset: { width: 0, height: 2 },
|
||||||
|
shadowRadius: 5,
|
||||||
|
elevation: 2,
|
||||||
|
},
|
||||||
|
koinText: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
textAlign: "center",
|
||||||
|
color: "#2D572C",
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
postButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 15,
|
||||||
|
borderRadius: 10,
|
||||||
|
marginBottom: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
width: "90%",
|
||||||
|
alignSelf: "center",
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowOffset: { width: 0, height: 5 },
|
||||||
|
shadowRadius: 8,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
postButtonText: {
|
||||||
|
fontSize: 18,
|
||||||
|
color: "#fff",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
mediaThumbnail: {
|
||||||
|
width: 300, // Adjust size for visibility
|
||||||
|
height: 200, // Adjust size for visibility
|
||||||
|
marginVertical: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
backgroundColor: "#f0f0f0",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default KontribusiScreen;
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { View, Text, StyleSheet, ActivityIndicator } from "react-native";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const LoadingKontribusi = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
// Menunggu selama 2 detik dan kemudian pindah ke halaman Home
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
navigation.replace("KontribusiBerhasil"); // Ganti 'Home' dengan nama screen tujuan
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer); // Membersihkan timer saat komponen dihapus
|
||||||
|
}, [navigation]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.overlay}>
|
||||||
|
<ActivityIndicator size="large" color="#fff" />
|
||||||
|
<Text style={styles.loadingText}>Tunggu sebentar...</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Warna hijau gelap sebagai latar belakang
|
||||||
|
},
|
||||||
|
overlay: {
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Transparansi gelap untuk overlay
|
||||||
|
padding: 20,
|
||||||
|
borderRadius: 10,
|
||||||
|
},
|
||||||
|
loadingText: {
|
||||||
|
marginTop: 10,
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#fff",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default LoadingKontribusi;
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { View, Text, StyleSheet, ActivityIndicator } from "react-native";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const LoadingScreen = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
// Menunggu selama 2 detik dan kemudian pindah ke halaman Home
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
navigation.replace("PengaduanWargaNavigator", {
|
||||||
|
screen: "PengaduanBerhasil",
|
||||||
|
}); // Ganti 'Home' dengan nama screen tujuan
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer); // Membersihkan timer saat komponen dihapus
|
||||||
|
}, [navigation]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.overlay}>
|
||||||
|
<ActivityIndicator size="large" color="#fff" />
|
||||||
|
<Text style={styles.loadingText}>Tunggu sebentar...</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Warna hijau gelap sebagai latar belakang
|
||||||
|
},
|
||||||
|
overlay: {
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Transparansi gelap untuk overlay
|
||||||
|
padding: 20,
|
||||||
|
borderRadius: 10,
|
||||||
|
},
|
||||||
|
loadingText: {
|
||||||
|
marginTop: 10,
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#fff",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default LoadingScreen;
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, Text, Button, StyleSheet, TouchableOpacity } from "react-native";
|
||||||
|
import { MaterialCommunityIcons } from "@expo/vector-icons"; // Menggunakan ikon ceklis
|
||||||
|
|
||||||
|
const PengaduanBerhasil = ({ navigation }) => {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.content}>
|
||||||
|
<MaterialCommunityIcons name="cloud-check" size={140} color="white" />
|
||||||
|
<Text style={styles.title}>PENGADUAN BERHASIL !</Text>
|
||||||
|
<Text style={styles.message}>
|
||||||
|
Mohon pastikan informasi yang diberikan sudah sesuai, agar kami dapat
|
||||||
|
segera menindaklanjuti.
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.subMessage}>
|
||||||
|
Laporan anda telah diterima dan sedang menunggu verifikasi
|
||||||
|
</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
// onPress={() => console.log("Daftar Submit")}
|
||||||
|
onPress={() => navigation.navigate("BerandaPengaduan")}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>LIHAT PENGADUAN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Warna hijau gelap
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#435739", // Transparansi gelap untuk efek overlay
|
||||||
|
padding: 30,
|
||||||
|
borderRadius: 15,
|
||||||
|
width: "80%",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#ffea00",
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#fff",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
subMessage: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#ffea00",
|
||||||
|
textAlign: "center",
|
||||||
|
marginTop: 10,
|
||||||
|
padding: 3,
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingHorizontal: 50,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginTop: 20,
|
||||||
|
borderRadius: 25,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 15,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default PengaduanBerhasil;
|
||||||
|
|
@ -0,0 +1,284 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
ScrollView,
|
||||||
|
StyleSheet,
|
||||||
|
Image,
|
||||||
|
FlatList,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import * as Location from "expo-location";
|
||||||
|
import * as ImagePicker from "expo-image-picker";
|
||||||
|
import { Picker } from "@react-native-picker/picker"; // Import Picker
|
||||||
|
|
||||||
|
const desaOptions = ["Cangkringan", "Bogo", "Pesukidul", "Grojogan"];
|
||||||
|
const kecamatanOptions = ["Nganjuk", "Bagor", "Berbek", "Pace", "Wilangan"];
|
||||||
|
|
||||||
|
export default function PengaduanSampah() {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
const [form, setForm] = useState({
|
||||||
|
nama: "",
|
||||||
|
noHp: "",
|
||||||
|
tanggal: "",
|
||||||
|
kategori: "",
|
||||||
|
namaJalan: "",
|
||||||
|
desa: "",
|
||||||
|
kecamatan: "",
|
||||||
|
tempat: "",
|
||||||
|
catatan: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const [imageUris, setImageUris] = useState([]); // Using array for multiple images
|
||||||
|
const [location, setLocation] = useState(null);
|
||||||
|
const [filteredDesa, setFilteredDesa] = useState(desaOptions);
|
||||||
|
|
||||||
|
const handleInputChange = (key, value) => {
|
||||||
|
setForm({ ...form, [key]: value });
|
||||||
|
};
|
||||||
|
|
||||||
|
// Filter desa based on input
|
||||||
|
const handleDesaSearch = (text) => {
|
||||||
|
setForm({ ...form, desa: text });
|
||||||
|
setFilteredDesa(
|
||||||
|
desaOptions.filter((desa) =>
|
||||||
|
desa.toLowerCase().includes(text.toLowerCase())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCurrentLocation = async () => {
|
||||||
|
const { status } = await Location.requestForegroundPermissionsAsync();
|
||||||
|
if (status !== "granted") {
|
||||||
|
alert("Izin lokasi ditolak");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Get user location
|
||||||
|
const loc = await Location.getCurrentPositionAsync({
|
||||||
|
accuracy: Location.Accuracy.High,
|
||||||
|
});
|
||||||
|
setLocation(loc.coords);
|
||||||
|
|
||||||
|
// Geocoding API
|
||||||
|
const geocodeUrl = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${loc.coords.latitude},${loc.coords.longitude}&key=YOUR_GOOGLE_MAPS_API_KEY`;
|
||||||
|
|
||||||
|
const response = await fetch(geocodeUrl);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.status === "OK" && data.results.length > 0) {
|
||||||
|
const address = data.results[0].address_components;
|
||||||
|
|
||||||
|
const street =
|
||||||
|
address.find((component) => component.types.includes("route"))
|
||||||
|
?.long_name || "";
|
||||||
|
const village =
|
||||||
|
address.find((component) => component.types.includes("locality"))
|
||||||
|
?.long_name || "";
|
||||||
|
const place =
|
||||||
|
address.find((component) => component.types.includes("neighborhood"))
|
||||||
|
?.long_name || "";
|
||||||
|
|
||||||
|
setForm((prevForm) => ({
|
||||||
|
...prevForm,
|
||||||
|
namaJalan: street,
|
||||||
|
desa: village,
|
||||||
|
tempat: place,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
alert("Tidak dapat menemukan alamat untuk lokasi ini.");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error getting address or location:", error);
|
||||||
|
alert("Terjadi kesalahan saat mengambil alamat atau lokasi.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const pickImage = async () => {
|
||||||
|
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
|
||||||
|
if (status !== "granted") {
|
||||||
|
alert("Sorry, we need camera roll permissions to make this work!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await ImagePicker.launchImageLibraryAsync({
|
||||||
|
allowsEditing: true,
|
||||||
|
quality: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.canceled && result.assets.length > 0) {
|
||||||
|
// Add new image URI to the imageUris array
|
||||||
|
setImageUris((prevImages) => [...prevImages, result.assets[0].uri]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
// Cek semua field
|
||||||
|
if (!form.nama || !form.noHp || !form.tempat) {
|
||||||
|
alert("Harap lengkapi semua informasi yang diperlukan!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validasi
|
||||||
|
console.log("Data Laporan:", { ...form, imageUris, location });
|
||||||
|
// alert("Laporan berhasil dikirim!");
|
||||||
|
navigation.navigate("PengaduanBerhasil");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView contentContainerStyle={styles.container}>
|
||||||
|
{/* Back Button */}
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
style={styles.backButton}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#000" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>PENGADUAN SAMPAH</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Nama Warga (Contoh: Johan Okta)"
|
||||||
|
value={form.nama}
|
||||||
|
onChangeText={(text) => handleInputChange("nama", text)}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="No. HP Warga (Contoh: 081234567890)"
|
||||||
|
keyboardType="phone-pad"
|
||||||
|
value={form.noHp}
|
||||||
|
onChangeText={(text) => handleInputChange("noHp", text)}
|
||||||
|
/>
|
||||||
|
<Text style={styles.section}>LOKASI KEJADIAN</Text>
|
||||||
|
|
||||||
|
{/* Kecamatan Dropdown */}
|
||||||
|
<Text style={styles.inputLabel}>Kecamatan</Text>
|
||||||
|
<Picker
|
||||||
|
selectedValue={form.kecamatan}
|
||||||
|
onValueChange={(itemValue) => handleInputChange("kecamatan", itemValue)}
|
||||||
|
style={styles.input}
|
||||||
|
>
|
||||||
|
{kecamatanOptions.map((kecamatan, index) => (
|
||||||
|
<Picker.Item key={index} label={kecamatan} value={kecamatan} />
|
||||||
|
))}
|
||||||
|
</Picker>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
placeholder="Tempat Kejadian (Contoh: Desa Cangkringan gang 4, Depan Toko)"
|
||||||
|
value={form.tempat}
|
||||||
|
onChangeText={(text) => handleInputChange("tempat", text)}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={[styles.input, { height: 100 }]}
|
||||||
|
multiline
|
||||||
|
placeholder="Catatan"
|
||||||
|
value={form.catatan}
|
||||||
|
onChangeText={(text) => handleInputChange("catatan", text)}
|
||||||
|
/>
|
||||||
|
<Text style={styles.section}>BUKTI PENDUKUNG</Text>
|
||||||
|
<View style={styles.row}>
|
||||||
|
<TouchableOpacity style={styles.buttonUpload} onPress={pickImage}>
|
||||||
|
<Text style={styles.buttonText}>Unggah</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.buttonUpload}
|
||||||
|
onPress={getCurrentLocation}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>Lokasi Saat Ini</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
{/* Display uploaded images */}
|
||||||
|
<ScrollView horizontal style={styles.imageGallery}>
|
||||||
|
{imageUris.map((uri, index) => (
|
||||||
|
<Image key={index} source={{ uri }} style={styles.imagePreview} />
|
||||||
|
))}
|
||||||
|
</ScrollView>
|
||||||
|
<TouchableOpacity style={styles.submitButton} onPress={handleSubmit}>
|
||||||
|
<Text style={styles.submitText}>LAPORKAN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flexGrow: 1,
|
||||||
|
padding: 30,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
paddingTop: 20,
|
||||||
|
marginTop: 40,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
position: "absolute",
|
||||||
|
top: 20,
|
||||||
|
left: 20,
|
||||||
|
zIndex: 10,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontWeight: "bold",
|
||||||
|
fontSize: 22,
|
||||||
|
marginBottom: 20,
|
||||||
|
color: "#000",
|
||||||
|
textAlign: "left",
|
||||||
|
marginLeft: 25,
|
||||||
|
},
|
||||||
|
section: {
|
||||||
|
marginTop: 20,
|
||||||
|
fontWeight: "600",
|
||||||
|
marginBottom: 10,
|
||||||
|
color: "#444",
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#aaa",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
inputLabel: {
|
||||||
|
fontWeight: "600",
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
row: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
},
|
||||||
|
buttonUpload: {
|
||||||
|
backgroundColor: "#ccc",
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 8,
|
||||||
|
flex: 1,
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
imagePreview: {
|
||||||
|
marginTop: 10,
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
borderRadius: 10,
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
imageGallery: {
|
||||||
|
flexDirection: "row",
|
||||||
|
marginTop: 10,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
submitButton: {
|
||||||
|
marginTop: 30,
|
||||||
|
backgroundColor: "#2f4f2f",
|
||||||
|
padding: 15,
|
||||||
|
borderRadius: 10,
|
||||||
|
},
|
||||||
|
submitText: {
|
||||||
|
color: "#fff",
|
||||||
|
textAlign: "center",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,230 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
ScrollView,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons"; // Importing icons
|
||||||
|
|
||||||
|
const Donasi = ({ navigation }) => {
|
||||||
|
const [donationAmount, setDonationAmount] = useState("");
|
||||||
|
const [selectedGoal, setSelectedGoal] = useState(null);
|
||||||
|
const [description, setDescription] = useState("");
|
||||||
|
|
||||||
|
// Format donation input with thousands separator
|
||||||
|
const formatAmount = (amount) => {
|
||||||
|
return amount
|
||||||
|
.replace(/[^\d]/g, "") // Remove non-numeric characters
|
||||||
|
.replace(/\B(?=(\d{3})+(?!\d))/g, "."); // Add period as thousand separator
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDonationAmountChange = (value) => {
|
||||||
|
const formattedValue = formatAmount(value);
|
||||||
|
setDonationAmount(formattedValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle Goal Selection
|
||||||
|
const handleGoalSelection = (goal) => {
|
||||||
|
setSelectedGoal(goal);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if all fields are filled
|
||||||
|
const isFormValid = () => {
|
||||||
|
return donationAmount && selectedGoal && description.trim() !== "";
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView style={styles.container}>
|
||||||
|
{/* Header with Back Button */}
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#333" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>DONASI</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Donation Amount Input */}
|
||||||
|
<View style={styles.inputSection}>
|
||||||
|
<Text style={styles.inputLabel}>Jumlah Donasi</Text>
|
||||||
|
<View style={styles.donationInputContainer}>
|
||||||
|
<Text style={styles.rpLabel}>Rp.</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.donationInput}
|
||||||
|
placeholder="Masukkan jumlah donasi"
|
||||||
|
placeholderTextColor="#888" // Gray placeholder text color
|
||||||
|
keyboardType="numeric"
|
||||||
|
value={donationAmount}
|
||||||
|
onChangeText={handleDonationAmountChange}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Donation Goal Selection */}
|
||||||
|
<View style={styles.goalsSection}>
|
||||||
|
<Text style={styles.inputLabel}>Tujuan Donasi</Text>
|
||||||
|
<View style={styles.goalsContainer}>
|
||||||
|
{[
|
||||||
|
"Pengelolaan Sampah",
|
||||||
|
"Program Penghijauan",
|
||||||
|
"Edukasi Lingkungan",
|
||||||
|
"Fasilitas Ramah Lingkungan",
|
||||||
|
"Kegiatan Pembersihan Lingkungan",
|
||||||
|
].map((goal) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
key={goal}
|
||||||
|
style={[
|
||||||
|
styles.goalButton,
|
||||||
|
selectedGoal === goal && styles.selectedGoalButton,
|
||||||
|
]}
|
||||||
|
onPress={() => handleGoalSelection(goal)}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
selectedGoal === goal
|
||||||
|
? styles.selectedGoalText
|
||||||
|
: styles.goalText
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{goal}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Description Input */}
|
||||||
|
<View style={styles.inputSection}>
|
||||||
|
<Text style={styles.inputLabel}>Deskripsi</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.descriptionInput}
|
||||||
|
placeholder="Tuliskan deskripsi (opsional)"
|
||||||
|
multiline
|
||||||
|
numberOfLines={4}
|
||||||
|
value={description}
|
||||||
|
onChangeText={setDescription}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Next Button */}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[styles.nextButton, !isFormValid() && styles.disabledButton]}
|
||||||
|
onPress={() => isFormValid() && navigation.navigate("MetodeDonasi")}
|
||||||
|
disabled={!isFormValid()} // Disable if form is not valid
|
||||||
|
>
|
||||||
|
<Text style={styles.nextButtonText}>Selanjutnya</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 20,
|
||||||
|
backgroundColor: "#f9f9f9",
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
marginTop: 30,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
inputSection: {
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
inputLabel: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
donationInputContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
borderColor: "#ddd",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 8,
|
||||||
|
paddingLeft: 15,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
},
|
||||||
|
rpLabel: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
donationInput: {
|
||||||
|
height: 50,
|
||||||
|
flex: 1,
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
},
|
||||||
|
goalsSection: {
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
goalsContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
gap: 10,
|
||||||
|
},
|
||||||
|
goalButton: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "#ddd",
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
borderRadius: 5,
|
||||||
|
backgroundColor: "#f0f0f0",
|
||||||
|
},
|
||||||
|
selectedGoalButton: {
|
||||||
|
borderColor: "#2D572C",
|
||||||
|
backgroundColor: "#e0f7e0",
|
||||||
|
},
|
||||||
|
goalText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
selectedGoalText: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: "#2D572C",
|
||||||
|
},
|
||||||
|
descriptionInput: {
|
||||||
|
height: 100,
|
||||||
|
borderColor: "#ddd",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 8,
|
||||||
|
paddingLeft: 15,
|
||||||
|
paddingTop: 10,
|
||||||
|
fontSize: 14,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
},
|
||||||
|
nextButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 15,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
disabledButton: {
|
||||||
|
backgroundColor: "#b0b0b0", // Disabled button color
|
||||||
|
},
|
||||||
|
nextButtonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Donasi;
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
StyleSheet,
|
||||||
|
} from "react-native";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
|
||||||
|
const DonasiVerifikasi = () => {
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const [pin, setPin] = useState("");
|
||||||
|
|
||||||
|
const handlePinSubmit = () => {
|
||||||
|
if (pin.length === 6) {
|
||||||
|
alert("Pembayaran Tervalidasi");
|
||||||
|
} else {
|
||||||
|
alert("PIN harus 6 digit");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.header}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.backButton}
|
||||||
|
onPress={() => navigation.goBack()}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-back" size={24} color="#333" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.title}>VERIFIKASI PIN</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Text style={styles.instructionText}>
|
||||||
|
Masukkan PIN Anda untuk melanjutkan pembayaran
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
style={styles.pinInput}
|
||||||
|
secureTextEntry
|
||||||
|
keyboardType="numeric"
|
||||||
|
maxLength={6}
|
||||||
|
placeholder="Masukkan PIN"
|
||||||
|
value={pin}
|
||||||
|
onChangeText={setPin}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.submitButton}
|
||||||
|
// onPress={handlePinSubmit}
|
||||||
|
onPress={() => navigation.navigate("Donasiberhasil")}
|
||||||
|
>
|
||||||
|
<Text style={styles.submitButtonText}>Konfirmasi PIN</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 20,
|
||||||
|
backgroundColor: "#f9f9f9",
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: 30,
|
||||||
|
marginTop: 30,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
marginRight: 10,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#333",
|
||||||
|
},
|
||||||
|
instructionText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#666",
|
||||||
|
marginVertical: 15,
|
||||||
|
},
|
||||||
|
pinInput: {
|
||||||
|
borderBottomWidth: 2,
|
||||||
|
borderColor: "#333",
|
||||||
|
fontSize: 20,
|
||||||
|
paddingVertical: 10,
|
||||||
|
textAlign: "center",
|
||||||
|
marginVertical: 20,
|
||||||
|
},
|
||||||
|
submitButton: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 15,
|
||||||
|
borderRadius: 8,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
submitButtonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default DonasiVerifikasi;
|
||||||
|
|
@ -0,0 +1,162 @@
|
||||||
|
import React from "react";
|
||||||
|
import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
|
||||||
|
import { MaterialIcons } from "@expo/vector-icons";
|
||||||
|
|
||||||
|
const Donasiberhasil = ({ navigation }) => {
|
||||||
|
const currentDate = new Date().toLocaleDateString("id-ID", {
|
||||||
|
weekday: "long",
|
||||||
|
year: "numeric",
|
||||||
|
month: "long",
|
||||||
|
day: "numeric",
|
||||||
|
});
|
||||||
|
|
||||||
|
const donationAmount = 100000;
|
||||||
|
const paymentMethod = "Transfer DANA";
|
||||||
|
const description = "Pengelolaan Sampah";
|
||||||
|
const senderName = "Dina Dwi Anisa";
|
||||||
|
const accountName = "Dinas Lingkungan Hidup";
|
||||||
|
const transactionId = "DN230512XYZ";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.card}>
|
||||||
|
<MaterialIcons name="check-circle" size={70} color="#2D572C" />
|
||||||
|
<Text style={styles.successText}>Terima Kasih!</Text>
|
||||||
|
<Text style={styles.subText}>Donasi Anda Telah Berhasil</Text>
|
||||||
|
|
||||||
|
<View style={styles.separator} />
|
||||||
|
|
||||||
|
{/* Struk Donasi */}
|
||||||
|
<View style={styles.row}>
|
||||||
|
<Text style={styles.label}>Tanggal</Text>
|
||||||
|
<Text style={styles.value}>{currentDate}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.row}>
|
||||||
|
<Text style={styles.label}>ID Transaksi</Text>
|
||||||
|
<Text style={styles.value}>{transactionId}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.row}>
|
||||||
|
<Text style={styles.label}>Nama Pengirim</Text>
|
||||||
|
<Text style={styles.value}>{senderName}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.row}>
|
||||||
|
<Text style={styles.label}>Akun Tujuan</Text>
|
||||||
|
<Text style={styles.value}>{accountName}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.row}>
|
||||||
|
<Text style={styles.label}>Jumlah Donasi</Text>
|
||||||
|
<Text style={styles.amount}>
|
||||||
|
Rp {donationAmount.toLocaleString("id-ID")}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.row}>
|
||||||
|
<Text style={styles.label}>Tujuan Donasi</Text>
|
||||||
|
<Text style={styles.value}>{description}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.row}>
|
||||||
|
<Text style={styles.label}>Metode Pembayaran</Text>
|
||||||
|
<Text style={styles.value}>{paymentMethod}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.thankYou}>
|
||||||
|
<Text style={styles.thankText}>
|
||||||
|
Semoga kebaikan Anda membawa berkah bagi banyak orang. 💚
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.button}
|
||||||
|
onPress={() => navigation.navigate("Home")}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>Kembali ke Beranda</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Donasiberhasil;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#F2F2F2",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
width: "100%",
|
||||||
|
borderRadius: 16,
|
||||||
|
padding: 25,
|
||||||
|
alignItems: "center",
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 8,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
successText: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#2D572C",
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
subText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#444",
|
||||||
|
marginTop: 5,
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
separator: {
|
||||||
|
height: 1,
|
||||||
|
width: "100%",
|
||||||
|
backgroundColor: "#ccc",
|
||||||
|
marginVertical: 20,
|
||||||
|
},
|
||||||
|
row: {
|
||||||
|
width: "100%",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#333",
|
||||||
|
fontWeight: "500",
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: "#666",
|
||||||
|
textAlign: "right",
|
||||||
|
flexShrink: 1,
|
||||||
|
marginLeft: 20,
|
||||||
|
},
|
||||||
|
amount: {
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: "#2D572C",
|
||||||
|
},
|
||||||
|
thankYou: {
|
||||||
|
marginTop: 25,
|
||||||
|
marginBottom: 20,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
},
|
||||||
|
thankText: {
|
||||||
|
textAlign: "center",
|
||||||
|
color: "#555",
|
||||||
|
fontSize: 14,
|
||||||
|
fontStyle: "italic",
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
backgroundColor: "#2D572C",
|
||||||
|
paddingVertical: 14,
|
||||||
|
paddingHorizontal: 30,
|
||||||
|
borderRadius: 10,
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: "600",
|
||||||
|
},
|
||||||
|
});
|
||||||