Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
backend/
frontend/frontend_joya/node_modules/
frontend/frontend_joya/dist/
frontend/frontend_joya/.angular/
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "frontend/frontend_joya/node_modules/typescript/lib"
}
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
# tesffullstack
# tesffullstack — Cristian Joya

Prueba técnica full stack. Entrega por capas en ramas independientes:

| Rama | Contenido |
|------|-----------|
| `joya_bd` | Esquema MySQL `bd_joya` |
| `joya_backend` | API REST Spring Boot |
| `joya_frontend` | Cliente Angular `frontend_joya` |

## Rama actual: `joya_frontend`

Aplicación Angular para gestión de personas. Documentación en [`frontend/README.md`](frontend/README.md).
87 changes: 87 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Cliente Angular — rama `joya_frontend`

**Autor:** Cristian Joya
**Proyecto:** `frontend_joya`
**Stack:** Angular 20 · Angular Material · TypeScript · SCSS
**Puerto de desarrollo:** `4200`

## Contexto

Aplicación SPA que consume la API REST de la rama `joya_backend` para administrar el catálogo de personas. Implementa el flujo completo solicitado en la prueba: listado, alta, edición y eliminación, con retroalimentación visual al usuario según el contrato `status` / `msg` / `data`.

## Funcionalidad

| Pantalla | Ruta | Descripción |
|----------|------|-------------|
| Listado | `/` | Tabla con todas las personas; acciones Crear, Editar y Borrar por registro |
| Alta | `/nuevo` | Formulario vacío con botones Guardar y Cancelar |
| Edición | `/editar/:id` | Formulario precargado con los datos actuales |

## Integración

| Parámetro | Valor |
|-----------|-------|
| API base | `http://localhost:8080/api/persons` |
| CORS | Habilitado en backend para `http://localhost:4200` |

## Estructura

```
frontend/frontend_joya/
├── src/app/
│ ├── pages/person-list/ # Listado y eliminación
│ ├── pages/person-form/ # Crear y editar
│ ├── services/person.service.ts
│ └── models/
└── src/styles.scss # Tema Material y estilos globales
```

## Diseño

Interfaz basada en Angular Material: barra superior fija, tarjetas con sombra suave, tabla responsiva, formulario en rejilla de dos columnas, diálogo de confirmación para borrado y notificaciones tipo snackbar según el resultado de la API.

## Despliegue local

Requisitos: Node.js, npm y backend activo en el puerto `8080`. La aplicación se ejecuta con `ng serve` desde `frontend/frontend_joya` y queda disponible en `http://localhost:4200`.

## Evidencia

Capturas de la operación en el navegador (`capturas/`).

### Listado principal

Vista inicial con el directorio de personal y acciones por registro.

![Pantalla principal](capturas/pantalla_principal.jpg)

### Alta de persona

Formulario de registro, validación de campos obligatorios y confirmación de creación.

![Formulario de alta](capturas/crear_usuario.jpg)

![Validación de campos](capturas/crear_usuario_datos_incompletos.jpg)

![Usuario creado en aplicación](capturas/Usuario_creado.jpg)

![Usuario creado en base de datos](capturas/usuario_creado_bd.jpg)

### Edición de persona

Carga de datos existentes, actualización desde el formulario y verificación en BD.

![Formulario de edición](capturas/editar_persona.jpg)

![Persona actualizada en aplicación](capturas/persona_actualizada.jpg)

![Persona actualizada en base de datos](capturas/persona_actualizada_BD.jpg)

### Eliminación de persona

Confirmación de borrado, resultado en la interfaz y comprobación en BD.

![Confirmación de eliminación](capturas/eliminar_persona.jpg)

![Persona eliminada en aplicación](capturas/persona_eliminada.jpg)

![Persona eliminada en base de datos](capturas/persona_eliminada_bd.jpg)
Binary file added frontend/capturas/Usuario_creado.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/capturas/crear_usuario.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/capturas/editar_persona.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/capturas/eliminar_persona.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/capturas/pantalla_principal.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/capturas/persona_actualizada.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/capturas/persona_actualizada_BD.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/capturas/persona_eliminada.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/capturas/persona_eliminada_bd.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/capturas/usuario_creado_bd.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions frontend/frontend_joya/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Editor configuration, see https://editorconfig.org
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.ts]
quote_type = single
ij_typescript_use_double_quotes = false

[*.md]
max_line_length = off
trim_trailing_whitespace = false
42 changes: 42 additions & 0 deletions frontend/frontend_joya/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files.

# Compiled output
/dist
/tmp
/out-tsc
/bazel-out

# Node
/node_modules
npm-debug.log
yarn-error.log

# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*

# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings

# System files
.DS_Store
Thumbs.db
4 changes: 4 additions & 0 deletions frontend/frontend_joya/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template"]
}
20 changes: 20 additions & 0 deletions frontend/frontend_joya/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ng serve",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: start",
"url": "http://localhost:4200/"
},
{
"name": "ng test",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: test",
"url": "http://localhost:9876/debug.html"
}
]
}
42 changes: 42 additions & 0 deletions frontend/frontend_joya/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
},
{
"type": "npm",
"script": "test",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
}
]
}
98 changes: 98 additions & 0 deletions frontend/frontend_joya/angular.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"frontend_joya": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
"browser": "src/main.ts",
"polyfills": [
"zone.js"
],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.scss"
]
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kB",
"maximumError": "1MB"
},
{
"type": "anyComponentStyle",
"maximumWarning": "4kB",
"maximumError": "8kB"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular/build:dev-server",
"configurations": {
"production": {
"buildTarget": "frontend_joya:build:production"
},
"development": {
"buildTarget": "frontend_joya:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular/build:extract-i18n"
},
"test": {
"builder": "@angular/build:karma",
"options": {
"polyfills": [
"zone.js",
"zone.js/testing"
],
"tsConfig": "tsconfig.spec.json",
"inlineStyleLanguage": "scss",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.scss"
]
}
}
}
}
}
}
Loading