Parcourir la source

visual changes

iwa23-4 il y a 2 ans
Parent
commit
69de807301

+ 139 - 20
frontend/package-lock.json

@@ -33,7 +33,6 @@
         "karma-jasmine": "~5.1.0",
         "karma-jasmine-html-reporter": "~2.0.0",
         "postcss": "^8.4.24",
-        "tailwindcss": "^3.3.2",
         "typescript": "~4.9.4"
       }
     },
@@ -42,6 +41,8 @@
       "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
       "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=10"
       },
@@ -4096,7 +4097,9 @@
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
       "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/anymatch": {
       "version": "3.1.3",
@@ -4134,7 +4137,9 @@
       "version": "5.0.2",
       "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
       "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/argparse": {
       "version": "1.0.10",
@@ -4558,6 +4563,8 @@
       "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
       "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">= 6"
       }
@@ -5311,7 +5318,9 @@
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
       "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/dir-glob": {
       "version": "3.0.1",
@@ -5329,7 +5338,9 @@
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
       "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/dns-equal": {
       "version": "1.0.0",
@@ -7308,6 +7319,8 @@
       "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz",
       "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "bin": {
         "jiti": "bin/jiti.js"
       }
@@ -7746,6 +7759,8 @@
       "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
       "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=10"
       }
@@ -8518,6 +8533,8 @@
       "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
       "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "any-promise": "^1.0.0",
         "object-assign": "^4.0.1",
@@ -8983,6 +9000,8 @@
       "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
       "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">= 6"
       }
@@ -9529,6 +9548,8 @@
       "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
       "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">= 6"
       }
@@ -9592,6 +9613,8 @@
       "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
       "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "postcss-value-parser": "^4.0.0",
         "read-cache": "^1.0.0",
@@ -9609,6 +9632,8 @@
       "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
       "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "camelcase-css": "^2.0.1"
       },
@@ -9628,6 +9653,8 @@
       "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz",
       "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "lilconfig": "^2.0.5",
         "yaml": "^2.1.1"
@@ -9657,6 +9684,8 @@
       "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz",
       "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">= 14"
       }
@@ -9747,6 +9776,8 @@
       "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
       "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "postcss-selector-parser": "^6.0.11"
       },
@@ -9946,6 +9977,8 @@
       "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
       "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "pify": "^2.3.0"
       }
@@ -9955,6 +9988,8 @@
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
       "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -11204,6 +11239,8 @@
       "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz",
       "integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "@jridgewell/gen-mapping": "^0.3.2",
         "commander": "^4.0.0",
@@ -11226,6 +11263,8 @@
       "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
       "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "@jridgewell/set-array": "^1.0.1",
         "@jridgewell/sourcemap-codec": "^1.4.10",
@@ -11240,6 +11279,8 @@
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "balanced-match": "^1.0.0",
         "concat-map": "0.0.1"
@@ -11250,6 +11291,8 @@
       "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
       "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">= 6"
       }
@@ -11259,6 +11302,8 @@
       "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
       "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
@@ -11279,6 +11324,8 @@
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
       "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "brace-expansion": "^1.1.7"
       },
@@ -11324,6 +11371,8 @@
       "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz",
       "integrity": "sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "@alloc/quick-lru": "^5.2.0",
         "arg": "^5.0.2",
@@ -11362,6 +11411,8 @@
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
       "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "is-glob": "^4.0.3"
       },
@@ -11374,6 +11425,8 @@
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
       "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "is-core-module": "^2.11.0",
         "path-parse": "^1.0.7",
@@ -11649,6 +11702,8 @@
       "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
       "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "any-promise": "^1.0.0"
       }
@@ -11658,6 +11713,8 @@
       "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
       "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "thenify": ">= 3.1.0 < 4"
       },
