feat: Implement editing for shop contacts, social networks, schedule, and payment methods in Dashboard settings, and update ShopDetails UI styling.
This commit is contained in:
@@ -33,7 +33,7 @@ export const ShopDetailsTab = ({ shop }: { shop: BarberShop }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-8 text-slate-100">
|
||||
<div className="flex flex-col gap-8 text-slate-900">
|
||||
{/* Horário de atendimento */}
|
||||
<section>
|
||||
<h3 className="text-xl font-bold mb-4">Horário de atendimento</h3>
|
||||
@@ -41,12 +41,12 @@ export const ShopDetailsTab = ({ shop }: { shop: BarberShop }) => {
|
||||
{schedule.map((slot, i) => (
|
||||
<div key={i} className="flex items-center justify-between text-base">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={i === currentDayIndex ? 'text-slate-100' : 'text-slate-400'}>{slot.day}</span>
|
||||
<span className={i === currentDayIndex ? 'text-indigo-600 font-bold' : 'text-slate-500'}>{slot.day}</span>
|
||||
{i === currentDayIndex && (
|
||||
<span className="px-2 py-0.5 bg-emerald-900/40 text-emerald-400 rounded-md text-xs font-medium">Hoje</span>
|
||||
<span className="px-2 py-0.5 bg-indigo-100 text-indigo-700 rounded-md text-xs font-bold">Hoje</span>
|
||||
)}
|
||||
</div>
|
||||
<span className="text-slate-300">
|
||||
<span className="text-slate-700 font-medium">
|
||||
{slot.closed ? 'Fechado' : `${slot.open} - ${slot.close}`}
|
||||
</span>
|
||||
</div>
|
||||
@@ -54,72 +54,72 @@ export const ShopDetailsTab = ({ shop }: { shop: BarberShop }) => {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr className="border-white/10" />
|
||||
<hr className="border-slate-200" />
|
||||
|
||||
{/* Formas de pagamento */}
|
||||
<section>
|
||||
<h3 className="text-xl font-bold mb-4">Formas de pagamento</h3>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{paymentMethods.map((method, i) => (
|
||||
<span key={i} className="px-4 py-2 bg-white/5 border border-white/10 rounded-full text-sm text-slate-300 font-medium">
|
||||
<span key={i} className="px-4 py-2 bg-white border border-slate-200 rounded-full text-sm text-slate-700 font-medium shadow-sm">
|
||||
{method}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr className="border-white/10" />
|
||||
<hr className="border-slate-200" />
|
||||
|
||||
{/* Redes Sociais */}
|
||||
<section>
|
||||
<h3 className="text-xl font-bold mb-4">Redes Sociais</h3>
|
||||
<div className="flex gap-4">
|
||||
{socials.whatsapp && (
|
||||
<a href={socials.whatsapp} target="_blank" rel="noreferrer" className="w-12 h-12 flex items-center justify-center rounded-full bg-white/5 border border-white/10 text-slate-300 hover:bg-white/10 transition-colors">
|
||||
<a href={socials.whatsapp} target="_blank" rel="noreferrer" className="w-12 h-12 flex items-center justify-center rounded-full bg-white border border-slate-200 text-slate-600 hover:text-indigo-600 hover:border-indigo-200 shadow-sm transition-colors">
|
||||
<Smartphone size={22} />
|
||||
</a>
|
||||
)}
|
||||
{socials.instagram && (
|
||||
<a href={socials.instagram} target="_blank" rel="noreferrer" className="w-12 h-12 flex items-center justify-center rounded-full bg-white/5 border border-white/10 text-slate-300 hover:bg-white/10 transition-colors">
|
||||
<a href={socials.instagram} target="_blank" rel="noreferrer" className="w-12 h-12 flex items-center justify-center rounded-full bg-white border border-slate-200 text-slate-600 hover:text-indigo-600 hover:border-indigo-200 shadow-sm transition-colors">
|
||||
<Instagram size={22} />
|
||||
</a>
|
||||
)}
|
||||
{socials.facebook && (
|
||||
<a href={socials.facebook} target="_blank" rel="noreferrer" className="w-12 h-12 flex items-center justify-center rounded-full bg-white/5 border border-white/10 text-slate-300 hover:bg-white/10 transition-colors">
|
||||
<a href={socials.facebook} target="_blank" rel="noreferrer" className="w-12 h-12 flex items-center justify-center rounded-full bg-white border border-slate-200 text-slate-600 hover:text-indigo-600 hover:border-indigo-200 shadow-sm transition-colors">
|
||||
<Facebook size={22} />
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr className="border-white/10" />
|
||||
<hr className="border-slate-200" />
|
||||
|
||||
{/* Contacto */}
|
||||
<section>
|
||||
<h3 className="text-xl font-bold mb-4">Contacto</h3>
|
||||
<div className="flex flex-col gap-3">
|
||||
{contacts.phone1 && (
|
||||
<div className="flex items-center justify-between p-4 bg-white/5 border border-white/10 rounded-2xl">
|
||||
<div className="flex items-center justify-between p-4 bg-white border border-slate-200 shadow-sm rounded-2xl group">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-10 h-10 flex items-center justify-center bg-white/10 rounded-full text-slate-300">
|
||||
<div className="w-10 h-10 flex items-center justify-center bg-slate-50 border border-slate-100 rounded-full text-slate-500">
|
||||
<Smartphone size={20} />
|
||||
</div>
|
||||
<span className="text-slate-200 font-medium text-lg">{contacts.phone1}</span>
|
||||
<span className="text-slate-700 font-bold text-lg">{contacts.phone1}</span>
|
||||
</div>
|
||||
<button onClick={() => copyToClipboard(contacts.phone1!)} className="text-slate-400 hover:text-white transition-colors p-2">
|
||||
<button onClick={() => copyToClipboard(contacts.phone1!)} className="text-slate-400 hover:text-indigo-600 transition-colors p-2">
|
||||
<Copy size={20} />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{contacts.phone2 && (
|
||||
<div className="flex items-center justify-between p-4 bg-white/5 border border-white/10 rounded-2xl">
|
||||
<div className="flex items-center justify-between p-4 bg-white border border-slate-200 shadow-sm rounded-2xl group">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-10 h-10 flex items-center justify-center bg-white/10 rounded-full text-slate-300">
|
||||
<div className="w-10 h-10 flex items-center justify-center bg-slate-50 border border-slate-100 rounded-full text-slate-500">
|
||||
<Phone size={20} />
|
||||
</div>
|
||||
<span className="text-slate-200 font-medium text-lg">{contacts.phone2}</span>
|
||||
<span className="text-slate-700 font-bold text-lg">{contacts.phone2}</span>
|
||||
</div>
|
||||
<button onClick={() => copyToClipboard(contacts.phone2!)} className="text-slate-400 hover:text-white transition-colors p-2">
|
||||
<button onClick={() => copyToClipboard(contacts.phone2!)} className="text-slate-400 hover:text-indigo-600 transition-colors p-2">
|
||||
<Copy size={20} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@ import { Tabs } from '../components/ui/tabs';
|
||||
import { currency } from '../lib/format';
|
||||
import { useApp } from '../context/AppContext';
|
||||
import { supabase } from '../lib/supabase';
|
||||
import { Product, BarberShop } from '../types';
|
||||
import { Product, BarberShop, ShopSchedule } from '../types';
|
||||
import { BarChart, Bar, CartesianGrid, ResponsiveContainer, Tooltip, XAxis } from 'recharts';
|
||||
import { CalendarWeekView } from '../components/CalendarWeekView';
|
||||
import {
|
||||
@@ -146,6 +146,19 @@ function DashboardInner({ shop }: { shop: BarberShop }) {
|
||||
// Settings states
|
||||
const [editShopName, setEditShopName] = useState(shop.name);
|
||||
const [editShopAddress, setEditShopAddress] = useState(shop.address || '');
|
||||
const [editPaymentMethods, setEditPaymentMethods] = useState(shop.paymentMethods?.join(', ') || 'Dinheiro, Cartão de Crédito, Cartão de Débito');
|
||||
const [editSocials, setEditSocials] = useState(shop.socialNetworks || { whatsapp: '', instagram: '', facebook: '' });
|
||||
const [editContacts, setEditContacts] = useState(shop.contacts || { phone1: '', phone2: '' });
|
||||
const [editSchedule, setEditSchedule] = useState<ShopSchedule[]>(shop.schedule || [
|
||||
{ day: 'Segunda-feira', open: '09:00', close: '19:30' },
|
||||
{ day: 'Terça-feira', open: '09:00', close: '19:30' },
|
||||
{ day: 'Quarta-feira', open: '09:00', close: '19:30' },
|
||||
{ day: 'Quinta-feira', open: '09:00', close: '19:30' },
|
||||
{ day: 'Sexta-feira', open: '09:00', close: '19:30' },
|
||||
{ day: 'Sábado', open: '09:00', close: '19:00' },
|
||||
{ day: 'Domingo', open: '', close: '', closed: true },
|
||||
]);
|
||||
|
||||
const [isSavingSettings, setIsSavingSettings] = useState(false);
|
||||
const [showSaveSuccess, setShowSaveSuccess] = useState(false);
|
||||
|
||||
@@ -331,6 +344,10 @@ function DashboardInner({ shop }: { shop: BarberShop }) {
|
||||
await updateShopDetails(shop.id, {
|
||||
name: editShopName,
|
||||
address: editShopAddress,
|
||||
paymentMethods: editPaymentMethods.split(',').map(s => s.trim()).filter(Boolean),
|
||||
socialNetworks: editSocials,
|
||||
contacts: editContacts,
|
||||
schedule: editSchedule,
|
||||
});
|
||||
setShowSaveSuccess(true);
|
||||
setTimeout(() => setShowSaveSuccess(false), 3000);
|
||||
@@ -1071,6 +1088,104 @@ function DashboardInner({ shop }: { shop: BarberShop }) {
|
||||
placeholder="Rua, Número, Código Postal, Localidade"
|
||||
/>
|
||||
|
||||
<div className="pt-4 border-t border-slate-200">
|
||||
<h3 className="text-sm font-semibold text-slate-900 mb-4">Contactos e Redes Sociais</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<Input
|
||||
label="Telefone Principal"
|
||||
value={editContacts.phone1 || ''}
|
||||
onChange={(e) => setEditContacts({ ...editContacts, phone1: e.target.value })}
|
||||
placeholder="Ex: 910 000 000"
|
||||
/>
|
||||
<Input
|
||||
label="Telefone Secundário"
|
||||
value={editContacts.phone2 || ''}
|
||||
onChange={(e) => setEditContacts({ ...editContacts, phone2: e.target.value })}
|
||||
placeholder="Ex: 252 000 000"
|
||||
/>
|
||||
<Input
|
||||
label="Link do WhatsApp"
|
||||
value={editSocials.whatsapp || ''}
|
||||
onChange={(e) => setEditSocials({ ...editSocials, whatsapp: e.target.value })}
|
||||
placeholder="https://wa.me/351910000000"
|
||||
/>
|
||||
<Input
|
||||
label="Link do Instagram"
|
||||
value={editSocials.instagram || ''}
|
||||
onChange={(e) => setEditSocials({ ...editSocials, instagram: e.target.value })}
|
||||
placeholder="https://instagram.com/suabarbearia"
|
||||
/>
|
||||
<Input
|
||||
label="Link do Facebook"
|
||||
value={editSocials.facebook || ''}
|
||||
onChange={(e) => setEditSocials({ ...editSocials, facebook: e.target.value })}
|
||||
placeholder="https://facebook.com/suabarbearia"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pt-4 border-t border-slate-200">
|
||||
<h3 className="text-sm font-semibold text-slate-900 mb-4">Horário de Atendimento</h3>
|
||||
<div className="space-y-3">
|
||||
{editSchedule.map((slot, idx) => (
|
||||
<div key={idx} className="flex items-center gap-3">
|
||||
<div className="w-32">
|
||||
<span className={`text-sm font-medium ${slot.closed ? 'text-slate-400' : 'text-slate-700'}`}>{slot.day}</span>
|
||||
</div>
|
||||
{!slot.closed ? (
|
||||
<>
|
||||
<Input
|
||||
type="time"
|
||||
value={slot.open}
|
||||
onChange={(e) => {
|
||||
const newSchedule = [...editSchedule];
|
||||
newSchedule[idx].open = e.target.value;
|
||||
setEditSchedule(newSchedule);
|
||||
}}
|
||||
className="w-28"
|
||||
/>
|
||||
<span className="text-slate-400">-</span>
|
||||
<Input
|
||||
type="time"
|
||||
value={slot.close}
|
||||
onChange={(e) => {
|
||||
const newSchedule = [...editSchedule];
|
||||
newSchedule[idx].close = e.target.value;
|
||||
setEditSchedule(newSchedule);
|
||||
}}
|
||||
className="w-28"
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<div className="flex-1 text-sm text-slate-400 italic">Fechado</div>
|
||||
)}
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="ml-auto"
|
||||
onClick={() => {
|
||||
const newSchedule = [...editSchedule];
|
||||
newSchedule[idx].closed = !newSchedule[idx].closed;
|
||||
setEditSchedule(newSchedule);
|
||||
}}
|
||||
>
|
||||
{slot.closed ? 'Abrir' : 'Fechar'}
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pt-4 border-t border-slate-200 mb-6">
|
||||
<h3 className="text-sm font-semibold text-slate-900 mb-4">Formas de Pagamento</h3>
|
||||
<Input
|
||||
label="Métodos aceites (separados por vírgula)"
|
||||
value={editPaymentMethods}
|
||||
onChange={(e) => setEditPaymentMethods(e.target.value)}
|
||||
placeholder="Ex: Dinheiro, Cartão de Crédito, MBWay"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="pt-2 flex items-center gap-4">
|
||||
<Button
|
||||
onClick={handleSaveSettings}
|
||||
|
||||
@@ -120,7 +120,7 @@ export default function ShopDetails() {
|
||||
<BarberList barbers={shop.barbers} />
|
||||
</div>
|
||||
) : tab === 'detalhes' ? (
|
||||
<div className="bg-[#111] p-8 rounded-[3rem] border border-slate-800 shadow-2xl">
|
||||
<div className="bg-white/30 backdrop-blur-md p-8 rounded-[3rem] border border-white/50">
|
||||
<ShopDetailsTab shop={shop} />
|
||||
</div>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user