From d875e5689cb1ee6ae348b9c12bfcd2c47a117111 Mon Sep 17 00:00:00 2001
From: 230417 <230417@epvc.pt>
Date: Tue, 23 Jun 2026 15:37:48 +0100
Subject: [PATCH] fix(mobile): resolve profile navigation crash, organize
profile screen in tabs, clean explore page and inspect user role
---
src/pages/Explore.tsx | 16 +-
src/pages/Profile.tsx | 312 ++++++++++++++++++++------------------
src/pages/ShopDetails.tsx | 2 +-
3 files changed, 181 insertions(+), 149 deletions(-)
diff --git a/src/pages/Explore.tsx b/src/pages/Explore.tsx
index 8ed26d6..0060910 100644
--- a/src/pages/Explore.tsx
+++ b/src/pages/Explore.tsx
@@ -67,7 +67,13 @@ export default function Explore() {
navigation.navigate('Profile' as any)}
+ onPress={() => {
+ if (user) {
+ navigation.navigate('ProfileTab' as any);
+ } else {
+ navigation.navigate('Login' as any);
+ }
+ }}
>
@@ -114,7 +120,8 @@ export default function Explore() {
- {/* Categories Quick Grid */}
+ {/* Categories Quick Grid (hidden for now) */}
+ {false && (
Categorias Populares
@@ -140,8 +147,10 @@ export default function Explore() {
})}
+ )}
- {/* Promo Hero Banner */}
+ {/* Promo Hero Banner (hidden for now) */}
+ {false && (
@@ -161,6 +170,7 @@ export default function Explore() {
+ )}
{!shopsReady ? (
diff --git a/src/pages/Profile.tsx b/src/pages/Profile.tsx
index 739f536..37b5e4e 100644
--- a/src/pages/Profile.tsx
+++ b/src/pages/Profile.tsx
@@ -48,6 +48,11 @@ export default function Profile() {
} = useApp();
const [activeTab, setActiveTab] = useState(user?.role === 'barbearia' ? 'agenda_pessoal' : 'agenda');
+ useEffect(() => {
+ if (user) {
+ setActiveTab(user.role === 'barbearia' ? 'agenda_pessoal' : 'agenda');
+ }
+ }, [user?.role]);
const [reviewedAppointments, setReviewedAppointments] = useState>(new Set());
const [reviewTarget, setReviewTarget] = useState<{ appointmentId: string; shopId: string; shopName: string } | null>(null);
const [rating, setRating] = useState(0);
@@ -199,11 +204,11 @@ export default function Profile() {
)}
- {/* Dynamic Tab Bar (Only for Barber) */}
- {isBarber && (
-
-
- {[
+ {/* Dynamic Tab Bar */}
+
+
+ {isBarber ? (
+ [
['agenda_pessoal', 'Agenda Global'],
['reviews', 'Avaliações'],
['estatisticas', 'Resumo'],
@@ -216,164 +221,181 @@ export default function Profile() {
>
{label}
- ))}
-
-
- )}
+ ))
+ ) : (
+ [
+ ['agenda', 'Marcações'],
+ ['favoritos', 'Favoritos'],
+ ['compras', 'Compras'],
+ ].map(([id, label]) => (
+ setActiveTab(id)}
+ style={[styles.tabItem, activeTab === id && styles.tabActive]}
+ activeOpacity={0.8}
+ >
+ {label}
+
+ ))
+ )}
+
+
{/* Tab Content Area */}
- {/* CLIENTE VERTICAL LAYOUT */}
+ {/* CLIENTE TABS */}
{!isBarber && (
-
-
- {/* Minha Agenda Section */}
-
-
-
- As Minhas Marcações
-
-
- {myAppointments.length > 0 ? (
- myAppointments.map((appt) => {
- const shop = shops.find((s) => s.id === appt.shopId);
- const canReview = appt.status === 'concluido' && !reviewedAppointments.has(appt.id);
- const dateParts = appt.date.split(' ');
- const day = dateParts[0].split('-')[2];
- const month = new Date(dateParts[0]).toLocaleString('pt-PT', { month: 'short' }).toUpperCase();
-
- return (
-
-
-
- {month}
- {day}
-
-
-
- {shop?.name || 'Barbearia'}
-
-
- {dateParts[1]} • {currency(appt.total)}
+
+ {activeTab === 'agenda' && (
+
+
+
+ As Minhas Marcações
+
+
+ {myAppointments.length > 0 ? (
+ myAppointments.map((appt) => {
+ const shop = shops.find((s) => s.id === appt.shopId);
+ const canReview = appt.status === 'concluido' && !reviewedAppointments.has(appt.id);
+ const dateParts = appt.date.split(' ');
+ const day = dateParts[0].split('-')[2];
+ const month = new Date(dateParts[0]).toLocaleString('pt-PT', { month: 'short' }).toUpperCase();
+
+ return (
+
+
+
+ {month}
+ {day}
+
+
+
+ {shop?.name || 'Barbearia'}
+
+
+ {dateParts[1]} • {currency(appt.total)}
+
+
+
+
+ {statusLabel[appt.status]}
-
- {statusLabel[appt.status]}
-
-
-
- {canReview && (
-
- )}
-
- );
- })
- ) : (
-
-
-
+ {canReview && (
+
+ )}
+
+ );
+ })
+ ) : (
+
+
+
+
+ Sem marcações agendadas.
+
- Sem marcações agendadas.
-
-
- )}
+ )}
+
-
+ )}
- {/* Favoritos Section */}
-
-
-
- Espaços Favoritos
-
-
- {favoriteShops.length > 0 ? (
- favoriteShops.map((s) => (
- navigation.navigate('ShopDetails', { shopId: s.id })}
- activeOpacity={0.9}
- >
-
-
-
- {s.name}
-
-
-
- {s.address && s.address !== 'Endereço a definir' ? s.address : 'Morada por definir'}
-
-
-
-
-
- {(s.rating || 0).toFixed(1)}
-
-
-
- ))
- ) : (
-
-
-
-
- Ainda não tens favoritos.
-
- )}
-
-
-
- {/* Compras Section */}
-
-
-
- As Minhas Compras
-
-
- {myOrders.length > 0 ? (
- myOrders.map((order) => {
- const shop = shops.find((s) => s.id === order.shopId);
- return (
-
-
-
- {shop?.name || 'Barbearia'}
-
-
-
- {new Date(order.createdAt).toLocaleDateString('pt-PT')} • {order.items.length} item(s)
+ {activeTab === 'favoritos' && (
+
+
+
+ Espaços Favoritos
+
+
+ {favoriteShops.length > 0 ? (
+ favoriteShops.map((s) => (
+ navigation.navigate('ShopDetails', { shopId: s.id })}
+ activeOpacity={0.9}
+ >
+
+
+
+ {s.name}
+
+
+
+ {s.address && s.address !== 'Endereço a definir' ? s.address : 'Morada por definir'}
-
- {currency(order.total)}
-
- {statusLabel[order.status]}
+
+
+ {(s.rating || 0).toFixed(1)}
+
+
+
+ ))
+ ) : (
+
+
+
+
+ Ainda não tens favoritos.
+
+ )}
+
+
+ )}
+
+ {activeTab === 'compras' && (
+
+
+
+ As Minhas Compras
+
+
+ {myOrders.length > 0 ? (
+ myOrders.map((order) => {
+ const shop = shops.find((s) => s.id === order.shopId);
+ return (
+
+
+
+ {shop?.name || 'Barbearia'}
+
+
+
+ {new Date(order.createdAt).toLocaleDateString('pt-PT')} • {order.items.length} item(s)
+
+
+
+
+ {currency(order.total)}
+
+ {statusLabel[order.status]}
+
-
-
- );
- })
- ) : (
-
-
-
+
+ );
+ })
+ ) : (
+
+
+
+
+ Ainda não tens compras efetuadas.
- Ainda não tens compras efetuadas.
-
- )}
+ )}
+
-
+ )}
)}
diff --git a/src/pages/ShopDetails.tsx b/src/pages/ShopDetails.tsx
index daf5578..0f1d368 100644
--- a/src/pages/ShopDetails.tsx
+++ b/src/pages/ShopDetails.tsx
@@ -70,7 +70,7 @@ export default function ShopDetails() {
Alert.alert('Sucesso', 'Produto adicionado ao carrinho.');
};
- const schedule = (shop.schedule || defaultSchedule).filter(s => !s.isException);
+ const schedule = (shop.schedule || defaultSchedule).filter((s: any) => !s.isException);
const currentDayIndex = new Date().getDay() === 0 ? 6 : new Date().getDay() - 1;
const isFav = isFavorite(shop.id);