feat: forçar configurações de agendamento na pagina publica (limites de antecedência e bloqueio online)
Build and Deploy (Gitea Actions) / build-and-deploy (push) Successful in 2m41s
Details
Build and Deploy (Gitea Actions) / build-and-deploy (push) Successful in 2m41s
Details
This commit is contained in:
parent
944f7930d9
commit
2e22c112d3
|
|
@ -26,6 +26,7 @@ export default function PublicBookingPage({ params }: { params: Promise<{ slug:
|
|||
const [establishment, setEstablishment] = useState({
|
||||
name: '', type: 'barbearia', description: '', phone: '',
|
||||
address: '', rating: 5.0, reviews: 0,
|
||||
allowOnlineBooking: true, bookingAdvanceMin: 60, bookingAdvanceMaxDays: 30
|
||||
});
|
||||
|
||||
// Algoritmo dinâmico de fatiamento de grade
|
||||
|
|
@ -68,6 +69,9 @@ export default function PublicBookingPage({ params }: { params: Promise<{ slug:
|
|||
address: fullAddress || '',
|
||||
rating: 5.0,
|
||||
reviews: 0,
|
||||
allowOnlineBooking: profile.allowOnlineBooking !== false,
|
||||
bookingAdvanceMin: profile.bookingAdvanceMin || 60,
|
||||
bookingAdvanceMaxDays: profile.bookingAdvanceMaxDays || 30,
|
||||
});
|
||||
|
||||
// Gerar slots com horários do tenant
|
||||
|
|
@ -105,7 +109,8 @@ export default function PublicBookingPage({ params }: { params: Promise<{ slug:
|
|||
}, [slug]);
|
||||
|
||||
const today = new Date();
|
||||
const dates = Array.from({ length: 14 }, (_, i) => {
|
||||
const maxDays = establishment.bookingAdvanceMaxDays || 30;
|
||||
const dates = Array.from({ length: maxDays }, (_, i) => {
|
||||
const d = new Date(today);
|
||||
d.setDate(d.getDate() + i);
|
||||
return d;
|
||||
|
|
@ -195,6 +200,20 @@ export default function PublicBookingPage({ params }: { params: Promise<{ slug:
|
|||
);
|
||||
}
|
||||
|
||||
if (!establishment.allowOnlineBooking && !booked) {
|
||||
return (
|
||||
<div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--bg-primary)', color: 'white' }}>
|
||||
<div style={{ maxWidth: '440px', textAlign: 'center', padding: '40px', background: 'var(--bg-card)', borderRadius: 'var(--radius-lg)', border: '1px solid var(--border-color)', boxShadow: 'var(--shadow-lg)' }}>
|
||||
<div style={{ width: 80, height: 80, borderRadius: '50%', background: 'var(--danger-bg)', color: 'var(--danger)', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 24px' }}>
|
||||
<Calendar size={40} />
|
||||
</div>
|
||||
<h2 style={{ fontSize: '24px', fontWeight: 800, marginBottom: '16px', color: 'var(--text-primary)' }}>Agendamento Indisponível</h2>
|
||||
<p style={{ color: 'var(--text-secondary)' }}>O agendamento online está temporariamente desativado para este estabelecimento. Por favor, entre em contato diretamente pelo WhatsApp ou telefone.</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ minHeight: '100vh', background: 'var(--bg-primary)' }}>
|
||||
{/* HEADER */}
|
||||
|
|
@ -334,7 +353,16 @@ export default function PublicBookingPage({ params }: { params: Promise<{ slug:
|
|||
<Clock size={14} style={{ display: 'inline', marginRight: '6px' }} />Horários disponíveis
|
||||
</h3>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(90px, 1fr))', gap: '8px' }}>
|
||||
{(slots.length > 0 ? slots : ['09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '14:00', '14:30', '15:00', '15:30', '16:00', '16:30', '17:00', '17:30', '18:00']).map(slot => (
|
||||
{(slots.length > 0 ? slots : ['09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '14:00', '14:30', '15:00', '15:30', '16:00', '16:30', '17:00', '17:30', '18:00']).map(slot => {
|
||||
const isToday = selectedDate === today.toISOString().split('T')[0];
|
||||
const [sh, sm] = slot.split(':').map(Number);
|
||||
const slotMinutes = sh * 60 + sm;
|
||||
const currentMinutes = today.getHours() * 60 + today.getMinutes();
|
||||
const isPastOrTooSoon = isToday && (slotMinutes < currentMinutes + (establishment.bookingAdvanceMin || 60));
|
||||
|
||||
if (isPastOrTooSoon) return null;
|
||||
|
||||
return (
|
||||
<div key={slot} onClick={() => setSelectedTime(slot)} style={{
|
||||
padding: '12px', borderRadius: 'var(--radius-sm)', cursor: 'pointer', textAlign: 'center',
|
||||
fontWeight: 600, fontSize: '14px', transition: 'all 0.2s',
|
||||
|
|
@ -344,7 +372,7 @@ export default function PublicBookingPage({ params }: { params: Promise<{ slug:
|
|||
}}>
|
||||
{slot}
|
||||
</div>
|
||||
))}
|
||||
)})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ export async function GET(req: NextRequest) {
|
|||
interval: settings.interval || 30,
|
||||
workingDays: settings.working_days || [1, 2, 3, 4, 5, 6],
|
||||
allowOnlineBooking: settings.allow_online_booking !== false,
|
||||
bookingAdvanceMin: settings.booking_advance_min || 60,
|
||||
bookingAdvanceMaxDays: settings.booking_advance_max_days || 30,
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error('GET Profile error:', error);
|
||||
|
|
|
|||
Loading…
Reference in New Issue