fix(mobile): corrigir navegação do perfil, tabs no perfil cliente e deteção de role barbearia.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -95,10 +95,33 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
.from('profiles')
|
||||
.select('shop_id, role, name, fcm_token, shop_name')
|
||||
.eq('id', authUser.id)
|
||||
.single();
|
||||
.maybeSingle();
|
||||
|
||||
const role = (prof?.role as any) || authUser.user_metadata?.role || 'cliente';
|
||||
const shopId = prof?.shop_id || (role === 'barbearia' ? authUser.id : undefined);
|
||||
if (profErr) {
|
||||
console.warn('Erro ao carregar perfil:', profErr.message);
|
||||
}
|
||||
|
||||
const metadataRole = authUser.user_metadata?.role;
|
||||
const profileRole = prof?.role;
|
||||
const hasBarberMetadata = metadataRole === 'barbearia';
|
||||
const hasBarberProfile = profileRole === 'barbearia';
|
||||
const hasShopAssociation = Boolean(prof?.shop_id);
|
||||
|
||||
const { data: ownedShop } = await supabase
|
||||
.from('shops')
|
||||
.select('id')
|
||||
.or(`id.eq.${authUser.id},owner_id.eq.${authUser.id}`)
|
||||
.maybeSingle();
|
||||
|
||||
const role: User['role'] =
|
||||
hasBarberProfile || hasBarberMetadata || hasShopAssociation || ownedShop
|
||||
? 'barbearia'
|
||||
: 'cliente';
|
||||
|
||||
const shopId =
|
||||
prof?.shop_id ||
|
||||
ownedShop?.id ||
|
||||
(role === 'barbearia' ? authUser.id : undefined);
|
||||
|
||||
const nextUser: User = {
|
||||
id: authUser.id,
|
||||
@@ -110,6 +133,13 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
fcmToken: prof?.fcm_token || undefined,
|
||||
};
|
||||
|
||||
if (role === 'barbearia' && shopId && profileRole !== 'barbearia') {
|
||||
await supabase
|
||||
.from('profiles')
|
||||
.update({ role: 'barbearia', shop_id: shopId })
|
||||
.eq('id', authUser.id);
|
||||
}
|
||||
|
||||
// If it's a barber and the shop record doesn't exist, create it (matching web logic)
|
||||
if (role === 'barbearia' && shopId) {
|
||||
const { data: existingShop } = await supabase.from('shops').select('id').eq('id', shopId).single();
|
||||
|
||||
@@ -16,14 +16,6 @@ export default function Explore() {
|
||||
const [query, setQuery] = useState('');
|
||||
const [filter, setFilter] = useState<'todas' | 'top' | 'servicos'>('todas');
|
||||
|
||||
const categories = useMemo(() => [
|
||||
{ id: 'corte', label: 'Cortes', icon: 'cut-outline' as const, query: 'corte' },
|
||||
{ id: 'barba', label: 'Barba', icon: 'sparkles-outline' as const, query: 'barba' },
|
||||
{ id: 'lavagem', label: 'Lavagem', icon: 'water-outline' as const, query: 'lavar' },
|
||||
{ id: 'tratamento', label: 'Tratamentos', icon: 'leaf-outline' as const, query: 'tratamento' },
|
||||
{ id: 'rapido', label: 'Expresso', icon: 'flash-outline' as const, query: 'rápido' },
|
||||
], []);
|
||||
|
||||
const filtered = useMemo(() => {
|
||||
const normalized = query.trim().toLowerCase();
|
||||
return [...shops]
|
||||
@@ -44,12 +36,12 @@ export default function Explore() {
|
||||
|
||||
const featuredShops = filtered.slice(0, 3);
|
||||
|
||||
const handleCategoryPress = (catQuery: string) => {
|
||||
if (query.toLowerCase() === catQuery.toLowerCase()) {
|
||||
setQuery('');
|
||||
} else {
|
||||
setQuery(catQuery);
|
||||
const goToProfile = () => {
|
||||
if (!user) {
|
||||
navigation.navigate('Login');
|
||||
return;
|
||||
}
|
||||
navigation.getParent()?.navigate('ProfileTab' as never);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -67,13 +59,7 @@ export default function Explore() {
|
||||
<TouchableOpacity
|
||||
style={styles.avatarButton}
|
||||
activeOpacity={0.85}
|
||||
onPress={() => {
|
||||
if (user) {
|
||||
navigation.navigate('ProfileTab' as any);
|
||||
} else {
|
||||
navigation.navigate('Login' as any);
|
||||
}
|
||||
}}
|
||||
onPress={goToProfile}
|
||||
>
|
||||
<View style={styles.avatarGradient}>
|
||||
<Text style={styles.avatarText}>
|
||||
@@ -120,58 +106,6 @@ export default function Explore() {
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
||||
{/* Categories Quick Grid (hidden for now) */}
|
||||
{false && (
|
||||
<View style={styles.categoriesSection}>
|
||||
<Text style={styles.sectionTitle}>Categorias Populares</Text>
|
||||
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.categoriesScroll}>
|
||||
{categories.map((cat) => {
|
||||
const isSelected = query.toLowerCase() === cat.query.toLowerCase();
|
||||
return (
|
||||
<TouchableOpacity
|
||||
key={cat.id}
|
||||
style={styles.categoryItem}
|
||||
onPress={() => handleCategoryPress(cat.query)}
|
||||
activeOpacity={0.75}
|
||||
>
|
||||
<View style={[styles.categoryIconBg, isSelected && styles.categoryIconBgActive]}>
|
||||
<Ionicons
|
||||
name={cat.icon}
|
||||
size={24}
|
||||
color={isSelected ? colors.textInverse : colors.primary}
|
||||
/>
|
||||
</View>
|
||||
<Text style={[styles.categoryLabel, isSelected && styles.categoryLabelActive]}>{cat.label}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
})}
|
||||
</ScrollView>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* Promo Hero Banner (hidden for now) */}
|
||||
{false && (
|
||||
<View style={styles.promoBanner}>
|
||||
<View style={styles.promoContent}>
|
||||
<View style={styles.promoBadge}>
|
||||
<Text style={styles.promoBadgeText}>CAMPANHA</Text>
|
||||
</View>
|
||||
<Text style={styles.promoTitle}>Estilo Premium com 15% OFF</Text>
|
||||
<Text style={styles.promoSubtitle}>Agenda a tua primeira marcação online hoje e garante o teu desconto.</Text>
|
||||
<TouchableOpacity
|
||||
style={styles.promoButton}
|
||||
activeOpacity={0.9}
|
||||
onPress={() => handleCategoryPress('corte')}
|
||||
>
|
||||
<Text style={styles.promoButtonText}>Ver Cortes ⚡</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.promoVisual}>
|
||||
<Ionicons name="sparkles" size={80} color="rgba(255,255,255,0.08)" style={styles.promoBackgroundIcon} />
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{!shopsReady ? (
|
||||
<View style={styles.emptyState}>
|
||||
<Ionicons name="sync-outline" size={44} color={colors.primary} style={styles.loadingSpinner} />
|
||||
|
||||
@@ -48,11 +48,6 @@ export default function Profile() {
|
||||
} = useApp();
|
||||
|
||||
const [activeTab, setActiveTab] = useState<string>(user?.role === 'barbearia' ? 'agenda_pessoal' : 'agenda');
|
||||
useEffect(() => {
|
||||
if (user) {
|
||||
setActiveTab(user.role === 'barbearia' ? 'agenda_pessoal' : 'agenda');
|
||||
}
|
||||
}, [user?.role]);
|
||||
const [reviewedAppointments, setReviewedAppointments] = useState<Set<string>>(new Set());
|
||||
const [reviewTarget, setReviewTarget] = useState<{ appointmentId: string; shopId: string; shopName: string } | null>(null);
|
||||
const [rating, setRating] = useState(0);
|
||||
@@ -207,200 +202,170 @@ export default function Profile() {
|
||||
{/* Dynamic Tab Bar */}
|
||||
<View style={styles.tabBarContainer}>
|
||||
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.tabBar}>
|
||||
{isBarber ? (
|
||||
[
|
||||
['agenda_pessoal', 'Agenda Global'],
|
||||
['reviews', 'Avaliações'],
|
||||
['estatisticas', 'Resumo'],
|
||||
].map(([id, label]) => (
|
||||
<TouchableOpacity
|
||||
key={id}
|
||||
onPress={() => setActiveTab(id)}
|
||||
style={[styles.tabItem, activeTab === id && styles.tabActive]}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<Text style={[styles.tabText, activeTab === id && styles.tabTextActive]}>{label}</Text>
|
||||
</TouchableOpacity>
|
||||
))
|
||||
) : (
|
||||
[
|
||||
['agenda', 'Marcações'],
|
||||
['favoritos', 'Favoritos'],
|
||||
['compras', 'Compras'],
|
||||
].map(([id, label]) => (
|
||||
<TouchableOpacity
|
||||
key={id}
|
||||
onPress={() => setActiveTab(id)}
|
||||
style={[styles.tabItem, activeTab === id && styles.tabActive]}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<Text style={[styles.tabText, activeTab === id && styles.tabTextActive]}>{label}</Text>
|
||||
</TouchableOpacity>
|
||||
))
|
||||
)}
|
||||
{(isBarber
|
||||
? [
|
||||
['agenda_pessoal', 'Agenda Global'],
|
||||
['reviews', 'Avaliações'],
|
||||
['estatisticas', 'Resumo'],
|
||||
]
|
||||
: [
|
||||
['agenda', 'Marcações'],
|
||||
['favoritos', 'Favoritos'],
|
||||
['compras', 'Compras'],
|
||||
]
|
||||
).map(([id, label]) => (
|
||||
<TouchableOpacity
|
||||
key={id}
|
||||
onPress={() => setActiveTab(id)}
|
||||
style={[styles.tabItem, activeTab === id && styles.tabActive]}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<Text style={[styles.tabText, activeTab === id && styles.tabTextActive]}>{label}</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
||||
{/* Tab Content Area */}
|
||||
<View style={styles.tabContent}>
|
||||
|
||||
{/* CLIENTE TABS */}
|
||||
{!isBarber && (
|
||||
<View style={{ gap: 20 }}>
|
||||
{activeTab === 'agenda' && (
|
||||
<View>
|
||||
<View style={styles.clientSectionHeader}>
|
||||
<Ionicons name="calendar" size={20} color={colors.primary} />
|
||||
<Text style={styles.clientSectionTitle}>As Minhas Marcações</Text>
|
||||
</View>
|
||||
<View style={styles.listContainer}>
|
||||
{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();
|
||||
{/* CLIENTE: Marcações */}
|
||||
{!isBarber && activeTab === 'agenda' && (
|
||||
<View style={styles.listContainer}>
|
||||
{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 (
|
||||
<Card key={appt.id} style={styles.agendaCardPremium}>
|
||||
<View style={styles.agendaTop}>
|
||||
<View style={styles.calendarBlockPremium}>
|
||||
<Text style={styles.dateMonthPremium}>{month}</Text>
|
||||
<Text style={styles.dateDayPremium}>{day}</Text>
|
||||
</View>
|
||||
|
||||
return (
|
||||
<Card key={appt.id} style={styles.agendaCardPremium}>
|
||||
<View style={styles.agendaTop}>
|
||||
<View style={styles.calendarBlockPremium}>
|
||||
<Text style={styles.dateMonthPremium}>{month}</Text>
|
||||
<Text style={styles.dateDayPremium}>{day}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.agendaMain}>
|
||||
<Text style={styles.agendaShopPremium} numberOfLines={1}>{shop?.name || 'Barbearia'}</Text>
|
||||
<View style={styles.agendaMetaRow}>
|
||||
<Ionicons name="time-outline" size={14} color={colors.textMuted} />
|
||||
<Text style={styles.agendaTimePremium}>{dateParts[1]} • {currency(appt.total)}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={[styles.statusTagPremium, { backgroundColor: statusColor[appt.status] + '1A' }]}>
|
||||
<Text style={[styles.statusTextPremium, { color: statusColor[appt.status] }]}>{statusLabel[appt.status]}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{canReview && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
style={styles.reviewBtn}
|
||||
onPress={() => setReviewTarget({ appointmentId: appt.id, shopId: appt.shopId, shopName: shop?.name || 'Barbearia' })}
|
||||
>
|
||||
Avaliar Serviço ⭐
|
||||
</Button>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<View style={styles.emptyBlockPremium}>
|
||||
<View style={styles.emptyIconCircle}>
|
||||
<Ionicons name="calendar-outline" size={28} color={colors.primary} />
|
||||
<View style={styles.agendaMain}>
|
||||
<Text style={styles.agendaShopPremium} numberOfLines={1}>{shop?.name || 'Barbearia'}</Text>
|
||||
<View style={styles.agendaMetaRow}>
|
||||
<Ionicons name="time-outline" size={14} color={colors.textMuted} />
|
||||
<Text style={styles.agendaTimePremium}>{dateParts[1]} • {currency(appt.total)}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={[styles.statusTagPremium, { backgroundColor: statusColor[appt.status] + '1A' }]}>
|
||||
<Text style={[styles.statusTextPremium, { color: statusColor[appt.status] }]}>{statusLabel[appt.status]}</Text>
|
||||
</View>
|
||||
<Text style={styles.emptyTxtPremium}>Sem marcações agendadas.</Text>
|
||||
<Button size="sm" variant="ghost" onPress={() => navigation.navigate('ExploreTab' as never)}>Procurar Barbearias</Button>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{activeTab === 'favoritos' && (
|
||||
<View>
|
||||
<View style={styles.clientSectionHeader}>
|
||||
<Ionicons name="heart" size={20} color={colors.danger} />
|
||||
<Text style={styles.clientSectionTitle}>Espaços Favoritos</Text>
|
||||
</View>
|
||||
<View style={styles.listContainer}>
|
||||
{favoriteShops.length > 0 ? (
|
||||
favoriteShops.map((s) => (
|
||||
<TouchableOpacity
|
||||
key={s.id}
|
||||
onPress={() => navigation.navigate('ShopDetails', { shopId: s.id })}
|
||||
activeOpacity={0.9}
|
||||
|
||||
{canReview && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
style={styles.reviewBtn}
|
||||
onPress={() => setReviewTarget({ appointmentId: appt.id, shopId: appt.shopId, shopName: shop?.name || 'Barbearia' })}
|
||||
>
|
||||
<Card style={styles.shopCardPremium}>
|
||||
<Image source={{ uri: s.imageUrl || 'https://via.placeholder.com/100' }} style={styles.shopImageMini} />
|
||||
<View style={styles.shopCardBodyPremium}>
|
||||
<Text style={styles.shopNamePremium} numberOfLines={1}>{s.name}</Text>
|
||||
<View style={styles.shopLocationRow}>
|
||||
<Ionicons name="location-outline" size={13} color={colors.textMuted} />
|
||||
<Text style={styles.shopAddrPremium} numberOfLines={1}>
|
||||
{s.address && s.address !== 'Endereço a definir' ? s.address : 'Morada por definir'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.shopRatingBadgePremium}>
|
||||
<Ionicons name="star" size={14} color={colors.star} />
|
||||
<Text style={styles.shopRatingTextPremium}>{(s.rating || 0).toFixed(1)}</Text>
|
||||
</View>
|
||||
</Card>
|
||||
</TouchableOpacity>
|
||||
))
|
||||
) : (
|
||||
<View style={styles.emptyBlockPremium}>
|
||||
<View style={styles.emptyIconCircle}>
|
||||
<Ionicons name="heart-outline" size={28} color={colors.textSubtle} />
|
||||
</View>
|
||||
<Text style={styles.emptyTxtPremium}>Ainda não tens favoritos.</Text>
|
||||
</View>
|
||||
)}
|
||||
Avaliar Serviço ⭐
|
||||
</Button>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<View style={styles.emptyBlockPremium}>
|
||||
<View style={styles.emptyIconCircle}>
|
||||
<Ionicons name="calendar-outline" size={28} color={colors.primary} />
|
||||
</View>
|
||||
<Text style={styles.emptyTxtPremium}>Sem marcações agendadas.</Text>
|
||||
<Button size="sm" variant="ghost" onPress={() => navigation.navigate('ExploreTab' as never)}>Procurar Barbearias</Button>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{activeTab === 'compras' && (
|
||||
<View>
|
||||
<View style={styles.clientSectionHeader}>
|
||||
<Ionicons name="bag-handle" size={20} color={colors.primaryDark} />
|
||||
<Text style={styles.clientSectionTitle}>As Minhas Compras</Text>
|
||||
</View>
|
||||
<View style={styles.listContainer}>
|
||||
{myOrders.length > 0 ? (
|
||||
myOrders.map((order) => {
|
||||
const shop = shops.find((s) => s.id === order.shopId);
|
||||
return (
|
||||
<Card key={order.id} style={styles.orderCardPremium}>
|
||||
<View style={styles.orderTopPremium}>
|
||||
<View style={{ flex: 1, gap: 4 }}>
|
||||
<Text style={styles.orderShopPremium} numberOfLines={1}>{shop?.name || 'Barbearia'}</Text>
|
||||
<View style={styles.orderMetaRow}>
|
||||
<Ionicons name="calendar-outline" size={14} color={colors.textSubtle} />
|
||||
<Text style={styles.orderMetaPremium}>
|
||||
{new Date(order.createdAt).toLocaleDateString('pt-PT')} • {order.items.length} item(s)
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={{ alignItems: 'flex-end', gap: 6 }}>
|
||||
<Text style={styles.orderTotalPremium}>{currency(order.total)}</Text>
|
||||
<View style={[styles.statusTagPremium, { backgroundColor: statusColor[order.status] + '1A' }]}>
|
||||
<Text style={[styles.statusTextPremium, { color: statusColor[order.status] }]}>{statusLabel[order.status]}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Card>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<View style={styles.emptyBlockPremium}>
|
||||
<View style={styles.emptyIconCircle}>
|
||||
<Ionicons name="bag-handle-outline" size={28} color={colors.textSubtle} />
|
||||
{/* CLIENTE: Favoritos */}
|
||||
{!isBarber && activeTab === 'favoritos' && (
|
||||
<View style={styles.listContainer}>
|
||||
{favoriteShops.length > 0 ? (
|
||||
favoriteShops.map((s) => (
|
||||
<TouchableOpacity
|
||||
key={s.id}
|
||||
onPress={() => navigation.navigate('ShopDetails', { shopId: s.id })}
|
||||
activeOpacity={0.9}
|
||||
>
|
||||
<Card style={styles.shopCardPremium}>
|
||||
<Image source={{ uri: s.imageUrl || 'https://via.placeholder.com/100' }} style={styles.shopImageMini} />
|
||||
<View style={styles.shopCardBodyPremium}>
|
||||
<Text style={styles.shopNamePremium} numberOfLines={1}>{s.name}</Text>
|
||||
<View style={styles.shopLocationRow}>
|
||||
<Ionicons name="location-outline" size={13} color={colors.textMuted} />
|
||||
<Text style={styles.shopAddrPremium} numberOfLines={1}>
|
||||
{s.address && s.address !== 'Endereço a definir' ? s.address : 'Morada por definir'}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.emptyTxtPremium}>Ainda não tens compras efetuadas.</Text>
|
||||
</View>
|
||||
)}
|
||||
<View style={styles.shopRatingBadgePremium}>
|
||||
<Ionicons name="star" size={14} color={colors.star} />
|
||||
<Text style={styles.shopRatingTextPremium}>{(s.rating || 0).toFixed(1)}</Text>
|
||||
</View>
|
||||
</Card>
|
||||
</TouchableOpacity>
|
||||
))
|
||||
) : (
|
||||
<View style={styles.emptyBlockPremium}>
|
||||
<View style={styles.emptyIconCircle}>
|
||||
<Ionicons name="heart-outline" size={28} color={colors.textSubtle} />
|
||||
</View>
|
||||
<Text style={styles.emptyTxtPremium}>Ainda não tens favoritos.</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* CLIENTE: Compras */}
|
||||
{!isBarber && activeTab === 'compras' && (
|
||||
<View style={styles.listContainer}>
|
||||
{myOrders.length > 0 ? (
|
||||
myOrders.map((order) => {
|
||||
const shop = shops.find((s) => s.id === order.shopId);
|
||||
return (
|
||||
<Card key={order.id} style={styles.orderCardPremium}>
|
||||
<View style={styles.orderTopPremium}>
|
||||
<View style={{ flex: 1, gap: 4 }}>
|
||||
<Text style={styles.orderShopPremium} numberOfLines={1}>{shop?.name || 'Barbearia'}</Text>
|
||||
<View style={styles.orderMetaRow}>
|
||||
<Ionicons name="calendar-outline" size={14} color={colors.textSubtle} />
|
||||
<Text style={styles.orderMetaPremium}>
|
||||
{new Date(order.createdAt).toLocaleDateString('pt-PT')} • {order.items.length} item(s)
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={{ alignItems: 'flex-end', gap: 6 }}>
|
||||
<Text style={styles.orderTotalPremium}>{currency(order.total)}</Text>
|
||||
<View style={[styles.statusTagPremium, { backgroundColor: statusColor[order.status] + '1A' }]}>
|
||||
<Text style={[styles.statusTextPremium, { color: statusColor[order.status] }]}>{statusLabel[order.status]}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Card>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<View style={styles.emptyBlockPremium}>
|
||||
<View style={styles.emptyIconCircle}>
|
||||
<Ionicons name="bag-handle-outline" size={28} color={colors.textSubtle} />
|
||||
</View>
|
||||
<Text style={styles.emptyTxtPremium}>Ainda não tens compras efetuadas.</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* BARBER TABS */}
|
||||
{activeTab === 'agenda_pessoal' && (
|
||||
{isBarber && activeTab === 'agenda_pessoal' && (
|
||||
<View style={styles.listContainer}>
|
||||
<View style={styles.subTitleRow}>
|
||||
<Ionicons name="list-outline" size={16} color={colors.primary} />
|
||||
@@ -449,7 +414,7 @@ export default function Profile() {
|
||||
</View>
|
||||
)}
|
||||
|
||||
{activeTab === 'reviews' && (
|
||||
{isBarber && activeTab === 'reviews' && (
|
||||
<View style={styles.listContainer}>
|
||||
{shopReviews.length > 0 ? (
|
||||
shopReviews.map((r) => (
|
||||
@@ -479,7 +444,7 @@ export default function Profile() {
|
||||
</View>
|
||||
)}
|
||||
|
||||
{activeTab === 'estatisticas' && (
|
||||
{isBarber && activeTab === 'estatisticas' && (
|
||||
<View style={styles.listContainer}>
|
||||
<View style={styles.statsGrid}>
|
||||
<Card style={styles.statCardHalf}>
|
||||
|
||||
@@ -70,7 +70,7 @@ export default function ShopDetails() {
|
||||
Alert.alert('Sucesso', 'Produto adicionado ao carrinho.');
|
||||
};
|
||||
|
||||
const schedule = (shop.schedule || defaultSchedule).filter((s: any) => !s.isException);
|
||||
const schedule = (shop.schedule || defaultSchedule).filter(s => !s.isException);
|
||||
const currentDayIndex = new Date().getDay() === 0 ? 6 : new Date().getDay() - 1;
|
||||
const isFav = isFavorite(shop.id);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user