From 18d81d9267d730d1c1044d79401d4c071f50bf3d Mon Sep 17 00:00:00 2001
From: migudel <miguel.moras@estudiantes.uva.es>
Date: Mon, 21 Oct 2024 21:38:52 +0200
Subject: [PATCH] Mocked List hotels

---
 angular/RestClient/angular.json               |  11 +-
 angular/RestClient/package-lock.json          | 317 ++++++----------
 angular/RestClient/package.json               |   2 +
 angular/RestClient/src/app/app.component.html | 349 +-----------------
 angular/RestClient/src/app/app.config.ts      |   9 +-
 angular/RestClient/src/app/app.routes.ts      |  13 +-
 .../app/hotel-list/hotel-list.component.css   |   0
 .../app/hotel-list/hotel-list.component.html  |  52 +++
 .../hotel-list/hotel-list.component.spec.ts   |  23 ++
 .../app/hotel-list/hotel-list.component.ts    | 100 +++++
 .../shared/cliente-api-rest.service.spec.ts   |  16 +
 .../app/shared/cliente-api-rest.service.ts    |  48 +++
 .../src/app/shared/data.service.spec.ts       |  16 +
 .../RestClient/src/app/shared/data.service.ts |  23 ++
 angular/RestClient/src/index.html             |   2 +
 angular/RestClient/src/mocks/hotels.json      |   7 +
 angular/RestClient/src/styles.css             |   3 +
 angular/RestClient/src/types/Address.d.ts     |  11 +-
 angular/RestClient/src/types/Booking.d.ts     |  13 +-
 angular/RestClient/src/types/Date.d.ts        |   9 -
 angular/RestClient/src/types/Hotel.d.ts       |  11 +-
 angular/RestClient/src/types/Room.d.ts        |   9 +-
 angular/RestClient/src/types/User.d.ts        |   9 +-
 angular/RestClient/src/types/index.ts         |  11 +-
 24 files changed, 476 insertions(+), 588 deletions(-)
 create mode 100644 angular/RestClient/src/app/hotel-list/hotel-list.component.css
 create mode 100644 angular/RestClient/src/app/hotel-list/hotel-list.component.html
 create mode 100644 angular/RestClient/src/app/hotel-list/hotel-list.component.spec.ts
 create mode 100644 angular/RestClient/src/app/hotel-list/hotel-list.component.ts
 create mode 100644 angular/RestClient/src/app/shared/cliente-api-rest.service.spec.ts
 create mode 100644 angular/RestClient/src/app/shared/cliente-api-rest.service.ts
 create mode 100644 angular/RestClient/src/app/shared/data.service.spec.ts
 create mode 100644 angular/RestClient/src/app/shared/data.service.ts
 delete mode 100644 angular/RestClient/src/types/Date.d.ts

diff --git a/angular/RestClient/angular.json b/angular/RestClient/angular.json
index 0813b43..c17a30c 100644
--- a/angular/RestClient/angular.json
+++ b/angular/RestClient/angular.json
@@ -16,9 +16,7 @@
             "outputPath": "dist/rest-client",
             "index": "src/index.html",
             "browser": "src/main.ts",
-            "polyfills": [
-              "zone.js"
-            ],
+            "polyfills": ["zone.js"],
             "tsConfig": "tsconfig.app.json",
             "assets": [
               {
@@ -27,6 +25,7 @@
               }
             ],
             "styles": [
+              "@angular/material/prebuilt-themes/azure-blue.css",
               "src/styles.css"
             ],
             "scripts": [],
@@ -78,10 +77,7 @@
         "test": {
           "builder": "@angular-devkit/build-angular:karma",
           "options": {
-            "polyfills": [
-              "zone.js",
-              "zone.js/testing"
-            ],
+            "polyfills": ["zone.js", "zone.js/testing"],
             "tsConfig": "tsconfig.spec.json",
             "assets": [
               {
@@ -90,6 +86,7 @@
               }
             ],
             "styles": [
+              "@angular/material/prebuilt-themes/cyan-orange.css",
               "src/styles.css"
             ],
             "scripts": []
diff --git a/angular/RestClient/package-lock.json b/angular/RestClient/package-lock.json
index 1382fda..1299423 100644
--- a/angular/RestClient/package-lock.json
+++ b/angular/RestClient/package-lock.json
@@ -9,10 +9,12 @@
       "version": "0.0.0",
       "dependencies": {
         "@angular/animations": "^18.2.0",
+        "@angular/cdk": "^18.2.9",
         "@angular/common": "^18.2.0",
         "@angular/compiler": "^18.2.0",
         "@angular/core": "^18.2.0",
         "@angular/forms": "^18.2.0",
+        "@angular/material": "^18.2.9",
         "@angular/platform-browser": "^18.2.0",
         "@angular/platform-browser-dynamic": "^18.2.0",
         "@angular/platform-server": "^18.2.0",
@@ -356,6 +358,23 @@
         }
       }
     },
