diff --git a/frontend/admin-panel/src/App.tsx b/frontend/admin-panel/src/App.tsx
index 3d7ded3..ceb59a0 100644
--- a/frontend/admin-panel/src/App.tsx
+++ b/frontend/admin-panel/src/App.tsx
@@ -1,35 +1,20 @@
-import { useState } from 'react'
-import reactLogo from './assets/react.svg'
-import viteLogo from '/vite.svg'
-import './App.css'
+import { BrowserRouter, Routes, Route } from 'react-router-dom';
+import Login from './pages/Login';
+import Dashboard from './pages/Dashboard';
+import ProtectedLayout from './layouts/ProtectedLayout';
function App() {
- const [count, setCount] = useState(0)
-
return (
- <>
-
- Vite + React
-
-
-
- Edit src/App.tsx and save to test HMR
-
-
-
- Click on the Vite and React logos to learn more
-
- >
- )
+
+
+ } />
+
+ }>
+ } />
+
+
+
+ );
}
-export default App
+export default App;
diff --git a/frontend/admin-panel/src/layouts/ProtectedLayout.tsx b/frontend/admin-panel/src/layouts/ProtectedLayout.tsx
new file mode 100644
index 0000000..a87d2b9
--- /dev/null
+++ b/frontend/admin-panel/src/layouts/ProtectedLayout.tsx
@@ -0,0 +1,43 @@
+import { Navigate, Outlet } from 'react-router-dom';
+import { useAuthStore } from '../store/authStore';
+import { LogOut } from 'lucide-react';
+
+export default function ProtectedLayout() {
+ const { isAuthenticated, logout } = useAuthStore();
+
+ if (!isAuthenticated) {
+ return ;
+ }
+
+ return (
+
+ {/* Sidebar minimalista por ahora */}
+
+
+ {/* Main Content */}
+
+
+
+
+ );
+}
diff --git a/frontend/admin-panel/src/pages/Dashboard.tsx b/frontend/admin-panel/src/pages/Dashboard.tsx
new file mode 100644
index 0000000..67ec6b3
--- /dev/null
+++ b/frontend/admin-panel/src/pages/Dashboard.tsx
@@ -0,0 +1,8 @@
+export default function Dashboard() {
+ return (
+
+
Bienvenido al Panel de Administración
+
Seleccione una opción del menú para comenzar.
+
+ );
+}
diff --git a/frontend/admin-panel/src/pages/Login.tsx b/frontend/admin-panel/src/pages/Login.tsx
new file mode 100644
index 0000000..f467765
--- /dev/null
+++ b/frontend/admin-panel/src/pages/Login.tsx
@@ -0,0 +1,75 @@
+import { useState } from 'react';
+import { useAuthStore } from '../store/authStore';
+import { authService } from '../services/authService';
+import { useNavigate } from 'react-router-dom';
+import { LayoutDashboard, Lock } from 'lucide-react';
+
+export default function Login() {
+ const [username, setUsername] = useState('');
+ const [password, setPassword] = useState('');
+ const [error, setError] = useState('');
+ const setToken = useAuthStore((state) => state.setToken);
+ const navigate = useNavigate();
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ try {
+ const token = await authService.login(username, password);
+ setToken(token);
+ navigate('/');
+ } catch (err) {
+ setError('Credenciales inválidas');
+ }
+ };
+
+ return (
+
+
+
+
SIG-CM Admin
+
+ {error && (
+
+ {error}
+
+ )}
+
+
+
+
+ );
+}
diff --git a/frontend/admin-panel/src/services/api.ts b/frontend/admin-panel/src/services/api.ts
new file mode 100644
index 0000000..670cdda
--- /dev/null
+++ b/frontend/admin-panel/src/services/api.ts
@@ -0,0 +1,15 @@
+import axios from 'axios';
+
+const api = axios.create({
+ baseURL: 'https://localhost:7034/api', // Puerto HTTPS obtenido de launchSettings.json
+});
+
+api.interceptors.request.use((config) => {
+ const token = localStorage.getItem('token');
+ if (token) {
+ config.headers.Authorization = `Bearer ${token}`;
+ }
+ return config;
+});
+
+export default api;
diff --git a/frontend/admin-panel/src/services/authService.ts b/frontend/admin-panel/src/services/authService.ts
new file mode 100644
index 0000000..c34ed10
--- /dev/null
+++ b/frontend/admin-panel/src/services/authService.ts
@@ -0,0 +1,8 @@
+import api from './api';
+
+export const authService = {
+ login: async (username: string, password: string): Promise => {
+ const response = await api.post('/auth/login', { username, password });
+ return response.data.token;
+ }
+};
diff --git a/frontend/admin-panel/src/store/authStore.ts b/frontend/admin-panel/src/store/authStore.ts
new file mode 100644
index 0000000..cec4fcd
--- /dev/null
+++ b/frontend/admin-panel/src/store/authStore.ts
@@ -0,0 +1,21 @@
+import { create } from 'zustand';
+
+interface AuthState {
+ token: string | null;
+ isAuthenticated: boolean;
+ setToken: (token: string) => void;
+ logout: () => void;
+}
+
+export const useAuthStore = create((set) => ({
+ token: localStorage.getItem('token'),
+ isAuthenticated: !!localStorage.getItem('token'),
+ setToken: (token: string) => {
+ localStorage.setItem('token', token);
+ set({ token, isAuthenticated: true });
+ },
+ logout: () => {
+ localStorage.removeItem('token');
+ set({ token: null, isAuthenticated: false });
+ },
+}));