diff --git a/app/(tabs)/add.jsx b/app/(tabs)/add.jsx
index 48893bd..35f94eb 100644
--- a/app/(tabs)/add.jsx
+++ b/app/(tabs)/add.jsx
@@ -1,10 +1,11 @@
import { useState } from 'react';
import { StyleSheet, Platform, KeyboardAvoidingView, ScrollView } from 'react-native';
-import { TextInput, Button, Snackbar } from 'react-native-paper';
-import { locations } from '@/data/locations';
-
+import { TextInput, Button, Snackbar } from 'react-native-paper';
+import useLocationStore from '@/store';
export default function FormScreen() {
+ const addLocation = useLocationStore((state) => state.addLocation);
+
const [formData, setFormData] = useState({
name: '',
description: '',
@@ -15,13 +16,16 @@ export default function FormScreen() {
const [message, setMessage] = useState('');
const [visible, setVisible] = useState(false);
- const [location, setLocation] = useState(locations.sort((a, b) => b.id - a.id));
-
- const addLocation = () => {
- console.log(formData);
- if(formData.name && formData.description && formData.image && formData.area && formData.population) {
+ const handleAddLocation = () => {
+ if (
+ formData.name &&
+ formData.description &&
+ formData.image &&
+ formData.area &&
+ formData.population
+ ) {
const newLocation = {
- id: locations.length > 0 ? locations[0].id + 1 : 0,
+ id: Date.now(), // Generowanie unikalnego ID
name: formData.name,
description: formData.description,
image: formData.image,
@@ -29,9 +33,7 @@ export default function FormScreen() {
population: formData.population,
};
- setLocation([newLocation, ...location]);
-
- locations.push(newLocation);
+ addLocation(newLocation);
setFormData({
name: '',
@@ -42,75 +44,75 @@ export default function FormScreen() {
});
setMessage('Lokalizacja została dodana!');
setVisible(true);
- }else{
+ } else {
setMessage('Wypełnij wszystkie pola!');
setVisible(true);
}
- }
+ };
return (
-
- setVisible(false)}
- duration={3000}
- >
- {message}
-
+ style={{ flex: 1 }}
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
+ >
+
+ setVisible(false)}
+ duration={3000}
+ >
+ {message}
+
setFormData({ ...formData, name: e })}
-
- />
- setFormData({ ...formData, name: e })}
+ />
+ setFormData({ ...formData, description: e })}
- />
- setFormData({ ...formData, description: e })}
+ />
+ setFormData({ ...formData, image: e })}
- />
+ onChangeText={(e) => setFormData({ ...formData, image: e })}
+ />
setFormData({ ...formData, area: e })}
+ onChangeText={(e) => setFormData({ ...formData, area: e })}
/>
setFormData({ ...formData, population: e })}
+ keyboardType="numeric"
+ onChangeText={(e) => setFormData({ ...formData, population: e })}
/>
-
-
+ onPress={handleAddLocation}
+ >
+ Dodaj
+
);
@@ -123,7 +125,4 @@ const styles = StyleSheet.create({
justifyContent: 'flex-start',
alignItems: 'center',
},
- text: {
- color: '#fff',
- },
-});
+});
\ No newline at end of file
diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx
index 76034b3..3be9b20 100644
--- a/app/(tabs)/index.tsx
+++ b/app/(tabs)/index.tsx
@@ -1,31 +1,32 @@
import { View, StyleSheet, FlatList } from 'react-native';
-import { useTheme, Card, Text, Button} from 'react-native-paper';
+import { useTheme, Card, Text, Button } from 'react-native-paper';
import { Link } from 'expo-router';
-import { locations } from '@/data/locations';
+import useLocationStore from '@/store';
export default function Index() {
-const theme = useTheme();
-locations.sort((a, b) => b.id - a.id);
+ const theme = useTheme();
+ const locations = useLocationStore((state) => state.locations);
+
return (
-
-
+ item.name}
+ keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => (
-
-
-
+
+
+
{item.name}
{item.description.split('.')[0]}...
-
-
+
+
- )}>
-
+ )}
+ />
);
}
@@ -37,7 +38,4 @@ const styles = StyleSheet.create({
justifyContent: 'center',
alignItems: 'center',
},
- text: {
- color: '#fff',
- },
-});
+});
\ No newline at end of file
diff --git a/app/_layout.jsx b/app/_layout.jsx
index 87de867..d9f3d42 100644
--- a/app/_layout.jsx
+++ b/app/_layout.jsx
@@ -1,13 +1,21 @@
-import { Link, Stack } from 'expo-router';
-import { useColorScheme } from 'react-native';
+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 useLocationStore from '@/store';
export default function RootLayout() {
const colorScheme = useColorScheme();
const theme = colorScheme === 'dark' ? MD3DarkTheme :
MD3LightTheme;
+ const deleteLocation = useLocationStore((state) => state.deleteLocation);
+ const router = useRouter();
+
+ const handleDelete = (id) => {
+ deleteLocation(id);
+ router.replace('/');
+ };
return (
@@ -35,7 +43,12 @@ export default function RootLayout() {
),
})}
/>
-
+ ({ title: "Edycja",
+ headerRight: () => (
+ handleDelete(route.params.id)}/>
+ ), })}
+
+ />
);
diff --git a/app/location/[id].js b/app/location/[id].js
index a273e42..b3e40d2 100644
--- a/app/location/[id].js
+++ b/app/location/[id].js
@@ -1,50 +1,51 @@
import { View, ScrollView, StyleSheet } from 'react-native';
import { Text, Card } from 'react-native-paper';
import { useLocalSearchParams } from 'expo-router';
-import { locations } from '@/data/locations';
+import useLocationStore from '@/store';
export default function Location() {
const { id } = useLocalSearchParams();
- const location = locations.find(loc => loc.id == id);
+ const location = useLocationStore((state) =>
+ state.locations.find((loc) => loc.id == id)
+ );
if (!location) {
return (
- Brak lokalizaji - {id}
+ Brak lokalizacji - {id}
);
}
return (
-
-
-
-
-
- {location.name}
-
-
- Opis:
-
-
- {location.description}
-
-
+
+
+
+
+
+ {location.name}
+
+
+ Opis:
+
+ {location.description}
+
-
-
- Statystyki:
-
-
- Powierzchnia: {location.area} km²
+
+
+ Statystyki:
-
- Ludność: {location.population} osób
+
+ Powierzchnia: {location.area} km²
-
-
-
+
+ Ludność: {location.population} osób
+
+
+
+
+
);
}
@@ -58,4 +59,4 @@ const styles = StyleSheet.create({
text: {
color: '#fff',
},
-});
+});
\ No newline at end of file
diff --git a/app/location/edit/[id].js b/app/location/edit/[id].js
index b31a702..e4ead45 100644
--- a/app/location/edit/[id].js
+++ b/app/location/edit/[id].js
@@ -1,126 +1,131 @@
import { useState, useEffect } from 'react';
import { StyleSheet, Platform, ScrollView, KeyboardAvoidingView } from 'react-native';
-import { TextInput, Button, Snackbar } from 'react-native-paper';
-import { locations } from '@/data/locations';
+import { TextInput, Button, Snackbar } from 'react-native-paper';
import { useLocalSearchParams, useRouter } from 'expo-router';
+import useLocationStore from '@/store';
-export default function edit() {
- const { id } = useLocalSearchParams();
- const router = useRouter();
- const locationData = locations.find(loc => loc.id == id);
- const [formData, setFormData] = useState({
- name: '',
- description: '',
- image: '',
- area: '',
- population: '',
- });
+export default function EditLocation() {
+ const { id } = useLocalSearchParams();
+ const router = useRouter();
+ const location = useLocationStore((state) =>
+ state.locations.find((loc) => loc.id == id)
+ );
+ const updateLocation = useLocationStore((state) => state.updateLocation);
- const [message, setMessage] = useState('');
- const [visible, setVisible] = useState(false);
+ const [formData, setFormData] = useState({
+ name: '',
+ description: '',
+ image: '',
+ area: '',
+ population: '',
+ });
- useEffect(() => {
- if (locationData) {
- console.log(locationData);
- setFormData({
- name: locationData.name,
- description: locationData.description,
- image: locationData.image,
- area: locationData.area.toString(),
- population: locationData.population.toString(),
- });
- }
- }, [locationData]);
+ const [message, setMessage] = useState('');
+ const [visible, setVisible] = useState(false);
+ useEffect(() => {
+ if (location) {
+ setFormData({
+ name: location.name,
+ description: location.description,
+ image: location.image,
+ area: location.area.toString(),
+ population: location.population.toString(),
+ });
+ }
+ }, [location]);
- const editLocation = () => {
- if (
- formData.name &&
- formData.description &&
- formData.image &&
- formData.area &&
- formData.population
- ) {
- const index = locations.findIndex((loc) => loc.id == id);
- if (index !== -1) {
- locations[index] = { ...locations[index], ...formData };
- setMessage('Lokalizacja została zaktualizowana!');
- setVisible(true);
- }else{
- setMessage('Błąd spróbuj ponownie póżniej!');
- setVisible(true);
- }
- } else{
- setMessage('Wypełnij wszystkie pola!');
- setVisible(true);
- }
- };
+ const handleEditLocation = () => {
+ if (
+ formData.name &&
+ formData.description &&
+ formData.image &&
+ formData.area &&
+ formData.population
+ ) {
+ updateLocation(id, {
+ name: formData.name,
+ description: formData.description,
+ image: formData.image,
+ area: parseFloat(formData.area),
+ population: parseInt(formData.population, 10),
+ });
-
+ setMessage('Lokalizacja została zaktualizowana!');
+ setVisible(true);
+
+ // setTimeout(() => {
+ // router.replace(`/location/${id}`);
+ // }, 2000);
+ } else {
+ setMessage('Wypełnij wszystkie pola!');
+ setVisible(true);
+ }
+ };
return (
-
- setVisible(false)}
- duration={3000}
- >
- {message}
-
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
+ >
+
+ setVisible(false)}
+ duration={3000}
+ >
+ {message}
+
setFormData({ ...formData, name: e })}
-
- />
- setFormData({ ...formData, name: e })}
+ />
+ setFormData({ ...formData, description: e })}
- />
- setFormData({ ...formData, description: e })}
+ />
+ setFormData({ ...formData, image: e })}
- />
+ onChangeText={(e) => setFormData({ ...formData, image: e })}
+ />
setFormData({ ...formData, area: e })}
+ onChangeText={(e) => setFormData({ ...formData, area: e })}
/>
setFormData({ ...formData, population: e })}
+ keyboardType="numeric"
+ onChangeText={(e) => setFormData({ ...formData, population: e })}
/>
-
-
+ onPress={handleEditLocation}
+ >
+ Edytuj
+
);
@@ -133,7 +138,4 @@ const styles = StyleSheet.create({
justifyContent: 'flex-start',
alignItems: 'center',
},
- text: {
- color: '#fff',
- },
-});
+});
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 4d47cee..c8c6605 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,7 +20,8 @@
"react-native-paper": "^5.13.1",
"react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.4.0",
- "react-native-web": "~0.19.13"
+ "react-native-web": "~0.19.13",
+ "zustand": "^5.0.3"
},
"devDependencies": {
"@babel/core": "^7.20.0",
@@ -11773,6 +11774,35 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/zustand": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.3.tgz",
+ "integrity": "sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18.0.0",
+ "immer": ">=9.0.6",
+ "react": ">=18.0.0",
+ "use-sync-external-store": ">=1.2.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "use-sync-external-store": {
+ "optional": true
+ }
+ }
}
}
}
diff --git a/package.json b/package.json
index dc0b11c..ce31258 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,8 @@
"react-native-paper": "^5.13.1",
"react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.4.0",
- "react-native-web": "~0.19.13"
+ "react-native-web": "~0.19.13",
+ "zustand": "^5.0.3"
},
"devDependencies": {
"@babel/core": "^7.20.0",
diff --git a/store.js b/store.js
new file mode 100644
index 0000000..a7a7707
--- /dev/null
+++ b/store.js
@@ -0,0 +1,23 @@
+import { create } from 'zustand';
+import { locations as initialLocations } from '@/data/locations';
+
+console.log('Initial locations:', initialLocations);
+const useLocationStore = create((set) => ({
+ locations: initialLocations,
+ addLocation: (newLocation) =>
+ set((state) => ({
+ locations: [newLocation, ...state.locations],
+ })),
+ updateLocation: (id, updatedData) =>
+ set((state) => ({
+ locations: state.locations.map((loc) =>
+ loc.id == id ? { ...loc, ...updatedData } : loc
+ ),
+ })),
+ deleteLocation: (id) =>
+ set((state) => ({
+ locations: state.locations.filter((loc) => loc.id != id),
+ })),
+}));
+
+export default useLocationStore;
\ No newline at end of file