From 2218c5eb33eac5343f3f3941a504ce6c72717cb1 Mon Sep 17 00:00:00 2001 From: Andrii Solianyk Date: Sun, 8 Jun 2025 22:31:52 +0200 Subject: [PATCH] =?UTF-8?q?zdj=C4=99cia=20pobieraj=C4=85=20si=C4=99=20na?= =?UTF-8?q?=20g=C5=82=C3=B3wnej=20stronie=20+=20naprawiono=20kilka=20innyc?= =?UTF-8?q?h=20bug=C3=B3w.=20takich=20jak=20wy=C5=9Bwietlanie=20"Moich=20o?= =?UTF-8?q?g=C5=82osze=C5=84=20nie=20dla=20poprawnego=20id=20etc."?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ArtisanConnect/api/categories.jsx | 2 +- ArtisanConnect/api/notices.jsx | 25 +- ArtisanConnect/api/wishlist.jsx | 2 +- .../app/(tabs)/dashboard/userNotices.jsx | 12 +- ArtisanConnect/app/(tabs)/index.jsx | 6 +- ArtisanConnect/app/(tabs)/wishlist.jsx | 22 +- ArtisanConnect/components/NoticeCard.jsx | 10 +- ArtisanConnect/store/authStore.jsx | 257 +++++++++--------- 8 files changed, 172 insertions(+), 164 deletions(-) diff --git a/ArtisanConnect/api/categories.jsx b/ArtisanConnect/api/categories.jsx index ed76375..329bef6 100644 --- a/ArtisanConnect/api/categories.jsx +++ b/ArtisanConnect/api/categories.jsx @@ -8,7 +8,7 @@ export async function listCategories() { const headers = token ? { Authorization: `Bearer ${token}` } : {}; try { - const response = await axios.get(`${API_URL}/vars/categories`, { headers }); + const response = await axios.get(`${API_URL}/vars/categories`, { headers: headers }); return response.data; } catch (err) { console.error("Nie udało się pobrać listy kategorii.", err.response.status); diff --git a/ArtisanConnect/api/notices.jsx b/ArtisanConnect/api/notices.jsx index 70da796..222cdb8 100644 --- a/ArtisanConnect/api/notices.jsx +++ b/ArtisanConnect/api/notices.jsx @@ -33,12 +33,10 @@ export async function getNoticeById(noticeId) { } export async function createNotice(notice) { + const { token } = useAuthStore.getState(); + const headers = token ? { Authorization: `Bearer ${token}` } : {}; try { - const response = await axios.post(`${API_URL}/notices/add`, notice, { - headers: { - "Content-Type": "application/json", - }, - }); + const response = await axios.post(`${API_URL}/notices/add`, notice, {headers: headers}); if (response.data.noticeId !== null) { for (const imageUri of notice.image) { @@ -73,27 +71,26 @@ export async function getAllImagesByNoticeId(noticeId) { const { token } = useAuthStore.getState(); const headers = token ? { Authorization: `Bearer ${token}` } : {}; try { - const listResponse = await axios.get(`${API_URL}/images/list/${noticeId}`, { - headers, - }); + const listResponse = await axios.get(`${API_URL}/images/list/${noticeId}`, {headers: headers}); if (listResponse.data && listResponse.data.length > 0) { - return listResponse.data.map( - (imageName) => `${API_URL}/images/get/${imageName}` - ); + return listResponse.data.map((imageName) => ({ + uri: `${API_URL}/images/get/${imageName}`, + headers: headers, + })); } - return ["https://http.cat/404.jpg"]; + return [{ uri: "https://http.cat/404.jpg" }]; } catch (err) { if (err.response.status === 404) { // console.info(`Ogłoszenie o id: ${noticeId} nie posiada zdjęć.`); - return ["https://http.cat/404.jpg"]; + return [{ uri: "https://http.cat/404.jpg" }]; } console.warn( `Nie udało się pobrać listy zdjęć dla ogłoszenia o id: ${noticeId}`, err ); - return ["https://http.cat/404.jpg"]; + return [{ uri: "https://http.cat/404.jpg" }]; } } diff --git a/ArtisanConnect/api/wishlist.jsx b/ArtisanConnect/api/wishlist.jsx index 265fc71..279c319 100644 --- a/ArtisanConnect/api/wishlist.jsx +++ b/ArtisanConnect/api/wishlist.jsx @@ -1,6 +1,5 @@ import axios from "axios"; import { useAuthStore } from "@/store/authStore"; -// import FormData from 'form-data' const API_URL = "https://hopp.zikor.pl/api/v1/wishlist"; @@ -36,3 +35,4 @@ export async function getWishlist() { throw error; } } +`` \ No newline at end of file diff --git a/ArtisanConnect/app/(tabs)/dashboard/userNotices.jsx b/ArtisanConnect/app/(tabs)/dashboard/userNotices.jsx index 754746a..f70ece7 100644 --- a/ArtisanConnect/app/(tabs)/dashboard/userNotices.jsx +++ b/ArtisanConnect/app/(tabs)/dashboard/userNotices.jsx @@ -1,6 +1,6 @@ import { useNoticesStore } from "@/store/noticesStore"; import { NoticeCard } from "@/components/NoticeCard"; -import { Button, ButtonIcon, ButtonText } from "@/components/ui/button"; +import { Button, ButtonText } from "@/components/ui/button"; import { Box } from "@/components/ui/box"; import { Text } from "@/components/ui/text"; @@ -12,15 +12,17 @@ import { Linking } from "react-native"; import { Ionicons } from "@expo/vector-icons"; import { useToast, Toast, ToastTitle } from "@/components/ui/toast"; import { AppState } from "react-native"; +import { useAuthStore } from "@/store/authStore"; export default function UserNotices() { const { notices, fetchNotices, deleteNotice } = useNoticesStore(); const [isLoading, setIsLoading] = useState(true); const [isRedirecting, setIsRedirecting] = useState(false); - const currentUserId = 1; const toast = useToast(); const appState = useRef(AppState.currentState); const [toastId, setToastId] = useState(0); + const { user_id } = useAuthStore.getState(); + const currentUserId= user_id; useEffect(() => { if (!isRedirecting) return; @@ -28,9 +30,9 @@ export default function UserNotices() { if (state === "active") { setIsRedirecting(false); const paymentStatus = "CORRECT"; - if (paymentStatus == "INCORRECT") { + if (paymentStatus === "INCORRECT") { showNewToast("Płatność została anulowana."); - } else if (paymentStatus == "CORRECT") { + } else if (paymentStatus === "CORRECT") { showNewToast("Płatność została zrealizowana."); } else { showNewToast("Płatność jeszcze nie wpłynęła."); @@ -83,7 +85,7 @@ export default function UserNotices() { const paymentResult = await createPayment(); //trzeba dodać orderId if (paymentResult) { setIsRedirecting(true); - Linking.openURL(paymentResult); + await Linking.openURL(paymentResult); setWaitingForPayment(true); } else { console.log(`Nie udało się aktywować ogłoszenia ${noticeId}.`); diff --git a/ArtisanConnect/app/(tabs)/index.jsx b/ArtisanConnect/app/(tabs)/index.jsx index fa8ec69..23df1b5 100644 --- a/ArtisanConnect/app/(tabs)/index.jsx +++ b/ArtisanConnect/app/(tabs)/index.jsx @@ -1,4 +1,4 @@ -import { ScrollView, View } from "react-native"; +import { ScrollView } from "react-native"; import { useNoticesStore } from "@/store/noticesStore"; import { CategorySection } from "@/components/CategorySection"; import { NoticeSection } from "@/components/NoticeSection"; @@ -10,7 +10,7 @@ import { useEffect, useState } from "react"; import { SafeAreaView } from "react-native"; export default function Home() { - const token = useAuthStore((state) => state.token); + const { token } = useAuthStore.getState(); const router = useRouter(); const [isReady, setIsReady] = useState(false); const fetchNotices = useNoticesStore((state) => state.fetchNotices); @@ -35,7 +35,7 @@ export default function Home() { // console.log("Notices:", notices); // console.log("Notices length:", notices.length); - const activeNotices = notices.filter((notice) => notice.status == "ACTIVE"); + const activeNotices = notices.filter((notice) => notice.status === "ACTIVE"); // console.log("Activer Notices:", activeNotices.length); const latestNotices = [...activeNotices] .sort((a, b) => new Date(b.publishDate) - new Date(a.publishDate)) diff --git a/ArtisanConnect/app/(tabs)/wishlist.jsx b/ArtisanConnect/app/(tabs)/wishlist.jsx index 60c8f5d..e106281 100644 --- a/ArtisanConnect/app/(tabs)/wishlist.jsx +++ b/ArtisanConnect/app/(tabs)/wishlist.jsx @@ -4,25 +4,36 @@ import { NoticeCard } from "@/components/NoticeCard"; import { Ionicons } from "@expo/vector-icons"; import { Box } from "@/components/ui/box"; import { Text } from "@/components/ui/text"; -import { useEffect } from "react"; +import {useCallback} from "react"; +import { useFocusEffect } from "@react-navigation/native"; + export default function Wishlist() { const wishlistNotices = useWishlist((state) => state.wishlistNotices); const fetchWishlist = useWishlist((state) => state.fetchWishlist); - useEffect(() => { - fetchWishlist(); - }, []); + useFocusEffect( + useCallback(() => { + fetchWishlist(); + }, [fetchWishlist]) + ); + + const styles = { + container: { + margin: 10, + } + } // console.log("Wishlist notices:", wishlistNotices); if (wishlistNotices.length === 0) { return ( - + Brak ulubionych ogłoszeń ); } + return ( } /> ); diff --git a/ArtisanConnect/components/NoticeCard.jsx b/ArtisanConnect/components/NoticeCard.jsx index 9a72044..eff274d 100644 --- a/ArtisanConnect/components/NoticeCard.jsx +++ b/ArtisanConnect/components/NoticeCard.jsx @@ -34,7 +34,7 @@ export function NoticeCard({ notice }) { const fetchImage = async () => { if (!noticeId) { if (isMounted) { - setImage("https://http.cat/404.jpg"); + setImage({uri: "https://http.cat/404.jpg"}); setIsLoading(false); } return; @@ -45,13 +45,13 @@ export function NoticeCard({ notice }) { const images = await getAllImagesByNoticeId(noticeId); if (isMounted) { setImage( - images && images.length > 0 ? images[0] : "https://http.cat/404.jpg" + images && images.length > 0 ? images[0] : {uri: "https://http.cat/404.jpg"} ); } } catch (error) { console.error(`Error while loading image: ${error}`); if (isMounted) { - setImage("https://http.cat/404.jpg"); + setImage({uri: "https://http.cat/404.jpg"}); } } finally { if (isMounted) { @@ -81,9 +81,7 @@ export function NoticeCard({ notice }) { ) : ( image { - // Dodaj interceptor tylko raz - if (!axios.interceptors.response.handlers.length) { - axios.interceptors.response.use( - (response) => response, - (error) => { - if ( - (error.response && error.response.status === 401) || - error.response.status === 403 - ) { - set({ user: null, token: null, isLoading: false }); - delete axios.defaults.headers.common["Authorization"]; + persist( + (set, get) => { + if (!interceptorInitialized.current) { + axios.interceptors.response.use( + (response) => response, + (error) => { + if ( + (error.response && error.response.status === 401) || + error.response.status === 403 + ) { + set({user_id: null, token: null, isLoading: false}); + delete axios.defaults.headers.common["Authorization"]; + } + return Promise.reject(error); + } + ); + interceptorInitialized = true; } - return Promise.reject(error); - } - ); - } + return { + user_id: null, + token: null, + isLoading: false, + error: null, - return { - user_id: null, - token: null, - isLoading: false, - error: null, + signIn: async (email, password) => { + set({isLoading: true, error: null}); + try { + const response = await axios.post(`${API_URL}/auth/login`, { + email, + password, + }); - signIn: async (email, password) => { - set({ isLoading: true, error: null }); - try { - const response = await axios.post(`${API_URL}/auth/login`, { - email, - password, - }); + const user_id = response.data.user_id; + const token = response.data.token; + set({user_id: user_id, token: token, isLoading: false}); - const user_id = response.data.user_id; - const token = response.data.token; - set({ user_id: user_id, token: token, isLoading: false }); + axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; + } catch (error) { + set({ + error: error.response?.data?.message || error.message, + isLoading: false, + }); + throw error; + } + }, - axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; - } catch (error) { - set({ - error: error.response?.data?.message || error.message, - isLoading: false, - }); - throw error; - } + signUp: async (userData) => { + set({isLoading: true, error: null}); + try { + const response = await axios.post( + `${API_URL}/auth/register`, + userData, + { + headers: {"Content-Type": "application/json"}, + } + ); + + const user_id = response.data.user_id; + const token = response.data.token; + set({user_id: user_id, token: token, isLoading: false}); + + axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; + } catch (error) { + set({ + error: error.response?.data?.message || error.message, + isLoading: false, + }); + throw error; + } + }, + + signInWithGoogle: async (googleToken) => { + set({isLoading: true, error: null}); + try { + const response = await axios.post( + `${API_URL}/auth/google`, + {googleToken: googleToken}, + { + headers: {"Content-Type": "application/json"}, + } + ); + const user_id = response.data.user_id; + const token = response.data.token; + set({user_id: user_id, token: token, isLoading: false}); + + axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; + } catch (error) { + set({ + error: error.response?.data?.message || error.message, + isLoading: false, + }); + throw error; + } + }, + + signOut: async () => { + try { + await axios.post(`${API_URL}/auth/logout`); + } catch (error) { + console.error("Logout error:", error); + } finally { + delete axios.defaults.headers.common["Authorization"]; + set({user_id: null, token: null}); + } + }, + + // checkAuth: async () => { + // const { token } = useAuthStore.getState(); + // if (!token) return null; + + // set({ isLoading: true }); + // try { + // axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; + + // const response = await axios.get(`${API_URL}/auth/me`); + + // set({ user_id: response.data, isLoading: false }); + // return response.data; + // } catch (error) { + // delete axios.defaults.headers.common["Authorization"]; + // set({ user_id: null, token: null, isLoading: false }); + // return null; + // } + // }, + }; }, - - signUp: async (userData) => { - set({ isLoading: true, error: null }); - try { - const response = await axios.post( - `${API_URL}/auth/register`, - userData, - { - headers: { "Content-Type": "application/json" }, - } - ); - - const user_id = response.data.user_id; - const token = response.data.token; - set({ user_id: user_id, token: token, isLoading: false }); - - axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; - } catch (error) { - set({ - error: error.response?.data?.message || error.message, - isLoading: false, - }); - throw error; - } - }, - - signInWithGoogle: async (googleToken) => { - set({ isLoading: true, error: null }); - try { - const response = await axios.post( - `${API_URL}/auth/google`, - { googleToken: googleToken }, - { - headers: { "Content-Type": "application/json" }, - } - ); - const user_id = response.data.user_id; - const token = response.data.token; - set({ user_id: user_id, token: token, isLoading: false }); - - axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; - } catch (error) { - set({ - error: error.response?.data?.message || error.message, - isLoading: false, - }); - throw error; - } - }, - - signOut: async () => { - try { - await axios.post(`${API_URL}/auth/logout`); - } catch (error) { - console.error("Logout error:", error); - } finally { - delete axios.defaults.headers.common["Authorization"]; - set({ user_id: null, token: null }); - } - }, - - // checkAuth: async () => { - // const { token } = useAuthStore.getState(); - // if (!token) return null; - - // set({ isLoading: true }); - // try { - // axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; - - // const response = await axios.get(`${API_URL}/auth/me`); - - // set({ user_id: response.data, isLoading: false }); - // return response.data; - // } catch (error) { - // delete axios.defaults.headers.common["Authorization"]; - // set({ user_id: null, token: null, isLoading: false }); - // return null; - // } - // }, - }; - }, - { - name: "auth-storage", - storage: createJSONStorage(() => AsyncStorage), - } - ) + { + name: "auth-storage", + storage: createJSONStorage(() => AsyncStorage), + } + ) );