@@ -11732,7 +11789,9 @@
       "version": "0.1.13",
       "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
       "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/tslib": {
       "version": "2.5.3",
@@ -12576,7 +12635,9 @@
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
       "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "@ampproject/remapping": {
       "version": "2.2.0",
@@ -15473,7 +15534,9 @@
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
       "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "anymatch": {
       "version": "3.1.3",
@@ -15505,7 +15568,9 @@
       "version": "5.0.2",
       "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
       "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "argparse": {
       "version": "1.0.10",
@@ -15815,7 +15880,9 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
       "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "caniuse-lite": {
       "version": "1.0.30001499",
@@ -16380,7 +16447,9 @@
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
       "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "dir-glob": {
       "version": "3.0.1",
@@ -16395,7 +16464,9 @@
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
       "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "dns-equal": {
       "version": "1.0.0",
@@ -17910,7 +17981,9 @@
       "version": "1.18.2",
       "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz",
       "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "js-tokens": {
       "version": "4.0.0",
@@ -18242,7 +18315,9 @@
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
       "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "lines-and-columns": {
       "version": "1.2.4",
@@ -18852,6 +18927,8 @@
       "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
       "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "any-promise": "^1.0.0",
         "object-assign": "^4.0.1",
@@ -19203,7 +19280,9 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
       "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "object-inspect": {
       "version": "1.12.3",
@@ -19603,7 +19682,9 @@
       "version": "4.0.5",
       "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
       "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "piscina": {
       "version": "3.2.0",
@@ -19642,6 +19723,8 @@
       "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
       "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "postcss-value-parser": "^4.0.0",
         "read-cache": "^1.0.0",
@@ -19653,6 +19736,8 @@
       "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
       "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "camelcase-css": "^2.0.1"
       }
@@ -19662,6 +19747,8 @@
       "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz",
       "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "lilconfig": "^2.0.5",
         "yaml": "^2.1.1"
@@ -19671,7 +19758,9 @@
           "version": "2.3.1",
           "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz",
           "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         }
       }
     },
@@ -19727,6 +19816,8 @@
       "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
       "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "postcss-selector-parser": "^6.0.11"
       }
@@ -19865,6 +19956,8 @@
       "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
       "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "pify": "^2.3.0"
       },
@@ -19873,7 +19966,9 @@
           "version": "2.3.0",
           "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
           "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         }
       }
     },
@@ -20834,6 +20929,8 @@
       "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz",
       "integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "@jridgewell/gen-mapping": "^0.3.2",
         "commander": "^4.0.0",
@@ -20849,6 +20946,8 @@
           "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
           "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "@jridgewell/set-array": "^1.0.1",
             "@jridgewell/sourcemap-codec": "^1.4.10",
@@ -20860,6 +20959,8 @@
           "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
           "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -20869,13 +20970,17 @@
           "version": "4.1.1",
           "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
           "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "glob": {
           "version": "7.1.6",
           "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
           "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "fs.realpath": "^1.0.0",
             "inflight": "^1.0.4",
@@ -20890,6 +20995,8 @@
           "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
           "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
@@ -20922,6 +21029,8 @@
       "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz",
       "integrity": "sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "@alloc/quick-lru": "^5.2.0",
         "arg": "^5.0.2",
@@ -20953,6 +21062,8 @@
           "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
           "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "is-glob": "^4.0.3"
           }
@@ -20962,6 +21073,8 @@
           "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
           "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "is-core-module": "^2.11.0",
             "path-parse": "^1.0.7",
@@ -21162,6 +21275,8 @@
       "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
       "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "any-promise": "^1.0.0"
       }
@@ -21171,6 +21286,8 @@
       "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
       "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "thenify": ">= 3.1.0 < 4"
       }
@@ -21227,7 +21344,9 @@
       "version": "0.1.13",
       "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
       "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "tslib": {
       "version": "2.5.3",

+ 0 - 1
frontend/package.json

@@ -35,7 +35,6 @@
     "karma-jasmine": "~5.1.0",
     "karma-jasmine-html-reporter": "~2.0.0",
     "postcss": "^8.4.24",
-    "tailwindcss": "^3.3.2",
     "typescript": "~4.9.4"
   }
 }

+ 27 - 0
frontend/src/app/grademanager/grademanager.component.css

@@ -60,6 +60,7 @@
   margin-left: auto;
   margin-right: auto;
 }
