diff --git a/angular.json b/angular.json index 3213167..df41bf7 100644 --- a/angular.json +++ b/angular.json @@ -22,10 +22,20 @@ { "glob": "**/*", "input": "public" + }, + { + "glob": "**/*", + "input": "./node_modules/bootstrap-italia/", + "output": "/bootstrap-italia/" + }, + { + "glob": "**/*", + "input": "./node_modules/design-angular-kit/assets/i18n", + "output": "/bootstrap-italia/i18n/" } ], "styles": [ - "src/styles.css" + "src/styles.scss" ] }, "configurations": { @@ -33,13 +43,13 @@ "budgets": [ { "type": "initial", - "maximumWarning": "500kB", - "maximumError": "1MB" + "maximumWarning": "2MB", + "maximumError": "3MB" }, { "type": "anyComponentStyle", - "maximumWarning": "4kB", - "maximumError": "8kB" + "maximumWarning": "6kB", + "maximumError": "10kB" } ], "outputHashing": "all" @@ -70,4 +80,4 @@ } } } -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c6b7bcf..6f18e63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,14 +8,21 @@ "name": "validator-gui", "version": "0.0.0", "dependencies": { - "@angular/common": "^21.1.0", + "@angular/animations": "^21.1.2", + "@angular/common": "^21.1.2", "@angular/compiler": "^21.1.0", - "@angular/core": "^21.1.0", + "@angular/core": "^21.1.2", "@angular/forms": "^21.1.0", - "@angular/platform-browser": "^21.1.0", + "@angular/platform-browser": "^21.1.2", + "@angular/platform-browser-dynamic": "^21.1.2", "@angular/router": "^21.1.0", + "@ngx-translate/core": "^17.0.0", + "@ngx-translate/http-loader": "^17.0.0", + "bootstrap-italia": "^2.17.3", + "design-angular-kit": "^21.0.0", "rxjs": "~7.8.0", - "tslib": "^2.3.0" + "tslib": "^2.3.0", + "video.js": "^8.23.4" }, "devDependencies": { "@angular/build": "^21.1.2", @@ -322,6 +329,21 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular/animations": { + "version": "21.1.2", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-21.1.2.tgz", + "integrity": "sha512-8lVSH3y/Pq22ND9ng80UQwQRiIPIE7oD3vuV98Wufld59+s5g4PdJNqPhEVD5dkYD0gYQcm3jTIXSeYuOfpsUg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/core": "21.1.2" + } + }, "node_modules/@angular/build": { "version": "21.1.2", "resolved": "https://registry.npmjs.org/@angular/build/-/build-21.1.2.tgz", @@ -585,6 +607,24 @@ } } }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "21.1.2", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-21.1.2.tgz", + "integrity": "sha512-3+6Le0CuEpJFdJniD2ol6i9i7gmlJv+Qck5lxY+eHq2Ylj0VJ9sBIFaMBCmvdb6lz7QYnKoZr+Lhv1MX6hVXyg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "21.1.2", + "@angular/compiler": "21.1.2", + "@angular/core": "21.1.2", + "@angular/platform-browser": "21.1.2" + } + }, "node_modules/@angular/router": { "version": "21.1.2", "resolved": "https://registry.npmjs.org/@angular/router/-/router-21.1.2.tgz", @@ -903,6 +943,15 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", @@ -951,6 +1000,24 @@ "node": ">=6.9.0" } }, + "node_modules/@bundled-es-modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-Rk453EklPUPC3NRWc3VUNI/SSUjdBaFoaQvFRmNBNtMHVtOFD5AntiWg5kEE1hqcPqedYFDzxE3ZcMYPcA195w==", + "license": "ISC", + "dependencies": { + "deepmerge": "^4.3.1" + } + }, + "node_modules/@bundled-es-modules/postcss-calc-ast-parser": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/postcss-calc-ast-parser/-/postcss-calc-ast-parser-0.1.6.tgz", + "integrity": "sha512-y65TM5zF+uaxo9OeekJ3rxwTINlQvrkbZLogYvQYVoLtxm4xEiHfZ7e/MyiWbStYyWZVZkVqsaVU6F4SUK5XUA==", + "license": "ISC", + "dependencies": { + "postcss-calc-ast-parser": "^0.1.4" + } + }, "node_modules/@csstools/color-helpers": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", @@ -2615,6 +2682,32 @@ "url": "https://github.com/sponsors/Brooooooklyn" } }, + "node_modules/@ngx-translate/core": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-17.0.0.tgz", + "integrity": "sha512-Rft2D5ns2pq4orLZjEtx1uhNuEBerUdpFUG1IcqtGuipj6SavgB8SkxtNQALNDA+EVlvsNCCjC2ewZVtUeN6rg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": ">=16", + "@angular/core": ">=16" + } + }, + "node_modules/@ngx-translate/http-loader": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-17.0.0.tgz", + "integrity": "sha512-hgS8sa0ARjH9ll3PhkLTufeVXNI2DNR2uFKDhBgq13siUXzzVr/a31M6zgecrtwbA34iaBV01hsTMbMS8V7iIw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": ">=16", + "@angular/core": ">=16" + } + }, "node_modules/@npmcli/agent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.0.tgz", @@ -3178,6 +3271,16 @@ "license": "MIT", "optional": true }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rolldown/binding-android-arm64": { "version": "1.0.0-beta.58", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.58.tgz", @@ -3853,12 +3956,44 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/@splidejs/splide": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@splidejs/splide/-/splide-4.1.4.tgz", + "integrity": "sha512-5I30evTJcAJQXt6vJ26g2xEkG+l1nXcpEw4xpKh0/FWQ8ozmAeTbtniVtVmz2sH1Es3vgfC4SS8B2X4o5JMptA==", + "license": "MIT" + }, "node_modules/@standard-schema/spec": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "license": "MIT" }, + "node_modules/@tokens-studio/sd-transforms": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tokens-studio/sd-transforms/-/sd-transforms-2.0.3.tgz", + "integrity": "sha512-PyrmRb7FuJBHzsbuWNk/O06hJbaZ+RL7chmK7PRbEptaSruhANai7Kxja5CiYnTcxOj373uRMDPxoFwCHaVpvA==", + "license": "MIT", + "dependencies": { + "@bundled-es-modules/deepmerge": "^4.3.1", + "@bundled-es-modules/postcss-calc-ast-parser": "^0.1.6", + "@tokens-studio/types": "^0.5.1", + "colorjs.io": "^0.5.2", + "expr-eval-fork": "^3.0.1", + "is-mergeable-object": "^1.1.1" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "style-dictionary": "^5.0.0" + } + }, + "node_modules/@tokens-studio/types": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@tokens-studio/types/-/types-0.5.2.tgz", + "integrity": "sha512-rzMcZP0bj2E5jaa7Fj0LGgYHysoCrbrxILVbT0ohsCUH5uCHY/u6J7Qw/TE0n6gR9Js/c9ZO9T8mOoz0HdLMbA==", + "license": "MIT" + }, "node_modules/@tufjs/canonical-json": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", @@ -3894,6 +4029,15 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/bootstrap": { + "version": "5.2.10", + "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.2.10.tgz", + "integrity": "sha512-F2X+cd6551tep0MvVZ6nM8v7XgGN/twpdNDjqS1TUM7YFNEtQYWk+dKAnH+T1gr6QgCoGMPl487xw/9hXooa2g==", + "license": "MIT", + "dependencies": { + "@popperjs/core": "^2.9.2" + } + }, "node_modules/@types/chai": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", @@ -3919,6 +4063,54 @@ "dev": true, "license": "MIT" }, + "node_modules/@videojs/http-streaming": { + "version": "3.17.2", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.17.2.tgz", + "integrity": "sha512-VBQ3W4wnKnVKb/limLdtSD2rAd5cmHN70xoMf4OmuDd0t2kfJX04G+sfw6u2j8oOm2BXYM9E1f4acHruqKnM1g==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^4.1.1", + "aes-decrypter": "^4.0.2", + "global": "^4.4.0", + "m3u8-parser": "^7.2.0", + "mpd-parser": "^1.3.1", + "mux.js": "7.1.0", + "video.js": "^7 || ^8" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "video.js": "^8.19.0" + } + }, + "node_modules/@videojs/vhs-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-4.1.1.tgz", + "integrity": "sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "global": "^4.4.0" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + } + }, + "node_modules/@videojs/xhr": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.7.0.tgz", + "integrity": "sha512-giab+EVRanChIupZK7gXjHy90y3nncA2phIOyG3Ne5fvpiMJzvqYwiTOnEVW2S4CoYcuKJkomat7bMXA/UoUZQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "global": "~4.4.0", + "is-function": "^1.0.1" + } + }, "node_modules/@vitejs/plugin-basic-ssl": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.1.0.tgz", @@ -4043,6 +4235,15 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", + "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -4074,6 +4275,18 @@ "node": ">= 0.6" } }, + "node_modules/aes-decrypter": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.2.tgz", + "integrity": "sha512-lc+/9s6iJvuaRe5qDlMTpCFjnwpkeOXp8qP3oiZ5jsj1MRg+SBVUmmICrhxHvc8OELSmc+fEyyxAuppY6hrWzw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^4.1.1", + "global": "^4.4.0", + "pkcs7": "^1.0.4" + } + }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -4145,6 +4358,12 @@ "node": ">= 14.0.0" } }, + "node_modules/animejs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.2.2.tgz", + "integrity": "sha512-Ao95qWLpDPXXM+WrmwcKbl6uNlC5tjnowlaRYtuVDHHoygjtIPfDUoK9NthrlZsQSKjZXlmji2TrBUAVbiH0LQ==", + "license": "MIT" + }, "node_modules/ansi-escapes": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", @@ -4269,6 +4488,24 @@ "dev": true, "license": "ISC" }, + "node_modules/bootstrap-italia": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/bootstrap-italia/-/bootstrap-italia-2.17.3.tgz", + "integrity": "sha512-LkvI5jQd7SsrPRkItm4eSDqWd/wl1fMOEpEcFGKB0WdGpnjDIsqEVFIZklrn1zeLor9yvOA4y4IPVJfC5zexSw==", + "license": "BSD-3-Clause", + "dependencies": { + "@popperjs/core": "^2.11.6", + "@splidejs/splide": "^4.1.4", + "@types/bootstrap": "^5.2.6", + "animejs": "^3.2.1", + "design-tokens-italia": "^1.3.2", + "just-validate": "^4.3.0", + "minimasonry": "^1.3.2", + "progressbar.js": "^1.1.0", + "uuid": "^8.3.2", + "video.js": "^8.21.0" + } + }, "node_modules/browserslist": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", @@ -4595,6 +4832,12 @@ "dev": true, "license": "MIT" }, + "node_modules/colorjs.io": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", + "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", + "license": "MIT" + }, "node_modules/content-disposition": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", @@ -4798,6 +5041,15 @@ "dev": true, "license": "MIT" }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -4808,6 +5060,34 @@ "node": ">= 0.8" } }, + "node_modules/design-angular-kit": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/design-angular-kit/-/design-angular-kit-21.0.0.tgz", + "integrity": "sha512-GZhGPJNiIVMcwph5DSSvs4qxVYI9fyx/o25wWMj5tVT5a0OWr0gGRLYUGzwNk4Av7t7bXZY3txAYybMiJenO2g==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "^2.6.3" + }, + "peerDependencies": { + "@angular/animations": "^20.3.16", + "@angular/common": "^20.3.16", + "@angular/core": "^20.3.16", + "@angular/platform-browser": "^20.3.16", + "@angular/router": "^20.3.16", + "@ngx-translate/core": "^16.0.4", + "@ngx-translate/http-loader": "^16.0.1", + "bootstrap-italia": "^2.16.2" + } + }, + "node_modules/design-tokens-italia": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/design-tokens-italia/-/design-tokens-italia-1.3.2.tgz", + "integrity": "sha512-rrqwglULkGjDKcKmN48ta3kbJHxsRvVukdUhZOAos1c44lYTDZ51TheyuwlQ9Ff8b0SPLkDH5Ai88zweky+VsA==", + "license": "BSD-3-Clause", + "dependencies": { + "@tokens-studio/sd-transforms": "^2.0.2" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -4834,6 +5114,11 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -5158,6 +5443,15 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/expr-eval-fork": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/expr-eval-fork/-/expr-eval-fork-3.0.3.tgz", + "integrity": "sha512-BhC+hbc5lIVjygr840n5DEkW3MQq7H9o+mc1/N7Z5uIiCFVyESLL5DIE7LNq4CYUNxy+XjA+3jRrL/h0Kt2xcg==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, "node_modules/express": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", @@ -5319,7 +5613,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -5437,6 +5730,16 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "license": "MIT", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -5483,17 +5786,6 @@ "node": ">= 0.4" } }, - "node_modules/hono": { - "version": "4.11.7", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.7.tgz", - "integrity": "sha512-l7qMiNee7t82bH3SeyUCt9UF15EVmaBvsppY2zQtrbIhl/yzBTny+YUxsVjSjQ6gaqaeVtZmGocom8TzBlA4Yw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=16.9.0" - } - }, "node_modules/hosted-git-info": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", @@ -5746,6 +6038,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "license": "MIT" + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -5773,6 +6071,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-mergeable-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-mergeable-object/-/is-mergeable-object-1.1.1.tgz", + "integrity": "sha512-CPduJfuGg8h8vW74WOxHtHmtQutyQBzR+3MjQ6iDHIYdbOnm1YC7jv43SqCoU8OPGTJD4nibmiryA4kmogbGrA==", + "license": "MIT" + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -5958,6 +6262,12 @@ ], "license": "MIT" }, + "node_modules/just-validate": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/just-validate/-/just-validate-4.3.0.tgz", + "integrity": "sha512-9yS7ZnFk95vq+O7CAa7XZEJvZN5i6jTQWNhLwOjtgkSqiLxo7GZJhK8ViylP76fXPfHLs8tYWqi81XgxPF3OGA==", + "license": "MIT" + }, "node_modules/listr2": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", @@ -6040,6 +6350,12 @@ "@lmdb/lmdb-win32-x64": "3.4.4" } }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT" + }, "node_modules/log-symbols": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", @@ -6123,6 +6439,17 @@ "yallist": "^3.0.2" } }, + "node_modules/m3u8-parser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-7.2.0.tgz", + "integrity": "sha512-CRatFqpjVtMiMaKXxNvuI3I++vUumIXVVT/JpCpdU/FynV/ceVw1qpPyyBNindL+JlPMSesx+WX1QJaZEJSaMQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^4.1.1", + "global": "^4.4.0" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -6236,6 +6563,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/min-document": { + "version": "2.19.2", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.2.tgz", + "integrity": "sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==", + "license": "MIT", + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/minimasonry": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/minimasonry/-/minimasonry-1.3.2.tgz", + "integrity": "sha512-ygvf5JIR4NT1LbM6o8z1oz1icTkta72gXKwidvSqIVxuzVd/P21UI0Wbq1J+MStAu50Vvr8qWYNSz1W4uycqMQ==", + "license": "MIT" + }, "node_modules/minimatch": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.2.tgz", @@ -6385,6 +6727,21 @@ "node": ">= 18" } }, + "node_modules/mpd-parser": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-1.3.1.tgz", + "integrity": "sha512-1FuyEWI5k2HcmhS1HkKnUAQV7yFPfXPht2DnRRGtoiiAAW+ESTbtEXIDpRkwdU+XyrQuwrIym7UkoPKsZ0SyFw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^4.0.0", + "@xmldom/xmldom": "^0.8.3", + "global": "^4.4.0" + }, + "bin": { + "mpd-to-m3u8-json": "bin/parse.js" + } + }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", @@ -6446,6 +6803,23 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/mux.js": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-7.1.0.tgz", + "integrity": "sha512-NTxawK/BBELJrYsZThEulyUMDVlLizKdxyAsMuzoCD1eFj97BVaA8D/CvKsKu6FOLYkFojN5CbM9h++ZTZtknA==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.11.2", + "global": "^4.4.0" + }, + "bin": { + "muxjs-transmux": "bin/transmux.js" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -7020,6 +7394,18 @@ "node": ">=16.20.0" } }, + "node_modules/pkcs7": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pkcs7/-/pkcs7-1.0.4.tgz", + "integrity": "sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.5.5" + }, + "bin": { + "pkcs7": "bin/cli.js" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -7049,6 +7435,18 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-calc-ast-parser": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/postcss-calc-ast-parser/-/postcss-calc-ast-parser-0.1.4.tgz", + "integrity": "sha512-CebpbHc96zgFjGgdQ6BqBy6XIUgRx1xXWCAAk6oke02RZ5nxwo9KQejTg8y7uYEeI9kv8jKQPYjoe6REsY23vw==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^3.3.1" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", @@ -7056,6 +7454,12 @@ "dev": true, "license": "MIT" }, + "node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "license": "MIT" + }, "node_modules/proc-log": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", @@ -7066,6 +7470,25 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/progressbar.js": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/progressbar.js/-/progressbar.js-1.1.1.tgz", + "integrity": "sha512-FBsw3BKsUbb+hNeYfiP3xzvAAQrPi4DnGDw66bCmfuRCDLcslxyxv2GyYUdBSKFGSIBa73CUP5WMcl6F8AAXlw==", + "license": "MIT", + "dependencies": { + "lodash.merge": "^4.6.2", + "shifty": "^2.8.3" + } + }, "node_modules/promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", @@ -7496,6 +7919,15 @@ "node": ">=8" } }, + "node_modules/shifty": { + "version": "2.20.4", + "resolved": "https://registry.npmjs.org/shifty/-/shifty-2.20.4.tgz", + "integrity": "sha512-4Y0qRkg8ME5XN8yGNAwmFOmsIURGFKT9UQfNL6DDJQErYtN5HsjyoBuJn41ZQfTkuu2rIbRMn9qazjKsDpO2TA==", + "license": "MIT", + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -8102,6 +8534,15 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -8133,6 +8574,57 @@ "node": ">= 0.8" } }, + "node_modules/video.js": { + "version": "8.23.4", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-8.23.4.tgz", + "integrity": "sha512-qI0VTlYmKzEqRsz1Nppdfcaww4RSxZAq77z2oNSl3cNg2h6do5C8Ffl0KqWQ1OpD8desWXsCrde7tKJ9gGTEyQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/http-streaming": "^3.17.2", + "@videojs/vhs-utils": "^4.1.1", + "@videojs/xhr": "2.7.0", + "aes-decrypter": "^4.0.2", + "global": "4.4.0", + "m3u8-parser": "^7.2.0", + "mpd-parser": "^1.3.1", + "mux.js": "^7.0.1", + "videojs-contrib-quality-levels": "4.1.0", + "videojs-font": "4.2.0", + "videojs-vtt.js": "0.15.5" + } + }, + "node_modules/videojs-contrib-quality-levels": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-4.1.0.tgz", + "integrity": "sha512-TfrXJJg1Bv4t6TOCMEVMwF/CoS8iENYsWNKip8zfhB5kTcegiFYezEA0eHAJPU64ZC8NQbxQgOwAsYU8VXbOWA==", + "license": "Apache-2.0", + "dependencies": { + "global": "^4.4.0" + }, + "engines": { + "node": ">=16", + "npm": ">=8" + }, + "peerDependencies": { + "video.js": "^8" + } + }, + "node_modules/videojs-font": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-4.2.0.tgz", + "integrity": "sha512-YPq+wiKoGy2/M7ccjmlvwi58z2xsykkkfNMyIg4xb7EZQQNwB71hcSsB3o75CqQV7/y5lXkXhI/rsGAS7jfEmQ==", + "license": "Apache-2.0" + }, + "node_modules/videojs-vtt.js": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.5.tgz", + "integrity": "sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==", + "license": "Apache-2.0", + "dependencies": { + "global": "^4.3.1" + } + }, "node_modules/vite": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", diff --git a/package.json b/package.json index beded2a..9879cd2 100644 --- a/package.json +++ b/package.json @@ -23,14 +23,21 @@ "private": true, "packageManager": "npm@11.8.0", "dependencies": { - "@angular/common": "^21.1.0", + "@angular/animations": "^21.1.2", + "@angular/common": "^21.1.2", "@angular/compiler": "^21.1.0", - "@angular/core": "^21.1.0", + "@angular/core": "^21.1.2", "@angular/forms": "^21.1.0", - "@angular/platform-browser": "^21.1.0", + "@angular/platform-browser": "^21.1.2", + "@angular/platform-browser-dynamic": "^21.1.2", "@angular/router": "^21.1.0", + "@ngx-translate/core": "^17.0.0", + "@ngx-translate/http-loader": "^17.0.0", + "bootstrap-italia": "^2.17.3", + "design-angular-kit": "^21.0.0", "rxjs": "~7.8.0", - "tslib": "^2.3.0" + "tslib": "^2.3.0", + "video.js": "^8.23.4" }, "devDependencies": { "@angular/build": "^21.1.2", @@ -40,4 +47,4 @@ "typescript": "~5.9.2", "vitest": "^4.0.8" } -} \ No newline at end of file +} diff --git a/src/app/app.config.ts b/src/app/app.config.ts index cb1270e..e3145c9 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -2,10 +2,23 @@ import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/ import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; +import { provideDesignAngularKit } from 'design-angular-kit'; +import { provideHttpClient } from '@angular/common/http'; +import { provideTranslateService } from '@ngx-translate/core'; +import { provideTranslateHttpLoader } from '@ngx-translate/http-loader'; export const appConfig: ApplicationConfig = { providers: [ provideBrowserGlobalErrorListeners(), - provideRouter(routes) + provideRouter(routes), + provideHttpClient(), + provideTranslateService({ + loader: provideTranslateHttpLoader({ + prefix: '/bootstrap-italia/i18n/', + suffix: '.json', + }), + fallbackLang: 'it', + }), + provideDesignAngularKit(), ] }; diff --git a/src/app/app.html b/src/app/app.html index e0118a1..f3ec4a9 100644 --- a/src/app/app.html +++ b/src/app/app.html @@ -1,342 +1,8 @@ - - - - - - - - - - - -
-
-
- -

