add authentication with login form and token management

This commit is contained in:
Egor Pozharov
2026-04-16 12:47:42 +06:00
parent be0b13acbf
commit c373d82135
8 changed files with 262 additions and 6 deletions

View File

@@ -1,8 +1,11 @@
import { useState, useEffect, lazy, Suspense } from 'react';
import { Truck, Loader2 } from 'lucide-react';
import { Truck, Loader2, LogOut } from 'lucide-react';
import { DeliveryForm } from './components/delivery/DeliveryForm';
import { LoginForm } from './components/auth/LoginForm';
import { ToastContainer } from './components/ui/Toast';
import { Button } from './components/ui/Button';
import { useDeliveryStore } from './stores/deliveryStore';
import { useAuthStore } from './stores/authStore';
// Lazy load pages for code splitting
const Dashboard = lazy(() => import('./pages/Dashboard'));
@@ -22,15 +25,21 @@ function App() {
const [formDate, setFormDate] = useState<string>('');
const [isSubmitting, setIsSubmitting] = useState(false);
const { isAuthenticated, isAuthChecking, restoreAuth, logout } = useAuthStore();
const addDelivery = useDeliveryStore(state => state.addDelivery);
const fetchDeliveryCounts = useDeliveryStore(state => state.fetchDeliveryCounts);
// Refresh counts when form closes
// Restore auth on mount
useEffect(() => {
if (!isFormOpen) {
restoreAuth();
}, [restoreAuth]);
// Refresh counts when form closes (only when authenticated)
useEffect(() => {
if (isAuthenticated && !isFormOpen) {
fetchDeliveryCounts();
}
}, [isFormOpen, fetchDeliveryCounts]);
}, [isAuthenticated, isFormOpen, fetchDeliveryCounts]);
const handleDateSelect = (date: string) => {
setSelectedDate(date);
@@ -67,6 +76,25 @@ function App() {
}
};
// Show loading while checking auth
if (isAuthChecking) {
return (
<div className="min-h-screen flex items-center justify-center bg-[#fbf8fb]">
<Loader2 className="w-8 h-8 animate-spin text-[#1B263B]" />
</div>
);
}
// Show login form if not authenticated
if (!isAuthenticated) {
return (
<>
<LoginForm />
<ToastContainer />
</>
);
}
return (
<div className="min-h-screen bg-[#fbf8fb]">
<header className="sticky top-0 z-40 bg-[#1B263B] text-white shadow-md">
@@ -78,8 +106,19 @@ function App() {
</div>
<h1 className="text-lg font-semibold hidden sm:block">Delivery Tracker</h1>
</div>
<div className="text-sm text-white/70">
{view === 'dashboard' ? 'Панель управления' : `Доставки на ${selectedDate}`}
<div className="flex items-center gap-4">
<div className="text-sm text-white/70">
{view === 'dashboard' ? 'Панель управления' : `Доставки на ${selectedDate}`}
</div>
<Button
variant="ghost"
size="sm"
onClick={logout}
className="text-white hover:bg-white/10"
>
<LogOut size={18} className="mr-1" />
Выйти
</Button>
</div>
</div>
</div>