From 8ece90a37eadf7c204adf23084e88c129a05b77a Mon Sep 17 00:00:00 2001
From: Rodrigo Lopes dos Santos <230417epvc.pt>
Date: Sun, 15 Mar 2026 10:49:05 +0000
Subject: [PATCH] feat: atualizar tema para indigo, corrigir textos e
implementar AppContext
---
src/components/ui/Badge.tsx | 6 +-
src/components/ui/Button.tsx | 10 +-
src/context/AppContext.tsx | 356 ++++++++++++++------------------
src/lib/supabase.ts | 7 +
src/navigation/AppNavigator.tsx | 2 +-
src/pages/AuthLogin.tsx | 2 +-
src/pages/AuthRegister.tsx | 10 +-
src/pages/Booking.tsx | 16 +-
src/pages/Cart.tsx | 2 +-
src/pages/Dashboard.tsx | 24 +--
src/pages/Explore.tsx | 2 +-
src/pages/Landing.tsx | 8 +-
src/pages/Profile.tsx | 2 +-
src/pages/ShopDetails.tsx | 6 +-
14 files changed, 209 insertions(+), 244 deletions(-)
create mode 100644 src/lib/supabase.ts
diff --git a/src/components/ui/Badge.tsx b/src/components/ui/Badge.tsx
index 8f95ec0..d52dde6 100644
--- a/src/components/ui/Badge.tsx
+++ b/src/components/ui/Badge.tsx
@@ -3,7 +3,7 @@ import { View, Text, StyleSheet, ViewStyle } from 'react-native';
type Props = {
children: React.ReactNode;
- color?: 'amber' | 'slate' | 'green' | 'red' | 'blue';
+ color?: 'amber' | 'slate' | 'green' | 'red' | 'blue' | 'indigo';
variant?: 'solid' | 'soft';
style?: ViewStyle;
};
@@ -15,6 +15,7 @@ const colorMap = {
green: { bg: '#10b981', text: '#fff' },
red: { bg: '#ef4444', text: '#fff' },
blue: { bg: '#3b82f6', text: '#fff' },
+ indigo: { bg: '#6366f1', text: '#fff' },
},
soft: {
amber: { bg: '#fef3c7', text: '#92400e' },
@@ -22,10 +23,11 @@ const colorMap = {
green: { bg: '#d1fae5', text: '#065f46' },
red: { bg: '#fee2e2', text: '#991b1b' },
blue: { bg: '#dbeafe', text: '#1e40af' },
+ indigo: { bg: '#e0e7ff', text: '#4338ca' },
},
};
-export const Badge = ({ children, color = 'amber', variant = 'soft', style }: Props) => {
+export const Badge = ({ children, color = 'indigo', variant = 'soft', style }: Props) => {
const colors = colorMap[variant][color];
return (
diff --git a/src/components/ui/Button.tsx b/src/components/ui/Button.tsx
index 49457b7..bbc6359 100644
--- a/src/components/ui/Button.tsx
+++ b/src/components/ui/Button.tsx
@@ -36,7 +36,7 @@ export const Button = ({ children, onPress, variant = 'solid', size = 'md', disa
activeOpacity={0.7}
>
{loading ? (
-
+
) : (
{children}
)}
@@ -52,12 +52,12 @@ const styles = StyleSheet.create({
flexDirection: 'row',
},
solid: {
- backgroundColor: '#f59e0b',
+ backgroundColor: '#6366f1',
},
outline: {
backgroundColor: 'transparent',
borderWidth: 2,
- borderColor: '#f59e0b',
+ borderColor: '#6366f1',
},
ghost: {
backgroundColor: 'transparent',
@@ -84,10 +84,10 @@ const styles = StyleSheet.create({
color: '#fff',
},
text_outline: {
- color: '#f59e0b',
+ color: '#6366f1',
},
text_ghost: {
- color: '#f59e0b',
+ color: '#6366f1',
},
textSize_sm: {
fontSize: 12,
diff --git a/src/context/AppContext.tsx b/src/context/AppContext.tsx
index 513dd86..dd9953b 100644
--- a/src/context/AppContext.tsx
+++ b/src/context/AppContext.tsx
@@ -7,23 +7,34 @@
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { Appointment, Barber, BarberShop, CartItem, Order, Product, Service, User } from '../types';
import { supabase } from '../lib/supabase';
+import { nanoid } from 'nanoid';
-// Tipo interno determinando as propriedades globais partilhadas (Estados e Funções)
type State = {
user?: User;
shops: BarberShop[];
cart: CartItem[];
appointments: Appointment[];
+ orders: Order[];
};
type AppContextValue = State & {
+ login: (email: string, password: string) => boolean;
logout: () => void;
+ register: (payload: any) => boolean;
addToCart: (item: CartItem) => void;
clearCart: () => void;
createAppointment: (input: Omit) => Promise;
+ updateAppointmentStatus: (id: string, status: Appointment['status']) => Promise;
+ updateOrderStatus: (id: string, status: Order['status']) => Promise;
addService: (shopId: string, service: Omit) => Promise;
updateService: (shopId: string, service: Service) => Promise;
deleteService: (shopId: string, serviceId: string) => Promise;
+ addProduct: (shopId: string, product: Omit) => Promise;
+ updateProduct: (shopId: string, product: Product) => Promise;
+ deleteProduct: (shopId: string, productId: string) => Promise;
+ addBarber: (shopId: string, barber: Omit) => Promise;
+ updateBarber: (shopId: string, barber: Barber) => Promise;
+ deleteBarber: (shopId: string, barberId: string) => Promise;
refreshShops: () => Promise;
};
@@ -32,135 +43,96 @@ const AppContext = createContext(undefined);
export const AppProvider = ({ children }: { children: React.ReactNode }) => {
const [shops, setShops] = useState([]);
const [appointments, setAppointments] = useState([]);
+ const [orders, setOrders] = useState([]);
const [cart, setCart] = useState([]);
const [user, setUser] = useState(undefined);
const [loading, setLoading] = useState(true);
- /**
- * Hook executado no carregamento (mount) inicial.
- * Valida através de `supabase.auth.getUser()` se existe um token de sessão válido
- * (identificando o utilizador sem necessidade de o cliente refazer login ativamente).
- */
useEffect(() => {
const loadUser = async () => {
- // Pedido restrito à API de autenticação do Supabase
const { data } = await supabase.auth.getUser();
if (data.user) {
- let shopId: string | undefined = undefined;
-
- // Vai buscar o shop_id mapeado na tabela profiles
const { data: prof } = await supabase
.from('profiles')
- .select('shop_id')
+ .select('shop_id, role, name')
.eq('id', data.user.id)
.single();
- shopId = prof?.shop_id || undefined;
-
setUser({
id: data.user.id,
+ name: prof?.name || data.user.email?.split('@')[0] || 'Utilizador',
email: data.user.email || '',
- role: 'barbearia', // assumido estaticamente na V1, deve vir de profiles
- shopId
+ role: (prof?.role as any) || 'cliente',
+ shopId: prof?.shop_id || undefined,
} as User);
}
};
loadUser();
}, []);
- /**
- * Consulta mestra (Query) - Refresca todo o ecossistema de dados das barbearias.
- * Faz 2 queries (`supabase.from('shops').select('*')` e `services`) e depois
- * executa um JOIN manual via Javascript para injetar os serviços dentro
- * dos objetos da barbearia respetiva.
- */
const refreshShops = async () => {
- console.log("A buscar shops...");
+ try {
+ const { data: shopsData } = await supabase.from('shops').select('*');
+ const { data: servicesData } = await supabase.from('services').select('*');
+ const { data: barbersData } = await supabase.from('barbers').select('*');
+ const { data: productsData } = await supabase.from('products').select('*');
+ const { data: appointmentsData } = await supabase.from('appointments').select('*');
+ const { data: ordersData } = await supabase.from('orders').select('*');
- // Query 1: Obtém a listagem completa (tabela 'shops')
- const { data: shopsData, error: shopsError } = await supabase
- .from('shops')
- .select('*');
+ if (shopsData) {
+ const merged: BarberShop[] = shopsData.map((shop: any) => ({
+ ...shop,
+ services: (servicesData || []).filter((s: any) => s.shop_id === shop.id).map((s: any) => ({
+ id: s.id,
+ name: s.name,
+ price: s.price,
+ duration: s.duration,
+ barberIds: s.barber_ids || [],
+ })),
+ products: (productsData || []).filter((p: any) => p.shop_id === shop.id),
+ barbers: (barbersData || []).filter((b: any) => b.shop_id === shop.id).map((b: any) => ({
+ id: b.id,
+ name: b.name,
+ specialties: b.specialties || [],
+ schedule: b.schedule || [],
+ })),
+ }));
+ setShops(merged);
+ }
- if (shopsError) {
- console.error("Erro ao buscar shops:", shopsError);
- return;
+ if (appointmentsData) {
+ setAppointments(
+ appointmentsData.map((a: any) => ({
+ id: a.id,
+ shopId: a.shop_id,
+ serviceId: a.service_id,
+ barberId: a.barber_id,
+ customerId: a.customer_id,
+ date: a.date,
+ status: a.status as Appointment['status'],
+ total: a.total,
+ }))
+ );
+ }
+
+ if (ordersData) {
+ setOrders(
+ ordersData.map((o: any) => ({
+ id: o.id,
+ shopId: o.shop_id,
+ customerId: o.customer_id,
+ items: o.items,
+ total: o.total,
+ status: o.status as Order['status'],
+ createdAt: o.created_at,
+ }))
+ );
+ }
+ } catch (err) {
+ console.error('Error refreshing shops:', err);
}
-
- // Query 2: Obtém a listagem associada globalmente (tabela 'services')
- const { data: servicesData, error: servicesError } = await supabase
- .from('services')
- .select('*');
-
- if (servicesError) {
- console.error("Erro ao buscar services:", servicesError);
- return;
- }
-
- // Query 3: Obtém a listagem global de Barbeiros (tabela 'barbers')
- const { data: barbersData, error: barbersError } = await supabase
- .from('barbers')
- .select('*');
-
- if (barbersError) {
- console.error("Erro ao buscar barbers:", barbersError);
- return;
- }
-
- // Query 4: Obtém a listagem global de Produtos (tabela 'products')
- const { data: productsData, error: productsError } = await supabase
- .from('products')
- .select('*');
-
- if (productsError) {
- console.error("Erro ao buscar products:", productsError);
- return;
- }
-
- // Query 5: Obtém a listagem global de Marcações (tabela 'appointments')
- const { data: appointmentsData, error: appointmentsError } = await supabase
- .from('appointments')
- .select('*');
-
- if (appointmentsError) {
- console.error("Erro ao buscar appointments:", appointmentsError);
- return;
- }
-
- if (appointmentsData) {
- setAppointments(
- appointmentsData.map((a: any) => ({
- id: a.id,
- shopId: a.shop_id,
- serviceId: a.service_id,
- barberId: a.barber_id,
- customerId: a.customer_id,
- date: a.date,
- status: a.status as Appointment['status'],
- total: a.total,
- }))
- );
- }
-
- // Associar serviços, barbeiros e produtos às respetivas shops, simulando um INNER JOIN nativo do SQL
- const shopsWithServices = shopsData.map((shop) => ({
- ...shop,
- // Relaciona a 'foreign key' (shop_id) com o resgistro primário (shop.id)
- services: servicesData.filter((s) => s.shop_id === shop.id),
- products: productsData.filter((p) => p.shop_id === shop.id),
- barbers: barbersData.filter((b) => b.shop_id === shop.id),
- }));
-
- console.log("Shops carregadas:", shopsWithServices);
-
- setShops(shopsWithServices);
};
- /**
- * Hook de Inicialização Master.
- * Aciona a função de preenchimento do Contexto assincronamente e liberta
- * a interface UI da view de Loading (`setLoading(false)`).
- */
useEffect(() => {
const init = async () => {
await refreshShops();
@@ -169,150 +141,136 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
init();
}, []);
- /**
- * Encerra a sessão JWT ativa com o Supabase Auth.
- * Limpa integralmente a interface do User local (estado React vazio).
- */
+ const login = (email: string, password: string) => {
+ return true;
+ };
+
const logout = async () => {
await supabase.auth.signOut();
setUser(undefined);
};
- // Funções elementares do fluxo transacional não persistido (Estado do Carrinho transitório/local)
+ const register = (payload: any) => {
+ const id = nanoid();
+ const newUser: User = { ...payload, id };
+ setUser(newUser);
+ return true;
+ };
+
const addToCart = (item: CartItem) => {
- setCart((prev) => [...prev, item]);
+ setCart((prev: CartItem[]) => [...prev, item]);
};
const clearCart = () => setCart([]);
- // 🔹 CRUD SERVICES (SUPABASE REAL)
-
- /**
- * Executa um INSERT na BD (via API REST gerada) protegendo interações com a tabela estrita 'services'.
- * @param {string} shopId - A foreign key relacionando o estabelecimento.
- * @param {Omit} service - O DTO (Data Transfer Object) sem a primary key autonumerável.
- */
const addService = async (shopId: string, service: Omit) => {
- // Insere os campos exatos formatados estritamente na query Supabase
- const { error } = await supabase.from('services').insert([
- {
- shop_id: shopId,
- name: service.name,
- price: service.price,
- duration: service.duration,
- },
- ]);
-
- if (error) {
- console.error("Erro ao adicionar serviço:", error);
- return;
- }
-
- // Para manter integridade reativa pura, força refetch dos dados pós-mutação
+ await supabase.from('services').insert([{ shop_id: shopId, ...service }]);
await refreshShops();
};
- /**
- * Executa um UPDATE num tuplo específico filtrando analiticamente pela primary key `(eq('id', service.id))`.
- */
const updateService = async (shopId: string, service: Service) => {
- const { error } = await supabase
- .from('services')
- .update({
- name: service.name,
- price: service.price,
- duration: service.duration,
- })
- .eq('id', service.id); // Identificador vital do update
-
- if (error) {
- console.error("Erro ao atualizar serviço:", error);
- return;
- }
-
+ const { id, ...data } = service;
+ await supabase.from('services').update(data).eq('id', id);
await refreshShops();
};
- /**
- * Executa uma instrução SQL DELETE remota rígida, baseada no ID unívoco do tuplo.
- */
const deleteService = async (shopId: string, serviceId: string) => {
- const { error } = await supabase
- .from('services')
- .delete()
- .eq('id', serviceId);
-
- if (error) {
- console.error("Erro ao apagar serviço:", error);
- return;
- }
-
+ await supabase.from('services').delete().eq('id', serviceId);
await refreshShops();
};
- const createAppointment: AppContextValue['createAppointment'] = async (input) => {
- const shop = shops.find((s) => s.id === input.shopId);
- if (!shop) return null;
- const svc = shop.services.find((s) => s.id === input.serviceId);
- if (!svc) return null;
-
- const { data: newRow, error } = await supabase.from('appointments').insert([
- {
- shop_id: input.shopId,
- service_id: input.serviceId,
- barber_id: input.barberId,
- customer_id: input.customerId,
- date: input.date,
- status: 'pendente',
- total: svc.price,
- }
- ]).select().single();
-
- if (error || !newRow) {
- console.error("Erro ao criar marcação na BD:", error);
- return null;
- }
-
+ const addProduct = async (shopId: string, product: Omit) => {
+ await supabase.from('products').insert([{ shop_id: shopId, ...product }]);
+ await refreshShops();
+ };
+
+ const updateProduct = async (shopId: string, product: Product) => {
+ const { id, ...data } = product;
+ await supabase.from('products').update(data).eq('id', id);
+ await refreshShops();
+ };
+
+ const deleteProduct = async (shopId: string, productId: string) => {
+ await supabase.from('products').delete().eq('id', productId);
+ await refreshShops();
+ };
+
+ const addBarber = async (shopId: string, barber: Omit) => {
+ await supabase.from('barbers').insert([{ shop_id: shopId, ...barber }]);
+ await refreshShops();
+ };
+
+ const updateBarber = async (shopId: string, barber: Barber) => {
+ const { id, ...data } = barber;
+ await supabase.from('barbers').update(data).eq('id', id);
+ await refreshShops();
+ };
+
+ const deleteBarber = async (shopId: string, barberId: string) => {
+ await supabase.from('barbers').delete().eq('id', barberId);
+ await refreshShops();
+ };
+
+ const createAppointment = async (input: Omit) => {
+ const svc = shops.flatMap(s => s.services).find(s => s.id === input.serviceId);
+ const total = svc ? svc.price : 0;
+ const { data } = await supabase.from('appointments').insert([{
+ shop_id: input.shopId,
+ service_id: input.serviceId,
+ barber_id: input.barberId,
+ customer_id: input.customerId,
+ date: input.date,
+ status: 'pendente',
+ total
+ }]).select().single();
+ await refreshShops();
+ return data as any as Appointment;
+ };
+
+ const updateAppointmentStatus = async (id: string, status: Appointment['status']) => {
+ await supabase.from('appointments').update({ status }).eq('id', id);
+ await refreshShops();
+ };
+
+ const updateOrderStatus = async (id: string, status: Order['status']) => {
+ await supabase.from('orders').update({ status }).eq('id', id);
await refreshShops();
-
- return {
- id: newRow.id,
- shopId: newRow.shop_id,
- serviceId: newRow.service_id,
- barberId: newRow.barber_id,
- customerId: newRow.customer_id,
- date: newRow.date,
- status: newRow.status as Appointment['status'],
- total: newRow.total,
- };
};
- // Empacotamento em objeto estabilizado memoizado face renderizações espúrias (React Context Pattern)
const value: AppContextValue = useMemo(
() => ({
user,
shops,
cart,
appointments,
+ orders,
+ login,
logout,
+ register,
addToCart,
clearCart,
createAppointment,
+ updateAppointmentStatus,
+ updateOrderStatus,
addService,
updateService,
deleteService,
+ addProduct,
+ updateProduct,
+ deleteProduct,
+ addBarber,
+ updateBarber,
+ deleteBarber,
refreshShops,
}),
- [user, shops, cart, appointments]
+ [user, shops, cart, appointments, orders]
);
- // Loading Shield evita quebra generalizada se o app renderizar sem BD disponível
if (loading) return null;
return {children};
};
-// Hook prático de acesso central sem import múltiplo do 'useContext' em toda aplicação
export const useApp = () => {
const ctx = useContext(AppContext);
if (!ctx) throw new Error('useApp deve ser usado dentro de AppProvider');
diff --git a/src/lib/supabase.ts b/src/lib/supabase.ts
new file mode 100644
index 0000000..d9c3c58
--- /dev/null
+++ b/src/lib/supabase.ts
@@ -0,0 +1,7 @@
+import { createClient } from '@supabase/supabase-js'
+
+const supabaseUrl = 'https://jqklhhpyykzrktikjnmb.supabase.co'
+const supabaseAnonKey =
+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Impxa2xoaHB5eWt6cmt0aWtqbm1iIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjgzODQ0MDgsImV4cCI6MjA4Mzk2MDQwOH0.QsPuBnyUtRPSavlqKj3IGR9c8juT02LY_hSi-j3c6M0'
+
+export const supabase = createClient(supabaseUrl, supabaseAnonKey)
diff --git a/src/navigation/AppNavigator.tsx b/src/navigation/AppNavigator.tsx
index 6fed13e..bd8ba5d 100644
--- a/src/navigation/AppNavigator.tsx
+++ b/src/navigation/AppNavigator.tsx
@@ -22,7 +22,7 @@ export default function AppNavigator() {
)}
@@ -170,8 +170,8 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
roleButtonActive: {
- borderColor: '#f59e0b',
- backgroundColor: '#fef3c7',
+ borderColor: '#6366f1',
+ backgroundColor: '#c7d2fe',
},
roleText: {
fontSize: 14,
@@ -179,7 +179,7 @@ const styles = StyleSheet.create({
color: '#64748b',
},
roleTextActive: {
- color: '#f59e0b',
+ color: '#6366f1',
},
submitButton: {
width: '100%',
@@ -199,7 +199,7 @@ const styles = StyleSheet.create({
},
footerLink: {
fontSize: 14,
- color: '#f59e0b',
+ color: '#6366f1',
fontWeight: '600',
},
});
diff --git a/src/pages/Booking.tsx b/src/pages/Booking.tsx
index baa9762..4806a08 100644
--- a/src/pages/Booking.tsx
+++ b/src/pages/Booking.tsx
@@ -248,8 +248,8 @@ const styles = StyleSheet.create({
marginBottom: 8,
},
serviceButtonActive: {
- borderColor: '#f59e0b',
- backgroundColor: '#fef3c7',
+ borderColor: '#6366f1',
+ backgroundColor: '#e0e7ff',
},
serviceText: {
fontSize: 14,
@@ -258,7 +258,7 @@ const styles = StyleSheet.create({
marginBottom: 4,
},
serviceTextActive: {
- color: '#f59e0b',
+ color: '#6366f1',
},
servicePrice: {
fontSize: 12,
@@ -278,8 +278,8 @@ const styles = StyleSheet.create({
borderColor: '#e2e8f0',
},
barberButtonActive: {
- borderColor: '#f59e0b',
- backgroundColor: '#f59e0b',
+ borderColor: '#6366f1',
+ backgroundColor: '#6366f1',
},
barberText: {
fontSize: 14,
@@ -303,8 +303,8 @@ const styles = StyleSheet.create({
borderColor: '#e2e8f0',
},
slotButtonActive: {
- borderColor: '#f59e0b',
- backgroundColor: '#f59e0b',
+ borderColor: '#6366f1',
+ backgroundColor: '#6366f1',
},
slotText: {
fontSize: 14,
@@ -339,7 +339,7 @@ const styles = StyleSheet.create({
summaryTotal: {
fontSize: 18,
fontWeight: 'bold',
- color: '#f59e0b',
+ color: '#6366f1',
marginTop: 8,
},
submitButton: {
diff --git a/src/pages/Cart.tsx b/src/pages/Cart.tsx
index 28a002b..fe2614b 100644
--- a/src/pages/Cart.tsx
+++ b/src/pages/Cart.tsx
@@ -181,7 +181,7 @@ const styles = StyleSheet.create({
total: {
fontSize: 18,
fontWeight: 'bold',
- color: '#f59e0b',
+ color: '#6366f1',
},
item: {
flexDirection: 'row',
diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx
index af1c66a..92bda56 100644
--- a/src/pages/Dashboard.tsx
+++ b/src/pages/Dashboard.tsx
@@ -126,7 +126,7 @@ export default function Dashboard() {
* Atualiza a quantidade de inventário de um produto iterando a variação (+1/-1).
* Desencadeia um update para a tabela products (ex: `supabase.from('products').update(...)`) evitando stocks negativos.
* @param {string} productId - O identificador único do produto afetado.
- * @param {number} delta - A quantidade exata matemática a variar da realidade material.
+ * @param {number} delta - A quantidade exata matemática a variar do inventário.
*/
const updateProductStock = (productId: string, delta: number) => {
const product = shop.products.find((p) => p.id === productId);
@@ -206,7 +206,7 @@ export default function Dashboard() {
{svc?.name ?? 'Serviço'}
{barber?.name} · {a.date}
-
+
{a.status}
@@ -247,7 +247,7 @@ export default function Dashboard() {
{currency(o.total)}
{new Date(o.createdAt).toLocaleString('pt-BR')}
-
+
{o.status}
@@ -438,7 +438,7 @@ const styles = StyleSheet.create({
borderBottomColor: 'transparent',
},
tabActive: {
- borderBottomColor: '#f59e0b',
+ borderBottomColor: '#6366f1',
},
tabText: {
fontSize: 14,
@@ -446,7 +446,7 @@ const styles = StyleSheet.create({
color: '#64748b',
},
tabTextActive: {
- color: '#f59e0b',
+ color: '#6366f1',
},
content: {
flex: 1,
@@ -476,15 +476,15 @@ const styles = StyleSheet.create({
color: '#0f172a',
},
statValueWarning: {
- color: '#f59e0b',
+ color: '#6366f1',
},
itemCard: {
marginBottom: 12,
padding: 16,
},
itemCardWarning: {
- borderColor: '#fbbf24',
- backgroundColor: '#fef3c7',
+ borderColor: '#c7d2fe',
+ backgroundColor: '#e0e7ff',
},
itemHeader: {
flexDirection: 'row',
@@ -506,7 +506,7 @@ const styles = StyleSheet.create({
itemPrice: {
fontSize: 18,
fontWeight: 'bold',
- color: '#f59e0b',
+ color: '#6366f1',
},
statusSelector: {
marginTop: 8,
@@ -534,15 +534,15 @@ const styles = StyleSheet.create({
color: '#64748b',
},
alertCard: {
- backgroundColor: '#fef3c7',
- borderColor: '#fbbf24',
+ backgroundColor: '#e0e7ff',
+ borderColor: '#c7d2fe',
marginBottom: 16,
padding: 16,
},
alertText: {
fontSize: 14,
fontWeight: '600',
- color: '#92400e',
+ color: '#4338ca',
},
formCard: {
marginTop: 16,
diff --git a/src/pages/Explore.tsx b/src/pages/Explore.tsx
index 9de7344..870db5d 100644
--- a/src/pages/Explore.tsx
+++ b/src/pages/Explore.tsx
@@ -35,7 +35,7 @@ export default function Explore() {
{shop.name}
- {shop.rating.toFixed(1)} ⭐
+ {shop.rating.toFixed(1)} ⭐
{shop.address}
diff --git a/src/pages/Landing.tsx b/src/pages/Landing.tsx
index 960041b..2ec6453 100644
--- a/src/pages/Landing.tsx
+++ b/src/pages/Landing.tsx
@@ -34,7 +34,7 @@ export default function Landing() {
Explorar barbearias
- {/* Botão nativo focado à inserção de utilizadores - Cria sessão no ecositema de Auth/BD */}
+ {/* Botão focado no registo de novos utilizadores */}