diff --git a/api/locations.jsx b/api/locations.jsx
index 228a605..5c03e50 100644
--- a/api/locations.jsx
+++ b/api/locations.jsx
@@ -6,15 +6,43 @@ export async function listLocations() {
try {
const response = await axios.get(`${API_URL}/locations/all`);
if (!response) {
- throw new Error("No locations found");
+ return "No locations found";
}
- return response.data;
+
+ // Нормализуем изображения в полученных данных
+ return response.data.map(location => ({
+ ...location,
+ imageSource: normalizeImageSource(location.image)
+ }));
} catch (error) {
console.error("Error fetching locations:", error);
throw error;
}
}
+const normalizeImageSource = (image) => {
+ if (!image) return null;
+
+ // Проверка, является ли изображение URL
+ if (typeof image === 'string') {
+ // Если строка начинается с http или https, это URL
+ if (image.startsWith('http://') || image.startsWith('https://')) {
+ return { uri: image };
+ }
+
+ // Проверка на base64
+ if (image.startsWith('data:image')) {
+ return { uri: image };
+ } else if (image.length > 100) {
+ // Предполагаем, что это base64 без префикса
+ return { uri: `data:image/jpeg;base64,${image}` };
+ }
+ }
+
+ // Возвращаем null для неправильного формата
+ return null;
+}
+
export async function getLocation(id) {
try {
const location = await axios.get(`${API_URL}/locations/${id}`);
@@ -22,7 +50,7 @@ export async function getLocation(id) {
throw new Error("Location not found");
}
- return location.data;
+ return [...location.data, {image: normalizeImageSource(location.image)}];
} catch (error) {
console.error("Error fetching location:", error);
throw error;
diff --git a/app/(tabs)/add.jsx b/app/(tabs)/add.jsx
index 99c0cf2..1c76fe9 100644
--- a/app/(tabs)/add.jsx
+++ b/app/(tabs)/add.jsx
@@ -1,172 +1,239 @@
-import { useState } from "react";
+import {useState} from "react";
import {
- StyleSheet,
- Platform,
- KeyboardAvoidingView,
- ScrollView,
- Image,
+ StyleSheet,
+ Platform,
+ KeyboardAvoidingView,
+ ScrollView,
+ Image,
+ View,
} from "react-native";
-import { TextInput, Button, Snackbar } from "react-native-paper";
-import { requestCameraPermissionsAsync, launchCameraAsync } from 'expo-image-picker';
+import {TextInput, Button, Snackbar, Text} from "react-native-paper";
+import {requestCameraPermissionsAsync, launchCameraAsync} from 'expo-image-picker';
import useLocationStore from "@/locationStore";
export default function FormScreen() {
- const [formData, setFormData] = useState({
- name: "",
- description: "",
- image: "",
- area: 0,
- population: 0,
- });
- const [message, setMessage] = useState("");
- const [visible, setVisible] = useState(false);
- const [picture, setPicture] = useState(null);
-
- const addLocation = useLocationStore((state) => state.addLocation);
-
- const handleAddLocation = async () => {
- if (
- formData.name &&
- formData.description &&
- formData.image &&
- formData.area &&
- formData.population
- ) {
- const newLocation = {
- id: Date.now(),
- name: formData.name,
- description: formData.description,
- image: formData.image,
- area: parseFloat(formData.area),
- population: parseInt(formData.population),
- };
-
- const added = await addLocation(newLocation);
- setFormData({
+ const [formData, setFormData] = useState({
name: "",
description: "",
image: "",
area: 0,
population: 0,
- });
- if (added != null) {
- setMessage("Lokalizacja została dodana!");
- setVisible(true);
- } else {
- setMessage("Wystąpił błąd podczas dodawania lokalizacji!");
- setVisible(true);
- }
- } else {
- setMessage("Wypełnij wszystkie pola!");
- setVisible(true);
- }
- };
-
- const takePicture = async () => {
- const {status} = await requestCameraPermissionsAsync();
- if (status !== 'granted') {
- return;
- }
- const result = await launchCameraAsync({
- allowsEditing: false,
});
+ const [message, setMessage] = useState("");
+ const [visible, setVisible] = useState(false);
+ const [picture, setPicture] = useState(null);
+ const [imageMethod, setImageMethod] = useState(null); // null, 'link' или 'camera'
- if (!result.canceled && result.assets && result.assets.length > 0) {
- setPicture(result.assets[0].uri);
+ const addLocation = useLocationStore((state) => state.addLocation);
+
+ const handleAddLocation = async () => {
+ if (
+ formData.name &&
+ formData.description &&
+ formData.image &&
+ formData.area &&
+ formData.population
+ ) {
+ const newLocation = {
+ id: Date.now(),
+ name: formData.name,
+ description: formData.description,
+ image: formData.image,
+ area: parseFloat(formData.area),
+ population: parseInt(formData.population),
+ };
+
+ const added = await addLocation(newLocation);
+ setFormData({
+ name: "",
+ description: "",
+ image: "",
+ area: 0,
+ population: 0,
+ });
+ setPicture(null);
+ setImageMethod(null);
+
+ if (added != null) {
+ setMessage("Lokalizacja została dodana!");
+ setVisible(true);
+ } else {
+ setMessage("Wystąpił błąd podczas dodawania lokalizacji!");
+ setVisible(true);
+ }
+ } else {
+ setMessage("Wypełnij wszystkie pola!");
+ console.log(formData);
+ setVisible(true);
+ }
+ };
+
+ const takePicture = async () => {
+ const {status} = await requestCameraPermissionsAsync();
+ if (status !== 'granted') {
+ setMessage("Brak uprawnień do kamery!");
+ setVisible(true);
+ return;
+ }
+ const result = await launchCameraAsync({
+ allowsEditing: false,
+ base64: true,
+ });
+
+ if (!result.canceled && result.assets && result.assets.length > 0) {
+ const image = result.assets[0];
+ setPicture(image.uri);
+ console.log(image.base64);
+ setFormData({...formData, image: image.base64});
+ }
}
- }
- return (
-
-
- setVisible(false)}
- duration={3000}
+ const selectImageMethod = (method) => {
+ setImageMethod(method);
+ if (method === 'camera') {
+ takePicture()
+ } else {
+ setFormData({...formData, image: ""});
+ setPicture(null);
+ }
+ }
+
+ return (
+
- {message}
-
- setFormData({ ...formData, name: e })}
- />
- setFormData({ ...formData, description: e })}
- />
- setFormData({ ...formData, image: e })}
- />
- setFormData({ ...formData, area: e })}
- />
- setFormData({ ...formData, population: e })}
- />
-
-
- {picture && (
-
- )}
-
-
- );
+
+ setVisible(false)}
+ duration={3000}
+ >
+ {message}
+
+ Jak chcesz dodać zdjęcie?
+
+
+
+
+
+ {imageMethod === 'link' && (
+ setFormData({...formData, image: e})}
+ />
+ )}
+
+
+ {picture && (
+
+
+
+ )}
+ setFormData({...formData, name: e})}
+ />
+ setFormData({...formData, description: e})}
+ />
+ setFormData({...formData, area: e})}
+ />
+ setFormData({...formData, population: e})}
+ />
+
+
+
+ );
}
const styles = StyleSheet.create({
- container: {
- flex: 1,
- backgroundColor: "#25292e",
- justifyContent: "flex-start",
- alignItems: "center",
- },
- image: {
- width: 100,
- height: 100,
- borderStyle: "solid",
- borderColor: "#fff",
- borderWidth: 1,
- },
-});
+ container: {
+ flex: 1,
+ backgroundColor: "#25292e",
+ justifyContent: "flex-start",
+ alignItems: "center",
+ padding: 10,
+ },
+ imageContainer: {
+ width: "100%",
+ alignItems: "flex-start",
+ marginVertical: 10,
+ },
+ image: {
+ width: 150,
+ height: 150,
+ borderStyle: "solid",
+ borderColor: "#fff",
+ borderWidth: 1,
+ borderRadius: 5,
+ },
+ imageMethodButtons: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ width: '100%',
+ marginVertical: 10,
+ },
+ methodButton: {
+ flex: 1,
+ marginHorizontal: 5,
+ },
+ label: {
+ marginTop: 10,
+ marginBottom: 10,
+ color: "#fff",
+ verticalAlign: "middle",
+ textAlign: "center",
+ }
+});
\ No newline at end of file
diff --git a/app/(tabs)/index.jsx b/app/(tabs)/index.jsx
index a5d3d01..3f32506 100644
--- a/app/(tabs)/index.jsx
+++ b/app/(tabs)/index.jsx
@@ -20,10 +20,10 @@ export default function Index() {
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => (
-
+
{item.name}
diff --git a/app/location/[id].jsx b/app/location/[id].jsx
index 9442be1..683cd19 100644
--- a/app/location/[id].jsx
+++ b/app/location/[id].jsx
@@ -1,4 +1,4 @@
-import { View, ScrollView, StyleSheet, ActivityIndicator } from "react-native";
+import { View, ScrollView, StyleSheet } from "react-native";
import { useEffect } from "react";
import { useTheme, Text, Card } from "react-native-paper";
import { useLocalSearchParams } from "expo-router";
@@ -33,7 +33,7 @@ export default function Location() {