From e5caf1c462ced014cd44a79e18ff94c297d393ff Mon Sep 17 00:00:00 2001 From: Dsupanta Date: Sun, 6 Sep 2026 18:39:10 -0300 Subject: [PATCH] Initial commit --- .env.example | 7 ++ .gitignore | 47 ++++++++++++ README.md | 108 ++++++++++++++++++++++++++ index.html | 12 +++ package.json | 19 +++++ src/App.vue | 201 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main.ts | 5 ++ src/style.css | 2 + tsconfig.json | 15 ++++ vite.config.ts | 9 +++ 10 files changed, 425 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 README.md create mode 100644 index.html create mode 100644 package.json create mode 100644 src/App.vue create mode 100644 src/main.ts create mode 100644 src/style.css create mode 100644 tsconfig.json create mode 100644 vite.config.ts diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..4bf42e9 --- /dev/null +++ b/.env.example @@ -0,0 +1,7 @@ +# Example environment variables - do NOT commit secrets +VITE_COGNITO_USER_POOL_ID= +VITE_COGNITO_CLIENT_ID= +VITE_API_URL=https://your-api-id.execute-api..amazonaws.com + +# Optional: if you have a Cognito Hosted UI domain you can add it to enable redirects +# VITE_COGNITO_HOSTED_UI_DOMAIN=your-domain.auth..amazoncognito.com diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d7ca306 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +# Node +node_modules/ +package-lock.json +yarn.lock +pnpm-lock.yaml + +# Environment +.env +.env.* +!.env.example + +# Build outputs +dist/ +build/ +out/ +.cache/ + +# Vite/Next/CRA +.next/ +.cache/ + +# Static analysis +coverage/ + +# Logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# AWS / Amplify +aws-exports.js +aws-exports.ts +amplify/ + +# Credentials and keys +*.pem +*.key +credentials +aws-credentials + +# Editor / OS +.vscode/ +.idea/ +.DS_Store + +# Misc +*.local diff --git a/README.md b/README.md new file mode 100644 index 0000000..56fb4bd --- /dev/null +++ b/README.md @@ -0,0 +1,108 @@ +iot-front-dashboard +==================== + +Resumen +------ +Aplicación web sencilla (Vue 3 + Vite + TypeScript) para visualizar las mediciones IoT. Está diseñada como una primera versión didáctica, deliberadamente simple, de modo que los alumnos puedan luego refactorizarla. + +Tecnologías +---------- +- Vue 3 +- Vite +- TypeScript +- HTML / CSS +- Amazon Cognito (autenticación) + +Estructura +--------- +``` +iot-front-dashboard/ +├── package.json +├── vite.config.ts +├── tsconfig.json +├── .env.example +├── index.html +└── src/ + ├── main.ts + ├── App.vue + └── style.css +``` + +Variables de entorno +------------------- +Copiar `.env.example` a `.env` y ajustar valores: + +- VITE_COGNITO_USER_POOL_ID: (no obligatorio para esta primera versión) +- VITE_COGNITO_CLIENT_ID: (no obligatorio para esta primera version) +- VITE_API_URL: URL base de la API (por ejemplo https://.execute-api..amazonaws.com) + +No pongas credenciales reales en el repositorio. + +Login y obtención del JWT +------------------------- +Esta primera versión implementa un login simple: el usuario debe obtener un JWT (id o access token) desde Cognito y pegarlo en la aplicación. El token se almacena en localStorage como `iot_token`. + +Cómo obtener un token desde Cognito (sugerencias): +- Usar el Hosted UI de Cognito (si el App Client está configurado con callback y dominio) y copiar el token desde la URL o desde las herramientas de desarrollador. +- Obtener un token con herramientas administrativas o scripts (ej. usar AWS CLI/AdminInitiateAuth si se dispone de permisos). + +Nota: automatizar el flujo de login (Hosted UI redirect / Authorization Code) requiere configurar callback URLs y dominio en el App Client y puede ser añadido en versiones posteriores. + +Ejecución local +--------------- +1. Instalar dependencias: + +```bash +npm install +``` + +2. Crear `.env` a partir de `.env.example` y ajustar VITE_API_URL. + +3. Ejecutar la app en modo desarrollo: + +```bash +npm run dev +``` + +Uso +--- +1. Obtener un JWT de Cognito (ver sección anterior). +2. Pegar el token en el textarea y hacer click en "Usar token (Login)". +3. La app llamará a `GET ${VITE_API_URL}/readings` enviando el header `Authorization: Bearer `. +4. Verás indicadores sencillos (temperatura/humedad actuales) y una tabla con las lecturas. + +API esperada +----------- +El endpoint `/readings` debe devolver JSON con la forma: + +```json +{ + "data": [ + { + "deviceId": "ARDUINO-01", + "timestamp": "2026-09-02T18:00:00Z", + "temperature": 24.7, + "humidity": 58.2 + } + ] +} +``` + +Estados iniciales y manejo de errores +----------------------------------- +- Cargando: "Cargando datos..." +- Error simple: "No fue posible obtener los datos" +- 401: mostrado como "No autorizado (401)" (API Gateway/Cognito normalmente maneja la validación) + +Refactorización posterior +------------------------- +Esta versión concentra gran parte de la lógica en `App.vue` intencionalmente. En tareas posteriores se pedirá a los alumnos que separen responsabilidades (componentes, servicios HTTP, manejo de estado) y mejoren la experiencia y seguridad. + +Relación con Cognito y la API +---------------------------- +- Cognito emite el JWT que la app usará como bearer token. +- La API (API Gateway + Cognito Authorizer + Lambda) protege `/readings` y delega la autenticación a Cognito. + +Contacto +-------- +Proyecto educativo — implementación simple para fines didácticos. diff --git a/index.html b/index.html new file mode 100644 index 0000000..ef9cf4e --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + IoT Front Dashboard + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..15db7a3 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "iot-front-dashboard", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "vue": "^3.3.0" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^4.0.0", + "vite": "^5.0.0", + "typescript": "^5.0.0", + "vue-tsc": "^1.0.0" + } +} diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..dca8c01 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,201 @@ + + + + + diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..fe5bae3 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,5 @@ +import { createApp } from 'vue' +import App from './App.vue' +import './style.css' + +createApp(App).mount('#app') diff --git a/src/style.css b/src/style.css new file mode 100644 index 0000000..e9066c0 --- /dev/null +++ b/src/style.css @@ -0,0 +1,2 @@ +html, body, #app { height: 100%; margin: 0; } +body { background: #f0f2f5; } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..aa22831 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"] + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..8084277 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +export default defineConfig({ + plugins: [vue()], + server: { + port: 5173 + } +})