atualizações do dashboard
This commit is contained in:
@@ -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 } from '../types';
|
||||
import { Product, BarberShop } from '../types';
|
||||
import { BarChart, Bar, CartesianGrid, ResponsiveContainer, Tooltip, XAxis } from 'recharts';
|
||||
import { CalendarWeekView } from '../components/CalendarWeekView';
|
||||
import {
|
||||
@@ -71,12 +71,35 @@ const parseDate = (value: string) => new Date(value.replace(' ', 'T'));
|
||||
type TabId = 'overview' | 'appointments' | 'history' | 'orders' | 'services' | 'products' | 'barbers' | 'settings';
|
||||
|
||||
export default function Dashboard() {
|
||||
const { user, shops, shopsReady } = useApp();
|
||||
const shop = shops.find((s) => s.id === user?.shopId);
|
||||
|
||||
if (!user || user.role !== 'barbearia') return <div>Área exclusiva para barbearias.</div>;
|
||||
|
||||
if (!shop && !shopsReady) {
|
||||
return (
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '60vh' }}>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<div style={{
|
||||
width: 40, height: 40, border: '4px solid #e2e8f0', borderTopColor: '#6366f1',
|
||||
borderRadius: '50%', animation: 'spin 0.8s linear infinite', margin: '0 auto 12px'
|
||||
}} />
|
||||
<p style={{ color: '#64748b', fontSize: 14 }}>A carregar painel...</p>
|
||||
<style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (!shop) return <div>Barbearia não encontrada.</div>;
|
||||
|
||||
return <DashboardInner shop={shop} />;
|
||||
}
|
||||
|
||||
function DashboardInner({ shop }: { shop: BarberShop }) {
|
||||
// Importa estado global interligado com Supabase (ex: updateAppointmentStatus reflete-se na BD)
|
||||
const {
|
||||
user,
|
||||
users,
|
||||
shops,
|
||||
shopsReady,
|
||||
appointments,
|
||||
orders,
|
||||
updateAppointmentStatus,
|
||||
@@ -90,10 +113,6 @@ export default function Dashboard() {
|
||||
deleteBarber,
|
||||
updateShopDetails,
|
||||
} = useApp();
|
||||
const shop = shops.find((s) => s.id === user?.shopId);
|
||||
|
||||
|
||||
|
||||
|
||||
const [activeTab, setActiveTab] = useState<TabId>('overview');
|
||||
const [period, setPeriod] = useState<keyof typeof periods>('semana');
|
||||
@@ -115,26 +134,6 @@ export default function Dashboard() {
|
||||
const [barberName, setBarberName] = useState('');
|
||||
const [barberSpecs, setBarberSpecs] = useState('');
|
||||
|
||||
if (!user || user.role !== 'barbearia') return <div>Área exclusiva para barbearias.</div>;
|
||||
|
||||
// Aguarda o refreshShops terminar antes de declarar que a loja não existe
|
||||
// (Evita o erro imediatamente após o registo quando os dados ainda estão a carregar)
|
||||
if (!shop && !shopsReady) {
|
||||
return (
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '60vh' }}>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<div style={{
|
||||
width: 40, height: 40, border: '4px solid #e2e8f0', borderTopColor: '#6366f1',
|
||||
borderRadius: '50%', animation: 'spin 0.8s linear infinite', margin: '0 auto 12px'
|
||||
}} />
|
||||
<p style={{ color: '#64748b', fontSize: 14 }}>A carregar painel...</p>
|
||||
<style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (!shop) return <div>Barbearia não encontrada.</div>;
|
||||
|
||||
const periodMatch = periods[period];
|
||||
|
||||
// Agendamentos filtrados pela barbearia logada e pela janela de tempo selecionada
|
||||
|
||||
Reference in New Issue
Block a user