import { useState, useEffect } from 'react'; import { Store, Clock, Globe, Bell, Palette, Shield, Save, Copy, ExternalLink, Check, Link, Loader, Plus, Trash2 } from 'lucide-react'; const tabs = [ { id: 'general', label: 'Geral', icon: Store }, { id: 'hours', label: 'Horários', icon: Clock }, { id: 'booking', label: 'Reservas Online', icon: Globe }, { id: 'notifications', label: 'Notificações', icon: Bell }, { id: 'appearance', label: 'Aparência', icon: Palette }, { id: 'security', label: 'Segurança', icon: Shield }, ]; const businessTypes = [ { value: 'barbearia', label: '💈 Barbearia' }, { value: 'manicure', label: '💅 Manicure / Nail Designer' }, { value: 'massagem', label: '💆 Massagem / Spa' }, { value: 'estetica', label: '✨ Estética' }, { value: 'salao', label: '💇 Salão de Beleza' }, { value: 'outro', label: '🏢 Outro' }, ]; export default function Settings() { const [activeTab, setActiveTab] = useState('general'); const [saved, setSaved] = useState(false); const [copied, setCopied] = useState(false); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); // General const [tenantName, setTenantName] = useState(''); const [slug, setSlug] = useState(''); const [businessType, setBusinessType] = useState('barbearia'); const [phone, setPhone] = useState(''); const [email, setEmail] = useState(''); const [address, setAddress] = useState(''); const [city, setCity] = useState(''); const [state, setState] = useState('SP'); const [zipCode, setZipCode] = useState(''); const [description, setDescription] = useState(''); // Hours const [startTime, setStartTime] = useState('09:00'); const [endTime, setEndTime] = useState('19:00'); const [intervalTime, setIntervalTime] = useState(30); const [workingDays, setWorkingDays] = useState([false, true, true, true, true, true, true]); // Booking const [allowOnline, setAllowOnline] = useState(true); const [requireConfirmation, setRequireConfirmation] = useState(false); const [autoReminders, setAutoReminders] = useState(true); const [allowCancel, setAllowCancel] = useState(true); const [bookingAdvanceMin, setBookingAdvanceMin] = useState(60); const [bookingAdvanceMaxDays, setBookingAdvanceMaxDays] = useState(30); const [cancellationLimitMin, setCancellationLimitMin] = useState(120); // Notifications const [notifyNew, setNotifyNew] = useState(true); const [notifyCancel, setNotifyCancel] = useState(true); const [notifyClient, setNotifyClient] = useState(true); const [dailySummary, setDailySummary] = useState(false); const [weeklyReport, setWeeklyReport] = useState(true); const [reminderMinutes, setReminderMinutes] = useState(60); // Appearance const [themeColor, setThemeColor] = useState('#6C63FF'); // Custom Schedules per day & per professional const [professionals, setProfessionals] = useState([]); const [selectedProfId, setSelectedProfId] = useState('all'); const [dailySchedules, setDailySchedules] = useState<{ active: boolean; shifts: { start: string; end: string }[] }>([ { active: false, shifts: [{ start: '09:00', end: '18:00' }] }, // Dom { active: true, shifts: [{ start: '08:00', end: '12:00' }, { start: '13:00', end: '18:00' }] }, // Seg { active: true, shifts: [{ start: '08:00', end: '12:00' }, { start: '13:00', end: '18:00' }] }, // Ter { active: true, shifts: [{ start: '08:00', end: '12:00' }, { start: '13:00', end: '18:00' }] }, // Qua { active: true, shifts: [{ start: '08:00', end: '12:00' }, { start: '13:00', end: '18:00' }] }, // Qui { active: true, shifts: [{ start: '08:00', end: '12:00' }, { start: '13:00', end: '18:00' }] }, // Sex { active: true, shifts: [{ start: '08:00', end: '17:00' }] }, // Sáb ]); const [profSchedules, setProfSchedules] = useState>({}); const normalizeSchedule = (rawList: any) => { if (!Array.isArray(rawList) || rawList.length === 0) { return [ { active: false, shifts: [{ start: '09:00', end: '18:00' }] }, { active: true, shifts: [{ start: '08:00', end: '12:00' }, { start: '13:00', end: '18:00' }] }, { active: true, shifts: [{ start: '08:00', end: '12:00' }, { start: '13:00', end: '18:00' }] }, { active: true, shifts: [{ start: '08:00', end: '12:00' }, { start: '13:00', end: '18:00' }] }, { active: true, shifts: [{ start: '08:00', end: '12:00' }, { start: '13:00', end: '18:00' }] }, { active: true, shifts: [{ start: '08:00', end: '12:00' }, { start: '13:00', end: '18:00' }] }, { active: true, shifts: [{ start: '08:00', end: '17:00' }] }, ]; } return [0, 1, 2, 3, 4, 5, 6].map((dayIdx) => { const item = rawList[dayIdx]; if (!item) return { active: dayIdx > 0, shifts: [{ start: '09:00', end: '18:00' }] }; if (Array.isArray(item.shifts) && item.shifts.length > 0) { return { active: !!item.active, shifts: item.shifts }; } return { active: !!item.active, shifts: [{ start: item.start || '09:00', end: item.end || '19:00' }] }; }); }; // Security const [currentPassword, setCurrentPassword] = useState(''); const [newPassword, setNewPassword] = useState(''); const [confirmNewPassword, setConfirmNewPassword] = useState(''); const [securityError, setSecurityError] = useState(''); const [securitySuccess, setSecuritySuccess] = useState(''); // Carrega dados do banco de dados useEffect(() => { const fetchSettings = async () => { const activeSlug = localStorage.getItem('agendapro_tenant_slug') || 'barbearia-premium'; setSlug(activeSlug); try { const res = await fetch(`/api/tenant/settings?slug=${activeSlug}`); if (res.ok) { const data = await res.json(); setTenantName(data.name || ''); setBusinessType(data.businessType || 'barbearia'); setPhone(data.phone || ''); setEmail(data.email || ''); setAddress(data.address || ''); setCity(data.city || ''); setState(data.state || 'SP'); setZipCode(data.zipCode || ''); setDescription(data.description || ''); setThemeColor(data.themeColor || '#6C63FF'); setStartTime(data.startTime || '09:00'); setEndTime(data.endTime || '19:00'); setIntervalTime(data.interval || 30); setAllowOnline(data.allowOnlineBooking !== false); setRequireConfirmation(data.requireConfirmation || false); setAutoReminders(data.sendReminders !== false); setAllowCancel(data.allowCancellation !== false); setBookingAdvanceMin(data.bookingAdvanceMin || 60); setBookingAdvanceMaxDays(data.bookingAdvanceMaxDays || 30); setCancellationLimitMin(data.cancellationLimitMin || 120); setNotifyNew(data.notifyNewAppointment !== false); setNotifyCancel(data.notifyCancellation !== false); setNotifyClient(data.notifyClientReminder !== false); setDailySummary(data.dailySummary || false); setWeeklyReport(data.weeklyReport !== false); setReminderMinutes(data.reminderMinutesBefore || 60); // Converte workingDays [1,2,3,4,5,6] para array booleano [dom,seg,...,sab] const wd = data.workingDays || [1, 2, 3, 4, 5, 6]; setWorkingDays([0, 1, 2, 3, 4, 5, 6].map(d => wd.includes(d))); if (data.dailySchedules) { setDailySchedules(normalizeSchedule(data.dailySchedules)); } if (data.profSchedules) { const normalizedMap: Record = {}; Object.keys(data.profSchedules).forEach(k => { normalizedMap[k] = normalizeSchedule(data.profSchedules[k]); }); setProfSchedules(normalizedMap); } // Carrega profissionais para horario individual const teamRes = await fetch(`/api/tenant/team?slug=${activeSlug}`); if (teamRes.ok) { const teamData = await teamRes.json(); setProfessionals(teamData || []); } // Aplica cor do tema if (data.themeColor) { document.documentElement.style.setProperty('--accent', data.themeColor); document.documentElement.style.setProperty('--accent-glow', `${data.themeColor}26`); } } } catch (err) { console.error('Erro ao carregar configurações:', err); } finally { setLoading(false); } }; fetchSettings(); }, []); const publicUrl = typeof window !== 'undefined' ? `${window.location.origin}/${slug}/agendar` : `/${slug}/agendar`; const handleSave = async () => { setSaving(true); // Converte workingDays boolean[] para int[] const wdInts = workingDays.map((active, i) => active ? i : -1).filter(i => i >= 0); try { const res = await fetch('/api/tenant/settings', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ slug, name: tenantName, businessType, phone, email, address, city, state, zipCode, description, themeColor, workingDays: wdInts, startTime, endTime, interval: intervalTime, allowOnlineBooking: allowOnline, requireConfirmation, sendReminders: autoReminders, reminderMinutesBefore: reminderMinutes, allowCancellation: allowCancel, bookingAdvanceMin, bookingAdvanceMaxDays, cancellationLimitMin, notifyNewAppointment: notifyNew, notifyCancellation: notifyCancel, notifyClientReminder: notifyClient, dailySummary, weeklyReport, dailySchedules, profSchedules, }) }); if (res.ok) { // Atualiza localStorage para manter compatibilidade localStorage.setItem('agendapro_tenant_name', tenantName); if (typeof window !== 'undefined') window.dispatchEvent(new Event('storage')); setSaved(true); setTimeout(() => setSaved(false), 2000); } } catch (err) { console.error('Erro ao salvar:', err); } finally { setSaving(false); } }; const handleChangePassword = async () => { setSecurityError(''); setSecuritySuccess(''); if (!currentPassword || !newPassword) { setSecurityError('Preencha todos os campos.'); return; } if (newPassword !== confirmNewPassword) { setSecurityError('A nova senha e a confirmação não conferem.'); return; } try { const token = localStorage.getItem('agendapro_token'); const res = await fetch('/api/auth/change-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token, currentPassword, newPassword }) }); const data = await res.json(); if (res.ok) { setSecuritySuccess('Senha alterada com sucesso!'); setCurrentPassword(''); setNewPassword(''); setConfirmNewPassword(''); } else { setSecurityError(data.error || 'Erro ao alterar senha.'); } } catch (err) { setSecurityError('Falha de conexão com o servidor.'); } }; if (loading) return
Carregando configurações...
; return (
{tabs.map(t => { const Icon = t.icon; return ( ); })}
{activeTab === 'general' && (

Informações do Estabelecimento

setTenantName(e.target.value)} />
setPhone(e.target.value)} />
setEmail(e.target.value)} />
setAddress(e.target.value)} />
setCity(e.target.value)} />
setZipCode(e.target.value)} />