+
 .my-btn {
   width: 100%;
   color: #fff;
@@ -80,3 +81,29 @@
   outline: none;
   box-shadow: 0 0 0 4px rgba(26, 32, 44, 0.2);
 }
+
+.label {
+  display: block;
+  margin-bottom: 0.5rem;
+  font-size: 1.5rem;
+  font-weight: 500;
+  color: #333;
+}
+
+.custom-select {
+  appearance: none;
+  background-color: #f9f9f9;
+  border: 1px solid #ddd;
+  color: #222;
+  font-size: 12px;
+  padding: 5px;
+  width: 100%;
+  border-radius: 8px;
+  outline: none;
+}
+
+.error-message {
+  margin-top: 0.5rem;
+  font-size: 0.875rem;
+  color: #ff0000;
+}

+ 68 - 71
frontend/src/app/grademanager/grademanager.component.html

@@ -1,76 +1,73 @@
 <div class="container">
-        <div class="row">
-          <h1 class="subject-title">{{subject?.name}}</h1>
-        </div>
+  <div class="row">
+    <h1 class="subject-title">{{subject?.name}}</h1>
+  </div>
 
-        <div class="container">
-          <form class="form" (ngSubmit)="f.form.valid && addGrade()" #f="ngForm" novalidate>
-            <div class="form-group">
-              <label for="grade" class="block mb-2 text-2xl font-medium text-gray-900">Grade</label>
-              <select id="grade" name="grade" [(ngModel)]="form.grade" #grade="ngModel" required
-                      class="form-control bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5">
-                <option [value]="2">2</option>
-                <option [value]="3">3</option>
-                <option [value]="4">4</option>
-                <option [value]="5">5</option>
-              </select>
-              <div *ngIf="f.submitted && grade.invalid">
-                <div class="mt-2 text-sm font-light text-gray-500" *ngIf="['grade.errors?.required']">Grade is required</div>
-              </div>
-            </div>
-            <div class="form-group">
-              <label for="student" class="block mb-2 text-2xl font-medium text-gray-900">Student</label>
-              <select id="student" name="student" [(ngModel)]="form.student" #student="ngModel" required
-                      class="form-control bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5">
-                <option *ngFor="let student of studentList" [value]="student.id">{{ student.firstname }} {{ student.lastname }}</option>
-              </select>
-              <div *ngIf="f.submitted && student.invalid">
-                <div class="mt-2 text-sm font-light text-gray-500" *ngIf="['student.errors?.required']">Student is required</div>
-              </div>
-            </div>
-            <div class="form-group">
-              <button type="submit" class="my-btn"
-                      >Add Grade</button>
-            </div>
-          </form>
+  <div class="container">
+    <form class="form" (ngSubmit)="f.form.valid && addGrade()" #f="ngForm" novalidate>
+      <div class="form-group">
+        <label for="grade" class="label">Grade</label>
+        <select id="grade" name="grade" [(ngModel)]="form.grade" #grade="ngModel" required class="custom-select">
+          <option [value]="2">2</option>
+          <option [value]="3">3</option>
+          <option [value]="4">4</option>
+          <option [value]="5">5</option>
+        </select>
+        <div *ngIf="f.submitted && grade.invalid">
+          <div class="error-message" *ngIf="['grade.errors?.required']">Grade is required</div>
         </div>
