From 1a8144aee40d1cce69ffeb073627544388888635 Mon Sep 17 00:00:00 2001 From: Patryk Date: Thu, 15 May 2025 00:06:38 +0200 Subject: [PATCH] add Zustand and del unnecessary files --- App.js | 20 ------- api/locations.jsx | 104 ++++++++++++++++----------------- app/(tabs)/add.jsx | 11 ++-- app/(tabs)/index.jsx | 76 ++++++++----------------- app/_layout.jsx | 77 +++++++++++++++---------- app/location/[id].jsx | 56 ++++++++---------- app/location/edit/[id].jsx | 114 ++++++++++++++++++++----------------- locationStore.js | 75 ++++++++++++++++++++++++ package-lock.json | 8 +-- package.json | 2 +- 10 files changed, 295 insertions(+), 248 deletions(-) delete mode 100644 App.js create mode 100644 locationStore.js diff --git a/App.js b/App.js deleted file mode 100644 index 231df82..0000000 --- a/App.js +++ /dev/null @@ -1,20 +0,0 @@ -// import { StatusBar } from 'expo-status-bar'; -// import { StyleSheet, Text, View } from 'react-native'; - -// export default function App() { -// return ( -// -// Open up App.js to start working on your app! -// -// -// ); -// } - -// const styles = StyleSheet.create({ -// container: { -// flex: 1, -// backgroundColor: '#fff', -// alignItems: 'center', -// justifyContent: 'center', -// }, -// }); diff --git a/api/locations.jsx b/api/locations.jsx index 3d2835a..228a605 100644 --- a/api/locations.jsx +++ b/api/locations.jsx @@ -3,71 +3,73 @@ import axios from "axios"; const API_URL = "https://hopp.zikor.pl"; export async function listLocations() { - try { - const response = await axios.get(`${API_URL}/locations/all`); - if (!response) { - throw new Error("No locations found"); - } - return response.data; - } catch (error) { - console.error("Error fetching locations:", error); - throw error; + try { + const response = await axios.get(`${API_URL}/locations/all`); + if (!response) { + throw new Error("No locations found"); } + return response.data; + } catch (error) { + console.error("Error fetching locations:", error); + throw error; + } } export async function getLocation(id) { - try { - const location = await axios.get(`${API_URL}/locations/${id}`); - if (!location) { - throw new Error("Location not found"); - } - - return location.data; - } catch (error) { - console.error("Error fetching location:", error); - throw error; + try { + const location = await axios.get(`${API_URL}/locations/${id}`); + if (!location) { + throw new Error("Location not found"); } + + return location.data; + } catch (error) { + console.error("Error fetching location:", error); + throw error; + } } export async function addLocation(location) { - try { - const response = await axios.post(`${API_URL}/locations/add`, location, { - headers: { - "Content-Type": "application/json", - } - }); - if (!response) { - throw new Error("Failed to add location"); - } - return response.data; - } catch (error) { - console.error("Error adding location:", error); - throw error; + try { + const response = await axios.post(`${API_URL}/locations/add`, location, { + headers: { + "Content-Type": "application/json", + }, + }); + if (!response) { + throw new Error("Failed to add location"); } + return response.data; + } catch (error) { + console.error("Error adding location:", error); + throw error; + } } export async function updateLocation(id, location) { - try { - const response = await axios.put(`${API_URL}/locations/${id}`, location, { headers: { "Content-Type": "application/json" } }); - if (!response) { - throw new Error("Failed to add location"); - } - return response.data; - } catch (error) { - console.error("Error while updating location:", error); - throw error; + try { + const response = await axios.put(`${API_URL}/locations/${id}`, location, { + headers: { "Content-Type": "application/json" }, + }); + if (!response) { + throw new Error("Failed to add location"); } + return response.data; + } catch (error) { + console.error("Error while updating location:", error); + throw error; + } } export async function deleteLocation(id) { - try { - const response = await axios.delete(`${API_URL}/locations/${id}`); - if (!response) { - throw new Error("Failed to delete location"); - } - return response.data; - } catch (error) { - console.error("Error while deleting location:", error); - throw error; + try { + const response = await axios.delete(`${API_URL}/locations/${id}`); + if (!response) { + throw new Error("Failed to delete location"); } -} \ No newline at end of file + return response.data; + } catch (error) { + console.error("Error while deleting location:", error); + throw error; + } +} diff --git a/app/(tabs)/add.jsx b/app/(tabs)/add.jsx index 09f54ec..c19ce81 100644 --- a/app/(tabs)/add.jsx +++ b/app/(tabs)/add.jsx @@ -6,7 +6,7 @@ import { ScrollView, } from "react-native"; import { TextInput, Button, Snackbar } from "react-native-paper"; -import { addLocation } from "@/api/locations"; +import useLocationStore from "@/locationStore"; export default function FormScreen() { const [formData, setFormData] = useState({ @@ -19,7 +19,9 @@ export default function FormScreen() { const [message, setMessage] = useState(""); const [visible, setVisible] = useState(false); - const handleAddLocation = () => { + const addLocation = useLocationStore((state) => state.addLocation); + + const handleAddLocation = async () => { if ( formData.name && formData.description && @@ -36,8 +38,7 @@ export default function FormScreen() { population: parseInt(formData.population), }; - addLocation(newLocation); - + const added = await addLocation(newLocation); setFormData({ name: "", description: "", @@ -45,7 +46,7 @@ export default function FormScreen() { area: 0, population: 0, }); - if(addLocation != null) { + if (added != null) { setMessage("Lokalizacja została dodana!"); setVisible(true); } else { diff --git a/app/(tabs)/index.jsx b/app/(tabs)/index.jsx index 6bdc6c7..a722dd4 100644 --- a/app/(tabs)/index.jsx +++ b/app/(tabs)/index.jsx @@ -1,56 +1,36 @@ -import { View, StyleSheet, FlatList, ActivityIndicator, RefreshControl } from 'react-native'; -import { useTheme, Card, Text, Button } from 'react-native-paper'; -import { Link } from 'expo-router'; -import { useState, useEffect } from 'react'; -import { listLocations } from '@/api/locations'; +import { + View, + StyleSheet, + FlatList, + ActivityIndicator, + RefreshControl, +} from "react-native"; +import { useTheme, Card, Text, Button } from "react-native-paper"; +import { Link } from "expo-router"; +import { useState, useEffect } from "react"; +import useLocationStore from "@/locationStore"; export default function Index() { const theme = useTheme(); - const [locations, setLocations] = useState([]); - const [loading, setLoading] = useState(true); - const [refreshing, setRefreshing] = useState(false); - - const fetchLocations = async () => { - try { - const data = await listLocations(); - setLocations(data); - } catch (error) { - console.error("Error fetching locations:", error); - } finally { - setLoading(false); - } - }; - - const onRefresh = async () => { - setRefreshing(true); - await fetchLocations(); - setRefreshing(false); - }; - - useEffect(() => { - fetchLocations(); - }, []); - - if (loading) { - return ( - - - - ); - } + const { locations } = useLocationStore(); return ( - + item.id.toString()} renderItem={({ item }) => ( - + {item.name} - {item.description && item.description.split('.')[0]}... + {item.description && item.description.split(".")[0]}... @@ -60,14 +40,6 @@ export default function Index() { )} - refreshControl={ - - } /> ); @@ -76,8 +48,8 @@ export default function Index() { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: '#25292e', - justifyContent: 'center', - alignItems: 'center', + backgroundColor: "#25292e", + justifyContent: "center", + alignItems: "center", }, -}); \ No newline at end of file +}); diff --git a/app/_layout.jsx b/app/_layout.jsx index 60c8b2e..d83f581 100644 --- a/app/_layout.jsx +++ b/app/_layout.jsx @@ -1,33 +1,42 @@ -import { Link, Stack, useRouter } from 'expo-router'; -import { useColorScheme } from 'react-native'; -import { PaperProvider } from 'react-native-paper'; -import { MD3LightTheme, MD3DarkTheme } from 'react-native-paper'; -import Ionicons from '@expo/vector-icons/Ionicons'; -import { deleteLocation } from '@/api/locations'; +import { Link, Stack, useRouter } from "expo-router"; +import { useColorScheme } from "react-native"; +import { PaperProvider } from "react-native-paper"; +import { MD3LightTheme, MD3DarkTheme } from "react-native-paper"; +import { useEffect } from "react"; +import Ionicons from "@expo/vector-icons/Ionicons"; +import useLocationStore from "@/locationStore"; export default function RootLayout() { const colorScheme = useColorScheme(); - const theme = colorScheme === 'dark' ? MD3DarkTheme : - MD3LightTheme; + const theme = colorScheme === "dark" ? MD3DarkTheme : MD3LightTheme; const router = useRouter(); + const fetchLocations = useLocationStore((state) => state.fetchLocations); - const handleDelete = (id) => { - deleteLocation(id); - while (router.canGoBack()) { - router.back(); + useEffect(() => { + fetchLocations(); + }, []); + + console.log(); + const deleteLocation = useLocationStore((state) => state.deleteLocation); + + const handleDelete = async (id) => { + const isDeleted = await deleteLocation(id); + if (isDeleted) { + router.replace("/"); } - router.replace('/'); }; return ( - - + + - + ), })} /> - ({ - title: "Edycja", - headerRight: () => ( - handleDelete(route.params.id)} /> - ), - })} - + ({ + title: "Edycja", + headerRight: () => ( + handleDelete(route.params.id)} + /> + ), + })} /> diff --git a/app/location/[id].jsx b/app/location/[id].jsx index 6c7d248..9442be1 100644 --- a/app/location/[id].jsx +++ b/app/location/[id].jsx @@ -1,38 +1,25 @@ -import { View, ScrollView, StyleSheet, ActivityIndicator } from 'react-native'; -import { useTheme, Text, Card } from 'react-native-paper'; -import { useLocalSearchParams } from 'expo-router'; -import { useEffect, useState } from 'react'; -import { getLocation } from '@/api/locations'; +import { View, ScrollView, StyleSheet, ActivityIndicator } from "react-native"; +import { useEffect } from "react"; +import { useTheme, Text, Card } from "react-native-paper"; +import { useLocalSearchParams } from "expo-router"; +import useLocationStore from "@/locationStore"; export default function Location() { const theme = useTheme(); const { id } = useLocalSearchParams(); - const [location, setLocation] = useState(null); - const [loading, setLoading] = useState(true); + const getLocation = useLocationStore((state) => state.getLocation); + const fetchLocations = useLocationStore((state) => state.fetchLocations); + const loading = useLocationStore((state) => state.loading); + + const location = getLocation(id); useEffect(() => { - const fetchLocation = async () => { - try { - const data = await getLocation(id) - setLocation(data); - } catch (error) { - console.error("Error fetching location:", error); - } finally { - setLoading(false); - } + if (!location && !loading) { + fetchLocations(); } - fetchLocation(); - }, [id]); + }, [location, loading, fetchLocations]); - if (loading) { - return ( - - - - ); - } - - if (!location) { + if (loading || !location) { return ( Brak lokalizacji - {id} @@ -44,7 +31,10 @@ export default function Location() { - + {location.name} @@ -75,11 +65,11 @@ export default function Location() { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: '#25292e', - justifyContent: 'center', - alignItems: 'center', + backgroundColor: "#25292e", + justifyContent: "center", + alignItems: "center", }, text: { - color: '#fff', + color: "#fff", }, -}); \ No newline at end of file +}); diff --git a/app/location/edit/[id].jsx b/app/location/edit/[id].jsx index 43624bf..e0ddce4 100644 --- a/app/location/edit/[id].jsx +++ b/app/location/edit/[id].jsx @@ -1,8 +1,16 @@ -import { useState, useEffect } from 'react'; -import { StyleSheet, Platform, ScrollView, KeyboardAvoidingView, View, ActivityIndicator } from 'react-native'; -import { TextInput, Button, Snackbar, useTheme } from 'react-native-paper'; -import { useLocalSearchParams, useRouter } from 'expo-router'; -import { getLocation, updateLocation } from '@/api/locations'; +import { useState, useEffect } from "react"; +import { + StyleSheet, + Platform, + ScrollView, + KeyboardAvoidingView, + View, + ActivityIndicator, +} from "react-native"; +import { TextInput, Button, Snackbar, useTheme } from "react-native-paper"; +import { useLocalSearchParams, useRouter } from "expo-router"; +// import { getLocation } from "@/api/locations"; +import useLocationStore from "@/locationStore"; export default function EditLocation() { const theme = useTheme(); @@ -10,40 +18,34 @@ export default function EditLocation() { const router = useRouter(); const [loading, setLoading] = useState(true); const [formData, setFormData] = useState({ - name: '', - description: '', - image: '', - area: '', - population: '', + name: "", + description: "", + image: "", + area: "", + population: "", }); - const [message, setMessage] = useState(''); + const [message, setMessage] = useState(""); const [visible, setVisible] = useState(false); + const updateLocation = useLocationStore((state) => state.updateLocation); + const getLocation = useLocationStore((state) => state.getLocation); + useEffect(() => { - const fetchLocation = async () => { - try { - const data = await getLocation(id) - - if (data) { - setFormData({ - name: data.name, - description: data.description, - image: data.image, - area: data.area.toString(), - population: data.population.toString(), - }); - } - } catch (error) { - console.error("Error fetching location:", error); - } finally { - setLoading(false); - } + const data = getLocation(id); + if (data) { + setFormData({ + name: data.name, + description: data.description, + image: data.image, + area: data.area.toString(), + population: data.population.toString(), + }); } - fetchLocation(); - }, [id]); + setLoading(false); + }, [id, getLocation]); - const handleEditLocation = () => { + const handleEditLocation = async () => { if ( formData.name && formData.description && @@ -51,7 +53,8 @@ export default function EditLocation() { formData.area && formData.population ) { - const response = updateLocation(id, { + // console.log("Form data:", formData); + const response = await updateLocation(id, { name: formData.name, description: formData.description, image: formData.image, @@ -60,25 +63,30 @@ export default function EditLocation() { }); if (response) { - setMessage('Lokalizacja została zaktualizowana!'); + setMessage("Lokalizacja została zaktualizowana!"); setVisible(true); - while (router.canGoBack()) { // Pop from stack until one element is left - router.back(); - } - router.replace("/"); // Replace the last remaining stack element + // while (router.canGoBack()) { + // Pop from stack until one element is left + // router.back(); + // } + setTimeout(() => { + router.replace("/"); + }, 300); // Replace the last remaining stack element } else { - setMessage('Wystąpił błąd podczas aktualizacji lokalizacji!'); + setMessage("Wystąpił błąd podczas aktualizacji lokalizacji!"); setVisible(true); } } else { - setMessage('Wypełnij wszystkie pola!'); + setMessage("Wypełnij wszystkie pola!"); setVisible(true); } }; if (loading) { return ( - + ); @@ -87,7 +95,7 @@ export default function EditLocation() { return ( setFormData({ ...formData, name: e })} /> @@ -109,7 +117,7 @@ export default function EditLocation() { mode="outlined" label="Opis" placeholder="Wpisz opis" - style={{ margin: 10, width: '100%' }} + style={{ margin: 10, width: "100%" }} multiline={true} value={formData.description} onChangeText={(e) => setFormData({ ...formData, description: e })} @@ -119,7 +127,7 @@ export default function EditLocation() { label="Link do zdjęcia" multiline={true} placeholder="Wpisz link do zdjęcia" - style={{ margin: 10, width: '100%' }} + style={{ margin: 10, width: "100%" }} value={formData.image} onChangeText={(e) => setFormData({ ...formData, image: e })} /> @@ -127,7 +135,7 @@ export default function EditLocation() { mode="outlined" label="Powierzchnia" placeholder="Wpisz powierzchnię" - style={{ margin: 10, width: '100%' }} + style={{ margin: 10, width: "100%" }} value={formData.area} keyboardType="numeric" onChangeText={(e) => setFormData({ ...formData, area: e })} @@ -136,15 +144,15 @@ export default function EditLocation() { mode="outlined" label="Ludność" placeholder="Wpisz liczbę ludności" - style={{ margin: 10, width: '100%' }} + style={{ margin: 10, width: "100%" }} value={formData.population} keyboardType="numeric" onChangeText={(e) => setFormData({ ...formData, population: e })} />