diff --git a/ArtisanConnect/api/categories.jsx b/ArtisanConnect/api/categories.jsx
index 8ebbebb..9b95b55 100644
--- a/ArtisanConnect/api/categories.jsx
+++ b/ArtisanConnect/api/categories.jsx
@@ -13,6 +13,6 @@ export async function listCategories() {
});
return response.data;
} catch (err) {
- console.error("Nie udało się pobrać listy kategorii.", err.response.status);
+ // console.error("Nie udało się pobrać listy kategorii.", err.response.status);
}
}
diff --git a/ArtisanConnect/api/client.jsx b/ArtisanConnect/api/client.jsx
index 2faf2fa..4793d4d 100644
--- a/ArtisanConnect/api/client.jsx
+++ b/ArtisanConnect/api/client.jsx
@@ -7,10 +7,9 @@ export async function getUserById(userId) {
const { token } = useAuthStore.getState();
const headers = token ? { Authorization: `Bearer ${token}` } : {};
try {
- const response = await axios.get(
- `${API_URL}/clients/get/${userId}`,
- headers
- );
+ const response = await axios.get(`${API_URL}/clients/get/${userId}`, {
+ headers: headers,
+ });
return response.data;
} catch (err) {
console.error(
diff --git a/ArtisanConnect/app/(tabs)/index.jsx b/ArtisanConnect/app/(tabs)/index.jsx
index b9b3099..63d8a26 100644
--- a/ArtisanConnect/app/(tabs)/index.jsx
+++ b/ArtisanConnect/app/(tabs)/index.jsx
@@ -15,15 +15,15 @@ export default function Home() {
const [isReady, setIsReady] = useState(false);
const fetchNotices = useNoticesStore((state) => state.fetchNotices);
- useEffect(() => {
- setIsReady(true);
- }, []);
+ // useEffect(() => {
+ // setIsReady(true);
+ // }, []);
- useEffect(() => {
- if (isReady && !token) {
- router.replace("/login");
- }
- }, [isReady, token, router]);
+ // useEffect(() => {
+ // if (isReady && !token) {
+ // router.replace("/login");
+ // }
+ // }, [isReady, token, router]);
useEffect(() => {
if (token) {
diff --git a/ArtisanConnect/app/notice/[id].jsx b/ArtisanConnect/app/notice/[id].jsx
index 5ad9b2f..9c1a4be 100644
--- a/ArtisanConnect/app/notice/[id].jsx
+++ b/ArtisanConnect/app/notice/[id].jsx
@@ -5,7 +5,6 @@ import { Heading } from "@/components/ui/heading";
import { Image } from "@/components/ui/image";
import { Text } from "@/components/ui/text";
import { VStack } from "@/components/ui/vstack";
-import { Avatar, AvatarImage, AvatarFallbackText } from "@gluestack-ui/themed";
import { Ionicons } from "@expo/vector-icons";
import {
ActivityIndicator,
@@ -13,16 +12,14 @@ import {
FlatList,
View,
TextInput,
- SafeAreaView, Alert,
} from "react-native";
import { useEffect, useState, useRef } from "react";
import { useNoticesStore } from "@/store/noticesStore";
import { useWishlist } from "@/store/wishlistStore";
import { Pressable, ScrollView } from "react-native";
import { getUserById } from "@/api/client";
-import * as ScreenOrientation from "expo-screen-orientation";
-import { useAuthStore } from "@/store/authStore";
-import { sendEmail } from "@/api/email";
+
+const { width } = Dimensions.get("window");
export default function NoticeDetails() {
const { id } = useLocalSearchParams();
@@ -33,148 +30,49 @@ export default function NoticeDetails() {
const [notice, setNotice] = useState(null);
const [user, setUser] = useState(null);
const [isUserLoading, setIsUserLoading] = useState(true);
- const [isLandscape, setIsLandscape] = useState(false);
const flatListRef = useRef(null);
const [currentIndex, setCurrentIndex] = useState(0);
+
const [isMessageFormVisible, setIsMessageFormVisible] = useState(false);
const [message, setMessage] = useState("");
- const [isSending, setIsSending] = useState(false);
+ const [Email, setEmail] = useState("");
+ const handleSendMessage = () => {
+ console.log("Wiadomość do:", user?.email);
+ console.log("Email nadawcy:", Email);
+ console.log("Treść:", message);
-
- const handleSendMessage = async () => {
- setIsSending(true);
- console.log("Rozpoczynanie procesu wysyłania wiadomości...");
-
- const { user_id, token } = useAuthStore.getState();
- console.log("Dane z authStore:", { user_id, token });
-
- if (!user_id || !token) {
- console.error("Brak danych zalogowanego użytkownika.");
- Alert.alert("Błąd", "Zaloguj się, aby wysłać wiadomość.");
- setIsSending(false);
- return;
- }
-
- let currentUserEmail = "";
- try {
- console.log(`Pobieranie danych użytkownika dla user_id: ${user_id}`);
- const currentUser = await getUserById(user_id);
- console.log("Dane zalogowanego użytkownika:", currentUser);
- currentUserEmail = currentUser?.email;
- if (!currentUserEmail) {
- console.error("Nie znaleziono adresu email zalogowanego użytkownika.");
- Alert.alert("Błąd", "Nie znaleziono adresu email zalogowanego użytkownika.");
- setIsSending(false);
- return;
- }
- console.log(`Pobrano email zalogowanego użytkownika: ${currentUserEmail}`);
- } catch (error) {
- console.error("Błąd podczas pobierania danych użytkownika:", error);
- Alert.alert("Błąd", "Nie udało się pobrać danych użytkownika. Spróbuj ponownie później.");
- setIsSending(false);
- return;
- }
-
- const emailData = {
- to: user?.email || "",
- subject: `Zapytanie ${currentUserEmail} o ogłoszenie ${notice.title}`,
- body: message,
- };
- console.log("Dane emaila do wysyłki:", emailData);
-
- if (!emailData.to || !emailData.subject || !emailData.body) {
- console.error("Walidacja nieudana: brakujące pola w emailData.");
- Alert.alert("Błąd", "Wszystkie pola są wymagane!");
- setIsSending(false);
- return;
- }
-
- const result = await sendEmail(emailData);
- if (result.success) {
- console.log("Wiadomość wysłana pomyślnie!", result.result);
- setIsMessageFormVisible(false);
- setMessage("");
- Alert.alert("Sukces", "Wiadomość została wysłana!");
- } else {
- console.error("Błąd podczas wysyłania wiadomości:", result.error);
- Alert.alert("Błąd", `Nie udało się wysłać wiadomości: ${result.error}`);
- }
- setIsSending(false);
- console.log("Zakończono proces wysyłania wiadomości.");
+ setIsMessageFormVisible(false);
+ setMessage("");
+ setEmail("");
};
- const formatDate = (dateString) => {
- const date = new Date(dateString);
- return date.toLocaleDateString("pl-PL", {
- year: "numeric",
- month: "2-digit",
- day: "2-digit",
- });
- };
+ const formatDate = (dateString) => {
+ const date = new Date(dateString);
+ return date.toLocaleDateString("pl-PL", {
+ year: "numeric",
+ month: "2-digit",
+ day: "2-digit",
+ });
+ };
const { getNoticeById, getAllImagesByNoticeId } = useNoticesStore();
const toggleNoticeInWishlist = useWishlist(
- (state) => state.toggleNoticeInWishlist
+ (state) => state.toggleNoticeInWishlist
);
const isInWishlist = useWishlist((state) =>
- id ? state.wishlistNotices.some((item) => item.noticeId == id) : false
+ id ? state.wishlistNotices.some((item) => item.noticeId === id) : false
);
-
const onViewableItemsChanged = useRef(({ viewableItems }) => {
if (viewableItems.length > 0) {
setCurrentIndex(viewableItems[0].index);
}
+ }).current;
const viewabilityConfig = useRef({
itemVisiblePercentThreshold: 70,
}).current;
- useEffect(() => {
- const unlockOrientation = async () => {
- try {
- await ScreenOrientation.unlockAsync();
- } catch (err) {
- console.error("Error unlocking orientation:", err);
- }
- };
-
- const getInitialOrientation = async () => {
- try {
- const orientation = await ScreenOrientation.getOrientationAsync();
- setIsLandscape(
- orientation === ScreenOrientation.Orientation.LANDSCAPE_LEFT ||
- orientation === ScreenOrientation.Orientation.LANDSCAPE_RIGHT
- );
- } catch (err) {
- console.error("Error getting initial orientation:", err);
- }
- };
-
- unlockOrientation();
- getInitialOrientation();
-
- const subscription = ScreenOrientation.addOrientationChangeListener(
- ({ orientationInfo }) => {
- const isLandscapeMode =
- orientationInfo.orientation ===
- ScreenOrientation.Orientation.LANDSCAPE_LEFT ||
- orientationInfo.orientation ===
- ScreenOrientation.Orientation.LANDSCAPE_RIGHT;
- setIsLandscape(isLandscapeMode);
- }
- );
-
- return () => {
- ScreenOrientation.removeOrientationChangeListener(subscription);
- ScreenOrientation.lockAsync(
- ScreenOrientation.OrientationLock.PORTRAIT_UP
- ).catch((err) =>
- console.error("Error locking orientation on unmount:", err)
- );
- };
- }, []);
-
useEffect(() => {
const fetchNotice = async () => {
setIsLoading(true);
@@ -202,15 +100,14 @@ export default function NoticeDetails() {
if (notice) {
try {
const fetchedImages = await getAllImagesByNoticeId(notice.noticeId);
- console.log("Fetched images:", fetchedImages);
setImages(
- fetchedImages && fetchedImages.length > 0
- ? fetchedImages
- : ["https://http.cat/404.jpg"]
+ fetchedImages && fetchedImages.length > 0
+ ? fetchedImages
+ : { uri: "https://http.cat/404.jpg" }
);
} catch (err) {
console.error("Error while loading images:", err);
- setImages(["https://http.cat/404.jpg"]);
+ setImage({ uri: "https://http.cat/404.jpg" });
} finally {
setIsImageLoading(false);
}
@@ -220,10 +117,22 @@ export default function NoticeDetails() {
if (notice) {
fetchImage();
}
+ }, [notice]);
- if (!notice) {
- return Nie znaleziono ogłoszenia;
- }
+ useEffect(() => {
+ const fetchUser = async () => {
+ if (notice && notice.clientId) {
+ setIsUserLoading(true);
+ try {
+ const userData = await getUserById(notice.clientId);
+ setUser(userData);
+ } catch (err) {
+ console.error("Nie udało się pobrać danych użytkownika:", err);
+ } finally {
+ setIsUserLoading(false);
+ }
+ }
+ };
fetchUser();
}, [notice]);
@@ -233,209 +142,197 @@ export default function NoticeDetails() {
}
if (error) {
- return Błąd, spróbuj ponownie później: {error.message};
+ return Błąd, spróbuj ponownie póżniej: {error.message};
}
if (!notice) {
return Nie znaleziono ogłoszenia;
}
- const renderImageSection = () => {
- if (isImageLoading) {
- return (
-
-
-
- );
- }
-
- return (
-
+ return (
+
+
+ {isImageLoading ? (
+
+
+
+ ) : (
+
(
-
- console.error("Image load error:", e.nativeEvent.error)}
- />
-
- )}
- keyExtractor={(item, index) => index.toString()}
+ ref={flatListRef}
+ data={images}
+ horizontal
+ snapToInterval={width}
+ snapToAlignment="start"
+ decelerationRate="fast"
+ showsHorizontalScrollIndicator={false}
+ pagingEnabled
+ onViewableItemsChanged={onViewableItemsChanged}
+ viewabilityConfig={viewabilityConfig}
+ renderItem={({ item, index }) => (
+
+
+
+ )}
+ keyExtractor={(item, index) => index.toString()}
/>
+
{images.length > 1 && (
-
- {images.map((_, index) => (
-
- ))}
-
+
+ {images.map((_, index) => (
+
+ ))}
+
)}
- );
- };
+ )}
- return (
-
-
-
+
+
+ {formatDate(notice.publishDate)}
+
+
+ {notice.title}
+
+
+
+
+ Cena:
+ {notice.price} zł
+
+
+ {
+ toggleNoticeInWishlist(id);
}}
- />
-
- {renderImageSection()}
-
-
- {formatDate(notice.publishDate)}
-
-
- {notice.title}
-
-
-
- Cena:
- {notice.price} zł
-
- {
- toggleNoticeInWishlist(id);
- }}
- >
-
+
+
+
+
+
+ Kategoria:{" "}
+ {notice.category}
+
+
+
+ Opis ogloszenia
+
+ {notice.description}
+
+
+
+
+ Uzytkownik:
+ {isUserLoading ? (
+
+ ) : user ? (
+ <>
+
+
-
-
-
-
- Kategoria:{" "}
- {notice.category}
-
-
-
- Opis ogłoszenia
- {notice.description}
-
-
- Użytkownik:
- {isUserLoading ? (
-
- ) : user ? (
- <>
-
-
-
-
- {user.firstName?.[0]}
- {user.lastName?.[0]}
-
-
-
-
-
- {user.firstName} {user.lastName}
-
-
- Email: {user.email}
-
- setIsMessageFormVisible(true)}
- className="mt-3 bg-blue-500 py-2 px-4 rounded-md"
- >
-
- Wyślij wiadomość
-
-
-
-
- Zobacz więcej ogłoszeń od {user.firstName}
-
-
-
- >
- ) : (
- Błąd podczas ładowania danych użytkownika
- )}
-
-
-
- {isMessageFormVisible && (
-
-
-
- Wyślij wiadomość do {user?.firstName}
+
+
+
+
+ {user.firstName} {user.lastName}
- Do:
-
- {user?.email || "Brak adresu e-mail"}
+
+ Email: {user.email}
- Temat:
-
- Zapytanie o ogłoszenie '{notice.title || "Brak nazwy ogłoszenia"}'
-
- Treść:
-
-
- setIsMessageFormVisible(false)}
- className="bg-gray-300 py-2 px-4 rounded-md"
- >
- Anuluj
-
-
- {isSending ? (
-
- ) : (
- Wyślij
- )}
-
-
-
-
- )}
-
-
+ setIsMessageFormVisible(true)}
+ className="mt-3 bg-primary-500 py-2 px-4 rounded-md"
+ >
+
+ Wyślij wiadomość
+
+
+
+
+ Zobacz więcej ogłoszeń od {user.firstName}
+
+
+
+ >
+ ) : (
+ Błąd podczas ładowania danych użytkownika
+ )}
+
+
+
+ {isMessageFormVisible && (
+
+
+
+ Wyślij wiadomość do {user?.firstName}
+
+
+ Do:
+
+ {user?.email || "Brak adresu e-mail"}
+
+ Twój e-mail:
+
+
+
+
+
+ setIsMessageFormVisible(false)}
+ className="bg-gray-300 py-2 px-4 rounded-md"
+ >
+ Anuluj
+
+
+
+ Wyślij
+
+
+
+
+ )}
+
);
}
diff --git a/ArtisanConnect/components/CategorySection.jsx b/ArtisanConnect/components/CategorySection.jsx
index cb82cd1..7d6fa60 100644
--- a/ArtisanConnect/components/CategorySection.jsx
+++ b/ArtisanConnect/components/CategorySection.jsx
@@ -1,6 +1,5 @@
import { View, FlatList } from "react-native";
import { useEffect, useState } from "react";
-import { useAuthStore } from "@/store/authStore";
import { Heading } from "@/components/ui/heading";
import { Text } from "@/components/ui/text";
import { Link } from "expo-router";
@@ -17,7 +16,6 @@ export function CategorySection({ notices, title }) {
setCategoryMap(data);
}
};
-
fetchCategories();
}, []);
diff --git a/ArtisanConnect/store/authStore.jsx b/ArtisanConnect/store/authStore.jsx
index fd9a468..5ad2d40 100644
--- a/ArtisanConnect/store/authStore.jsx
+++ b/ArtisanConnect/store/authStore.jsx
@@ -11,22 +11,23 @@ let interceptorInitialized = false;
export const useAuthStore = create(
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;
- // }
+ 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"];
+ router.replace("/login");
+ }
+ return Promise.reject(error);
+ }
+ );
+ interceptorInitialized = true;
+ }
return {
user_id: null,
token: null,