feat: implement automatic shop creation for barbers and add error handling to data mutation methods
This commit is contained in:
@@ -91,22 +91,39 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const applySupabaseUser = async (authUser: any): Promise<User | undefined> => {
|
||||
if (!authUser) return undefined;
|
||||
|
||||
const { data: prof } = await supabase
|
||||
const { data: prof, error: profErr } = await supabase
|
||||
.from('profiles')
|
||||
.select('shop_id, role, name, fcm_token')
|
||||
.select('shop_id, role, name, fcm_token, shop_name')
|
||||
.eq('id', authUser.id)
|
||||
.single();
|
||||
|
||||
const role = (prof?.role as any) || authUser.user_metadata?.role || 'cliente';
|
||||
const shopId = prof?.shop_id || (role === 'barbearia' ? authUser.id : undefined);
|
||||
|
||||
const nextUser: User = {
|
||||
id: authUser.id,
|
||||
name: prof?.name || authUser.user_metadata?.name || authUser.email?.split('@')[0] || 'Utilizador',
|
||||
email: authUser.email || '',
|
||||
password: '',
|
||||
role: (prof?.role as any) || authUser.user_metadata?.role || 'cliente',
|
||||
shopId: prof?.shop_id || undefined,
|
||||
role,
|
||||
shopId,
|
||||
fcmToken: prof?.fcm_token || undefined,
|
||||
};
|
||||
|
||||
// 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();
|
||||
if (!existingShop) {
|
||||
const shopName = prof?.shop_name || authUser.user_metadata?.shopName || `Barbearia de ${nextUser.name}`;
|
||||
await supabase.from('shops').insert([{
|
||||
id: shopId,
|
||||
name: shopName,
|
||||
address: 'Endereço a definir',
|
||||
rating: 0,
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
setUser(nextUser);
|
||||
|
||||
registerForPushNotificationsAsync().then((token) => {
|
||||
@@ -366,13 +383,17 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const clearCart = () => setCart([]);
|
||||
|
||||
const addService = async (shopId: string, service: Omit<Service, 'id'>) => {
|
||||
await supabase.from('services').insert([{
|
||||
const { error } = await supabase.from('services').insert([{
|
||||
shop_id: shopId,
|
||||
name: service.name,
|
||||
price: service.price,
|
||||
duration: service.duration,
|
||||
barber_ids: service.barberIds || [],
|
||||
}]);
|
||||
if (error) {
|
||||
console.error('Erro addService:', error);
|
||||
throw error;
|
||||
}
|
||||
await refreshShops();
|
||||
};
|
||||
|
||||
@@ -392,7 +413,16 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
};
|
||||
|
||||
const addProduct = async (shopId: string, product: Omit<Product, 'id'>) => {
|
||||
await supabase.from('products').insert([{ shop_id: shopId, ...product }]);
|
||||
const { error } = await supabase.from('products').insert([{
|
||||
shop_id: shopId,
|
||||
name: product.name,
|
||||
price: product.price,
|
||||
stock: product.stock
|
||||
}]);
|
||||
if (error) {
|
||||
console.error('Erro addProduct:', error);
|
||||
throw error;
|
||||
}
|
||||
await refreshShops();
|
||||
};
|
||||
|
||||
@@ -408,13 +438,17 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
};
|
||||
|
||||
const addBarber = async (shopId: string, barber: Omit<Barber, 'id'>) => {
|
||||
await supabase.from('barbers').insert([{
|
||||
const { error } = await supabase.from('barbers').insert([{
|
||||
shop_id: shopId,
|
||||
name: barber.name,
|
||||
specialties: barber.specialties,
|
||||
schedule: barber.schedule,
|
||||
schedule: barber.schedule || [],
|
||||
image_url: barber.imageUrl,
|
||||
}]);
|
||||
if (error) {
|
||||
console.error('Erro addBarber:', error);
|
||||
throw error;
|
||||
}
|
||||
await refreshShops();
|
||||
};
|
||||
|
||||
@@ -436,6 +470,7 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const updateShopDetails = async (shopId: string, payload: Partial<BarberShop>) => {
|
||||
const { services, products, barbers, id, imageUrl, paymentMethods, socialNetworks, contacts, schedule, ...rest } = payload;
|
||||
const updateData: Record<string, any> = { ...rest };
|
||||
|
||||
if (imageUrl !== undefined) updateData.image_url = imageUrl;
|
||||
if (paymentMethods !== undefined) updateData.payment_methods = paymentMethods;
|
||||
if (socialNetworks !== undefined) updateData.social_networks = socialNetworks;
|
||||
@@ -443,13 +478,16 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
if (schedule !== undefined) updateData.schedule = schedule;
|
||||
|
||||
const { error } = await supabase.from('shops').update(updateData).eq('id', shopId);
|
||||
if (error) throw error;
|
||||
if (error) {
|
||||
console.error('Erro updateShopDetails:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (payload.name) {
|
||||
await supabase.from('profiles').update({ shop_name: payload.name }).eq('shop_id', shopId);
|
||||
}
|
||||
|
||||
setShops((prev) => prev.map((shop) => (shop.id === shopId ? { ...shop, ...payload } : shop)));
|
||||
await refreshShops();
|
||||
};
|
||||
|
||||
const submitReview = async (shopId: string, appointmentId: string, rating: number, comment: string) => {
|
||||
|
||||
@@ -262,9 +262,13 @@ export default function Dashboard() {
|
||||
<TextInput style={[styles.input, {flex: 1}]} placeholder="Duração (min)" placeholderTextColor="#475569" keyboardType="numeric" value={formSvc.duration} onChangeText={t => setFormSvc({...formSvc, duration: t})} />
|
||||
</View>
|
||||
<Button size="sm" onPress={async () => {
|
||||
await addService(shop.id, { name: formSvc.name, price: Number(formSvc.price), duration: Number(formSvc.duration), barberIds: [] });
|
||||
setFormSvc({ name: '', price: '', duration: '' });
|
||||
Alert.alert('Sucesso', 'Serviço adicionado.');
|
||||
try {
|
||||
await addService(shop.id, { name: formSvc.name, price: Number(formSvc.price), duration: Number(formSvc.duration), barberIds: [] });
|
||||
setFormSvc({ name: '', price: '', duration: '' });
|
||||
Alert.alert('Sucesso', 'Serviço adicionado.');
|
||||
} catch (e: any) {
|
||||
Alert.alert('Erro', e.message || 'Erro ao adicionar serviço.');
|
||||
}
|
||||
}}>Adicionar Serviço</Button>
|
||||
</Card>
|
||||
</View>
|
||||
@@ -293,9 +297,13 @@ export default function Dashboard() {
|
||||
<TextInput style={[styles.input, {flex: 1}]} placeholder="Stock" placeholderTextColor="#475569" keyboardType="numeric" value={formProd.stock} onChangeText={t => setFormProd({...formProd, stock: t})} />
|
||||
</View>
|
||||
<Button size="sm" onPress={async () => {
|
||||
await addProduct(shop.id, { name: formProd.name, price: Number(formProd.price), stock: Number(formProd.stock) });
|
||||
setFormProd({ name: '', price: '', stock: '' });
|
||||
Alert.alert('Sucesso', 'Produto adicionado.');
|
||||
try {
|
||||
await addProduct(shop.id, { name: formProd.name, price: Number(formProd.price), stock: Number(formProd.stock) });
|
||||
setFormProd({ name: '', price: '', stock: '' });
|
||||
Alert.alert('Sucesso', 'Produto adicionado.');
|
||||
} catch (e: any) {
|
||||
Alert.alert('Erro', e.message || 'Erro ao adicionar produto.');
|
||||
}
|
||||
}}>Adicionar Produto</Button>
|
||||
</Card>
|
||||
</View>
|
||||
@@ -324,13 +332,17 @@ export default function Dashboard() {
|
||||
<TextInput style={styles.input} placeholder="Nome do profissional" placeholderTextColor="#475569" value={formBarb.name} onChangeText={t => setFormBarb({...formBarb, name: t})} />
|
||||
<TextInput style={styles.input} placeholder="Especialidades (separadas por vírgula)" placeholderTextColor="#475569" value={formBarb.specialties} onChangeText={t => setFormBarb({...formBarb, specialties: t})} />
|
||||
<Button size="sm" onPress={async () => {
|
||||
await addBarber(shop.id, {
|
||||
name: formBarb.name,
|
||||
specialties: formBarb.specialties.split(',').map(s => s.trim()).filter(Boolean),
|
||||
schedule: []
|
||||
});
|
||||
setFormBarb({ name: '', specialties: '' });
|
||||
Alert.alert('Sucesso', 'Membro adicionado.');
|
||||
try {
|
||||
await addBarber(shop.id, {
|
||||
name: formBarb.name,
|
||||
specialties: formBarb.specialties.split(',').map(s => s.trim()).filter(Boolean),
|
||||
schedule: []
|
||||
});
|
||||
setFormBarb({ name: '', specialties: '' });
|
||||
Alert.alert('Sucesso', 'Membro adicionado.');
|
||||
} catch (e: any) {
|
||||
Alert.alert('Erro', e.message || 'Erro ao adicionar membro.');
|
||||
}
|
||||
}}>Adicionar Membro</Button>
|
||||
</Card>
|
||||
</View>
|
||||
|
||||
Reference in New Issue
Block a user