+    "node_modules/@angular/cdk": {
+      "version": "18.2.9",
+      "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.9.tgz",
+      "integrity": "sha512-hV2dXpvy2TLwCsRtI/ZXkb2EoaJiellRr+kbcnKwO15LFoz3mTAOhKtsvu7yOyURkaPiI605qiIZrPP4zLL1qw==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "optionalDependencies": {
+        "parse5": "^7.1.2"
+      },
+      "peerDependencies": {
+        "@angular/common": "^18.0.0 || ^19.0.0",
+        "@angular/core": "^18.0.0 || ^19.0.0",
+        "rxjs": "^6.5.3 || ^7.4.0"
+      }
+    },
     "node_modules/@angular/cli": {
       "version": "18.2.8",
       "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.8.tgz",
@@ -455,6 +474,36 @@
         "typescript": ">=5.4 <5.6"
       }
     },
+    "node_modules/@angular/compiler-cli/node_modules/chokidar": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz",
+      "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "readdirp": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular/compiler-cli/node_modules/readdirp": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz",
+      "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "type": "individual",
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
     "node_modules/@angular/core": {
       "version": "18.2.8",
       "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.8.tgz",
@@ -489,6 +538,24 @@
         "rxjs": "^6.5.3 || ^7.4.0"
       }
     },
+    "node_modules/@angular/material": {
+      "version": "18.2.9",
+      "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.9.tgz",
+      "integrity": "sha512-M2oCgPPIMMd6BLgEJCD+FvdC7gRDeCjj9yktNn3ctHmkKUWRvpJ3xRBH/WjVXb+9fPCCW1iNwZI7+bN1fHE7cA==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "peerDependencies": {
+        "@angular/animations": "^18.0.0 || ^19.0.0",
+        "@angular/cdk": "18.2.9",
+        "@angular/common": "^18.0.0 || ^19.0.0",
+        "@angular/core": "^18.0.0 || ^19.0.0",
+        "@angular/forms": "^18.0.0 || ^19.0.0",
+        "@angular/platform-browser": "^18.0.0 || ^19.0.0",
+        "rxjs": "^6.5.3 || ^7.4.0"
+      }
+    },
     "node_modules/@angular/platform-browser": {
       "version": "18.2.8",
       "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.8.tgz",
@@ -5556,19 +5623,41 @@
       "license": "MIT"
     },
     "node_modules/chokidar": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz",
-      "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==",
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "readdirp": "^4.0.1"
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
       },
       "engines": {
-        "node": ">= 14.16.0"
+        "node": ">= 8.10.0"
       },
       "funding": {
         "url": "https://paulmillr.com/funding/"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/chokidar/node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
     "node_modules/chownr": {
@@ -8741,31 +8830,6 @@
         "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
-    "node_modules/karma/node_modules/chokidar": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
-      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "anymatch": "~3.1.2",
-        "braces": "~3.0.2",
-        "glob-parent": "~5.1.2",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.6.0"
-      },
-      "engines": {
-        "node": ">= 8.10.0"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
     "node_modules/karma/node_modules/cliui": {
       "version": "7.0.4",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
@@ -8805,19 +8869,6 @@
       "dev": true,
       "license": "MIT"
     },
-    "node_modules/karma/node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
     "node_modules/karma/node_modules/is-fullwidth-code-point": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -8828,32 +8879,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/karma/node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/karma/node_modules/readdirp": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "picomatch": "^2.2.1"
-      },
-      "engines": {
-        "node": ">=8.10.0"
-      }
-    },
     "node_modules/karma/node_modules/source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -10854,7 +10879,7 @@
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.0.tgz",
       "integrity": "sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==",
-      "dev": true,
+      "devOptional": true,
       "license": "MIT",
       "dependencies": {
         "entities": "^4.5.0"
@@ -11348,17 +11373,29 @@
       }
     },
     "node_modules/readdirp": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz",
-      "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
       "dev": true,
       "license": "MIT",
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
       "engines": {
-        "node": ">= 14.16.0"
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/readdirp/node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.6"
       },
       "funding": {
-        "type": "individual",
-        "url": "https://paulmillr.com/funding/"
+        "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
     "node_modules/reflect-metadata": {
@@ -11789,70 +11826,6 @@
         }
       }
     },
-    "node_modules/sass/node_modules/chokidar": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
-      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "anymatch": "~3.1.2",
-        "braces": "~3.0.2",
-        "glob-parent": "~5.1.2",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.6.0"
-      },
-      "engines": {
-        "node": ">= 8.10.0"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/sass/node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/sass/node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/sass/node_modules/readdirp": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "picomatch": "^2.2.1"
-      },
-      "engines": {
-        "node": ">=8.10.0"
-      }
-    },
     "node_modules/sax": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
@@ -14022,31 +13995,6 @@
         "balanced-match": "^1.0.0"
       }
     },
-    "node_modules/webpack-dev-server/node_modules/chokidar": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
-      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "anymatch": "~3.1.2",
-        "braces": "~3.0.2",
-        "glob-parent": "~5.1.2",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.6.0"
-      },
-      "engines": {
-        "node": ">= 8.10.0"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
     "node_modules/webpack-dev-server/node_modules/glob": {
       "version": "10.4.5",
       "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
@@ -14068,19 +14016,6 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/webpack-dev-server/node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
     "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": {
       "version": "2.0.7",
       "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
@@ -14132,32 +14067,6 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/webpack-dev-server/node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/webpack-dev-server/node_modules/readdirp": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "picomatch": "^2.2.1"
-      },
-      "engines": {
-        "node": ">=8.10.0"
-      }
-    },
     "node_modules/webpack-dev-server/node_modules/rimraf": {
       "version": "5.0.10",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",
diff --git a/angular/RestClient/package.json b/angular/RestClient/package.json
index 9b17eb5..f7aac8a 100644
--- a/angular/RestClient/package.json
+++ b/angular/RestClient/package.json
@@ -12,10 +12,12 @@
   "private": true,
   "dependencies": {
     "@angular/animations": "^18.2.0",
+    "@angular/cdk": "^18.2.9",
     "@angular/common": "^18.2.0",
     "@angular/compiler": "^18.2.0",
     "@angular/core": "^18.2.0",
     "@angular/forms": "^18.2.0",
+    "@angular/material": "^18.2.9",
     "@angular/platform-browser": "^18.2.0",
     "@angular/platform-browser-dynamic": "^18.2.0",
     "@angular/platform-server": "^18.2.0",
diff --git a/angular/RestClient/src/app/app.component.html b/angular/RestClient/src/app/app.component.html
index 36093e1..07855f6 100644
--- a/angular/RestClient/src/app/app.component.html
+++ b/angular/RestClient/src/app/app.component.html
@@ -1,336 +1,13 @@
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-<!-- * * * * * * * * * * * The content below * * * * * * * * * * * -->
-<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * -->
-<!-- * * * * * * * * * * and can be replaced.  * * * * * * * * * * -->
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-<!-- * * * * * * * * * Delete the template below * * * * * * * * * -->
-<!-- * * * * * * * to get started with your project! * * * * * * * -->
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-
-<style>
-  :host {
-    --bright-blue: oklch(51.01% 0.274 263.83);
-    --electric-violet: oklch(53.18% 0.28 296.97);
-    --french-violet: oklch(47.66% 0.246 305.88);
-    --vivid-pink: oklch(69.02% 0.277 332.77);
-    --hot-red: oklch(61.42% 0.238 15.34);
-    --orange-red: oklch(63.32% 0.24 31.68);
-
-    --gray-900: oklch(19.37% 0.006 300.98);
-    --gray-700: oklch(36.98% 0.014 302.71);
-    --gray-400: oklch(70.9% 0.015 304.04);
-
-    --red-to-pink-to-purple-vertical-gradient: linear-gradient(
-      180deg,
-      var(--orange-red) 0%,
-      var(--vivid-pink) 50%,
-      var(--electric-violet) 100%
-    );
-
-    --red-to-pink-to-purple-horizontal-gradient: linear-gradient(
-      90deg,
-      var(--orange-red) 0%,
-      var(--vivid-pink) 50%,
-      var(--electric-violet) 100%
-    );
-
-    --pill-accent: var(--bright-blue);
-
-    font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
-      Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
-      "Segoe UI Symbol";
-    box-sizing: border-box;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale;
-  }
-
-  h1 {
-    font-size: 3.125rem;
-    color: var(--gray-900);
-    font-weight: 500;
-    line-height: 100%;
-    letter-spacing: -0.125rem;
-    margin: 0;
-    font-family: "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
-      Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
-      "Segoe UI Symbol";
-  }
-
-  p {
-    margin: 0;
-    color: var(--gray-700);
-  }
-
-  main {
-    width: 100%;
-    min-height: 100%;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    padding: 1rem;
-    box-sizing: inherit;
-    position: relative;
-  }
-
-  .angular-logo {
-    max-width: 9.2rem;
-  }
-
-  .content {
-    display: flex;
-    justify-content: space-around;
-    width: 100%;
-    max-width: 700px;
-    margin-bottom: 3rem;
-  }
-
-  .content h1 {
-    margin-top: 1.75rem;
-  }
-
-  .content p {
-    margin-top: 1.5rem;
-  }
-
-  .divider {
-    width: 1px;
-    background: var(--red-to-pink-to-purple-vertical-gradient);
-    margin-inline: 0.5rem;
-  }
-
-  .pill-group {
-    display: flex;
-    flex-direction: column;
-    align-items: start;
-    flex-wrap: wrap;
-    gap: 1.25rem;
-  }
-
-  .pill {
-    display: flex;
-    align-items: center;
-    --pill-accent: var(--bright-blue);
-    background: color-mix(in srgb, var(--pill-accent) 5%, transparent);
-    color: var(--pill-accent);
-    padding-inline: 0.75rem;
-    padding-block: 0.375rem;
-    border-radius: 2.75rem;
-    border: 0;
-    transition: background 0.3s ease;
-    font-family: var(--inter-font);
-    font-size: 0.875rem;
-    font-style: normal;
-    font-weight: 500;
-    line-height: 1.4rem;
-    letter-spacing: -0.00875rem;
-    text-decoration: none;
-  }
-
-  .pill:hover {
-    background: color-mix(in srgb, var(--pill-accent) 15%, transparent);
-  }
-
-  .pill-group .pill:nth-child(6n + 1) {
-    --pill-accent: var(--bright-blue);
-  }
-  .pill-group .pill:nth-child(6n + 2) {
-    --pill-accent: var(--french-violet);
-  }
-  .pill-group .pill:nth-child(6n + 3),
-  .pill-group .pill:nth-child(6n + 4),
-  .pill-group .pill:nth-child(6n + 5) {
-    --pill-accent: var(--hot-red);
-  }
-
-  .pill-group svg {
-    margin-inline-start: 0.25rem;
-  }
-
-  .social-links {
-    display: flex;
-    align-items: center;
-    gap: 0.73rem;
-    margin-top: 1.5rem;
-  }
-
-  .social-links path {
-    transition: fill 0.3s ease;
-    fill: var(--gray-400);
-  }
-
-  .social-links a:hover svg path {
-    fill: var(--gray-900);
-  }
-
-  @media screen and (max-width: 650px) {
-    .content {
-      flex-direction: column;
-      width: max-content;
-    }
-
-    .divider {
-      height: 1px;
-      width: 100%;
-      background: var(--red-to-pink-to-purple-horizontal-gradient);
-      margin-block: 1.5rem;
-    }
-  }
-</style>
-
-<main class="main">
-  <div class="content">
-    <div class="left-side">
-      <svg
-        xmlns="http://www.w3.org/2000/svg"
-        viewBox="0 0 982 239"
-        fill="none"
-        class="angular-logo"
-      >
-        <g clip-path="url(#a)">
-          <path
-            fill="url(#b)"
-            d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.602 64.311h-44.431Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.039-7.037 7.037 0 12.846 1.145 17.347 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.745 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.618 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.009 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.092 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.814 58.814 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
-          />
-          <path
-            fill="url(#c)"
-            d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.602 64.311h-44.431Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.039-7.037 7.037 0 12.846 1.145 17.347 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.745 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.618 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.009 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.092 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.814 58.814 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
-          />
-        </g>
-        <defs>
-          <radialGradient
-            id="c"
-            cx="0"
-            cy="0"
-            r="1"
-            gradientTransform="rotate(118.122 171.182 60.81) scale(205.794)"
-            gradientUnits="userSpaceOnUse"
-          >
-            <stop stop-color="#FF41F8" />
-            <stop offset=".707" stop-color="#FF41F8" stop-opacity=".5" />
-            <stop offset="1" stop-color="#FF41F8" stop-opacity="0" />
-          </radialGradient>
-          <linearGradient
-            id="b"
-            x1="0"
-            x2="982"
-            y1="192"
-            y2="192"
-            gradientUnits="userSpaceOnUse"
-          >
-            <stop stop-color="#F0060B" />
-            <stop offset="0" stop-color="#F0070C" />
-            <stop offset=".526" stop-color="#CC26D5" />
-            <stop offset="1" stop-color="#7702FF" />
-          </linearGradient>
-          <clipPath id="a"><path fill="#fff" d="M0 0h982v239H0z" /></clipPath>
-        </defs>
-      </svg>
-      <h1>Hello, {{ title }}</h1>
-      <p>Congratulations! Your app is running. 🎉</p>
-    </div>
-    <div class="divider" role="separator" aria-label="Divider"></div>
-    <div class="right-side">
-      <div class="pill-group">
-        @for (item of [
-          { title: 'Explore the Docs', link: 'https://angular.dev' },
-          { title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' },
-          { title: 'CLI Docs', link: 'https://angular.dev/tools/cli' },
-          { title: 'Angular Language Service', link: 'https://angular.dev/tools/language-service' },
-          { title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' },
-        ]; track item.title) {
-          <a
-            class="pill"
-            [href]="item.link"
-            target="_blank"
-            rel="noopener"
-          >
-            <span>{{ item.title }}</span>
-            <svg
-              xmlns="http://www.w3.org/2000/svg"
-              height="14"
-              viewBox="0 -960 960 960"
-              width="14"
-              fill="currentColor"
-            >
-              <path
-                d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z"
-              />
-            </svg>
-          </a>
-        }
-      </div>
-      <div class="social-links">
-        <a
-          href="https://github.com/angular/angular"
-          aria-label="Github"
-          target="_blank"
-          rel="noopener"
-        >
-          <svg
-            width="25"
-            height="24"
-            viewBox="0 0 25 24"
-            fill="none"
-            xmlns="http://www.w3.org/2000/svg"
-            alt="Github"
-          >
-            <path
-              d="M12.3047 0C5.50634 0 0 5.50942 0 12.3047C0 17.7423 3.52529 22.3535 8.41332 23.9787C9.02856 24.0946 9.25414 23.7142 9.25414 23.3871C9.25414 23.0949 9.24389 22.3207 9.23876 21.2953C5.81601 22.0377 5.09414 19.6444 5.09414 19.6444C4.53427 18.2243 3.72524 17.8449 3.72524 17.8449C2.61064 17.082 3.81137 17.0973 3.81137 17.0973C5.04697 17.1835 5.69604 18.3647 5.69604 18.3647C6.79321 20.2463 8.57636 19.7029 9.27978 19.3881C9.39052 18.5924 9.70736 18.0499 10.0591 17.7423C7.32641 17.4347 4.45429 16.3765 4.45429 11.6618C4.45429 10.3185 4.9311 9.22133 5.72065 8.36C5.58222 8.04931 5.16694 6.79833 5.82831 5.10337C5.82831 5.10337 6.85883 4.77319 9.2121 6.36459C10.1965 6.09082 11.2424 5.95546 12.2883 5.94931C13.3342 5.95546 14.3801 6.09082 15.3644 6.36459C17.7023 4.77319 18.7328 5.10337 18.7328 5.10337C19.3942 6.79833 18.9789 8.04931 18.8559 8.36C19.6403 9.22133 20.1171 10.3185 20.1171 11.6618C20.1171 16.3888 17.2409 17.4296 14.5031 17.7321C14.9338 18.1012 15.3337 18.8559 15.3337 20.0084C15.3337 21.6552 15.3183 22.978 15.3183 23.3779C15.3183 23.7009 15.5336 24.0854 16.1642 23.9623C21.0871 22.3484 24.6094 17.7341 24.6094 12.3047C24.6094 5.50942 19.0999 0 12.3047 0Z"
-            />
-          </svg>
-        </a>
-        <a
-          href="https://twitter.com/angular"
-          aria-label="Twitter"
-          target="_blank"
-          rel="noopener"
-        >
-          <svg
-            width="24"
-            height="24"
-            viewBox="0 0 24 24"
-            fill="none"
-            xmlns="http://www.w3.org/2000/svg"
-            alt="Twitter"
-          >
-            <path
-              d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"
-            />
-          </svg>
-        </a>
-        <a
-          href="https://www.youtube.com/channel/UCbn1OgGei-DV7aSRo_HaAiw"
-          aria-label="Youtube"
-          target="_blank"
-          rel="noopener"
-        >
-          <svg
-            width="29"
-            height="20"
-            viewBox="0 0 29 20"
-            fill="none"
-            xmlns="http://www.w3.org/2000/svg"
-            alt="Youtube"
-          >
-            <path
-              fill-rule="evenodd"
-              clip-rule="evenodd"
-              d="M27.4896 1.52422C27.9301 1.96749 28.2463 2.51866 28.4068 3.12258C29.0004 5.35161 29.0004 10 29.0004 10C29.0004 10 29.0004 14.6484 28.4068 16.8774C28.2463 17.4813 27.9301 18.0325 27.4896 18.4758C27.0492 18.9191 26.5 19.2389 25.8972 19.4032C23.6778 20 14.8068 20 14.8068 20C14.8068 20 5.93586 20 3.71651 19.4032C3.11363 19.2389 2.56449 18.9191 2.12405 18.4758C1.68361 18.0325 1.36732 17.4813 1.20683 16.8774C0.613281 14.6484 0.613281 10 0.613281 10C0.613281 10 0.613281 5.35161 1.20683 3.12258C1.36732 2.51866 1.68361 1.96749 2.12405 1.52422C2.56449 1.08095 3.11363 0.76113 3.71651 0.596774C5.93586 0 14.8068 0 14.8068 0C14.8068 0 23.6778 0 25.8972 0.596774C26.5 0.76113 27.0492 1.08095 27.4896 1.52422ZM19.3229 10L11.9036 5.77905V14.221L19.3229 10Z"
-            />
-          </svg>
-        </a>
-      </div>
-    </div>
-  </div>
-</main>
-
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-<!-- * * * * * * * * * * * The content above * * * * * * * * * * * * -->
-<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * * -->
-<!-- * * * * * * * * * * and can be replaced.  * * * * * * * * * * * -->
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-<!-- * * * * * * * * * * End of Placeholder  * * * * * * * * * * * * -->
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-
-
-<router-outlet />
+<!-- compiled and minified CSS -->
+<link
+  rel="stylesheet"
+  href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css"
+/>
+<!-- jQuery library -->
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
+<!-- compiled JavaScript -->
+<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
+<div class="container">
+  <h3>Ejemplo angular. Gestión de reservas</h3>
+  <router-outlet></router-outlet>
+</div>
diff --git a/angular/RestClient/src/app/app.config.ts b/angular/RestClient/src/app/app.config.ts
index 52cd710..4f22ef9 100644
--- a/angular/RestClient/src/app/app.config.ts
+++ b/angular/RestClient/src/app/app.config.ts
@@ -3,7 +3,14 @@ import { provideRouter } from '@angular/router';
 
 import { routes } from './app.routes';
 import { provideClientHydration } from '@angular/platform-browser';
+import { provideHttpClient, withFetch } from '@angular/common/http';
+import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
 
 export const appConfig: ApplicationConfig = {
-  providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideClientHydration()]
+  providers: [
+    provideZoneChangeDetection({ eventCoalescing: true }),
+    provideRouter(routes),
+    provideClientHydration(),
+    provideHttpClient(withFetch()), provideAnimationsAsync(),
+  ],
 };
diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts
index dc39edb..1a20159 100644
--- a/angular/RestClient/src/app/app.routes.ts
+++ b/angular/RestClient/src/app/app.routes.ts
@@ -1,3 +1,14 @@
 import { Routes } from '@angular/router';
+import { HotelListComponent } from './hotel-list/hotel-list.component';
 
-export const routes: Routes = [];
+export const routes: Routes = [
+  {
+    path: 'hotels',
+    component: HotelListComponent,
+  },
+  {
+    path: '**',
+    redirectTo: 'hotels',
+    pathMatch: 'full',
+  },
+];
diff --git a/angular/RestClient/src/app/hotel-list/hotel-list.component.css b/angular/RestClient/src/app/hotel-list/hotel-list.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/angular/RestClient/src/app/hotel-list/hotel-list.component.html b/angular/RestClient/src/app/hotel-list/hotel-list.component.html
new file mode 100644
index 0000000..33fdff6
--- /dev/null
+++ b/angular/RestClient/src/app/hotel-list/hotel-list.component.html
@@ -0,0 +1,52 @@
+<div class="container">
+  <h2>Hotel List</h2>
+  <mat-accordion>
+    @for(hotel of hotels; track hotel.id) {
+    <mat-expansion-panel>
+      <mat-expansion-panel-header>
+        <mat-panel-title> {{ hotel.name }} </mat-panel-title>
+        <mat-panel-description>
+          {{ hotel.address.streetKind }} {{ hotel.address.streetName }} No.
+          {{ hotel.address.number }}, {{ hotel.address.postCode }}
+          {{ hotel.address.otherInfo }}
+        </mat-panel-description>
+      </mat-expansion-panel-header>
+
+      <table mat-table [dataSource]="hotel.rooms" class="mat-elevation-z8">
+        <ng-container matColumnDef="roomNumber">
+          <th mat-header-cell *matHeaderCellDef>Room Number</th>
+          <td mat-cell *matCellDef="let room">{{ room.roomNumber }}</td>
+        </ng-container>
+
+        <ng-container matColumnDef="type">
+          <th mat-header-cell *matHeaderCellDef>Type</th>
+          <td mat-cell *matCellDef="let room">{{ room.type }}</td>
+        </ng-container>
+
+        <ng-container matColumnDef="available">
+          <th mat-header-cell *matHeaderCellDef>Available</th>
+          <td mat-cell *matCellDef="let room">
+            <mat-slide-toggle
+              [checked]="room.available"
+              (change)="toggleRoomAvailability(hotel.id, room.id)"
+            ></mat-slide-toggle>
+          </td>
+        </ng-container>
+
+        <tr
+          mat-header-row
+          *matHeaderRowDef="['roomNumber', 'type', 'available']"
+        ></tr>
+        <tr
+          mat-row
+          *matRowDef="let row; columns: ['roomNumber', 'type', 'available']"
+        ></tr>
+      </table>
+
+      <button mat-raised-button (click)="deleteHotel(hotel.id)">
+        Delete Hotel
+      </button>
+    </mat-expansion-panel>
+    }
+  </mat-accordion>
+</div>
diff --git a/angular/RestClient/src/app/hotel-list/hotel-list.component.spec.ts b/angular/RestClient/src/app/hotel-list/hotel-list.component.spec.ts
new file mode 100644
index 0000000..ecc4715
--- /dev/null
+++ b/angular/RestClient/src/app/hotel-list/hotel-list.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HotelListComponent } from './hotel-list.component';
+
+describe('HotelListComponent', () => {
+  let component: HotelListComponent;
+  let fixture: ComponentFixture<HotelListComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [HotelListComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(HotelListComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/hotel-list/hotel-list.component.ts b/angular/RestClient/src/app/hotel-list/hotel-list.component.ts
new file mode 100644
index 0000000..f4dbbb4
--- /dev/null
+++ b/angular/RestClient/src/app/hotel-list/hotel-list.component.ts
@@ -0,0 +1,100 @@
+import { Component } from '@angular/core';
+import { RouterModule, Router } from '@angular/router';
+import { Hotel, Address } from '../../types';
+import {
+  MatAccordion,
+  MatExpansionPanel,
+  MatExpansionPanelDescription,
+  MatExpansionPanelHeader,
+  MatExpansionPanelTitle,
+} from '@angular/material/expansion';
+import { MatSlideToggle } from '@angular/material/slide-toggle';
+import { MatTable, MatTableModule } from '@angular/material/table';
+import { MatButton } from '@angular/material/button';
+
+import hotels from '../../mocks/hotels.json';
+import { ClienteApiRestService } from '../shared/cliente-api-rest.service';
+
+@Component({
+  selector: 'app-hotel-list',
+  standalone: true,
+  imports: [
+    RouterModule,
+    MatAccordion,
+    MatSlideToggle,
+    MatButton,
+    MatTable,
+    MatTableModule,
+    MatExpansionPanel,
+    MatExpansionPanelHeader,
+    MatExpansionPanelTitle,
+    MatExpansionPanelDescription,
+  ],
+  templateUrl: './hotel-list.component.html',
+  styleUrl: './hotel-list.component.css',
+})
+export class HotelListComponent {
+  hotels!: Hotel[];
+  mostrarMensaje!: boolean;
+  mensaje!: string;
+
+  constructor(private router: Router, private client: ClienteApiRestService) {}
+
+  ngOnInit() {
+    this.getHotelsResponse();
+  }
+
+  getHotelsResponse() {
+    this.hotels = hotels as Hotel[];
+    return;
+    this.client.getAllHotels().subscribe({
+      next: (resp) => {
+        if (resp.body != null) this.hotels = resp.body;
+      },
+      error(err) {
+        console.log('Error al traer la lista: ' + err.message);
+        throw err;
+      },
+    });
+  }
+
+  deleteHotel(id: number) {
+    if (!confirm(`Borrar hotel con id ${id}. Continuar?`)) return;
+    this.hotels = this.hotels.filter((h) => h.id !== id);
+    return;
+
+    this.client.deleteHotel(id).subscribe({
+      next: (resp) => {
+        if (resp.status < 400) {
+          this.mostrarMensaje = true;
+          this.mensaje = resp.body as string;
+          this.getHotelsResponse();
+        } else {
+          this.mostrarMensaje = true;
+          this.mensaje = 'Error al eliminar registro';
+        }
+      },
+      error: (err) => {
+        console.log('Error al borrar: ' + err.message);
+        throw err;
+      },
+    });
+  }
+
+  toggleRoomAvailability(hotelId: number, roomId: number) {
+    const target = hotels
+      .find((hotel) => hotel.id === hotelId)!
+      .rooms.find((room) => room.id === roomId);
+    if (!target) {
+      alert('Error');
+      return;
+    }
+    const availability = !target.available;
+    target.available = availability;
+    alert(`Change availability from room ${roomId} to ${availability}`);
+  }
+
+  goToEdit(hotelId: number): void {
+    this.router.navigate(['/hotels', hotelId, 'edit']);
+  }
+}
diff --git a/angular/RestClient/src/app/shared/cliente-api-rest.service.spec.ts b/angular/RestClient/src/app/shared/cliente-api-rest.service.spec.ts
new file mode 100644
index 0000000..737c944
--- /dev/null
+++ b/angular/RestClient/src/app/shared/cliente-api-rest.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { ClienteApiRestService } from './cliente-api-rest.service';
+
+describe('ClienteApiRestService', () => {
+  let service: ClienteApiRestService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(ClienteApiRestService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/shared/cliente-api-rest.service.ts b/angular/RestClient/src/app/shared/cliente-api-rest.service.ts
new file mode 100644
index 0000000..9924876
--- /dev/null
+++ b/angular/RestClient/src/app/shared/cliente-api-rest.service.ts
@@ -0,0 +1,48 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+import hotels from '../../mocks/hotels.json';
+import { Hotel } from '../../types';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class ClienteApiRestService {
+  private static readonly BASE_URI = 'http://localhost:8080';
+  private static readonly HOTEL_URI = `${ClienteApiRestService.BASE_URI}/hotels`;
+  constructor(private http: HttpClient) {}
+
+  getAllHotels() {
+    const url = `${ClienteApiRestService.HOTEL_URI}`;
+    return this.http.get<Hotel[]>(url, { observe: 'response' });
+  }
+
+  deleteHotel(id: number) {
+    const url = `${ClienteApiRestService.HOTEL_URI}/${id}`;
+    return this.http.delete(url, { observe: 'response', responseType: 'text' });
+  }
+
+  addHotel(hotel: Hotel) {
+    const url = `${ClienteApiRestService.HOTEL_URI}`;
+    return this.http.post(url, hotel, {
+      observe: 'response',
+      responseType: 'text',
+    });
+  }
+
+  alterRoomAvailability(
+    hotelId: number,
+    roomId: number,
+    availability: boolean
+  ) {
+    const url = `${ClienteApiRestService.HOTEL_URI}/${hotelId}/rooms/${roomId}`;
+    return this.http.patch(
+      url,
+      { availability },
+      {
+        observe: 'response',
+        responseType: 'text',
+      }
+    );
+  }
+}
diff --git a/angular/RestClient/src/app/shared/data.service.spec.ts b/angular/RestClient/src/app/shared/data.service.spec.ts
new file mode 100644
index 0000000..38e8d9e
--- /dev/null
+++ b/angular/RestClient/src/app/shared/data.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { DataService } from './data.service';
+
+describe('DataService', () => {
+  let service: DataService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(DataService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/shared/data.service.ts b/angular/RestClient/src/app/shared/data.service.ts
new file mode 100644
index 0000000..f22afae
--- /dev/null
+++ b/angular/RestClient/src/app/shared/data.service.ts
@@ -0,0 +1,23 @@
+import { Injectable } from '@angular/core';
+import { BehaviorSubject } from 'rxjs';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class DataService {
+  private message = new BehaviorSubject('hotel list');
+  currentMessage = this.message.asObservable();
+
+  private showMessage = new BehaviorSubject<boolean>(false);
+  showCurrentMessage = this.showMessage.asObservable();
+
+  constructor() {}
+
+  setMessage(message: string) {
+    this.message.next(message);
+  }
+
+  setShowCurrentMessage(valor: boolean) {
+    this.showMessage.next(valor);
+  }
+}
diff --git a/angular/RestClient/src/index.html b/angular/RestClient/src/index.html
index 4f03192..1890531 100644
--- a/angular/RestClient/src/index.html
+++ b/angular/RestClient/src/index.html
@@ -6,6 +6,8 @@
   <base href="/">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="icon" type="image/x-icon" href="favicon.ico">
+  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
+  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
 </head>
 <body>
   <app-root></app-root>
diff --git a/angular/RestClient/src/mocks/hotels.json b/angular/RestClient/src/mocks/hotels.json
index 2f3b194..1138111 100644
--- a/angular/RestClient/src/mocks/hotels.json
+++ b/angular/RestClient/src/mocks/hotels.json
@@ -1,7 +1,9 @@
 [
   {
+    "id": 1,
     "name": "Hotel 1",
     "address": {
+      "id": 1,
       "streetName": "Aca al lao",
       "streetKind": "Alargada",
       "number": 12,
@@ -9,11 +11,13 @@
     },
     "rooms": [
       {
+        "id": 1,
         "roomNumber": "101",
         "type": "SINGLE",
         "available": true
       },
       {
+        "id": 2,
         "roomNumber": "102",
         "type": "DOUBLE",
         "available": false
@@ -21,8 +25,10 @@
     ]
   },
   {
+    "id": 2,
     "name": "Hotel 2",
     "address": {
+      "id": 2,
       "streetName": "Calle de la plaza",
       "streetKind": "Alargada",
       "number": 12,
@@ -30,6 +36,7 @@
     },
     "rooms": [
       {
+        "id": 3,
         "roomNumber": "103",
         "type": "SUITE",
         "available": true
diff --git a/angular/RestClient/src/styles.css b/angular/RestClient/src/styles.css
index 90d4ee0..7e7239a 100644
--- a/angular/RestClient/src/styles.css
+++ b/angular/RestClient/src/styles.css
@@ -1 +1,4 @@
 /* You can add global styles to this file, and also import other style files */
+
+html, body { height: 100%; }
+body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
diff --git a/angular/RestClient/src/types/Address.d.ts b/angular/RestClient/src/types/Address.d.ts
index 35716e0..093601b 100644
--- a/angular/RestClient/src/types/Address.d.ts
+++ b/angular/RestClient/src/types/Address.d.ts
@@ -1,7 +1,8 @@
 export interface Address {
-	streetKind: string;
-	streetName: string;
-	number: number;
-	postCode: string;
-	otherInfo?: string;
+  id: number;
+  streetKind: string;
+  streetName: string;
+  number: number;
+  postCode: string;
+  otherInfo?: string;
 }
diff --git a/angular/RestClient/src/types/Booking.d.ts b/angular/RestClient/src/types/Booking.d.ts
index 0ff96ec..aac08c6 100644
--- a/angular/RestClient/src/types/Booking.d.ts
+++ b/angular/RestClient/src/types/Booking.d.ts
@@ -1,9 +1,10 @@
-import { Room } from "./Room";
-import { User } from "./User";
+import { Room } from './Room';
+import { User } from './User';
 
 export interface Booking {
-	startDate: Date;
-	endDate: Date;
-	user: User;
-	room: Room;
+  id: number;
+  startDate: Date;
+  endDate: Date;
+  user: User;
+  room: Room;
 }
diff --git a/angular/RestClient/src/types/Date.d.ts b/angular/RestClient/src/types/Date.d.ts
deleted file mode 100644
index 0ff96ec..0000000
--- a/angular/RestClient/src/types/Date.d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Room } from "./Room";
-import { User } from "./User";
-
-export interface Booking {
-	startDate: Date;
-	endDate: Date;
-	user: User;
-	room: Room;
-}
diff --git a/angular/RestClient/src/types/Hotel.d.ts b/angular/RestClient/src/types/Hotel.d.ts
index 24cfc4c..c4183aa 100644
--- a/angular/RestClient/src/types/Hotel.d.ts
+++ b/angular/RestClient/src/types/Hotel.d.ts
@@ -1,8 +1,9 @@
-import { Address } from "./Address";
-import { Room } from "./Room";
+import { Address } from './Address';
+import { Room } from './Room';
 
 export interface Hotel {
-	name: string;
-	address: Address;
-	rooms: Room[];
+  id: number;
+  name: string;
+  address: Address;
+  rooms: Room[];
 }
diff --git a/angular/RestClient/src/types/Room.d.ts b/angular/RestClient/src/types/Room.d.ts
index 63726b1..d15b514 100644
--- a/angular/RestClient/src/types/Room.d.ts
+++ b/angular/RestClient/src/types/Room.d.ts
@@ -1,6 +1,7 @@
 export interface Room {
-	roomNumber: String;
-	// type: "single" | "double" | "suite";
-	type: "SINGLE" | "DOUBLE" | "SUITE";
-	available: boolean;
+  id: number;
+  roomNumber: String;
+  // type: "single" | "double" | "suite";
+  type: 'SINGLE' | 'DOUBLE' | 'SUITE';
+  available: boolean;
 }
diff --git a/angular/RestClient/src/types/User.d.ts b/angular/RestClient/src/types/User.d.ts
index 32b6f77..ac99f9d 100644
--- a/angular/RestClient/src/types/User.d.ts
+++ b/angular/RestClient/src/types/User.d.ts
@@ -1,6 +1,7 @@
 export interface User {
-	name: string;
-	email: String;
-	// status: "noBookings" | "withActiveBookings" | "withInactiveBookings";
-	status: "NO_BOOKINGS" | "WITH_ACTIVE_BOOKINGS" | "WITH_INACTIVE_BOOKINGS";
+  id: number;
+  name: string;
+  email: String;
+  // status: "noBookings" | "withActiveBookings" | "withInactiveBookings";
+  status: 'NO_BOOKINGS' | 'WITH_ACTIVE_BOOKINGS' | 'WITH_INACTIVE_BOOKINGS';
 }
diff --git a/angular/RestClient/src/types/index.ts b/angular/RestClient/src/types/index.ts
index 9d2e33a..8ec6255 100644
--- a/angular/RestClient/src/types/index.ts
+++ b/angular/RestClient/src/types/index.ts
@@ -1,6 +1,5 @@
-export type * from "./User";
-export type * from "./Address";
-export type * from "./Date";
-export type * from "./Hotel";
-export type * from "./Room";
-export type * from "./User";
+export type * from './User';
+export type * from './Address';
+export type * from './Hotel';
+export type * from './Room';
+export type * from './User';
-- 
GitLab