Hello, {{ title() }}

-

Congratulations! Your app is running. 🎉

-
- -
-
- @for (item of [ - { title: 'Explore the Docs', link: 'https://angular.dev' }, - { title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' }, - { title: 'Prompt and best practices for AI', link: 'https://angular.dev/ai/develop-with-ai'}, - { 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) { - - {{ item.title }} - - - - - } -
- -
-
-
- - - - - - - - +
+ +
- +
+ +
\ No newline at end of file diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index dc39edb..59a0299 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,3 +1,19 @@ import { Routes } from '@angular/router'; +import { HomePage } from './pages/home/home'; +import { LoginPage } from './pages/login/login'; -export const routes: Routes = []; +export const routes: Routes = [ + { + path: '', + component: HomePage, + pathMatch: 'full' + }, + { + path: 'login', + component: LoginPage + }, + { + path: '**', + redirectTo: '' + } +]; \ No newline at end of file diff --git a/src/app/app.ts b/src/app/app.ts index 58a07e9..2889167 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -1,12 +1,19 @@ -import { Component, signal } from '@angular/core'; +import { Component, inject, signal } from '@angular/core'; import { RouterOutlet } from '@angular/router'; +import { Header } from "./components/header/header"; +import { AuthenticationService } from './services/authentication'; @Component({ selector: 'app-root', - imports: [RouterOutlet], + imports: [ RouterOutlet, Header], templateUrl: './app.html', styleUrl: './app.css' }) export class App { - protected readonly title = signal('validator-gui'); -} + protected readonly title = signal('validator-gui'); + + protected authService = inject(AuthenticationService); + + loggedInUser = this.authService.loggedInUser; + + } diff --git a/src/app/components/header/header.css b/src/app/components/header/header.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/header/header.html b/src/app/components/header/header.html new file mode 100644 index 0000000..890d2de --- /dev/null +++ b/src/app/components/header/header.html @@ -0,0 +1,35 @@ + + + @if (loggedInUser()) { + + + Mario Rossi + + } @else { + +
+ + Accedi all'area riservata +
+
+ } +
+ + + +
+
Validatore Sistemi Fiscali
+
ISTI SiFi Group
+
+
+
+ + + Home + + +
\ No newline at end of file diff --git a/src/app/components/header/header.spec.ts b/src/app/components/header/header.spec.ts new file mode 100644 index 0000000..f6d7d05 --- /dev/null +++ b/src/app/components/header/header.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Header } from './header'; + +describe('Header', () => { + let component: Header; + let fixture: ComponentFixture
; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [Header] + }) + .compileComponents(); + + fixture = TestBed.createComponent(Header); + component = fixture.componentInstance; + await fixture.whenStable(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/header/header.ts b/src/app/components/header/header.ts new file mode 100644 index 0000000..6d075f4 --- /dev/null +++ b/src/app/components/header/header.ts @@ -0,0 +1,18 @@ +import { Component, inject } from '@angular/core'; +import { DesignAngularKitModule, ItTooltipDirective } from 'design-angular-kit'; +import { AuthenticationService } from '../../services/authentication'; +import { InitialsPipe } from '../../pipes/initials-pipe-pipe'; +import { RouterLink } from "@angular/router"; + +@Component({ + selector: 'app-header', + imports: [DesignAngularKitModule, InitialsPipe, RouterLink], + templateUrl: './header.html', + styleUrl: './header.css', +}) +export class Header { + + protected authService = inject(AuthenticationService); + + loggedInUser = this.authService.loggedInUser; +} diff --git a/src/app/directives/logged-in.spec.ts b/src/app/directives/logged-in.spec.ts new file mode 100644 index 0000000..3bcecf1 --- /dev/null +++ b/src/app/directives/logged-in.spec.ts @@ -0,0 +1,8 @@ +import { LoggedIn } from './logged-in'; + +describe('LoggedIn', () => { + it('should create an instance', () => { + const directive = new LoggedIn(); + expect(directive).toBeTruthy(); + }); +}); diff --git a/src/app/directives/logged-in.ts b/src/app/directives/logged-in.ts new file mode 100644 index 0000000..b55d57e --- /dev/null +++ b/src/app/directives/logged-in.ts @@ -0,0 +1,18 @@ +import { Directive, TemplateRef, ViewContainerRef } from '@angular/core'; +import { AuthenticationService } from '../services/authentication'; + +@Directive({ + selector: '[loggedIn]', + standalone: true +}) +export class LoggedInDirective { + constructor( + tpl: TemplateRef, + vcr: ViewContainerRef, + auth: AuthenticationService + ) { + if (auth.isLoggedIn()) { + vcr.createEmbeddedView(tpl); + } + } +} \ No newline at end of file diff --git a/src/app/guards/auth-guard.spec.ts b/src/app/guards/auth-guard.spec.ts new file mode 100644 index 0000000..0ffeaf0 --- /dev/null +++ b/src/app/guards/auth-guard.spec.ts @@ -0,0 +1,17 @@ +import { TestBed } from '@angular/core/testing'; +import { CanActivateFn } from '@angular/router'; + +import { authGuard } from './auth-guard'; + +describe('authGuard', () => { + const executeGuard: CanActivateFn = (...guardParameters) => + TestBed.runInInjectionContext(() => authGuard(...guardParameters)); + + beforeEach(() => { + TestBed.configureTestingModule({}); + }); + + it('should be created', () => { + expect(executeGuard).toBeTruthy(); + }); +}); diff --git a/src/app/guards/auth-guard.ts b/src/app/guards/auth-guard.ts new file mode 100644 index 0000000..6ca2d74 --- /dev/null +++ b/src/app/guards/auth-guard.ts @@ -0,0 +1,16 @@ +import { CanActivateFn } from '@angular/router'; +import { inject } from '@angular/core'; +import { Router } from '@angular/router'; +import { AuthenticationService } from '../services/authentication'; + +export const authGuard: CanActivateFn = (route, state) => { + const authService = inject(AuthenticationService); + const router = inject(Router); + if (authService.isLoggedIn()) { + return true; // Allow access + } else { + router.navigate(['/']); + return false; // Deny access + } +}; + diff --git a/src/app/model/user.ts b/src/app/model/user.ts new file mode 100644 index 0000000..3d81e25 --- /dev/null +++ b/src/app/model/user.ts @@ -0,0 +1,4 @@ +export type User = { + username: string; + email: string; +}; \ No newline at end of file diff --git a/src/app/pages/home/home.css b/src/app/pages/home/home.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/home/home.html b/src/app/pages/home/home.html new file mode 100644 index 0000000..1ae983f --- /dev/null +++ b/src/app/pages/home/home.html @@ -0,0 +1,21 @@ +
+

+ Benvenuto nel sistema di validazione dei dati fiscali +

+ +

+ Un servizio per la validazione automatica dei dati, progettato per + garantire qualità, affidabilità e trasparenza. +

+ +
+ +

+ Il sistema consente di verificare la correttezza delle informazioni + attraverso regole configurabili e controlli avanzati. +

+ +

+ L’accesso alle funzionalità complete è riservato agli utenti autenticati. +

+
diff --git a/src/app/pages/home/home.spec.ts b/src/app/pages/home/home.spec.ts new file mode 100644 index 0000000..70dd3ad --- /dev/null +++ b/src/app/pages/home/home.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Home } from './home'; + +describe('Home', () => { + let component: Home; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [Home] + }) + .compileComponents(); + + fixture = TestBed.createComponent(Home); + component = fixture.componentInstance; + await fixture.whenStable(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/home/home.ts b/src/app/pages/home/home.ts new file mode 100644 index 0000000..c5b14b4 --- /dev/null +++ b/src/app/pages/home/home.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-home', + imports: [], + templateUrl: './home.html', + styleUrl: './home.css', +}) +export class HomePage { + +} diff --git a/src/app/pages/login/login.css b/src/app/pages/login/login.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/login/login.html b/src/app/pages/login/login.html new file mode 100644 index 0000000..147cfc4 --- /dev/null +++ b/src/app/pages/login/login.html @@ -0,0 +1 @@ +

login works!

diff --git a/src/app/pages/login/login.spec.ts b/src/app/pages/login/login.spec.ts new file mode 100644 index 0000000..8d4c63e --- /dev/null +++ b/src/app/pages/login/login.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Login } from './login'; + +describe('Login', () => { + let component: Login; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [Login] + }) + .compileComponents(); + + fixture = TestBed.createComponent(Login); + component = fixture.componentInstance; + await fixture.whenStable(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/login/login.ts b/src/app/pages/login/login.ts new file mode 100644 index 0000000..5e617cc --- /dev/null +++ b/src/app/pages/login/login.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-login', + imports: [], + templateUrl: './login.html', + styleUrl: './login.css', +}) +export class LoginPage { + + + +} diff --git a/src/app/pipes/initials-pipe-pipe.spec.ts b/src/app/pipes/initials-pipe-pipe.spec.ts new file mode 100644 index 0000000..67d5356 --- /dev/null +++ b/src/app/pipes/initials-pipe-pipe.spec.ts @@ -0,0 +1,8 @@ +import { InitialsPipePipe } from './initials-pipe-pipe'; + +describe('InitialsPipePipe', () => { + it('create an instance', () => { + const pipe = new InitialsPipePipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/src/app/pipes/initials-pipe-pipe.ts b/src/app/pipes/initials-pipe-pipe.ts new file mode 100644 index 0000000..1f6b845 --- /dev/null +++ b/src/app/pipes/initials-pipe-pipe.ts @@ -0,0 +1,20 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ name: 'initials' }) +export class InitialsPipe implements PipeTransform { + + transform(fullName: string): string { + if (!fullName) return ''; + + const parts = fullName.trim().split(/\s+/); + + if (parts.length === 1) { + return parts[0].charAt(0).toUpperCase(); + } + + return ( + parts[0].charAt(0) + + parts[parts.length - 1].charAt(0) + ).toUpperCase(); + } +} \ No newline at end of file diff --git a/src/app/services/authentication.spec.ts b/src/app/services/authentication.spec.ts new file mode 100644 index 0000000..d3617bd --- /dev/null +++ b/src/app/services/authentication.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { Authentication } from './authentication'; + +describe('Authentication', () => { + let service: Authentication; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(Authentication); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/authentication.ts b/src/app/services/authentication.ts new file mode 100644 index 0000000..cd46227 --- /dev/null +++ b/src/app/services/authentication.ts @@ -0,0 +1,29 @@ +import { Injectable, signal } from '@angular/core'; +import { User } from '../model/user'; + +@Injectable({ + providedIn: 'root', +}) +export class AuthenticationService { + + private user = signal(null); + + + loggedInUser = this.user.asReadonly(); + + login(username: string, password: string) { + this.user.set({ username, email: 'test@email.it' }); // Simulate a successful login with a dummy user + localStorage.setItem('loggedInUser', JSON.stringify({ username, email: '' })); + } + + logout() { + localStorage.removeItem('loggedInUser'); + this.user.set(null); + } + + isLoggedIn(): boolean { + const storedUser = localStorage.getItem('loggedInUser'); + this.user.set(storedUser != null ? JSON.parse(storedUser) : null); + return storedUser != null; + } +} diff --git a/src/styles.css b/src/styles.css deleted file mode 100644 index 90d4ee0..0000000 --- a/src/styles.css +++ /dev/null @@ -1 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ diff --git a/src/styles.scss b/src/styles.scss new file mode 100644 index 0000000..ec066a4 --- /dev/null +++ b/src/styles.scss @@ -0,0 +1,68 @@ +/* You can add global styles to this file, and also import other style files */ +@use 'bootstrap-italia/src/scss/bootstrap-italia'; + +// Variabili Bootstrap Italia già disponibili se importi bootstrap-italia +$primary: var(--bs-primary); +$gray-700: var(--bs-gray-700); +$gray-600: var(--bs-gray-600); +$gray-300: var(--bs-gray-300); + +.home-content { + max-width: 960px; + margin: 0 auto; + padding: 3rem 1.5rem; + + // Titolo principale + &__title { + font-family: var(--bs-font-sans-serif); + font-size: 2.25rem; + font-weight: 600; + line-height: 1.2; + color: $primary; + margin-bottom: 1.5rem; + } + + // Sottotitolo / testo introduttivo + &__lead { + font-size: 1.125rem; + line-height: 1.6; + color: $gray-700; + margin-bottom: 2rem; + } + + // Testo standard + &__text { + font-size: 1rem; + line-height: 1.6; + color: $gray-600; + margin-bottom: 1rem; + } + + // Separatore soft + &__divider { + margin: 2.5rem 0; + border-top: 1px solid $gray-300; + } + + // Link istituzionale + a { + color: $primary; + font-weight: 500; + text-decoration: underline; + + &:hover { + text-decoration: none; + } + } +} + +/* Responsive */ +@media (max-width: 768px) { + .home-content { + padding: 2rem 1rem; + + &__title { + font-size: 1.75rem; + } + } +}