215 lines
7.4 KiB
TypeScript
215 lines
7.4 KiB
TypeScript
|
|
|
||
|
|
import React, { useState, useEffect } from 'react';
|
||
|
|
import { View, Product, OrderItem } from './types';
|
||
|
|
import LoginView from './views/LoginView';
|
||
|
|
import HomeMenuView from './views/HomeMenuView';
|
||
|
|
import SalesDashboardView from './views/SalesDashboardView';
|
||
|
|
import ProductSearchView from './views/ProductSearchView';
|
||
|
|
import CheckoutView from './views/CheckoutView';
|
||
|
|
import Header from './components/Header';
|
||
|
|
import CartDrawer from './components/CartDrawer';
|
||
|
|
import ConfirmDialog from './components/ConfirmDialog';
|
||
|
|
import { useAuth } from './src/contexts/AuthContext';
|
||
|
|
import { useCart } from './src/hooks/useCart';
|
||
|
|
import { shoppingService } from './src/services/shopping.service';
|
||
|
|
|
||
|
|
const App: React.FC = () => {
|
||
|
|
const { isAuthenticated, isLoading, logout: authLogout, user } = useAuth();
|
||
|
|
const {
|
||
|
|
cart,
|
||
|
|
isLoading: isCartLoading,
|
||
|
|
addToCart,
|
||
|
|
updateQuantity,
|
||
|
|
removeFromCart,
|
||
|
|
refreshCart,
|
||
|
|
clearCart,
|
||
|
|
} = useCart();
|
||
|
|
const [currentView, setCurrentView] = useState<View>(View.LOGIN);
|
||
|
|
const [isCartOpen, setIsCartOpen] = useState(false);
|
||
|
|
const [showLogoutConfirm, setShowLogoutConfirm] = useState(false);
|
||
|
|
|
||
|
|
// Redirecionar baseado no estado de autenticação
|
||
|
|
useEffect(() => {
|
||
|
|
console.log('Auth state changed:', { isAuthenticated, isLoading, user: !!user });
|
||
|
|
if (!isLoading) {
|
||
|
|
if (isAuthenticated && user) {
|
||
|
|
console.log('Redirecionando para HOME_MENU');
|
||
|
|
setCurrentView(View.HOME_MENU);
|
||
|
|
} else if (!isAuthenticated) {
|
||
|
|
console.log('Redirecionando para LOGIN');
|
||
|
|
setCurrentView(View.LOGIN);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}, [isAuthenticated, isLoading, user]);
|
||
|
|
|
||
|
|
// Recarregar carrinho quando navegar para a página de produtos (como no Angular)
|
||
|
|
useEffect(() => {
|
||
|
|
if (currentView === View.PRODUCT_SEARCH && isAuthenticated && user) {
|
||
|
|
console.log('🛒 [APP] Navegando para ProductSearchView, recarregando carrinho...');
|
||
|
|
const cartId = shoppingService.getCart();
|
||
|
|
if (cartId) {
|
||
|
|
console.log('🛒 [APP] CartId encontrado, chamando refreshCart:', cartId);
|
||
|
|
refreshCart();
|
||
|
|
} else {
|
||
|
|
console.log('🛒 [APP] Nenhum cartId encontrado no localStorage');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}, [currentView, isAuthenticated, user, refreshCart]);
|
||
|
|
|
||
|
|
const handleLogin = () => {
|
||
|
|
// Login é gerenciado pelo LoginView através do contexto
|
||
|
|
if (isAuthenticated) {
|
||
|
|
setCurrentView(View.HOME_MENU);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleLogout = () => {
|
||
|
|
// Mostrar confirmação antes de fazer logout
|
||
|
|
setShowLogoutConfirm(true);
|
||
|
|
};
|
||
|
|
|
||
|
|
const executeLogout = () => {
|
||
|
|
console.log("🚪 [APP] Iniciando processo de logout...");
|
||
|
|
|
||
|
|
// 1. Limpar carrinho usando o hook
|
||
|
|
clearCart();
|
||
|
|
console.log("🚪 [APP] Estado do carrinho limpo");
|
||
|
|
|
||
|
|
// 2. Limpar dados de autenticação (token, user) do localStorage e contexto
|
||
|
|
authLogout();
|
||
|
|
console.log("🚪 [APP] Dados de autenticação removidos");
|
||
|
|
|
||
|
|
// 3. Redirecionar para login
|
||
|
|
setCurrentView(View.LOGIN);
|
||
|
|
console.log("🚪 [APP] Redirecionado para tela de login");
|
||
|
|
setShowLogoutConfirm(false);
|
||
|
|
};
|
||
|
|
|
||
|
|
// Handler para novo pedido - limpa todos os dados do pedido atual
|
||
|
|
const handleNewOrder = () => {
|
||
|
|
console.log("🆕 [APP] Iniciando novo pedido...");
|
||
|
|
|
||
|
|
// 1. Limpar carrinho usando o hook
|
||
|
|
clearCart();
|
||
|
|
console.log("🆕 [APP] Estado do carrinho limpo");
|
||
|
|
|
||
|
|
// 2. Limpar todos os dados do localStorage relacionados ao pedido
|
||
|
|
shoppingService.clearShoppingData();
|
||
|
|
console.log("🆕 [APP] Dados do pedido limpos do localStorage");
|
||
|
|
|
||
|
|
// 3. Fechar o carrinho se estiver aberto
|
||
|
|
setIsCartOpen(false);
|
||
|
|
|
||
|
|
// 4. Redirecionar para a página de produtos se não estiver lá
|
||
|
|
if (currentView !== View.PRODUCT_SEARCH) {
|
||
|
|
setCurrentView(View.PRODUCT_SEARCH);
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log("🆕 [APP] Novo pedido iniciado com sucesso");
|
||
|
|
};
|
||
|
|
|
||
|
|
// Handler para adicionar item ao carrinho
|
||
|
|
const handleAddToCart = async (product: Product | OrderItem) => {
|
||
|
|
try {
|
||
|
|
await addToCart(product);
|
||
|
|
// Abrir o carrinho automaticamente ao adicionar
|
||
|
|
setIsCartOpen(true);
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error('🛒 [APP] Erro ao adicionar item ao carrinho:', error);
|
||
|
|
// O hook já trata o erro, apenas logamos aqui
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const renderView = () => {
|
||
|
|
const isDashboardOrSearch = currentView === View.SALES_DASHBOARD || currentView === View.PRODUCT_SEARCH || currentView === View.CHECKOUT;
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="flex flex-col h-screen lg:h-screen overflow-hidden fixed inset-0 lg:relative lg:inset-auto">
|
||
|
|
{isDashboardOrSearch && user && (
|
||
|
|
<Header
|
||
|
|
user={{
|
||
|
|
name: user.username || user.name || 'Usuário',
|
||
|
|
store: user.store || 'Loja'
|
||
|
|
}}
|
||
|
|
currentView={currentView}
|
||
|
|
onNavigate={setCurrentView}
|
||
|
|
cartCount={cart.reduce((acc, i) => acc + i.quantity, 0)}
|
||
|
|
onCartClick={() => setIsCartOpen(true)}
|
||
|
|
onLogout={handleLogout}
|
||
|
|
/>
|
||
|
|
)}
|
||
|
|
<div className="flex-1 overflow-auto bg-slate-50 lg:overflow-auto">
|
||
|
|
{(() => {
|
||
|
|
switch (currentView) {
|
||
|
|
case View.LOGIN:
|
||
|
|
return <LoginView onLogin={handleLogin} />;
|
||
|
|
case View.HOME_MENU:
|
||
|
|
return user ? (
|
||
|
|
<HomeMenuView
|
||
|
|
onNavigate={setCurrentView}
|
||
|
|
user={{
|
||
|
|
name: user.username || user.name || 'Usuário',
|
||
|
|
store: user.store || 'Loja'
|
||
|
|
}}
|
||
|
|
onLogout={handleLogout}
|
||
|
|
/>
|
||
|
|
) : null;
|
||
|
|
case View.SALES_DASHBOARD:
|
||
|
|
return <SalesDashboardView onNavigate={setCurrentView} onNewOrder={handleNewOrder} />;
|
||
|
|
case View.PRODUCT_SEARCH:
|
||
|
|
return <ProductSearchView onAddToCart={handleAddToCart} />;
|
||
|
|
case View.CHECKOUT:
|
||
|
|
return (
|
||
|
|
<CheckoutView
|
||
|
|
cart={cart}
|
||
|
|
onBack={() => setCurrentView(View.PRODUCT_SEARCH)}
|
||
|
|
onCartUpdate={refreshCart}
|
||
|
|
onClearCart={clearCart}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
default:
|
||
|
|
return <LoginView onLogin={handleLogin} />;
|
||
|
|
}
|
||
|
|
})()}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Carrinho Global */}
|
||
|
|
<CartDrawer
|
||
|
|
isOpen={isCartOpen}
|
||
|
|
onClose={() => setIsCartOpen(false)}
|
||
|
|
items={cart}
|
||
|
|
onUpdateQuantity={updateQuantity}
|
||
|
|
onRemove={removeFromCart}
|
||
|
|
onCheckout={() => {
|
||
|
|
setIsCartOpen(false);
|
||
|
|
setCurrentView(View.CHECKOUT);
|
||
|
|
}}
|
||
|
|
onNewOrder={handleNewOrder}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="min-h-screen lg:min-h-screen">
|
||
|
|
{/* Meta tag para mobile app-like experience */}
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
||
|
|
{renderView()}
|
||
|
|
|
||
|
|
{/* Confirmação de Logout */}
|
||
|
|
<ConfirmDialog
|
||
|
|
isOpen={showLogoutConfirm}
|
||
|
|
type="warning"
|
||
|
|
title="Confirmar Saída"
|
||
|
|
message="Deseja realmente sair do sistema? Todos os dados não salvos serão perdidos."
|
||
|
|
onConfirm={executeLogout}
|
||
|
|
onClose={() => setShowLogoutConfirm(false)}
|
||
|
|
confirmText="Sair"
|
||
|
|
cancelText="Cancelar"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
export default App;
|