-
-        <div class="row">
-          <table class="grade-table">
-            <thead>
-            <tr>
-              <th class="table-header">Name</th>
-              <th class="table-header">lastname</th>
-              <th class="table-header">Grades</th>
-            </tr>
-            </thead>
-            <tbody>
-            <ng-container *ngFor="let student of studentList; index as i">
-              <tr [class.even-row]="i % 2 === 1">
-                <td class="table-cell">{{ student.firstname }}</td>
-                <td class="table-cell">{{ student.lastname }}</td>
-                <td class="table-cell">
-                  <div class="grades-container">
-                    <ng-container *ngFor="let grade of gradeList">
-                      <div *ngIf="grade.student.id === student.id" (dblclick)="editGrade(grade)">
-                        <ng-container *ngIf="selectedGrade !== grade; else editMode">
-                          <span class="grade">{{ grade.grade }}</span>
-                        </ng-container>
-                        <ng-template #editMode>
-                          <select [(ngModel)]="selectedGradeValue" (blur)="cancelEdit()" (keydown.enter)="saveEdit()" class="grade-edit">
-                            <option [value]="2">2</option>
-                            <option [value]="3">3</option>
-                            <option [value]="4">4</option>
-                            <option [value]="5">5</option>
-                          </select>
-                        </ng-template>
-                      </div>
-                    </ng-container>
-                  </div>
-                </td>
-              </tr>
-            </ng-container>
-            </tbody>
-          </table>
+      </div>
+      <div class="form-group">
+        <label for="student" class="label">Student</label>
+        <select id="student" name="student" [(ngModel)]="form.student" #student="ngModel" required class="custom-select">
+          <option *ngFor="let student of studentList" [value]="student.id">{{ student.firstname }} {{ student.lastname }}</option>
+        </select>
+        <div *ngIf="f.submitted && student.invalid">
+          <div class="error-message" *ngIf="['student.errors?.required']">Student is required</div>
         </div>
       </div>
+      <div class="form-group">
+        <button type="submit" class="my-btn">Add Grade</button>
+      </div>
+    </form>
+  </div>
+
+  <div class="row">
+    <table class="grade-table">
+      <thead>
+      <tr>
+        <th class="table-header">Name</th>
+        <th class="table-header">Last Name</th>
+        <th class="table-header">Grades</th>
+      </tr>
+      </thead>
+      <tbody>
+      <ng-container *ngFor="let student of studentList; index as i">
+        <tr [class.even-row]="i % 2 === 1">
+          <td class="table-cell">{{ student.firstname }}</td>
+          <td class="table-cell">{{ student.lastname }}</td>
+          <td class="table-cell">
+            <div class="grades-container">
+              <ng-container *ngFor="let grade of gradeList">
+                <div *ngIf="grade.student.id === student.id" (dblclick)="editGrade(grade)">
+                  <ng-container *ngIf="selectedGrade !== grade; else editMode">
+                    <span class="grade">{{ grade.grade }}</span>
+                  </ng-container>
+                  <ng-template #editMode>
+                    <select [(ngModel)]="selectedGradeValue" (blur)="cancelEdit()" (keydown.enter)="saveEdit()" class="grade-edit">
+                      <option [value]="2">2</option>
+                      <option [value]="3">3</option>
+                      <option [value]="4">4</option>
+                      <option [value]="5">5</option>
+                    </select>
+                  </ng-template>
+                </div>
+              </ng-container>
+            </div>
+          </td>
+        </tr>
+      </ng-container>
+      </tbody>
+    </table>
+  </div>
+</div>

+ 131 - 0
frontend/src/app/subject/subject.component.css

@@ -0,0 +1,131 @@
+.container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 24px;
+}
+
+.card {
+  width: 100%;
+  background-color: #f2f2f2;
+  border-radius: 8px;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+  margin-top: 0;
+  max-width: 28rem;
+  padding: 0;
+}
+
+.flex-container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 2rem;
+}
+
+.form {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 1rem;
+  padding: 1.25rem;
+}
+
+
+.label {
+  margin-bottom: 0.5rem;
+  font-size: 0.875rem;
+  font-weight: 500;
+  color: #111827;
+}
+
+.input {
+  background-color: #f9f9f9;
+  border: 1px solid #d1d5db;
+  color: #111827;
+  font-size: 0.875rem;
+  border-radius: 0.375rem;
+  padding: 0.625rem;
+  outline: none;
+}
+
+.error {
+  margin-top: 0.5rem;
+  font-size: 0.875rem;
+  font-weight: 300;
+  color: #9CA3AF;
+}
+
+.button {
+  width: 100%;
+  color: #fff;
+  font-weight: 500;
+  border-radius: 0.625rem;
+  font-size: 0.875rem;
+  padding: 0.625rem 1.25rem;
+  text-align: center;
+  background-color: #111827;
+  margin-top: 0.625rem;
+  margin-bottom: 0;
+  outline: none;
+  cursor: pointer;
+}
+
+.error-message {
+  margin-top: 0.5rem;
+  font-size: 0.875rem;
+  font-weight: 300;
+  color: #9CA3AF;
+}
+
+.subjects-container {
+  padding: 24px 6px;
+}
+
+.heading {
+  font-size: 1.875rem;
+  font-weight: 600;
+  color: #111827;
+  text-transform: uppercase;
+  margin-bottom: 1.25rem;
+}
+
+.empty-subjects {
+  font-size: 1.125rem;
+  font-weight: 600;
+  color: #111827;
+  text-transform: uppercase;
+  margin-bottom: 1.25rem;
+}
+
+.subjects-list {
+  display: grid;
+  grid-template-columns: repeat(4, minmax(0, 1fr));
+  gap: 0.75rem;
+}
+
+.subject-item {
+  list-style: none;
+}
+
+.subject-link {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  height: 100%;
+}
+
+.subject-name {
+  background-color: #f2f2f2;
+  font-size: 1.5rem;
+  padding: 0.75rem 1rem;
+  font-weight: 600;
+  border-radius: 0.375rem;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}

+ 15 - 17
frontend/src/app/subject/subject.component.html

@@ -1,18 +1,16 @@
-<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto lg:py-0">
-  <div class="w-full bg-gray-200 rounded-lg shadow md:mt-0 sm:max-w-md xl:p-0 ">
-    <form class="space-y-4 md:space-y-6 p-5" name="form" (ngSubmit)="f.form.valid && addSubject()" #f="ngForm" novalidate>
+<div class="container">
+  <div class="card">
+    <form class="form" name="form" (ngSubmit)="f.form.valid && addSubject()" #f="ngForm" novalidate>
       <div class="form-group">
-        <label for="username" id="username" class="block mb-2 text-sm font-medium text-gray-900">Name</label>
-        <input type="text" class="form-control bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5" name="name" [(ngModel)]="form.name" #name="ngModel"
-               required />
+        <input class="input" type="text" name="name" placeholder="Name" [(ngModel)]="form.name" #name="ngModel" required />
         <div *ngIf="f.submitted && name.invalid">
-          <div class="mt-2 text-sm font-light text-gray-500" *ngIf="['username.errors?.required']">Name is required</div>
+          <div class="error">Name is required</div>
         </div>
       </div>
       <div class="form-group">
-        <button class="w-full text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center bg-gray-900 hover:bg-gray-950 focus:ring-primary-800">Add subject</button>
-        <div *ngIf="f.submitted && isAddFailed" class="mt-2 text-sm font-light text-gray-500" >
-          Subject addition failed: {{errorMessage}}
+        <button class="button" type="submit">Add subject</button>
+        <div *ngIf="f.submitted && isAddFailed" class="error-message">
+          Subject addition failed: {{ errorMessage }}
         </div>
       </div>
     </form>
@@ -20,13 +18,13 @@
   </div>
 </div>
 
-<div class="px-6 py-8">
-  <h2 class="text-4xl font-semibold text-gray-950 uppercase mb-5">Your subjects:</h2>
-  <div *ngIf="subjectList?.length == 0" class="text-2xl font-semibold text-gray-950 uppercase mb-5">You have no subjects yet</div>
-  <ul class="grid grid-cols-4 gap-3">
-    <li *ngFor="let subject of subjectList">
-      <a class="text-center flex items-center justify-center w-full h-full" [routerLink]="['/subjects/',subject.id]">
-        <h2 class="bg-gray-200 text-3xl px-3 py-5 font-semibold rounded w-full h-full flex items-center justify-center">{{subject.name}}</h2>
+<div class="subjects-container">
+  <h2 class="heading">Your subjects:</h2>
+  <div *ngIf="subjectList?.length == 0" class="empty-subjects">You have no subjects yet</div>
+  <ul class="subjects-list">
+    <li *ngFor="let subject of subjectList" class="subject-item">
+      <a class="subject-link" [routerLink]="['/subjects/', subject.id]">
+        <h2 class="subject-name">{{ subject.name }}</h2>
       </a>
     </li>
   </ul>