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({
|
const [establishment, setEstablishment] = useState({
|
||||||
name: '', type: 'barbearia', description: '', phone: '',
|
name: '', type: 'barbearia', description: '', phone: '',
|
||||||
address: '', rating: 5.0, reviews: 0,
|
address: '', rating: 5.0, reviews: 0,
|
||||||
|
allowOnlineBooking: true, bookingAdvanceMin: 60, bookingAdvanceMaxDays: 30
|
||||||
});
|
});
|
||||||
|
|
||||||
// Algoritmo dinâmico de fatiamento de grade
|
// Algoritmo dinâmico de fatiamento de grade
|
||||||
|
|
@ -68,6 +69,9 @@ export default function PublicBookingPage({ params }: { params: Promise<{ slug:
|
||||||
address: fullAddress || '',
|
address: fullAddress || '',
|
||||||
rating: 5.0,
|
rating: 5.0,
|
||||||
reviews: 0,
|
reviews: 0,
|
||||||
|
allowOnlineBooking: profile.allowOnlineBooking !== false,
|
||||||
|
bookingAdvanceMin: profile.bookingAdvanceMin || 60,
|
||||||
|
bookingAdvanceMaxDays: profile.bookingAdvanceMaxDays || 30,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Gerar slots com horários do tenant
|
// Gerar slots com horários do tenant
|
||||||
|
|
@ -105,7 +109,8 @@ export default function PublicBookingPage({ params }: { params: Promise<{ slug:
|
||||||
}, [slug]);
|
}, [slug]);
|
||||||
|
|
||||||
const today = new Date();
|
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);
|
const d = new Date(today);
|
||||||
d.setDate(d.getDate() + i);
|
d.setDate(d.getDate() + i);
|
||||||
return d;
|
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 (
|
return (
|
||||||
<div style={{ minHeight: '100vh', background: 'var(--bg-primary)' }}>
|
<div style={{ minHeight: '100vh', background: 'var(--bg-primary)' }}>
|
||||||
{/* HEADER */}
|
{/* 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
|
<Clock size={14} style={{ display: 'inline', marginRight: '6px' }} />Horários disponíveis
|
||||||
</h3>
|
</h3>
|
||||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(90px, 1fr))', gap: '8px' }}>
|
<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={{
|
<div key={slot} onClick={() => setSelectedTime(slot)} style={{
|
||||||
padding: '12px', borderRadius: 'var(--radius-sm)', cursor: 'pointer', textAlign: 'center',
|
padding: '12px', borderRadius: 'var(--radius-sm)', cursor: 'pointer', textAlign: 'center',
|
||||||
fontWeight: 600, fontSize: '14px', transition: 'all 0.2s',
|
fontWeight: 600, fontSize: '14px', transition: 'all 0.2s',
|
||||||
|
|
@ -344,7 +372,7 @@ export default function PublicBookingPage({ params }: { params: Promise<{ slug:
|
||||||
}}>
|
}}>
|
||||||
{slot}
|
{slot}
|
||||||
</div>
|
</div>
|
||||||
))}
|
)})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ export async function GET(req: NextRequest) {
|
||||||
interval: settings.interval || 30,
|
interval: settings.interval || 30,
|
||||||
workingDays: settings.working_days || [1, 2, 3, 4, 5, 6],
|
workingDays: settings.working_days || [1, 2, 3, 4, 5, 6],
|
||||||
allowOnlineBooking: settings.allow_online_booking !== false,
|
allowOnlineBooking: settings.allow_online_booking !== false,
|
||||||
|
bookingAdvanceMin: settings.booking_advance_min || 60,
|
||||||
|
bookingAdvanceMaxDays: settings.booking_advance_max_days || 30,
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('GET Profile error:', error);
|
console.error('GET Profile error:', error);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue