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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,4 @@ dist

# pauek
users.html
*index*
4 changes: 4 additions & 0 deletions Constant/constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const USER_API_URL = 'https://randomuser.me/api?results=';
export const USERS_TO_LOAD = 20;
export const USERS_PER_PAGE = 25;
export const MAIN_HTML = "index"
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ Para hacer esta práctica hay que:
- Al finalizar, se debe descargar un ZIP y entregar en el Campus Online de UPC School (habrá una tarea para ello).

**Muy importante**: la solución debe sustituir el código original (no debe quedar rastro, ni nombres, ni nada de nada). Si bien el ejemplo puede contener partes reaprovechables, se recomienda empezar _desde cero_ (ya que eso produce un aprendizaje de mucha más profundidad).

https://randomuser.me/documentation#howto
6 changes: 6 additions & 0 deletions Services/PrintServices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { User } from "../user.js";

export interface PrintServices {
printPages(pages: Array<string>, baseNamePage:string): void;
printUsersDetails(users: Array<User>, pages: Array<string>) :void;
}
19 changes: 19 additions & 0 deletions Services/PrintServicesImp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { writeFile } from "fs/promises";
import { PrintServices } from "./PrintServices.js";
import { User } from "../user.js";

export class PrintServicesImp implements PrintServices {
constructor() {}
public async printPages(pages: Array<string>, baseNamePage: string) {
for (let i = 0; i < pages.length; i++) {
const page = pages[i];
await writeFile(`${baseNamePage}.html`, page);
}
}

public async printUsersDetails(users: Array<User>, pages: Array<string>) {
for (let i = 0; i < pages.length; i++) {
await writeFile(`users_details/${users[i].fullName}.html`, pages[i]);
}
}
}
5 changes: 5 additions & 0 deletions Services/RenderServices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { User } from "../user.js";
export interface RenderServices{
renderUsers(User: Array<User>): Array<string> ;
renderUsersDetails(user: Array<User>): Array<string> ;
};
342 changes: 342 additions & 0 deletions Services/RenderServicesImp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,342 @@
import { RenderServices } from "./RenderServices.js";
import { User } from "../user.js";
import {
USERS_TO_LOAD,
USERS_PER_PAGE,
MAIN_HTML,
} from "../Constant/constant.js";

export class RenderServicesImp implements RenderServices {
constructor() {}

private renderHead(title: string): string {
return `<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>
<style>
body {
margin: 0;
padding: 0;
}

.titulo{
align-items: center;
margin-left: 0.7rem;
}

.user-grid {
justify-items: center;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}

.user-grid > * {
width: 250px;
min-width: 210px;
max-width: 220px;
}

.user {
font-family: sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0.4rem;
border-bottom: 1px solid #ddd;
background-image: linear-gradient(to bottom, #1d9dec, #bfdcec);
max-width: 220px;
color: white;
}

.user .data {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
margin-left: 0.5rem;
}

.user img {
width: 5rem;
height: 5rem;
border-radius: 50%;
margin-right: 0.7rem;
margin-left: 0.7rem;
}

.user .name {
font-weight: bold;
}

.user .email {
font-family: monospace;
}

.ver-mas {
background-color: #1d9dec;
color: white;
padding: 0.5rem 1rem;
border: none;
border-radius: 0.3rem;
cursor: pointer;
text-decoration: none;
}

.ver-mas:hover {
background-color: navy;
}
</style>
</head>`;
}

private rendeBody(users: Array<User>): string {
let html =
`<div class="titulo">
<h1>Lista de usuarios obteneidos de la API: randomuser.me</h1>
</div><div class="user-grid">`;
for (const user of users) {
html += `<div class="user">
<div class="data">
<div class="name">${user.fullName}</div>
</div>
<img src="${user.picture.medium}" />
<div class="data">
<div class="name">Email:</div>
<div class="email">${user.email}</div>
<div class="name">Celular:</div>
<div class="email">${user.cell}</div>
</div>
<a href = "users_details/${user.fullName}.html" class="ver-mas">Ver más</a>
</div>`;
}
html += "</div>";
return html;
}

public renderUsers(users: Array<User>): Array<string> {
const pages: number = Math.ceil(USERS_TO_LOAD / USERS_PER_PAGE);
const allHtmlPages: Array<string> = [];
let htmlPage: string = "";
let from: number = 0;
let until: number = USERS_PER_PAGE;

for (let i: number = 0; i < pages; i++) {
const sliceOfUsers = users.slice(from, until);
htmlPage = `<html>
${this.renderHead(`Lista de Usuarios`)}
<body>
${this.rendeBody(sliceOfUsers)}
</body>
</html>`;

allHtmlPages.push(htmlPage);

from = until + 1;
until =
until + USERS_PER_PAGE <= users.length - 1
? until + USERS_PER_PAGE
: users.length - 1;
}

return allHtmlPages;
}

private renderUserDetailHead(title: string): string {
return `<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>
<link
rel="stylesheet"
href="https://unpkg.com/[email protected]/dist/leaflet.css"/>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<style>
:root {
font-family: sans-serif;
font-size: large;
}

html,
body {
height: 100%;
}

body {
display: flex;
align-items: center;
justify-content: center;
}

.contenedor {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}

.user {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0.4rem;
background-image: linear-gradient(to bottom, #1d9dec, #bfdcec);
color: white;
width: 20%;
min-width: 20rem;
height: 49rem;
}

.user .titulo_de_seccion {
display: flex;
flex-wrap: wrap;
height: 2rem;
margin-bottom: 1rem;
}

.user .details {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
margin-left: 0.5rem;
}

.user .icono {
width: 2rem;
height: 2rem;
margin-top: 0rem;
margin-right: 0.7rem;
margin-left: 0;
}

.user img {
width: 7rem;
height: 7rem;
margin-top: 4rem;
margin-right: 0.7rem;
margin-left: 0.7rem;
}

.user .name {
font-weight: bold;
font-size: xx-large;
margin-top: 1rem;
}

.user .title {
font-weight: bold;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}

.user .data {
font-family: monospace;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}

.user .seccion {
font-family: monospace;
font-size: small;
font-style: italic;
margin-bottom: 0.5rem;
}

.mapContenedor {
display: flex;
flex-direction: column;
padding: 0.4rem;
}
.mapContenedor #mapid {
width: 40rem;
height: 48.7rem;
}

.linea {
border: none;
border-top: 1px solid #000000;
height: 0;
}
</style>
</head>`;
}

private rendeUserDetailBody(user: User): string {
const html = `<div class="contenedor">
<div class="user">
<img src="${user.picture.large}"/>
<div class="details">
<div class="name">${user.fullName}</div>
</div>
<div class="details">
<div class="titulo_de_seccion">
<img class="icono" src="../img/contacto.png" />
<div class="title">Acerca</div>
</div>
<hr class="linea" />
<div class="seccion">Informacion de contacto</div>
<div class="title">Email:</div>
<div class="data">
<a
style="text-decoration: none"
ref="mailto:${user.email}">${user.email}</a>
</div>
<div class="title">Celular:</div>
<div class="data">${user.cell}</div>

<div class="titulo_de_seccion">
<img class="icono" src="../img/localizacion.png" />
<div class="title">Localizacion</div>
</div>
<hr class="linea" />

<div class="seccion">Residencia</div>
<div class="title">Calle:</div>
<div class="data">${user.location.street.number} ${user.location.street.name}</div>
<div class="title">Ciudad:</div>
<div class="data">${user.location.city}</div>
<div class="title">Estado:</div>
<div class="data">${user.location.state}</div>
<div class="title">Pais:</div>
<div class="data">${user.location.country}</div>
<div class="title">Codigo Postal:</div>
<div class="data">${user.location.postcode}</div>
</div>
</div>
<div class="mapContenedor">
<div class="tile">Donde vive ${user.fullName}:</div>
<div id="mapid"></div>
</div>
</div>
<script>
const mapa = L.map("mapid").setView([${user.location.coordinates.latitude}, ${user.location.coordinates.longitude}], 13);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 18,
tileSize: 512,
zoomOffset: -1,
subdomains: "abc",
}).addTo(mapa);
</script>
`;

return html;
}

public renderUsersDetails(users: Array<User>): Array<string> {
const allHtmlPages: Array<string> = users.map((user: User) => {
let htmlPage: string = "";
htmlPage = `<html>
${this.renderUserDetailHead(`Detalles de contacto: ${user.fullName}`)}
<body>
${this.rendeUserDetailBody(user)}
</body>
</html>`;

return htmlPage;
});

return allHtmlPages;
}
}
4 changes: 4 additions & 0 deletions Services/UserServices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { User } from "../user.js";
export interface UserServices{
getUsers(n: number): Promise<User[]>;
};
Loading