FlotillasGPS - Sistema completo de monitoreo de flotillas GPS

Sistema completo para monitoreo y gestion de flotas de vehiculos con:
- Backend FastAPI con PostgreSQL/TimescaleDB
- Frontend React con TypeScript y TailwindCSS
- App movil React Native con Expo
- Soporte para dispositivos GPS, Meshtastic y celulares
- Video streaming en vivo con MediaMTX
- Geocercas, alertas, viajes y reportes
- Autenticacion JWT y WebSockets en tiempo real

Documentacion completa y guias de usuario incluidas.
This commit is contained in:
FlotillasGPS Developer
2026-01-21 08:18:00 +00:00
commit 51d78bacf4
248 changed files with 50171 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'
import { User, LoginCredentials, AuthResponse } from '@/types'
import { authApi } from '@/api/auth'
import { clearTokens, getAccessToken } from '@/api/client'
interface AuthState {
user: User | null
isAuthenticated: boolean
isLoading: boolean
error: string | null
// Actions
login: (credentials: LoginCredentials) => Promise<void>
logout: () => Promise<void>
loadUser: () => Promise<void>
updateUser: (data: Partial<User>) => void
clearError: () => void
setLoading: (loading: boolean) => void
}
export const useAuthStore = create<AuthState>()(
persist(
(set, get) => ({
user: null,
isAuthenticated: false,
isLoading: false,
error: null,
login: async (credentials: LoginCredentials) => {
set({ isLoading: true, error: null })
try {
const response: AuthResponse = await authApi.login(credentials)
set({
user: response.user,
isAuthenticated: true,
isLoading: false,
error: null,
})
} catch (error) {
set({
user: null,
isAuthenticated: false,
isLoading: false,
error: error instanceof Error ? error.message : 'Error de autenticacion',
})
throw error
}
},
logout: async () => {
set({ isLoading: true })
try {
await authApi.logout()
} catch {
// Ignore logout errors
} finally {
clearTokens()
set({
user: null,
isAuthenticated: false,
isLoading: false,
error: null,
})
}
},
loadUser: async () => {
const token = getAccessToken()
if (!token) {
set({ isAuthenticated: false, user: null })
return
}
set({ isLoading: true })
try {
const user = await authApi.getProfile()
set({
user,
isAuthenticated: true,
isLoading: false,
})
} catch {
clearTokens()
set({
user: null,
isAuthenticated: false,
isLoading: false,
})
}
},
updateUser: (data: Partial<User>) => {
const { user } = get()
if (user) {
set({ user: { ...user, ...data } })
}
},
clearError: () => set({ error: null }),
setLoading: (loading: boolean) => set({ isLoading: loading }),
}),
{
name: 'flotillas-auth',
storage: createJSONStorage(() => localStorage),
partialize: (state) => ({
user: state.user,
isAuthenticated: state.isAuthenticated,
}),
}
)
)