uplodowanie wszystkich zdjęć które są wybrane przy dodawaniu produktu

This commit is contained in:
2025-05-05 15:01:25 +02:00
parent 1a8fe7bb1d
commit 845a2e9593
4 changed files with 1483 additions and 192 deletions

View File

@@ -2,6 +2,7 @@ import axios from "axios";
import FormData from 'form-data'
const API_URL = "https://testowe.zikor.pl/api/v1";
// const API_URL = "http://172.20.10.2:8080/api/v1";
export async function listNotices() {
@@ -35,7 +36,10 @@ export async function createNotice(notice) {
// console.log("Image url: ", notice.image)
if (response.data.noticeId !== null) {
uploadImage(response.data.noticeId, notice.image);
notice.image.forEach(imageUri => {
uploadImage(response.data.noticeId, imageUri);
});
// uploadImage(response.data.noticeId, notice.image);
}
} catch (error) {
@@ -63,18 +67,15 @@ export async function getImageByNoticeId(noticeId) {
export const uploadImage = async (noticeId, imageUri) => {
console.log("Started upload image");
console.log(imageUri);
// Utwórz obiekt FormData
const formData = new FormData();
// Zdobądź nazwę pliku z URI
const filename = imageUri.split('/').pop();
// Określ typ MIME (możesz dostosować lub wykrywać dynamicznie)
const match = /\.(\w+)$/.exec(filename);
const type = match ? `image/${match[1]}` : 'image/jpeg';
// Dodaj plik do FormData w formacie akceptowanym przez serwer
formData.append('file', {
uri: imageUri,
name: filename,

View File

@@ -1,11 +1,12 @@
import { useState, useEffect } from "react";
import { Image, StyleSheet } from "react-native";
import { Button, ButtonText } from "@/components/ui/button";
import { FormControl } from "@/components/ui/form-control";
import { Input, InputField } from "@/components/ui/input";
import { Text } from "@/components/ui/text";
import { VStack } from "@/components/ui/vstack";
import { Textarea, TextareaInput } from "@/components/ui/textarea";
import {useState, useEffect} from "react";
import {Image, StyleSheet} from "react-native";
import {Button, ButtonText} from "@/components/ui/button";
import {FormControl} from "@/components/ui/form-control";
import {Input, InputField} from "@/components/ui/input";
import {Text} from "@/components/ui/text";
import {VStack} from "@/components/ui/vstack";
import {Textarea, TextareaInput} from "@/components/ui/textarea";
import {ScrollView} from '@gluestack-ui/themed';
import * as ImagePicker from 'expo-image-picker';
import {
Select,
@@ -19,8 +20,8 @@ import {
SelectScrollView,
} from "@/components/ui/select";
import { ChevronDownIcon } from "@/components/ui/icon";
import { useMutation } from "@tanstack/react-query";
import {ChevronDownIcon} from "@/components/ui/icon";
import {useMutation} from "@tanstack/react-query";
import {createNotice} from "@/api/notices";
import {listCategories} from "@/api/categories";
@@ -29,7 +30,7 @@ export default function CreateNotice() {
const [description, setDescription] = useState("");
const [price, setPrice] = useState("");
const [category, setCategory] = useState("");
const [image, setImage] = useState(null);
const [image, setImage] = useState([]);
const [selectItems, setSelectItems] = useState([]);
useEffect(() => {
@@ -119,21 +120,32 @@ export default function CreateNotice() {
if (!result.canceled) {
// await uploadImage(1, result.assets[0].uri);
setImage(result.assets[0].uri);
setImage(result.assets.map(asset => asset.uri));
}
};
return (
<ScrollView h="$80" w="$80">
<FormControl className="p-4 border rounded-lg border-outline-300">
<VStack space="xl">
<VStack space="xs">
<Text className="text-typography-500">Zdjęcie</Text>
<VStack space="md">
<Text className="text-typography-500">Zdjęcia</Text>
<Button onPress={pickImage}>
<ButtonText>
Upload image
Wybierz zdjęcia
</ButtonText>
</Button>
{image && <Image source={{ uri: image }} style={styles.image}/>}
<Text size="sm"
bold="true"
>
Pierwsze zdjęcie będzie zdjęciem głównym</Text>
{image && image.length > 0 && (
<VStack space="xs" className="flex-row flex-wrap">
{image.map((img, index) => (
<Image key={index} source={{uri: img}} style={styles.image} className="m-1"/>
))}
</VStack>
)}
</VStack>
<VStack space="xs">
@@ -179,15 +191,15 @@ export default function CreateNotice() {
isInvalid={error.category}
>
<SelectTrigger variant="outline" size="md">
<SelectInput placeholder="Wybierz kategorię" />
<SelectIcon className="mr-3" as={ChevronDownIcon} />
<SelectInput placeholder="Wybierz kategorię"/>
<SelectIcon className="mr-3" as={ChevronDownIcon}/>
</SelectTrigger>
<SelectPortal>
<SelectBackdrop />
<SelectContent style={{ maxHeight: 400 }}>
<SelectBackdrop/>
<SelectContent style={{maxHeight: 400}}>
<SelectScrollView>
{selectItems.map((item) => (
<SelectItem key={item.value} label={item.label} value={item.value} />
<SelectItem key={item.value} label={item.label} value={item.value}/>
))}
</SelectScrollView>
</SelectContent>
@@ -195,13 +207,14 @@ export default function CreateNotice() {
</Select>
</VStack>
<Button
className="ml-auto"
className="mt-5 w-full"
onPress={() => addNotice()}
disabled={noticeMutation.isLoading}
>
<ButtonText className="text-typography-0">Save</ButtonText>
<ButtonText className="text-typography-0">Dodaj</ButtonText>
</Button>
</VStack>
</FormControl>
</ScrollView>
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -11,6 +11,7 @@
"dependencies": {
"@expo/html-elements": "^0.4.2",
"@expo/vector-icons": "^14.1.0",
"@gluestack-style/react": "^1.0.57",
"@gluestack-ui/actionsheet": "^0.2.53",
"@gluestack-ui/button": "^1.0.14",
"@gluestack-ui/form-control": "^0.1.19",
@@ -21,6 +22,7 @@
"@gluestack-ui/overlay": "^0.1.22",
"@gluestack-ui/select": "^0.1.31",
"@gluestack-ui/textarea": "^0.1.25",
"@gluestack-ui/themed": "^1.1.73",
"@gluestack-ui/toast": "^1.0.9",
"@legendapp/motion": "^2.4.0",
"@tanstack/react-query": "^5.74.4",