Compare commits
	
		
			31 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 3532968b33 | |||
| 6bb49db4ee | |||
| 38fb111f7a | |||
| a50447f457 | |||
| b1a2044631 | |||
| c883920caa | |||
| 21453ef272 | |||
| 10182433f8 | |||
| b338f33a63 | |||
| cb82200481 | |||
| 9abf74d6d2 | |||
| 50e81a6cb5 | |||
| 8fae1fb6b3 | |||
| 372fa110ec | |||
| 35bec9fe58 | |||
| 93d67bdba9 | |||
| a5e72a18e3 | |||
| 91d2f46b93 | |||
| c60bae4533 | |||
| 43ac878d44 | |||
| ceabd06a43 | |||
| 9bfc0c5338 | |||
| fb8206ff13 | |||
| dceb0ef461 | |||
| 88bc1982ca | |||
| e741a9d7e7 | |||
| 65f1d22205 | |||
| d867c08aba | |||
| 6193eff38e | |||
| f1929e7cf9 | |||
| 08642d7618 | 
							
								
								
									
										101
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								.drone.yml
									
									
									
									
									
								
							| @@ -1,101 +0,0 @@ | |||||||
| --- |  | ||||||
| kind: secret |  | ||||||
| name: docker_username |  | ||||||
| get: |  | ||||||
|   path: odit-registry-builder |  | ||||||
|   name: username |  | ||||||
|  |  | ||||||
| --- |  | ||||||
| kind: secret |  | ||||||
| name: docker_password |  | ||||||
| get: |  | ||||||
|   path: odit-registry-builder |  | ||||||
|   name: password |  | ||||||
|  |  | ||||||
| --- |  | ||||||
| kind: secret |  | ||||||
| name: git_ssh |  | ||||||
| get: |  | ||||||
|   path: odit-git-bot |  | ||||||
|   name: sshkey |  | ||||||
|  |  | ||||||
| --- |  | ||||||
| kind: secret |  | ||||||
| name: npm_url |  | ||||||
| get: |  | ||||||
|   path: odit-npm-cache |  | ||||||
|   name: url |  | ||||||
|  |  | ||||||
| --- |  | ||||||
| kind: pipeline |  | ||||||
| type: kubernetes |  | ||||||
| name: build:dev |  | ||||||
|  |  | ||||||
| steps: |  | ||||||
|   - name: run full license export |  | ||||||
|     depends_on: ["clone"] |  | ||||||
|     image: registry.odit.services/hub/library/node:19.7.0-alpine3.16 |  | ||||||
|     commands: |  | ||||||
|       - npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8 |  | ||||||
|       - pnpm i |  | ||||||
|       - pnpm licenses:export |  | ||||||
|     environment: |  | ||||||
|       NPM_REGISTRY_URL: |  | ||||||
|         from_secret: npm_url |  | ||||||
|   - name: push new licenses file to repo |  | ||||||
|     depends_on: ["run full license export"] |  | ||||||
|     image: appleboy/drone-git-push |  | ||||||
|     settings: |  | ||||||
|       branch: dev |  | ||||||
|       commit: true |  | ||||||
|       commit_message: new license file version [CI SKIP] |  | ||||||
|       author_email: bot@odit.services |  | ||||||
|       remote: git@git.odit.services:lfk/frontend.git |  | ||||||
|       ssh_key: |  | ||||||
|         from_secret: git_ssh |  | ||||||
|   - name: build dev |  | ||||||
|     depends_on: ["clone"] |  | ||||||
|     image: registry.odit.services/library/drone-kaniko |  | ||||||
|     settings: |  | ||||||
|       username: |  | ||||||
|         from_secret: docker_username |  | ||||||
|       password: |  | ||||||
|         from_secret: docker_password |  | ||||||
|       build_args: |  | ||||||
|         - NPM_REGISTRY_URL: |  | ||||||
|           from_secret: npm_url |  | ||||||
|       repo: lfk/frontend |  | ||||||
|       tags: |  | ||||||
|         - dev |  | ||||||
|       cache: true |  | ||||||
|       registry: registry.odit.services |  | ||||||
| trigger: |  | ||||||
|   branch: |  | ||||||
|     - dev |  | ||||||
|   event: |  | ||||||
|     - push |  | ||||||
|  |  | ||||||
| --- |  | ||||||
| kind: pipeline |  | ||||||
| type: kubernetes |  | ||||||
| name: build:tags |  | ||||||
| steps: |  | ||||||
|   - name: build $DRONE_TAG |  | ||||||
|     depends_on: ["clone"] |  | ||||||
|     image: registry.odit.services/library/drone-kaniko |  | ||||||
|     settings: |  | ||||||
|       username: |  | ||||||
|         from_secret: docker_username |  | ||||||
|       password: |  | ||||||
|         from_secret: docker_password |  | ||||||
|       build_args: |  | ||||||
|         - NPM_REGISTRY_URL: |  | ||||||
|           from_secret: npm_url |  | ||||||
|       repo: lfk/frontend |  | ||||||
|       tags: |  | ||||||
|         - "${DRONE_TAG}" |  | ||||||
|       cache: true |  | ||||||
|       registry: registry.odit.services |  | ||||||
| trigger: |  | ||||||
|   event: |  | ||||||
|     - tag |  | ||||||
							
								
								
									
										42
									
								
								.woodpecker/build.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								.woodpecker/build.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | steps: | ||||||
|  |   - name: run full license export | ||||||
|  |     image: registry.odit.services/hub/library/node:19.7.0-alpine3.16 | ||||||
|  |     commands: | ||||||
|  |       - npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8 | ||||||
|  |       - pnpm i | ||||||
|  |       - pnpm licenses:export | ||||||
|  |     secrets: | ||||||
|  |       - source: odit-npm-cache-url | ||||||
|  |         target: NPM_REGISTRY_URL | ||||||
|  |   - name: push new licenses file to repo | ||||||
|  |     image: appleboy/drone-git-push | ||||||
|  |     settings: | ||||||
|  |       branch: dev | ||||||
|  |       commit: true | ||||||
|  |       commit_message: new license file version [CI SKIP] | ||||||
|  |       author_email: bot@odit.services | ||||||
|  |       remote: git@git.odit.services:lfk/frontend.git | ||||||
|  |       ssh_key: | ||||||
|  |         from_secret: odit-git-bot-sshkey | ||||||
|  |   - name: build edge | ||||||
|  |     image: woodpeckerci/plugin-docker-buildx | ||||||
|  |     settings: | ||||||
|  |       repo: registry.odit.services/odit/website | ||||||
|  |       tags: | ||||||
|  |         - edge | ||||||
|  |       registry: registry.odit.services | ||||||
|  |       platforms: linux/amd64,linux/arm64 | ||||||
|  |       cache_from: registry.odit.services/odit/website:edge | ||||||
|  |       username: | ||||||
|  |         from_secret: odit-registry-builder-username | ||||||
|  |       password: | ||||||
|  |         from_secret: odit-registry-builder-password | ||||||
|  |     secrets: | ||||||
|  |       - source: odit-npm-cache-url | ||||||
|  |         target: NPM_REGISTRY_URL | ||||||
|  |  | ||||||
|  | when: | ||||||
|  |   event: | ||||||
|  |     - push | ||||||
|  |   branch: | ||||||
|  |     - dev | ||||||
							
								
								
									
										20
									
								
								.woodpecker/release.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.woodpecker/release.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | steps: | ||||||
|  |   - name: build tag | ||||||
|  |     image: woodpeckerci/plugin-docker-buildx | ||||||
|  |     settings: | ||||||
|  |       repo: registry.odit.services/lfk/frontend | ||||||
|  |       tags: | ||||||
|  |         - "${CI_COMMIT_TAG}" | ||||||
|  |       registry: registry.odit.services | ||||||
|  |       platforms: linux/amd64,linux/arm64 | ||||||
|  |       cache_from: registry.odit.services/lfk/frontend:latest | ||||||
|  |       username: | ||||||
|  |         from_secret: odit-registry-builder-username | ||||||
|  |       password: | ||||||
|  |         from_secret: odit-registry-builder-password | ||||||
|  |     secrets: | ||||||
|  |       - source: odit-npm-cache-url | ||||||
|  |         target: NPM_REGISTRY_URL | ||||||
|  | when: | ||||||
|  |   event: | ||||||
|  |     - tag | ||||||
							
								
								
									
										54
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -2,9 +2,63 @@ | |||||||
|  |  | ||||||
| All notable changes to this project will be documented in this file. Dates are displayed in UTC. | All notable changes to this project will be documented in this file. Dates are displayed in UTC. | ||||||
|  |  | ||||||
|  | #### [1.5.2](https://git.odit.services/lfk/frontend/compare/1.5.1...1.5.2) | ||||||
|  |  | ||||||
|  | - feat: improved dashboard titles ui + a11y [`21453ef`](https://git.odit.services/lfk/frontend/commit/21453ef272665c0b7c7b04009b7b74e110fbd988) | ||||||
|  | - feat: improved dashboard titles ui + a11y [`c883920`](https://git.odit.services/lfk/frontend/commit/c883920caaaaef30a8e54dd0e7eecd68943f3041) | ||||||
|  | - feat(dashboard): improved a11y of active sidebar menu item [`a50447f`](https://git.odit.services/lfk/frontend/commit/a50447f457ecc045995efb7b952b07ea09c91373) | ||||||
|  | - feat: improved mobile buttons + search ui [`38fb111`](https://git.odit.services/lfk/frontend/commit/38fb111f7a2b5a1a01b17b00e89ee081e4b91bd9) | ||||||
|  | - feat(i18n/de): rename "Track" to "Laufstrecke" [`1018243`](https://git.odit.services/lfk/frontend/commit/10182433f825968ee55298399b231173698a795c) | ||||||
|  | - feat(dashboard): improved mobile ui hamburger button [`b338f33`](https://git.odit.services/lfk/frontend/commit/b338f33a63ad8e98ab44deff2f80dbd5fe2a0fc2) | ||||||
|  | - feat(dashboard): match greeting style with rest of titles [`b1a2044`](https://git.odit.services/lfk/frontend/commit/b1a20446314d1b25e9f653bd2767b072fd629f97) | ||||||
|  | - feat(dashboard): add lfk icon and app name to mobile nav bar [`6bb49db`](https://git.odit.services/lfk/frontend/commit/6bb49db4eee95486f5a947d708b80a7a94d36933) | ||||||
|  | - feat(users/UsersOverview): improve ui by adding borders to badges [`cb82200`](https://git.odit.services/lfk/frontend/commit/cb82200481c629a0dd8b235821115ae4276948ca) | ||||||
|  |  | ||||||
|  | #### [1.5.1](https://git.odit.services/lfk/frontend/compare/1.5.0...1.5.1) | ||||||
|  |  | ||||||
|  | > 21 November 2024 | ||||||
|  |  | ||||||
|  | - chore(deps): pnpm@9 [`35bec9f`](https://git.odit.services/lfk/frontend/commit/35bec9fe584b93cd52e8bab4e469713468a67f70) | ||||||
|  | - chore(deps): bump some [`8fae1fb`](https://git.odit.services/lfk/frontend/commit/8fae1fb6b3e033f789d2568cbd2640c0d163dc53) | ||||||
|  | - fix(scanstations): CopyScanStationTokenModal open after create [`372fa11`](https://git.odit.services/lfk/frontend/commit/372fa110ec402dae166a302f2209c79353983148) | ||||||
|  | - 🚀RELEASE v1.5.1 [`9abf74d`](https://git.odit.services/lfk/frontend/commit/9abf74d6d217e7745c1055bdbfbe97de7b14572f) | ||||||
|  | - fix(config): add explicit window.config [`91d2f46`](https://git.odit.services/lfk/frontend/commit/91d2f46b934bcba1429bd1d96e772c25c42a3e28) | ||||||
|  | - fix(dockerfile): AS casing [`50e81a6`](https://git.odit.services/lfk/frontend/commit/50e81a6cb5773381e153cbec3bed7db820ced84a) | ||||||
|  | - refactor(scanstations/CopyScanStationTokenModal): drop dispatch [`a5e72a1`](https://git.odit.services/lfk/frontend/commit/a5e72a18e368b5a7ee7b4e1894de613ecb767f28) | ||||||
|  | - chore(deps): node:23.2.0 [`93d67bd`](https://git.odit.services/lfk/frontend/commit/93d67bdba90a67b45d8895d9facaf66e908d53d6) | ||||||
|  | - fix(tracks/AddTrackModal): i18n [`c60bae4`](https://git.odit.services/lfk/frontend/commit/c60bae45334c2aa90d8931da07691c196469da46) | ||||||
|  | - fix: tailwind config [`43ac878`](https://git.odit.services/lfk/frontend/commit/43ac878d44b556c6d7811610f6fe0c9a5eff305f) | ||||||
|  |  | ||||||
|  | #### [1.5.0](https://git.odit.services/lfk/frontend/compare/1.4.13...1.5.0) | ||||||
|  |  | ||||||
|  | > 20 November 2024 | ||||||
|  |  | ||||||
|  | - feat(ci)!: Switch to woodpecker [`fb8206f`](https://git.odit.services/lfk/frontend/commit/fb8206ff130f4f65dcf619a2a786e7d5895b77a1) | ||||||
|  | - 🚀RELEASE v1.5.0 [`ceabd06`](https://git.odit.services/lfk/frontend/commit/ceabd06a4319c3c9ffab680f909730d5bd789540) | ||||||
|  | - fix(components): Add missing toast imports [`9bfc0c5`](https://git.odit.services/lfk/frontend/commit/9bfc0c5338933e832d5df50457c7978c026d8df6) | ||||||
|  |  | ||||||
|  | #### [1.4.13](https://git.odit.services/lfk/frontend/compare/1.4.12...1.4.13) | ||||||
|  |  | ||||||
|  | > 31 July 2023 | ||||||
|  |  | ||||||
|  | - 🚀RELEASE v1.4.13 [`dceb0ef`](https://git.odit.services/lfk/frontend/commit/dceb0ef46197dc56e29c5f52a5bd8f9fe9b70b27) | ||||||
|  | - Show donations as euro in export [`88bc198`](https://git.odit.services/lfk/frontend/commit/88bc1982cab4481e2e9245f81eff27e095b66a0f) | ||||||
|  | - new license file version [CI SKIP] [`6193eff`](https://git.odit.services/lfk/frontend/commit/6193eff38e1a9d5726bc7d572ab36b921de843d0) | ||||||
|  |  | ||||||
|  | #### [1.4.12](https://git.odit.services/lfk/frontend/compare/1.4.11...1.4.12) | ||||||
|  |  | ||||||
|  | > 18 May 2023 | ||||||
|  |  | ||||||
|  | - 🚀RELEASE v1.4.12 [`65f1d22`](https://git.odit.services/lfk/frontend/commit/65f1d222050b0dec81fc847c1921b6135a55ce50) | ||||||
|  | - fix(donation/payment): Funny javascript number to float conversion where integers were needed [`d867c08`](https://git.odit.services/lfk/frontend/commit/d867c08aba234d3a7fe9e2311d37dc5e96fc2afc) | ||||||
|  | - new license file version [CI SKIP] [`08642d7`](https://git.odit.services/lfk/frontend/commit/08642d7618faeae31f0acfe776642c9fa156e5ff) | ||||||
|  |  | ||||||
| #### [1.4.11](https://git.odit.services/lfk/frontend/compare/1.4.10...1.4.11) | #### [1.4.11](https://git.odit.services/lfk/frontend/compare/1.4.10...1.4.11) | ||||||
|  |  | ||||||
|  | > 10 May 2023 | ||||||
|  |  | ||||||
| - chore(deps): Lockfile [`f77460b`](https://git.odit.services/lfk/frontend/commit/f77460bb0c8ce6d0f3d83a077017d5fc7bf55af7) | - chore(deps): Lockfile [`f77460b`](https://git.odit.services/lfk/frontend/commit/f77460bb0c8ce6d0f3d83a077017d5fc7bf55af7) | ||||||
|  | - 🚀RELEASE v1.4.11 [`373484c`](https://git.odit.services/lfk/frontend/commit/373484c2424bea7ae0d70d342e0ae2076aab1b6a) | ||||||
| - feat(orgs): Show total distance [`574e0dc`](https://git.odit.services/lfk/frontend/commit/574e0dcb051305bde2fc76d8456a35baec0cf309) | - feat(orgs): Show total distance [`574e0dc`](https://git.odit.services/lfk/frontend/commit/574e0dcb051305bde2fc76d8456a35baec0cf309) | ||||||
| - chore(deps): More bumps [`7b19a0a`](https://git.odit.services/lfk/frontend/commit/7b19a0aa08bb6c89c51d27c0d05777e8fcfdad17) | - chore(deps): More bumps [`7b19a0a`](https://git.odit.services/lfk/frontend/commit/7b19a0aa08bb6c89c51d27c0d05777e8fcfdad17) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| FROM registry.odit.services/hub/library/node:20.0.0-alpine3.17 as build | FROM registry.odit.services/hub/library/node:23.2.0-alpine3.20 AS build | ||||||
| ARG NPM_REGISTRY_URL=https://registry.npmjs.org | ARG NPM_REGISTRY_URL=https://registry.npmjs.org | ||||||
| WORKDIR /app | WORKDIR /app | ||||||
|  |  | ||||||
| COPY package.json pnpm-lock.yaml vite.config.js tailwind.config.js postcss.config.cjs index.html ./ | COPY package.json pnpm-lock.yaml vite.config.js tailwind.config.cjs postcss.config.cjs index.html ./ | ||||||
| RUN npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@8 | RUN npm config set registry $NPM_REGISTRY_URL && npm i -g pnpm@9 | ||||||
| RUN mkdir /pnpm && pnpm config set store-dir /pnpm && pnpm i | RUN mkdir /pnpm && pnpm config set store-dir /pnpm && pnpm i | ||||||
|  |  | ||||||
| COPY src ./src | COPY src ./src | ||||||
| @@ -11,6 +11,6 @@ COPY public ./public | |||||||
| RUN pnpm build | RUN pnpm build | ||||||
|  |  | ||||||
| # final image | # final image | ||||||
| FROM registry.odit.services/library/nginx-brotli:3.15 as final | FROM registry.odit.services/library/nginx-brotli:3.15 AS final | ||||||
| COPY --from=build /app/dist /usr/share/nginx/html | COPY --from=build /app/dist /usr/share/nginx/html | ||||||
| COPY ./nginx.conf /etc/nginx/nginx.conf | COPY ./nginx.conf /etc/nginx/nginx.conf | ||||||
| @@ -13,7 +13,7 @@ | |||||||
|  |  | ||||||
|   <body> |   <body> | ||||||
|     <span style="display: none; visibility: hidden" id="buildinfo" |     <span style="display: none; visibility: hidden" id="buildinfo" | ||||||
|       >RELEASE_INFO-1.4.11-RELEASE_INFO</span |       >RELEASE_INFO-1.5.2-RELEASE_INFO</span | ||||||
|     > |     > | ||||||
|     <noscript>You need to enable JavaScript to run this app.</noscript> |     <noscript>You need to enable JavaScript to run this app.</noscript> | ||||||
|     <script src="/env.js"></script> |     <script src="/env.js"></script> | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "@odit/lfk-frontend", |   "name": "@odit/lfk-frontend", | ||||||
|   "version": "1.4.11", |   "version": "1.5.2", | ||||||
|   "type": "module", |   "type": "module", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "i18n-order": "node order.js", |     "i18n-order": "node order.js", | ||||||
| @@ -14,14 +14,14 @@ | |||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@odit/license-exporter": "0.2.0", |     "@odit/license-exporter": "0.2.0", | ||||||
|     "@sveltejs/vite-plugin-svelte": "2.1.1", |     "@sveltejs/vite-plugin-svelte": "2.1.1", | ||||||
|     "auto-changelog": "2.4.0", |     "auto-changelog": "2.5.0", | ||||||
|     "autoprefixer": "10.4.14", |     "autoprefixer": "10.4.20", | ||||||
|     "postcss": "8.4.23", |     "postcss": "8.4.49", | ||||||
|     "prettier": "2.8.8", |     "prettier": "3.3.3", | ||||||
|     "prettier-plugin-svelte": "2.10.0", |     "prettier-plugin-svelte": "3.2.8", | ||||||
|     "release-it": "15.10.3", |     "release-it": "17.10.0", | ||||||
|     "svelte-select": "3.17.0", |     "svelte-select": "3.17.0", | ||||||
|     "tailwindcss": "3.3.2", |     "tailwindcss": "3.4.15", | ||||||
|     "vite": "4.3.3" |     "vite": "4.3.3" | ||||||
|   }, |   }, | ||||||
|   "release-it": { |   "release-it": { | ||||||
| @@ -42,11 +42,11 @@ | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@odit/lfk-client-js": "1.1.2", |     "@odit/lfk-client-js": "1.1.3", | ||||||
|     "@paralleldrive/cuid2": "2.2.0", |     "@paralleldrive/cuid2": "2.2.2", | ||||||
|     "@tanstack/svelte-table": "8.9.1", |     "@tanstack/svelte-table": "8.9.1", | ||||||
|     "bwip-js": "3.4.0", |     "bwip-js": "3.4.0", | ||||||
|     "check-password-strength": "2.0.7", |     "check-password-strength": "2.0.10", | ||||||
|     "csvtojson": "2.0.10", |     "csvtojson": "2.0.10", | ||||||
|     "localforage": "1.10.0", |     "localforage": "1.10.0", | ||||||
|     "marked": "4.3.0", |     "marked": "4.3.0", | ||||||
|   | |||||||
							
								
								
									
										5451
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5451
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -8,3 +8,4 @@ const config = { | |||||||
| 	default_password: "demo", | 	default_password: "demo", | ||||||
| 	prefersHashRouting: true, | 	prefersHashRouting: true, | ||||||
| }; | }; | ||||||
|  | window.config = config; | ||||||
|   | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -11,15 +11,16 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("cards")} |     {$_("cards")} | ||||||
|  |   </h4> | ||||||
|   {#if store.state.jwtinfo.userdetails.permissions.includes("CARD:CREATE")} |   {#if store.state.jwtinfo.userdetails.permissions.includes("CARD:CREATE")} | ||||||
|     <button |     <button | ||||||
|       on:click={() => { |       on:click={() => { | ||||||
|         modal_open = true; |         modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0" | ||||||
|     > |     > | ||||||
|       {$_("add-card")} |       {$_("add-card")} | ||||||
|     </button> |     </button> | ||||||
| @@ -28,12 +29,11 @@ | |||||||
|         bulk_modal_open = true; |         bulk_modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0" | ||||||
|     > |     > | ||||||
|       {$_("create-bulk-cards")} |       {$_("create-bulk-cards")} | ||||||
|     </button> |     </button> | ||||||
|   {/if} |   {/if} | ||||||
|   </span> |  | ||||||
|   <CardsOverview bind:current_cards bind:addCards /> |   <CardsOverview bind:current_cards bind:addCards /> | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  |  | ||||||
| <div class="text-center items-center justify-center"> | <div class="text-center items-center justify-center"> | ||||||
|   <p class="mb-16 text-lg text-gray-500"> |   <p class="mb-16 text-lg text-gray-500"> | ||||||
|     <img class="m-auto" style="height:15rem" src={cards_empty} alt="" /> |     <img class="m-auto mt-2" style="height:15rem" src={cards_empty} alt="" /> | ||||||
|     <span class="font-bold">{$_("there-are-no-cards-yet")}</span><br /> |     <span class="font-bold">{$_("there-are-no-cards-yet")}</span><br /> | ||||||
|     <span>{$_("add-your-first-card")}</span> |     <span>{$_("add-your-first-card")}</span> | ||||||
|   </p> |   </p> | ||||||
|   | |||||||
| @@ -219,7 +219,7 @@ | |||||||
|       {#if selected.length > 0} |       {#if selected.length > 0} | ||||||
|         <button |         <button | ||||||
|           type="button" |           type="button" | ||||||
|           class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm inline-flex" |           class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm inline-flex" | ||||||
|           id="options-menu" |           id="options-menu" | ||||||
|           on:click={async () => { |           on:click={async () => { | ||||||
|             const prom = []; |             const prom = []; | ||||||
|   | |||||||
| @@ -152,7 +152,7 @@ | |||||||
|           {#if delete_triggered} |           {#if delete_triggered} | ||||||
|             <button |             <button | ||||||
|               on:click={deleteContact} |               on:click={deleteContact} | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("confirm-deletion")}</button |               >{$_("confirm-deletion")}</button | ||||||
|             > |             > | ||||||
|             <button |             <button | ||||||
| @@ -169,7 +169,7 @@ | |||||||
|                 delete_triggered = true; |                 delete_triggered = true; | ||||||
|               }} |               }} | ||||||
|               type="button" |               type="button" | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("delete-contact")}</button |               >{$_("delete-contact")}</button | ||||||
|             > |             > | ||||||
|           {/if} |           {/if} | ||||||
| @@ -180,7 +180,7 @@ | |||||||
|             class:opacity-50={!save_enabled} |             class:opacity-50={!save_enabled} | ||||||
|             type="button" |             type="button" | ||||||
|             on:click={submit} |             on:click={submit} | ||||||
|             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|             >{$_("save-changes")}</button |             >{$_("save-changes")}</button | ||||||
|           > |           > | ||||||
|         {/if} |         {/if} | ||||||
|   | |||||||
| @@ -8,20 +8,20 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("contacts")} |     {$_("contacts")} | ||||||
|  |   </h4> | ||||||
|   {#if store.state.jwtinfo.userdetails.permissions.includes("CONTACT:CREATE")} |   {#if store.state.jwtinfo.userdetails.permissions.includes("CONTACT:CREATE")} | ||||||
|     <button |     <button | ||||||
|       on:click={() => { |       on:click={() => { | ||||||
|         modal_open = true; |         modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|     > |     > | ||||||
|       {$_("create-a-new-contact")} |       {$_("create-a-new-contact")} | ||||||
|     </button> |     </button> | ||||||
|   {/if} |   {/if} | ||||||
|   </span> |  | ||||||
|   <ContactsOverview bind:current_contacts /> |   <ContactsOverview bind:current_contacts /> | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ | |||||||
|         bind:value={searchvalue} |         bind:value={searchvalue} | ||||||
|         placeholder={$_("datatable.search")} |         placeholder={$_("datatable.search")} | ||||||
|         aria-label={$_("datatable.search")} |         aria-label={$_("datatable.search")} | ||||||
|         class="mb-4" |         class="mb-2 w-full sm:w-auto mt-1 sm:mt-0 p-2 rounded-md border" | ||||||
|       /> |       /> | ||||||
|       <div |       <div | ||||||
|         class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" |         class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" | ||||||
|   | |||||||
| @@ -24,12 +24,12 @@ | |||||||
|     </a> |     </a> | ||||||
|     <nav class="text-sm font-medium text-gray-600" aria-label="Main Navigation"> |     <nav class="text-sm font-medium text-gray-600" aria-label="Main Navigation"> | ||||||
|       <a |       <a | ||||||
|         class:bg-gray-100={$router.path === "/"} |         class:activenav={$router.path === "/"} | ||||||
|         class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |         class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|         href="/" |         href="/" | ||||||
|       > |       > | ||||||
|         <svg |         <svg | ||||||
|           class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |           class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|           xmlns="http://www.w3.org/2000/svg" |           xmlns="http://www.w3.org/2000/svg" | ||||||
|           viewBox="0 0 20 20" |           viewBox="0 0 20 20" | ||||||
|           fill="currentColor" |           fill="currentColor" | ||||||
| @@ -42,12 +42,12 @@ | |||||||
|       </a> |       </a> | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("ORGANIZATION:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("ORGANIZATION:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path.includes("/orgs/")} |           class:activenav={$router.path.includes("/orgs/")} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/orgs/" |           href="/orgs/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             xmlns="http://www.w3.org/2000/svg" |             xmlns="http://www.w3.org/2000/svg" | ||||||
|             viewBox="0 0 24 24" |             viewBox="0 0 24 24" | ||||||
| @@ -63,15 +63,15 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("USER:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("USER:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path === "/users/"} |           class:activenav={$router.path === "/users/"} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/users/" |           href="/users/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             xmlns="http://www.w3.org/2000/svg" |             xmlns="http://www.w3.org/2000/svg" | ||||||
|             width="24" |             width="24" | ||||||
|             height="24" |             height="24" | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             viewBox="0 0 24 24" |             viewBox="0 0 24 24" | ||||||
|             ><path fill="none" d="M0 0h24v24H0z" /> |             ><path fill="none" d="M0 0h24v24H0z" /> | ||||||
| @@ -84,12 +84,12 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("USERGROUP:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("USERGROUP:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path === "/groups/"} |           class:activenav={$router.path === "/groups/"} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/groups/" |           href="/groups/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             width="24" |             width="24" | ||||||
|             height="24" |             height="24" | ||||||
| @@ -105,14 +105,14 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path === "/runners/"} |           class:activenav={$router.path === "/runners/"} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/runners/" |           href="/runners/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             xmlns="http://www.w3.org/2000/svg" |             xmlns="http://www.w3.org/2000/svg" | ||||||
|             viewBox="0 0 24 24" |             viewBox="0 0 24 24" | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             width="24" |             width="24" | ||||||
|             height="24" |             height="24" | ||||||
| @@ -126,12 +126,12 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("TEAM:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("TEAM:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path === "/teams/"} |           class:activenav={$router.path === "/teams/"} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/teams/" |           href="/teams/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             width="24" |             width="24" | ||||||
|             height="24" |             height="24" | ||||||
| @@ -147,12 +147,12 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("DONOR:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("DONOR:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path.includes("/donors/")} |           class:activenav={$router.path.includes("/donors/")} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/donors/" |           href="/donors/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             xmlns="http://www.w3.org/2000/svg" |             xmlns="http://www.w3.org/2000/svg" | ||||||
|             viewBox="0 0 24 24" |             viewBox="0 0 24 24" | ||||||
| @@ -168,12 +168,12 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("DONATION:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("DONATION:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path.includes("/donations/")} |           class:activenav={$router.path.includes("/donations/")} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/donations/" |           href="/donations/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             xmlns="http://www.w3.org/2000/svg" |             xmlns="http://www.w3.org/2000/svg" | ||||||
|             viewBox="0 0 24 24" |             viewBox="0 0 24 24" | ||||||
| @@ -189,12 +189,12 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("TRACK:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("TRACK:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path === "/tracks/"} |           class:activenav={$router.path === "/tracks/"} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/tracks/" |           href="/tracks/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             width="24" |             width="24" | ||||||
|             height="24" |             height="24" | ||||||
| @@ -210,12 +210,12 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("CARD:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("CARD:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path === "/cards/"} |           class:activenav={$router.path === "/cards/"} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/cards/" |           href="/cards/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             width="24" |             width="24" | ||||||
|             height="24" |             height="24" | ||||||
| @@ -233,12 +233,12 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("SCAN:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("SCAN:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path === "/scans/"} |           class:activenav={$router.path === "/scans/"} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/scans/" |           href="/scans/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             width="24" |             width="24" | ||||||
|             height="24" |             height="24" | ||||||
| @@ -255,13 +255,13 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("CONTACT:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("CONTACT:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path === "/contacts/"} |           class:activenav={$router.path === "/contacts/"} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/contacts/" |           href="/contacts/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             xmlns="http://www.w3.org/2000/svg" |             xmlns="http://www.w3.org/2000/svg" | ||||||
|             viewBox="0 0 24 24" |             viewBox="0 0 24 24" | ||||||
|             width="24" |             width="24" | ||||||
| @@ -276,12 +276,12 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("STATION:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("STATION:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path === "/scanstations/"} |           class:activenav={$router.path === "/scanstations/"} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/scanstations/" |           href="/scanstations/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             width="24" |             width="24" | ||||||
|             height="24" |             height="24" | ||||||
| @@ -298,12 +298,12 @@ | |||||||
|       {/if} |       {/if} | ||||||
|       {#if store.state.jwtinfo.userdetails.permissions.includes("STATSCLIENT:GET")} |       {#if store.state.jwtinfo.userdetails.permissions.includes("STATSCLIENT:GET")} | ||||||
|         <a |         <a | ||||||
|           class:bg-gray-100={$router.path === "/statsclients/"} |           class:activenav={$router.path === "/statsclients/"} | ||||||
|           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |           class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|           href="/statsclients/" |           href="/statsclients/" | ||||||
|         > |         > | ||||||
|           <svg |           <svg | ||||||
|             class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |             class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|             fill="currentColor" |             fill="currentColor" | ||||||
|             width="24" |             width="24" | ||||||
|             height="24" |             height="24" | ||||||
| @@ -319,12 +319,12 @@ | |||||||
|         </a> |         </a> | ||||||
|       {/if} |       {/if} | ||||||
|       <a |       <a | ||||||
|         class:bg-gray-100={$router.path === "/settings/"} |         class:activenav={$router.path === "/settings/"} | ||||||
|         class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |         class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|         href="/settings/" |         href="/settings/" | ||||||
|       > |       > | ||||||
|         <svg |         <svg | ||||||
|           class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |           class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|           xmlns="http://www.w3.org/2000/svg" |           xmlns="http://www.w3.org/2000/svg" | ||||||
|           viewBox="0 0 20 20" |           viewBox="0 0 20 20" | ||||||
|           fill="currentColor" |           fill="currentColor" | ||||||
| @@ -338,12 +338,12 @@ | |||||||
|         <span>{$_("settings")}</span> |         <span>{$_("settings")}</span> | ||||||
|       </a> |       </a> | ||||||
|       <a |       <a | ||||||
|         class:bg-gray-100={$router.path === "/about/"} |         class:activenav={$router.path === "/about/"} | ||||||
|         class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |         class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|         href="/about/" |         href="/about/" | ||||||
|       > |       > | ||||||
|         <svg |         <svg | ||||||
|           class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |           class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|           xmlns="http://www.w3.org/2000/svg" |           xmlns="http://www.w3.org/2000/svg" | ||||||
|           fill="none" |           fill="none" | ||||||
|           stroke="currentColor" |           stroke="currentColor" | ||||||
| @@ -358,14 +358,14 @@ | |||||||
|       </a> |       </a> | ||||||
|       <button |       <button | ||||||
|         tabindex="0" |         tabindex="0" | ||||||
|         class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" |         class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-200 hover:text-gray-900" | ||||||
|         on:click={() => { |         on:click={() => { | ||||||
|           AuthService.authControllerLogout(); |           AuthService.authControllerLogout(); | ||||||
|           logout(); |           logout(); | ||||||
|         }} |         }} | ||||||
|       > |       > | ||||||
|         <svg |         <svg | ||||||
|           class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" |           class="flex-shrink-0 w-5 h-5 mr-2 transition group-hover:text-gray-600" | ||||||
|           fill="currentColor" |           fill="currentColor" | ||||||
|           width="24" |           width="24" | ||||||
|           height="24" |           height="24" | ||||||
| @@ -382,7 +382,7 @@ | |||||||
|   </div> |   </div> | ||||||
|   <div class="ml-0 transition md:ml-60"> |   <div class="ml-0 transition md:ml-60"> | ||||||
|     <header |     <header | ||||||
|       class="flex items-center justify-between w-full px-4 bg-white border-b h-14 md:hidden" |       class="flex items-center w-full px-4 bg-white border-b h-14 md:hidden" | ||||||
|     > |     > | ||||||
|       <button |       <button | ||||||
|         on:click={() => { |         on:click={() => { | ||||||
| @@ -390,18 +390,15 @@ | |||||||
|         }} |         }} | ||||||
|         class="block btn btn-light md:hidden" |         class="block btn btn-light md:hidden" | ||||||
|       > |       > | ||||||
|         <span class="sr-only">Menu</span><svg |         <span class="sr-only">Menu</span><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6"> | ||||||
|           class="w-4 h-4" |           <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" /> | ||||||
|           xmlns="http://www.w3.org/2000/svg" |         </svg> | ||||||
|           viewBox="0 0 20 20" |         </button | ||||||
|           fill="currentcolor" |  | ||||||
|           ><path |  | ||||||
|             fill-rule="evenodd" |  | ||||||
|             d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4A1 1 0 013 5zm0 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" |  | ||||||
|             clip-rule="evenodd" |  | ||||||
|           /></svg |  | ||||||
|         ></button |  | ||||||
|       > |       > | ||||||
|  |       <span class="inline-block"> | ||||||
|  |         <img src="/lfk-logo.png" alt="Logo" class="h-8 inline-block" /> | ||||||
|  |         <span class="text-lg font-bold">LfK!Admin</span> | ||||||
|  |       </span> | ||||||
|     </header> |     </header> | ||||||
|     <Toaster position="top-right" /> |     <Toaster position="top-right" /> | ||||||
|     <slot> |     <slot> | ||||||
|   | |||||||
| @@ -3,18 +3,16 @@ | |||||||
|   import { StatsService } from "@odit/lfk-client-js"; |   import { StatsService } from "@odit/lfk-client-js"; | ||||||
|   import store from "../../store"; |   import store from "../../store"; | ||||||
|   import StatCard from "./StatCard.svelte"; |   import StatCard from "./StatCard.svelte"; | ||||||
|   let navOpen = false; |  | ||||||
|   const stats_promise = StatsService.statsControllerGet(); |   const stats_promise = StatsService.statsControllerGet(); | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <div class="p-2 md:p-5 overflow-x-hidden"> | <div class="p-2 md:p-5 overflow-x-hidden"> | ||||||
|   <h1 class="text-3xl leading-tight mb-4"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("dashboard-greeting")}, |     {$_("dashboard-greeting")} <span class="text-blue-500" | ||||||
|     <span class="text-blue-500" |  | ||||||
|       >{store.state.jwtinfo.userdetails.firstname} |       >{store.state.jwtinfo.userdetails.firstname} | ||||||
|       {store.state.jwtinfo.userdetails.lastname}</span |       {store.state.jwtinfo.userdetails.lastname}</span | ||||||
|     > |     > | ||||||
|   </h1> |   </h4> | ||||||
|   {#await stats_promise} |   {#await stats_promise} | ||||||
|     <div |     <div | ||||||
|       class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" |       class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" | ||||||
| @@ -25,7 +23,7 @@ | |||||||
|     </div> |     </div> | ||||||
|   {:then stats} |   {:then stats} | ||||||
|     <div |     <div | ||||||
|       class="grid gap-2 grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 2xl:grid-cols-6 sm:gap-4" |       class="grid gap-1 grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 2xl:grid-cols-6 sm:gap-4" | ||||||
|     > |     > | ||||||
|       <StatCard |       <StatCard | ||||||
|         title={$_("runners")} |         title={$_("runners")} | ||||||
|   | |||||||
| @@ -7,13 +7,13 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <a {href}> | <a {href}> | ||||||
|   <div class="p-4 rounded-lg bg-white border border-grey-100"> |   <div class="p-3 py-4 sm:p-4 rounded-lg bg-white border border-grey-100"> | ||||||
|     <div class="flex flex-row items-center justify-between"> |     <div class="flex flex-row items-center justify-between"> | ||||||
|       <div class="flex flex-col"> |       <div class="flex flex-col"> | ||||||
|         <div class="text-xs uppercase font-normal text-grey-500"> |         <div class="text-md sm:text-xs uppercase font-normal text-grey-500"> | ||||||
|           {title} |           {title} | ||||||
|         </div> |         </div> | ||||||
|         <div class="text-xl font-bold font-mono">{value}</div> |         <div class="text-2xl sm:text-xl font-bold font-mono">{value}</div> | ||||||
|       </div> |       </div> | ||||||
|       <slot /> |       <slot /> | ||||||
|     </div> |     </div> | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ | |||||||
|       toast.loading($_("updating-donation")); |       toast.loading($_("updating-donation")); | ||||||
|       const editable = Object.assign({}, original_data); |       const editable = Object.assign({}, original_data); | ||||||
|       editable.donor = editable.donor.id; |       editable.donor = editable.donor.id; | ||||||
|       editable.paidAmount = paid_amount_input * 100; |       editable.paidAmount = Math.round(paid_amount_input * 100); | ||||||
|       if (editable.responseType == "DISTANCEDONATION" || editable.runner) { |       if (editable.responseType == "DISTANCEDONATION" || editable.runner) { | ||||||
|         editable.runner = editable.runner.id; |         editable.runner = editable.runner.id; | ||||||
|         DonationService.donationControllerPutDistance( |         DonationService.donationControllerPutDistance( | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
|     DonorService, |     DonorService, | ||||||
|     RunnerService, |     RunnerService, | ||||||
|   } from "@odit/lfk-client-js"; |   } from "@odit/lfk-client-js"; | ||||||
|  |   import toast from 'svelte-french-toast' | ||||||
|  |  | ||||||
|   import PromiseError from "../base/PromiseError.svelte"; |   import PromiseError from "../base/PromiseError.svelte"; | ||||||
|   import Select from "svelte-select"; |   import Select from "svelte-select"; | ||||||
|   | |||||||
| @@ -9,20 +9,20 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("donations")} |     {$_("donations")} | ||||||
|  |   </h4> | ||||||
|   {#if store.state.jwtinfo.userdetails.permissions.includes("DONATION:CREATE")} |   {#if store.state.jwtinfo.userdetails.permissions.includes("DONATION:CREATE")} | ||||||
|     <button |     <button | ||||||
|       on:click={() => { |       on:click={() => { | ||||||
|         modal_open = true; |         modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|     > |     > | ||||||
|       {$_("add-donation")} |       {$_("add-donation")} | ||||||
|     </button> |     </button> | ||||||
|   {/if} |   {/if} | ||||||
|   </span> |  | ||||||
|   <DonationsOverview bind:current_donations bind:addDonations /> |   <DonationsOverview bind:current_donations bind:addDonations /> | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  |  | ||||||
| <div class="text-center items-center justify-center"> | <div class="text-center items-center justify-center"> | ||||||
|   <p class="mb-16 text-lg text-gray-500"> |   <p class="mb-16 text-lg text-gray-500"> | ||||||
|     <img class="m-auto" style="height:15rem" src={donations_empty} alt="" /> |     <img class="m-auto mt-2" style="height:15rem" src={donations_empty} alt="" /> | ||||||
|     <span class="font-bold">{$_("there-are-no-donations-yet")}</span><br /> |     <span class="font-bold">{$_("there-are-no-donations-yet")}</span><br /> | ||||||
|     <span>{$_("add-your-fist-donation")}</span> |     <span>{$_("add-your-fist-donation")}</span> | ||||||
|   </p> |   </p> | ||||||
|   | |||||||
| @@ -231,7 +231,7 @@ | |||||||
|       bind:value={searchvalue} |       bind:value={searchvalue} | ||||||
|       placeholder={$_("datatable.search")} |       placeholder={$_("datatable.search")} | ||||||
|       aria-label={$_("datatable.search")} |       aria-label={$_("datatable.search")} | ||||||
|       class="mb-4" |       class="mb-2 w-full sm:w-auto mt-1 sm:mt-0 p-2 rounded-md border" | ||||||
|     /> |     /> | ||||||
|     <div |     <div | ||||||
|       class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" |       class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" | ||||||
|   | |||||||
| @@ -9,15 +9,16 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("donors")} |     {$_("donors")} | ||||||
|  |   </h4> | ||||||
|   {#if store.state.jwtinfo.userdetails.permissions.includes("DONOR:CREATE")} |   {#if store.state.jwtinfo.userdetails.permissions.includes("DONOR:CREATE")} | ||||||
|     <button |     <button | ||||||
|       on:click={() => { |       on:click={() => { | ||||||
|         modal_open = true; |         modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0" | ||||||
|     > |     > | ||||||
|       {$_("add-donor")} |       {$_("add-donor")} | ||||||
|     </button> |     </button> | ||||||
| @@ -35,7 +36,7 @@ | |||||||
|               d.firstname, |               d.firstname, | ||||||
|               d.middlename, |               d.middlename, | ||||||
|               d.lastname, |               d.lastname, | ||||||
|                 d.paidDonationAmount, |               (d.paidDonationAmount/100).toFixed(2), | ||||||
|               address, |               address, | ||||||
|             ]; |             ]; | ||||||
|           }); |           }); | ||||||
| @@ -58,12 +59,11 @@ | |||||||
|         hiddenElement.remove(); |         hiddenElement.remove(); | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0" | ||||||
|     > |     > | ||||||
|       {$_("sponsoring-quittungs-liste_herunterladen")} |       {$_("sponsoring-quittungs-liste_herunterladen")} | ||||||
|     </button> |     </button> | ||||||
|   {/if} |   {/if} | ||||||
|   </span> |  | ||||||
|   <DonorsOverview bind:current_donors bind:addDonors /> |   <DonorsOverview bind:current_donors bind:addDonors /> | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -202,7 +202,7 @@ | |||||||
|       bind:value={searchvalue} |       bind:value={searchvalue} | ||||||
|       placeholder={$_("datatable.search")} |       placeholder={$_("datatable.search")} | ||||||
|       aria-label={$_("datatable.search")} |       aria-label={$_("datatable.search")} | ||||||
|       class="mb-4" |       class="mb-2 w-full sm:w-auto mt-1 sm:mt-0 p-2 rounded-md border" | ||||||
|     /> |     /> | ||||||
|     <div |     <div | ||||||
|       class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" |       class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" | ||||||
|   | |||||||
| @@ -86,7 +86,7 @@ | |||||||
|               modal_open = false; |               modal_open = false; | ||||||
|             }} |             }} | ||||||
|             type="button" |             type="button" | ||||||
|             class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|           > |           > | ||||||
|             {$_("close")} |             {$_("close")} | ||||||
|           </button> |           </button> | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
|   import { _ } from "svelte-i18n"; |   import { _ } from "svelte-i18n"; | ||||||
|   import store from "../../store"; |   import store from "../../store"; | ||||||
|   import { UserGroupService } from "@odit/lfk-client-js"; |   import { UserGroupService } from "@odit/lfk-client-js"; | ||||||
|  |   import toast from 'svelte-french-toast' | ||||||
|  |  | ||||||
|   import PromiseError from "../base/PromiseError.svelte"; |   import PromiseError from "../base/PromiseError.svelte"; | ||||||
|   let data_loaded = false; |   let data_loaded = false; | ||||||
| @@ -131,7 +132,7 @@ | |||||||
|           {#if delete_triggered} |           {#if delete_triggered} | ||||||
|             <button |             <button | ||||||
|               on:click={deleteGroup} |               on:click={deleteGroup} | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("confirm-deletion")}</button |               >{$_("confirm-deletion")}</button | ||||||
|             > |             > | ||||||
|             <button |             <button | ||||||
| @@ -148,7 +149,7 @@ | |||||||
|                 delete_triggered = true; |                 delete_triggered = true; | ||||||
|               }} |               }} | ||||||
|               type="button" |               type="button" | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("delete-group")}</button |               >{$_("delete-group")}</button | ||||||
|             > |             > | ||||||
|           {/if} |           {/if} | ||||||
| @@ -159,7 +160,7 @@ | |||||||
|             class:opacity-50={!save_enabled} |             class:opacity-50={!save_enabled} | ||||||
|             type="button" |             type="button" | ||||||
|             on:click={submit} |             on:click={submit} | ||||||
|             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|             >{$_("save-changes")}</button |             >{$_("save-changes")}</button | ||||||
|           > |           > | ||||||
|         {/if} |         {/if} | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
|     CreatePermission, |     CreatePermission, | ||||||
|     UserGroupService, |     UserGroupService, | ||||||
|   } from "@odit/lfk-client-js"; |   } from "@odit/lfk-client-js"; | ||||||
|  |   import toast from 'svelte-french-toast' | ||||||
|  |  | ||||||
|   import PromiseError from "../base/PromiseError.svelte"; |   import PromiseError from "../base/PromiseError.svelte"; | ||||||
|   export let params; |   export let params; | ||||||
| @@ -142,13 +143,13 @@ | |||||||
|             class:opacity-50={save_enabled} |             class:opacity-50={save_enabled} | ||||||
|             type="button" |             type="button" | ||||||
|             on:click={submit} |             on:click={submit} | ||||||
|             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|             >{$_("save-changes")}</button |             >{$_("save-changes")}</button | ||||||
|           > |           > | ||||||
|         {:else} |         {:else} | ||||||
|           <button |           <button | ||||||
|             type="button" |             type="button" | ||||||
|             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-yellow-600 text-base font-medium text-white hover:bg-yellow-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-yellow-600 text-base font-medium text-white hover:bg-yellow-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-500 sm:w-auto sm:text-sm" | ||||||
|             >{$_("applying-changes")}</button |             >{$_("applying-changes")}</button | ||||||
|           > |           > | ||||||
|         {/if} |         {/if} | ||||||
| @@ -192,7 +193,7 @@ | |||||||
|                       } |                       } | ||||||
|                     }} |                     }} | ||||||
|                     type="button" |                     type="button" | ||||||
|                     class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-200 text-base font-medium text-black hover:bg-green-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:ml-3 sm:w-auto sm:text-sm" |                     class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-200 text-base font-medium text-black hover:bg-green-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:w-auto sm:text-sm" | ||||||
|                     >+</button |                     >+</button | ||||||
|                   > |                   > | ||||||
|                 </p> |                 </p> | ||||||
| @@ -232,7 +233,7 @@ | |||||||
|                     } |                     } | ||||||
|                   }} |                   }} | ||||||
|                   type="button" |                   type="button" | ||||||
|                   class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-300 text-base font-medium text-black hover:bg-red-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:ml-3 sm:w-auto sm:text-sm" |                   class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-300 text-base font-medium text-black hover:bg-red-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:w-auto sm:text-sm" | ||||||
|                   >-</button |                   >-</button | ||||||
|                 > |                 > | ||||||
|               </p> |               </p> | ||||||
|   | |||||||
| @@ -8,20 +8,20 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("user-groups")} |     {$_("user-groups")} | ||||||
|  |   </h4> | ||||||
|   {#if store.state.jwtinfo.userdetails.permissions.includes("USERGROUP:CREATE")} |   {#if store.state.jwtinfo.userdetails.permissions.includes("USERGROUP:CREATE")} | ||||||
|     <button |     <button | ||||||
|       on:click={() => { |       on:click={() => { | ||||||
|         modal_open = true; |         modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|     > |     > | ||||||
|       {$_("add-user-group")} |       {$_("add-user-group")} | ||||||
|     </button> |     </button> | ||||||
|   {/if} |   {/if} | ||||||
|   </span> |  | ||||||
|   <UserGroupsOverview bind:current_groups /> |   <UserGroupsOverview bind:current_groups /> | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ | |||||||
|         bind:value={searchvalue} |         bind:value={searchvalue} | ||||||
|         placeholder={$_("datatable.search")} |         placeholder={$_("datatable.search")} | ||||||
|         aria-label={$_("datatable.search")} |         aria-label={$_("datatable.search")} | ||||||
|         class="mb-4" |         class="mb-2 w-full sm:w-auto mt-1 sm:mt-0 p-2 rounded-md border" | ||||||
|       /> |       /> | ||||||
|       <div |       <div | ||||||
|         class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" |         class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
|     RunnerOrganizationService, |     RunnerOrganizationService, | ||||||
|   } from "@odit/lfk-client-js"; |   } from "@odit/lfk-client-js"; | ||||||
|   import { getLocaleFromNavigator, _ } from "svelte-i18n"; |   import { getLocaleFromNavigator, _ } from "svelte-i18n"; | ||||||
|  |   import toast from 'svelte-french-toast' | ||||||
|  |  | ||||||
|   import store from "../../store"; |   import store from "../../store"; | ||||||
|   import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte"; |   import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte"; | ||||||
| @@ -162,7 +163,7 @@ | |||||||
|               import_modal_open = true; |               import_modal_open = true; | ||||||
|             }} |             }} | ||||||
|             type="button" |             type="button" | ||||||
|             class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|           > |           > | ||||||
|             {$_("import-runners")} |             {$_("import-runners")} | ||||||
|           </button> |           </button> | ||||||
| @@ -171,7 +172,7 @@ | |||||||
|           {#if delete_triggered} |           {#if delete_triggered} | ||||||
|             <button |             <button | ||||||
|               on:click={deleteOrganization} |               on:click={deleteOrganization} | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("confirm-delete")}</button |               >{$_("confirm-delete")}</button | ||||||
|             > |             > | ||||||
|             <button |             <button | ||||||
| @@ -188,7 +189,7 @@ | |||||||
|                 delete_triggered = true; |                 delete_triggered = true; | ||||||
|               }} |               }} | ||||||
|               type="button" |               type="button" | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("delete-organization")}</button |               >{$_("delete-organization")}</button | ||||||
|             > |             > | ||||||
|           {/if} |           {/if} | ||||||
| @@ -199,7 +200,7 @@ | |||||||
|             disabled={!save_enabled} |             disabled={!save_enabled} | ||||||
|             class:opacity-50={!save_enabled} |             class:opacity-50={!save_enabled} | ||||||
|             type="button" |             type="button" | ||||||
|             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|             >{$_("save-changes")}</button |             >{$_("save-changes")}</button | ||||||
|           > |           > | ||||||
|         {/if} |         {/if} | ||||||
|   | |||||||
| @@ -58,7 +58,7 @@ | |||||||
|         bind:value={searchvalue} |         bind:value={searchvalue} | ||||||
|         placeholder={$_("datatable.search")} |         placeholder={$_("datatable.search")} | ||||||
|         aria-label={$_("datatable.search")} |         aria-label={$_("datatable.search")} | ||||||
|         class="mb-4" |         class="mb-2 w-full sm:w-auto mt-1 sm:mt-0 p-2 rounded-md border" | ||||||
|       /> |       /> | ||||||
|       <div class="h-12"> |       <div class="h-12"> | ||||||
|         <GenerateSponsoringContracts |         <GenerateSponsoringContracts | ||||||
|   | |||||||
| @@ -10,15 +10,16 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("organizations")} |     {$_("organizations")} | ||||||
|  |   </h4> | ||||||
|   {#if store.state.jwtinfo.userdetails.permissions.includes("ORGANIZATION:CREATE")} |   {#if store.state.jwtinfo.userdetails.permissions.includes("ORGANIZATION:CREATE")} | ||||||
|     <button |     <button | ||||||
|       on:click={() => { |       on:click={() => { | ||||||
|         modal_open = true; |         modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0" | ||||||
|     > |     > | ||||||
|       {$_("create-organization")} |       {$_("create-organization")} | ||||||
|     </button> |     </button> | ||||||
| @@ -29,12 +30,11 @@ | |||||||
|         import_modal_open = true; |         import_modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0" | ||||||
|     > |     > | ||||||
|       {$_("import-runners")} |       {$_("import-runners")} | ||||||
|     </button> |     </button> | ||||||
|   {/if} |   {/if} | ||||||
|   </span> |  | ||||||
|   <OrgOverview bind:current_organizations /> |   <OrgOverview bind:current_organizations /> | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
|     RunnerOrganizationService, |     RunnerOrganizationService, | ||||||
|     RunnerTeamService, |     RunnerTeamService, | ||||||
|   } from "@odit/lfk-client-js"; |   } from "@odit/lfk-client-js"; | ||||||
|  |   import toast from 'svelte-french-toast' | ||||||
|  |  | ||||||
|   import { init } from "@paralleldrive/cuid2"; |   import { init } from "@paralleldrive/cuid2"; | ||||||
|   const createId = init({ length: 10, fingerprint: "lfk-frontend" }); |   const createId = init({ length: 10, fingerprint: "lfk-frontend" }); | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ | |||||||
|   import Select from "svelte-select"; |   import Select from "svelte-select"; | ||||||
|   import { createEventDispatcher } from "svelte"; |   import { createEventDispatcher } from "svelte"; | ||||||
|   const dispatch = createEventDispatcher(); |   const dispatch = createEventDispatcher(); | ||||||
|  |   import toast from 'svelte-french-toast' | ||||||
|  |  | ||||||
|   export let modal_open; |   export let modal_open; | ||||||
|   $: selected_team = undefined; |   $: selected_team = undefined; | ||||||
|   | |||||||
| @@ -149,7 +149,7 @@ | |||||||
|           {#if delete_triggered} |           {#if delete_triggered} | ||||||
|             <button |             <button | ||||||
|               on:click={deleteRunner} |               on:click={deleteRunner} | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("confirm-deletion")}</button |               >{$_("confirm-deletion")}</button | ||||||
|             > |             > | ||||||
|             <button |             <button | ||||||
| @@ -175,7 +175,7 @@ | |||||||
|                 delete_triggered = true; |                 delete_triggered = true; | ||||||
|               }} |               }} | ||||||
|               type="button" |               type="button" | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("delete-runner")}</button |               >{$_("delete-runner")}</button | ||||||
|             > |             > | ||||||
|           {/if} |           {/if} | ||||||
| @@ -186,7 +186,7 @@ | |||||||
|             class:opacity-50={!save_enabled} |             class:opacity-50={!save_enabled} | ||||||
|             type="button" |             type="button" | ||||||
|             on:click={submit} |             on:click={submit} | ||||||
|             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|             >{$_("save-changes")}</button |             >{$_("save-changes")}</button | ||||||
|           > |           > | ||||||
|         {/if} |         {/if} | ||||||
|   | |||||||
| @@ -11,15 +11,16 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("runners")} |     {$_("runners")} | ||||||
|  |   </h4> | ||||||
|   {#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:CREATE")} |   {#if store.state.jwtinfo.userdetails.permissions.includes("RUNNER:CREATE")} | ||||||
|     <button |     <button | ||||||
|       on:click={() => { |       on:click={() => { | ||||||
|         modal_open = true; |         modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0" | ||||||
|     > |     > | ||||||
|       {$_("laeufer-hinzufuegen")} |       {$_("laeufer-hinzufuegen")} | ||||||
|     </button> |     </button> | ||||||
| @@ -28,12 +29,11 @@ | |||||||
|         import_modal_open = true; |         import_modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm mt-1 sm:mt-0" | ||||||
|     > |     > | ||||||
|       {$_("import-runners")} |       {$_("import-runners")} | ||||||
|     </button> |     </button> | ||||||
|   {/if} |   {/if} | ||||||
|   </span> |  | ||||||
|   <RunnersOverview bind:current_runners bind:addRunners /> |   <RunnersOverview bind:current_runners bind:addRunners /> | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,20 +9,20 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("scans")} |     {$_("scans")} | ||||||
|  |   </h4> | ||||||
|   {#if store.state.jwtinfo.userdetails.permissions.includes("SCAN:CREATE")} |   {#if store.state.jwtinfo.userdetails.permissions.includes("SCAN:CREATE")} | ||||||
|     <button |     <button | ||||||
|       on:click={() => { |       on:click={() => { | ||||||
|         modal_open = true; |         modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|     > |     > | ||||||
|       {$_("add-scan")} |       {$_("add-scan")} | ||||||
|     </button> |     </button> | ||||||
|   {/if} |   {/if} | ||||||
|   </span> |  | ||||||
|   <ScansOverview bind:current_scans bind:addScans /> |   <ScansOverview bind:current_scans bind:addScans /> | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  |  | ||||||
| <div class="text-center items-center justify-center"> | <div class="text-center items-center justify-center"> | ||||||
|   <p class="mb-16 text-lg text-gray-500"> |   <p class="mb-16 text-lg text-gray-500"> | ||||||
|     <img class="m-auto" style="height:15rem" src={scans_empty} alt="" /> |     <img class="m-auto mt-2" style="height:15rem" src={scans_empty} alt="" /> | ||||||
|     <span class="font-bold">{$_("there-are-no-scans-yet")}</span><br /> |     <span class="font-bold">{$_("there-are-no-scans-yet")}</span><br /> | ||||||
|     <span>{$_("add-your-fist-scan")}</span> |     <span>{$_("add-your-fist-scan")}</span> | ||||||
|   </p> |   </p> | ||||||
|   | |||||||
| @@ -220,7 +220,7 @@ | |||||||
|     {#if selected.length > 0} |     {#if selected.length > 0} | ||||||
|       <button |       <button | ||||||
|         type="button" |         type="button" | ||||||
|         class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm inline-flex" |         class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm inline-flex" | ||||||
|         id="options-menu" |         id="options-menu" | ||||||
|         on:click={async () => { |         on:click={async () => { | ||||||
|           const prom = []; |           const prom = []; | ||||||
|   | |||||||
| @@ -1,12 +1,11 @@ | |||||||
| <script> | <script> | ||||||
| 	import { _ } from "svelte-i18n"; | 	import { _ } from "svelte-i18n"; | ||||||
|  | 	import { tick } from "svelte"; | ||||||
|   import { tick, createEventDispatcher } from "svelte"; |  | ||||||
| 	import bwipjs from "bwip-js"; | 	import bwipjs from "bwip-js"; | ||||||
|  | 	import toast from "svelte-french-toast"; | ||||||
|  |  | ||||||
| 	export let copy_modal_open; | 	export let copy_modal_open; | ||||||
| 	export let new_station; | 	export let new_station; | ||||||
|   const dispatch = createEventDispatcher(); |  | ||||||
| 	let valueCopy = null; | 	let valueCopy = null; | ||||||
| 	let areaDom; | 	let areaDom; | ||||||
| 	let copied = false; | 	let copied = false; | ||||||
|   | |||||||
| @@ -111,7 +111,7 @@ | |||||||
|           {#if delete_triggered} |           {#if delete_triggered} | ||||||
|             <button |             <button | ||||||
|               on:click={deleteStation} |               on:click={deleteStation} | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("confirm-deletion")}</button |               >{$_("confirm-deletion")}</button | ||||||
|             > |             > | ||||||
|             <button |             <button | ||||||
| @@ -128,7 +128,7 @@ | |||||||
|                 delete_triggered = true; |                 delete_triggered = true; | ||||||
|               }} |               }} | ||||||
|               type="button" |               type="button" | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("delete-station")}</button |               >{$_("delete-station")}</button | ||||||
|             > |             > | ||||||
|           {/if} |           {/if} | ||||||
| @@ -139,7 +139,7 @@ | |||||||
|             class:opacity-50={!save_enabled} |             class:opacity-50={!save_enabled} | ||||||
|             type="button" |             type="button" | ||||||
|             on:click={submit} |             on:click={submit} | ||||||
|             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|             >{$_("save-changes")}</button |             >{$_("save-changes")}</button | ||||||
|           > |           > | ||||||
|         {/if} |         {/if} | ||||||
|   | |||||||
| @@ -1,36 +1,221 @@ | |||||||
| <script> | <script> | ||||||
| 	import { _ } from "svelte-i18n"; | 	import { _ } from "svelte-i18n"; | ||||||
| 	import store from "../../store"; | 	import store from "../../store"; | ||||||
|  | 	import { ScanStationService } from "@odit/lfk-client-js"; | ||||||
| 	import AddScanStationModal from "./AddScanStationModal.svelte"; | 	import AddScanStationModal from "./AddScanStationModal.svelte"; | ||||||
| 	import CopyScanStationTokenModal from "./CopyScanStationTokenModal.svelte"; | 	import CopyScanStationTokenModal from "./CopyScanStationTokenModal.svelte"; | ||||||
|   import ScanStationsOverview from "./ScanStationsOverview.svelte"; | 	import ScanStationsEmptyState from "./ScanStationsEmptyState.svelte"; | ||||||
|  | 	import ConfirmScanStationDeletion from "./ConfirmScanStationDeletion.svelte"; | ||||||
|  | 	import toast from "svelte-french-toast"; | ||||||
|  | 	// | ||||||
| 	export let modal_open = false; | 	export let modal_open = false; | ||||||
| 	export let copy_modal_open = false; | 	export let copy_modal_open = false; | ||||||
| 	export let new_station = {}; | 	export let new_station = {}; | ||||||
|  | 	// | ||||||
|  | 	const promise = ScanStationService.scanStationControllerGetAll().then( | ||||||
|  | 		(result) => { | ||||||
|  | 			current_stations = result; | ||||||
|  | 		} | ||||||
|  | 	); | ||||||
|  | 	$: searchvalue = ""; | ||||||
|  | 	$: active_deletes = []; | ||||||
|  | 	let delete_station = {}; | ||||||
| 	let current_stations = []; | 	let current_stations = []; | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> | 	<h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
| 		{$_("scanstations")} | 		{$_("scanstations")} | ||||||
|  | 	</h4> | ||||||
| 	{#if store.state.jwtinfo.userdetails.permissions.includes("STATION:CREATE")} | 	{#if store.state.jwtinfo.userdetails.permissions.includes("STATION:CREATE")} | ||||||
| 		<button | 		<button | ||||||
| 			on:click={() => { | 			on:click={() => { | ||||||
| 				modal_open = true; | 				modal_open = true; | ||||||
| 			}} | 			}} | ||||||
| 			type="button" | 			type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" | 			class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
| 		> | 		> | ||||||
| 			{$_("create-a-new-scanstation")} | 			{$_("create-a-new-scanstation")} | ||||||
| 		</button> | 		</button> | ||||||
| 	{/if} | 	{/if} | ||||||
|   </span> | 	<ConfirmScanStationDeletion | ||||||
|   <ScanStationsOverview | 		on:cancelDelete={(event) => { | ||||||
|     bind:current_stations | 			modal_open = false; | ||||||
|  | 			active_deletes[event.detail.id] = false; | ||||||
|  | 		}} | ||||||
| 		bind:modal_open | 		bind:modal_open | ||||||
|     bind:new_station | 		bind:delete_station | ||||||
|     bind:copy_modal_open |  | ||||||
| 	/> | 	/> | ||||||
|  | 	{#if store.state.jwtinfo.userdetails.permissions.includes("STATION:GET")} | ||||||
|  | 		{#await promise} | ||||||
|  | 			<div | ||||||
|  | 				class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" | ||||||
|  | 				role="alert" | ||||||
|  | 			> | ||||||
|  | 				<p class="font-bold">{$_("scanstations-are-being-loaded")}</p> | ||||||
|  | 				<p class="text-sm">{$_("this-might-take-a-moment")}</p> | ||||||
|  | 			</div> | ||||||
|  | 		{:then} | ||||||
|  | 			{#if current_stations.length === 0} | ||||||
|  | 				<ScanStationsEmptyState /> | ||||||
|  | 			{:else} | ||||||
|  | 				<input | ||||||
|  | 					type="search" | ||||||
|  | 					bind:value={searchvalue} | ||||||
|  | 					placeholder={$_("datatable.search")} | ||||||
|  | 					aria-label={$_("datatable.search")} | ||||||
|  | 					class="mb-2 w-full sm:w-auto mt-1 sm:mt-0 p-2 rounded-md border" | ||||||
|  | 				/> | ||||||
|  | 				<div | ||||||
|  | 					class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" | ||||||
|  | 				> | ||||||
|  | 					<table class="divide-y divide-gray-200 w-full"> | ||||||
|  | 						<thead class="bg-gray-50"> | ||||||
|  | 							<tr class="odd:bg-white even:bg-gray-100"> | ||||||
|  | 								<th | ||||||
|  | 									scope="col" | ||||||
|  | 									class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" | ||||||
|  | 								> | ||||||
|  | 									{$_("track")} | ||||||
|  | 								</th> | ||||||
|  | 								<th | ||||||
|  | 									scope="col" | ||||||
|  | 									class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" | ||||||
|  | 								> | ||||||
|  | 									{$_("description")} | ||||||
|  | 								</th> | ||||||
|  | 								<th | ||||||
|  | 									scope="col" | ||||||
|  | 									class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" | ||||||
|  | 								> | ||||||
|  | 									{$_("status")} | ||||||
|  | 								</th> | ||||||
|  | 								<th scope="col" class="relative px-6 py-3"> | ||||||
|  | 									<span class="sr-only">{$_("action")}</span> | ||||||
|  | 								</th> | ||||||
|  | 							</tr> | ||||||
|  | 						</thead> | ||||||
|  | 						<tbody class="divide-y divide-gray-200"> | ||||||
|  | 							{#each current_stations as s} | ||||||
|  | 								{#if Object.values(s) | ||||||
|  | 									.toString() | ||||||
|  | 									.toLowerCase() | ||||||
|  | 									.includes(searchvalue)} | ||||||
|  | 									<tr | ||||||
|  | 										class="odd:bg-white even:bg-gray-100" | ||||||
|  | 										data-rowid="station_{s.id}" | ||||||
|  | 									> | ||||||
|  | 										<td class="px-6 py-4 whitespace-nowrap"> | ||||||
|  | 											<div class="flex items-center"> | ||||||
|  | 												<div class="ml-4"> | ||||||
|  | 													<div class="text-sm font-medium text-gray-900"> | ||||||
|  | 														<a | ||||||
|  | 															href="../tracks" | ||||||
|  | 															class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800" | ||||||
|  | 														> | ||||||
|  | 															{s.track.name || s.track.distance + "m"}</a | ||||||
|  | 														> | ||||||
|  | 													</div> | ||||||
|  | 												</div> | ||||||
|  | 											</div> | ||||||
|  | 										</td> | ||||||
|  | 										<td class="px-6 py-4 whitespace-nowrap"> | ||||||
|  | 											<div class="flex items-center"> | ||||||
|  | 												<div class="ml-4"> | ||||||
|  | 													<div class="text-sm font-medium text-gray-900"> | ||||||
|  | 														{s.description} | ||||||
|  | 													</div> | ||||||
|  | 												</div> | ||||||
|  | 											</div> | ||||||
|  | 										</td> | ||||||
|  | 										<td class="px-6 py-4 whitespace-nowrap"> | ||||||
|  | 											<div class="flex items-center"> | ||||||
|  | 												{#if s.enabled} | ||||||
|  | 													<span | ||||||
|  | 														class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800" | ||||||
|  | 														>{$_("active")}</span | ||||||
|  | 													> | ||||||
|  | 												{:else} | ||||||
|  | 													<span | ||||||
|  | 														class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800" | ||||||
|  | 														>{$_("inactive")}</span | ||||||
|  | 													> | ||||||
|  | 												{/if} | ||||||
|  | 											</div> | ||||||
|  | 										</td> | ||||||
|  | 										{#if active_deletes[s.id] === true} | ||||||
|  | 											<td | ||||||
|  | 												class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium" | ||||||
|  | 											> | ||||||
|  | 												<button | ||||||
|  | 													on:click={() => { | ||||||
|  | 														active_deletes[s.id] = false; | ||||||
|  | 													}} | ||||||
|  | 													tabindex="0" | ||||||
|  | 													class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer" | ||||||
|  | 													>{$_("cancel-delete")}</button | ||||||
|  | 												> | ||||||
|  | 												<button | ||||||
|  | 													on:click={() => { | ||||||
|  | 														ScanStationService.scanStationControllerRemove( | ||||||
|  | 															s.id, | ||||||
|  | 															false | ||||||
|  | 														) | ||||||
|  | 															.then((resp) => { | ||||||
|  | 																current_stations = current_stations.filter( | ||||||
|  | 																	(obj) => obj.id !== s.id | ||||||
|  | 																); | ||||||
|  | 																toast($_("station-deleted")); | ||||||
|  | 															}) | ||||||
|  | 															.catch((err) => { | ||||||
|  | 																modal_open = true; | ||||||
|  | 																delete_station = s; | ||||||
|  | 															}); | ||||||
|  | 													}} | ||||||
|  | 													tabindex="0" | ||||||
|  | 													class="ml-4 text-red-600 hover:text-red-900 cursor-pointer" | ||||||
|  | 													>{$_("confirm-delete")}</button | ||||||
|  | 												> | ||||||
|  | 											</td> | ||||||
|  | 										{:else} | ||||||
|  | 											<td | ||||||
|  | 												class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium" | ||||||
|  | 											> | ||||||
|  | 												<a | ||||||
|  | 													href="/scanstations/{s.id}" | ||||||
|  | 													class="text-indigo-600 hover:text-indigo-900" | ||||||
|  | 													>{$_("details")}</a | ||||||
|  | 												> | ||||||
|  | 												{#if store.state.jwtinfo.userdetails.permissions.includes("STATION:DELETE")} | ||||||
|  | 													<button | ||||||
|  | 														on:click={() => { | ||||||
|  | 															active_deletes[s.id] = true; | ||||||
|  | 														}} | ||||||
|  | 														tabindex="0" | ||||||
|  | 														class="ml-4 text-red-600 hover:text-red-900 cursor-pointer" | ||||||
|  | 														>{$_("delete")}</button | ||||||
|  | 													> | ||||||
|  | 												{/if} | ||||||
|  | 											</td> | ||||||
|  | 										{/if} | ||||||
|  | 									</tr> | ||||||
|  | 								{/if} | ||||||
|  | 							{/each} | ||||||
|  | 						</tbody> | ||||||
|  | 					</table> | ||||||
|  | 				</div> | ||||||
|  | 			{/if} | ||||||
|  | 		{:catch error} | ||||||
|  | 			<div | ||||||
|  | 				class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500" | ||||||
|  | 			> | ||||||
|  | 				<span class="inline-block align-middle mr-8"> | ||||||
|  | 					<b class="capitalize">{$_("general_promise_error")}</b> | ||||||
|  | 					{error} | ||||||
|  | 				</span> | ||||||
|  | 			</div> | ||||||
|  | 		{/await} | ||||||
|  | 	{/if} | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
| {#if store.state.jwtinfo.userdetails.permissions.includes("STATION:CREATE")} | {#if store.state.jwtinfo.userdetails.permissions.includes("STATION:CREATE")} | ||||||
|   | |||||||
| @@ -1,195 +0,0 @@ | |||||||
| <script> |  | ||||||
|   import { _ } from "svelte-i18n"; |  | ||||||
|   import { ScanStationService } from "@odit/lfk-client-js"; |  | ||||||
|   const promise = ScanStationService.scanStationControllerGetAll().then( |  | ||||||
|     (result) => { |  | ||||||
|       current_stations = result; |  | ||||||
|     } |  | ||||||
|   ); |  | ||||||
|   import store from "../../store"; |  | ||||||
|   import ScanStationsEmptyState from "./ScanStationsEmptyState.svelte"; |  | ||||||
|   import ConfirmScanStationDeletion from "./ConfirmScanStationDeletion.svelte"; |  | ||||||
|   import toast from "svelte-french-toast"; |  | ||||||
|   $: searchvalue = ""; |  | ||||||
|   $: active_deletes = []; |  | ||||||
|   let delete_station = {}; |  | ||||||
|   let modal_open = false; |  | ||||||
|   export let current_stations = []; |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <ConfirmScanStationDeletion |  | ||||||
|   on:cancelDelete={(event) => { |  | ||||||
|     modal_open = false; |  | ||||||
|     active_deletes[event.detail.id] = false; |  | ||||||
|   }} |  | ||||||
|   bind:modal_open |  | ||||||
|   bind:delete_station |  | ||||||
| /> |  | ||||||
| {#if store.state.jwtinfo.userdetails.permissions.includes("STATION:GET")} |  | ||||||
|   {#await promise} |  | ||||||
|     <div |  | ||||||
|       class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" |  | ||||||
|       role="alert" |  | ||||||
|     > |  | ||||||
|       <p class="font-bold">{$_("scanstations-are-being-loaded")}</p> |  | ||||||
|       <p class="text-sm">{$_("this-might-take-a-moment")}</p> |  | ||||||
|     </div> |  | ||||||
|   {:then} |  | ||||||
|     {#if current_stations.length === 0} |  | ||||||
|       <ScanStationsEmptyState /> |  | ||||||
|     {:else} |  | ||||||
|       <input |  | ||||||
|         type="search" |  | ||||||
|         bind:value={searchvalue} |  | ||||||
|         placeholder={$_("datatable.search")} |  | ||||||
|         aria-label={$_("datatable.search")} |  | ||||||
|         class="mb-4" |  | ||||||
|       /> |  | ||||||
|       <div |  | ||||||
|         class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" |  | ||||||
|       > |  | ||||||
|         <table class="divide-y divide-gray-200 w-full"> |  | ||||||
|           <thead class="bg-gray-50"> |  | ||||||
|             <tr class="odd:bg-white even:bg-gray-100"> |  | ||||||
|               <th |  | ||||||
|                 scope="col" |  | ||||||
|                 class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" |  | ||||||
|               > |  | ||||||
|                 {$_("track")} |  | ||||||
|               </th> |  | ||||||
|               <th |  | ||||||
|                 scope="col" |  | ||||||
|                 class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" |  | ||||||
|               > |  | ||||||
|                 {$_("description")} |  | ||||||
|               </th> |  | ||||||
|               <th |  | ||||||
|                 scope="col" |  | ||||||
|                 class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" |  | ||||||
|               > |  | ||||||
|                 {$_("status")} |  | ||||||
|               </th> |  | ||||||
|               <th scope="col" class="relative px-6 py-3"> |  | ||||||
|                 <span class="sr-only">{$_("action")}</span> |  | ||||||
|               </th> |  | ||||||
|             </tr> |  | ||||||
|           </thead> |  | ||||||
|           <tbody class="divide-y divide-gray-200"> |  | ||||||
|             {#each current_stations as s} |  | ||||||
|               {#if Object.values(s) |  | ||||||
|                 .toString() |  | ||||||
|                 .toLowerCase() |  | ||||||
|                 .includes(searchvalue)} |  | ||||||
|                 <tr |  | ||||||
|                   class="odd:bg-white even:bg-gray-100" |  | ||||||
|                   data-rowid="station_{s.id}" |  | ||||||
|                 > |  | ||||||
|                   <td class="px-6 py-4 whitespace-nowrap"> |  | ||||||
|                     <div class="flex items-center"> |  | ||||||
|                       <div class="ml-4"> |  | ||||||
|                         <div class="text-sm font-medium text-gray-900"> |  | ||||||
|                           <a |  | ||||||
|                             href="../tracks" |  | ||||||
|                             class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800" |  | ||||||
|                           > |  | ||||||
|                             {s.track.name || s.track.distance + "m"}</a |  | ||||||
|                           > |  | ||||||
|                         </div> |  | ||||||
|                       </div> |  | ||||||
|                     </div> |  | ||||||
|                   </td> |  | ||||||
|                   <td class="px-6 py-4 whitespace-nowrap"> |  | ||||||
|                     <div class="flex items-center"> |  | ||||||
|                       <div class="ml-4"> |  | ||||||
|                         <div class="text-sm font-medium text-gray-900"> |  | ||||||
|                           {s.description} |  | ||||||
|                         </div> |  | ||||||
|                       </div> |  | ||||||
|                     </div> |  | ||||||
|                   </td> |  | ||||||
|                   <td class="px-6 py-4 whitespace-nowrap"> |  | ||||||
|                     <div class="flex items-center"> |  | ||||||
|                       {#if s.enabled} |  | ||||||
|                         <span |  | ||||||
|                           class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800" |  | ||||||
|                           >{$_("active")}</span |  | ||||||
|                         > |  | ||||||
|                       {:else} |  | ||||||
|                         <span |  | ||||||
|                           class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800" |  | ||||||
|                           >{$_("inactive")}</span |  | ||||||
|                         > |  | ||||||
|                       {/if} |  | ||||||
|                     </div> |  | ||||||
|                   </td> |  | ||||||
|                   {#if active_deletes[s.id] === true} |  | ||||||
|                     <td |  | ||||||
|                       class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium" |  | ||||||
|                     > |  | ||||||
|                       <button |  | ||||||
|                         on:click={() => { |  | ||||||
|                           active_deletes[s.id] = false; |  | ||||||
|                         }} |  | ||||||
|                         tabindex="0" |  | ||||||
|                         class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer" |  | ||||||
|                         >{$_("cancel-delete")}</button |  | ||||||
|                       > |  | ||||||
|                       <button |  | ||||||
|                         on:click={() => { |  | ||||||
|                           ScanStationService.scanStationControllerRemove( |  | ||||||
|                             s.id, |  | ||||||
|                             false |  | ||||||
|                           ) |  | ||||||
|                             .then((resp) => { |  | ||||||
|                               current_stations = current_stations.filter( |  | ||||||
|                                 (obj) => obj.id !== s.id |  | ||||||
|                               ); |  | ||||||
|                               toast($_("station-deleted")); |  | ||||||
|                             }) |  | ||||||
|                             .catch((err) => { |  | ||||||
|                               modal_open = true; |  | ||||||
|                               delete_station = s; |  | ||||||
|                             }); |  | ||||||
|                         }} |  | ||||||
|                         tabindex="0" |  | ||||||
|                         class="ml-4 text-red-600 hover:text-red-900 cursor-pointer" |  | ||||||
|                         >{$_("confirm-delete")}</button |  | ||||||
|                       > |  | ||||||
|                     </td> |  | ||||||
|                   {:else} |  | ||||||
|                     <td |  | ||||||
|                       class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium" |  | ||||||
|                     > |  | ||||||
|                       <a |  | ||||||
|                         href="/scanstations/{s.id}" |  | ||||||
|                         class="text-indigo-600 hover:text-indigo-900" |  | ||||||
|                         >{$_("details")}</a |  | ||||||
|                       > |  | ||||||
|                       {#if store.state.jwtinfo.userdetails.permissions.includes("STATION:DELETE")} |  | ||||||
|                         <button |  | ||||||
|                           on:click={() => { |  | ||||||
|                             active_deletes[s.id] = true; |  | ||||||
|                           }} |  | ||||||
|                           tabindex="0" |  | ||||||
|                           class="ml-4 text-red-600 hover:text-red-900 cursor-pointer" |  | ||||||
|                           >{$_("delete")}</button |  | ||||||
|                         > |  | ||||||
|                       {/if} |  | ||||||
|                     </td> |  | ||||||
|                   {/if} |  | ||||||
|                 </tr> |  | ||||||
|               {/if} |  | ||||||
|             {/each} |  | ||||||
|           </tbody> |  | ||||||
|         </table> |  | ||||||
|       </div> |  | ||||||
|     {/if} |  | ||||||
|   {:catch error} |  | ||||||
|     <div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500"> |  | ||||||
|       <span class="inline-block align-middle mr-8"> |  | ||||||
|         <b class="capitalize">{$_("general_promise_error")}</b> |  | ||||||
|         {error} |  | ||||||
|       </span> |  | ||||||
|     </div> |  | ||||||
|   {/await} |  | ||||||
| {/if} |  | ||||||
| @@ -2,6 +2,7 @@ | |||||||
|   import { _ } from "svelte-i18n"; |   import { _ } from "svelte-i18n"; | ||||||
|   import isEmail from "validator/es/lib/isEmail"; |   import isEmail from "validator/es/lib/isEmail"; | ||||||
|   import { MeService } from "@odit/lfk-client-js"; |   import { MeService } from "@odit/lfk-client-js"; | ||||||
|  |   import toast from 'svelte-french-toast' | ||||||
|  |  | ||||||
|   import ConfirmProfileDeletion from "./ConfirmProfileDeletion.svelte"; |   import ConfirmProfileDeletion from "./ConfirmProfileDeletion.svelte"; | ||||||
|   import PasswordStrength, { |   import PasswordStrength, { | ||||||
| @@ -168,7 +169,7 @@ | |||||||
|                   disabled={!save_enabled} |                   disabled={!save_enabled} | ||||||
|                   class:opacity-50={!save_enabled} |                   class:opacity-50={!save_enabled} | ||||||
|                   on:click={submit} |                   on:click={submit} | ||||||
|                   class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |                   class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|                 > |                 > | ||||||
|                   {$_("save-changes")} |                   {$_("save-changes")} | ||||||
|                 </button> |                 </button> | ||||||
| @@ -232,7 +233,7 @@ | |||||||
|                   disabled={!update_password_enabled} |                   disabled={!update_password_enabled} | ||||||
|                   class:opacity-50={!update_password_enabled} |                   class:opacity-50={!update_password_enabled} | ||||||
|                   on:click={changePassword} |                   on:click={changePassword} | ||||||
|                   class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |                   class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|                 > |                 > | ||||||
|                   {$_("update-password")} |                   {$_("update-password")} | ||||||
|                 </button> |                 </button> | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
|   import { tick, createEventDispatcher } from "svelte"; |   import { tick, createEventDispatcher } from "svelte"; | ||||||
|   export let copy_modal_open; |   export let copy_modal_open; | ||||||
|   export let new_client; |   export let new_client; | ||||||
|  |   import toast from 'svelte-french-toast' | ||||||
|   const dispatch = createEventDispatcher(); |   const dispatch = createEventDispatcher(); | ||||||
|   let valueCopy = null; |   let valueCopy = null; | ||||||
|   let areaDom; |   let areaDom; | ||||||
|   | |||||||
| @@ -82,7 +82,7 @@ | |||||||
|           {#if delete_triggered} |           {#if delete_triggered} | ||||||
|             <button |             <button | ||||||
|               on:click={deleteClient} |               on:click={deleteClient} | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("confirm-deletion")}</button |               >{$_("confirm-deletion")}</button | ||||||
|             > |             > | ||||||
|             <button |             <button | ||||||
| @@ -99,7 +99,7 @@ | |||||||
|                 delete_triggered = true; |                 delete_triggered = true; | ||||||
|               }} |               }} | ||||||
|               type="button" |               type="button" | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("delete-statsclient")}</button |               >{$_("delete-statsclient")}</button | ||||||
|             > |             > | ||||||
|           {/if} |           {/if} | ||||||
|   | |||||||
| @@ -11,20 +11,20 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("statsclients")} |     {$_("statsclients")} | ||||||
|  |   </h4> | ||||||
|   {#if store.state.jwtinfo.userdetails.permissions.includes("STATSCLIENT:CREATE")} |   {#if store.state.jwtinfo.userdetails.permissions.includes("STATSCLIENT:CREATE")} | ||||||
|     <button |     <button | ||||||
|       on:click={() => { |       on:click={() => { | ||||||
|         modal_open = true; |         modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|     > |     > | ||||||
|       {$_("create-a-new-statsclient")} |       {$_("create-a-new-statsclient")} | ||||||
|     </button> |     </button> | ||||||
|   {/if} |   {/if} | ||||||
|   </span> |  | ||||||
|   <StatsClientsOverview |   <StatsClientsOverview | ||||||
|     bind:current_clients |     bind:current_clients | ||||||
|     bind:modal_open |     bind:modal_open | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ | |||||||
|         bind:value={searchvalue} |         bind:value={searchvalue} | ||||||
|         placeholder={$_("datatable.search")} |         placeholder={$_("datatable.search")} | ||||||
|         aria-label={$_("datatable.search")} |         aria-label={$_("datatable.search")} | ||||||
|         class="mb-4" |         class="mb-2 w-full sm:w-auto mt-1 sm:mt-0 p-2 rounded-md border" | ||||||
|       /> |       /> | ||||||
|       <div |       <div | ||||||
|         class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" |         class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll" | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
|     RunnerTeamService, |     RunnerTeamService, | ||||||
|   } from "@odit/lfk-client-js"; |   } from "@odit/lfk-client-js"; | ||||||
|   import { getLocaleFromNavigator, _ } from "svelte-i18n"; |   import { getLocaleFromNavigator, _ } from "svelte-i18n"; | ||||||
|  |   import toast from 'svelte-french-toast' | ||||||
|  |  | ||||||
|   import store from "../../store"; |   import store from "../../store"; | ||||||
|   import Select from "svelte-select"; |   import Select from "svelte-select"; | ||||||
| @@ -125,7 +126,7 @@ | |||||||
|               import_modal_open = true; |               import_modal_open = true; | ||||||
|             }} |             }} | ||||||
|             type="button" |             type="button" | ||||||
|             class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|           > |           > | ||||||
|             {$_("import-runners")} |             {$_("import-runners")} | ||||||
|           </button> |           </button> | ||||||
| @@ -134,7 +135,7 @@ | |||||||
|           {#if delete_triggered} |           {#if delete_triggered} | ||||||
|             <button |             <button | ||||||
|               on:click={deleteTeam} |               on:click={deleteTeam} | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("confirm-delete")}</button |               >{$_("confirm-delete")}</button | ||||||
|             > |             > | ||||||
|             <button |             <button | ||||||
| @@ -151,7 +152,7 @@ | |||||||
|                 delete_triggered = true; |                 delete_triggered = true; | ||||||
|               }} |               }} | ||||||
|               type="button" |               type="button" | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("delete-team")}</button |               >{$_("delete-team")}</button | ||||||
|             > |             > | ||||||
|           {/if} |           {/if} | ||||||
| @@ -162,7 +163,7 @@ | |||||||
|             disabled={!save_enabled} |             disabled={!save_enabled} | ||||||
|             class:opacity-50={!save_enabled} |             class:opacity-50={!save_enabled} | ||||||
|             type="button" |             type="button" | ||||||
|             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|             >{$_("save-changes")}</button |             >{$_("save-changes")}</button | ||||||
|           > |           > | ||||||
|         {/if} |         {/if} | ||||||
|   | |||||||
| @@ -8,20 +8,20 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("teams")} |     {$_("teams")} | ||||||
|  |   </h4> | ||||||
|   {#if store.state.jwtinfo.userdetails.permissions.includes("TEAM:CREATE")} |   {#if store.state.jwtinfo.userdetails.permissions.includes("TEAM:CREATE")} | ||||||
|     <button |     <button | ||||||
|       on:click={() => { |       on:click={() => { | ||||||
|         modal_open = true; |         modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|     > |     > | ||||||
|       {$_("create-team")} |       {$_("create-team")} | ||||||
|     </button> |     </button> | ||||||
|   {/if} |   {/if} | ||||||
|   </span> |  | ||||||
|   <TeamsOverview bind:current_teams /> |   <TeamsOverview bind:current_teams /> | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ | |||||||
|         bind:value={searchvalue} |         bind:value={searchvalue} | ||||||
|         placeholder={$_("datatable.search")} |         placeholder={$_("datatable.search")} | ||||||
|         aria-label={$_("datatable.search")} |         aria-label={$_("datatable.search")} | ||||||
|         class="mb-4" |         class="mb-2 w-full sm:w-auto mt-1 sm:mt-0 p-2 rounded-md border" | ||||||
|       /> |       /> | ||||||
|       <div class="h-12"> |       <div class="h-12"> | ||||||
|         <GenerateSponsoringContracts |         <GenerateSponsoringContracts | ||||||
|   | |||||||
| @@ -223,7 +223,7 @@ | |||||||
|             type="button" |             type="button" | ||||||
|             class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" | ||||||
|           > |           > | ||||||
|             Create |             {$_("create")} | ||||||
|           </button> |           </button> | ||||||
|           <button |           <button | ||||||
|             on:click={() => { |             on:click={() => { | ||||||
|   | |||||||
| @@ -19,18 +19,18 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     Tracks |     {$_("tracks")} | ||||||
|  |   </h4> | ||||||
|   <button |   <button | ||||||
|     on:click={() => { |     on:click={() => { | ||||||
|       modal_open = true; |       modal_open = true; | ||||||
|     }} |     }} | ||||||
|     type="button" |     type="button" | ||||||
|       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |     class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|   > |   > | ||||||
|     {$_("create-track")} |     {$_("create-track")} | ||||||
|   </button> |   </button> | ||||||
|   </span> |  | ||||||
|   {#await tracks_promise} |   {#await tracks_promise} | ||||||
|     <div |     <div | ||||||
|       class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" |       class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" | ||||||
|   | |||||||
| @@ -162,7 +162,7 @@ | |||||||
|           {#if delete_triggered} |           {#if delete_triggered} | ||||||
|             <button |             <button | ||||||
|               on:click={deleteUser} |               on:click={deleteUser} | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("confirm-delete")}</button |               >{$_("confirm-delete")}</button | ||||||
|             > |             > | ||||||
|             <button |             <button | ||||||
| @@ -179,7 +179,7 @@ | |||||||
|                 delete_triggered = true; |                 delete_triggered = true; | ||||||
|               }} |               }} | ||||||
|               type="button" |               type="button" | ||||||
|               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm" |               class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm" | ||||||
|               >{$_("delete-user")}</button |               >{$_("delete-user")}</button | ||||||
|             > |             > | ||||||
|           {/if} |           {/if} | ||||||
| @@ -190,7 +190,7 @@ | |||||||
|             class:opacity-50={!save_enabled} |             class:opacity-50={!save_enabled} | ||||||
|             type="button" |             type="button" | ||||||
|             on:click={submit} |             on:click={submit} | ||||||
|             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|             >{$_("save-changes")}</button |             >{$_("save-changes")}</button | ||||||
|           > |           > | ||||||
|         {/if} |         {/if} | ||||||
|   | |||||||
| @@ -150,13 +150,13 @@ | |||||||
|             class:opacity-50={save_enabled} |             class:opacity-50={save_enabled} | ||||||
|             type="button" |             type="button" | ||||||
|             on:click={submit} |             on:click={submit} | ||||||
|             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|             >{$_("save-changes")}</button |             >{$_("save-changes")}</button | ||||||
|           > |           > | ||||||
|         {:else} |         {:else} | ||||||
|           <button |           <button | ||||||
|             type="button" |             type="button" | ||||||
|             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-yellow-600 text-base font-medium text-white hover:bg-yellow-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-500 sm:ml-3 sm:w-auto sm:text-sm" |             class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-yellow-600 text-base font-medium text-white hover:bg-yellow-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-500 sm:w-auto sm:text-sm" | ||||||
|             >{$_("applying-changes")}</button |             >{$_("applying-changes")}</button | ||||||
|           > |           > | ||||||
|         {/if} |         {/if} | ||||||
| @@ -203,7 +203,7 @@ | |||||||
|                       } |                       } | ||||||
|                     }} |                     }} | ||||||
|                     type="button" |                     type="button" | ||||||
|                     class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-200 text-base font-medium text-black hover:bg-green-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:ml-3 sm:w-auto sm:text-sm" |                     class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-200 text-base font-medium text-black hover:bg-green-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:w-auto sm:text-sm" | ||||||
|                     >+</button |                     >+</button | ||||||
|                   > |                   > | ||||||
|                 </p> |                 </p> | ||||||
| @@ -243,7 +243,7 @@ | |||||||
|                     } |                     } | ||||||
|                   }} |                   }} | ||||||
|                   type="button" |                   type="button" | ||||||
|                   class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-300 text-base font-medium text-black hover:bg-red-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:ml-3 sm:w-auto sm:text-sm" |                   class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-300 text-base font-medium text-black hover:bg-red-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:w-auto sm:text-sm" | ||||||
|                   >-</button |                   >-</button | ||||||
|                 > |                 > | ||||||
|               </p> |               </p> | ||||||
|   | |||||||
| @@ -8,20 +8,20 @@ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <section class="container p-5"> | <section class="container p-5"> | ||||||
|   <span class="mb-1 text-3xl font-extrabold leading-tight"> |   <h4 class="mb-1 text-3xl font-extrabold leading-tight font-mono"> | ||||||
|     {$_("users")} |     {$_("users")} | ||||||
|  |   </h4> | ||||||
|   {#if store.state.jwtinfo.userdetails.permissions.includes("USER:CREATE")} |   {#if store.state.jwtinfo.userdetails.permissions.includes("USER:CREATE")} | ||||||
|     <button |     <button | ||||||
|       on:click={() => { |       on:click={() => { | ||||||
|         modal_open = true; |         modal_open = true; | ||||||
|       }} |       }} | ||||||
|       type="button" |       type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm" |       class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm" | ||||||
|     > |     > | ||||||
|       {$_("create-user")} |       {$_("create-user")} | ||||||
|     </button> |     </button> | ||||||
|   {/if} |   {/if} | ||||||
|   </span> |  | ||||||
|   <UsersOverview bind:current_users /> |   <UsersOverview bind:current_users /> | ||||||
| </section> | </section> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ | |||||||
|         bind:value={searchvalue} |         bind:value={searchvalue} | ||||||
|         placeholder={$_("datatable.search")} |         placeholder={$_("datatable.search")} | ||||||
|         aria-label={$_("datatable.search")} |         aria-label={$_("datatable.search")} | ||||||
|         class="mb-4" |         class="mb-2 w-full sm:w-auto mt-1 sm:mt-0 p-2 rounded-md border" | ||||||
|       /> |       /> | ||||||
|       <!-- {/if} --> |       <!-- {/if} --> | ||||||
|       <!-- <button |       <!-- <button | ||||||
| @@ -45,7 +45,7 @@ | |||||||
|           advanced_search = !advanced_search; |           advanced_search = !advanced_search; | ||||||
|         }} |         }} | ||||||
|         type="button" |         type="button" | ||||||
|         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-600 text-base font-medium text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:ml-3 sm:w-auto sm:text-sm"> |         class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-600 text-base font-medium text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:w-auto sm:text-sm"> | ||||||
|         {#if advanced_search} |         {#if advanced_search} | ||||||
|           toggle simple search |           toggle simple search | ||||||
|         {:else}toggle advanced search{/if} |         {:else}toggle advanced search{/if} | ||||||
| @@ -105,12 +105,12 @@ | |||||||
|                   <td class="px-6 py-4 whitespace-nowrap"> |                   <td class="px-6 py-4 whitespace-nowrap"> | ||||||
|                     {#if u.enabled} |                     {#if u.enabled} | ||||||
|                       <span |                       <span | ||||||
|                         class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800" |                         class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full border bg-green-100 text-green-800" | ||||||
|                         >{$_("active")}</span |                         >{$_("active")}</span | ||||||
|                       > |                       > | ||||||
|                     {:else} |                     {:else} | ||||||
|                       <span |                       <span | ||||||
|                         class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800" |                         class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full border bg-red-100 text-red-800" | ||||||
|                         >{$_("inactive")}</span |                         >{$_("inactive")}</span | ||||||
|                       > |                       > | ||||||
|                     {/if} |                     {/if} | ||||||
| @@ -119,7 +119,7 @@ | |||||||
|                     {#each u.groups as g} |                     {#each u.groups as g} | ||||||
|                       <a |                       <a | ||||||
|                         href="../groups/{g.id}" |                         href="../groups/{g.id}" | ||||||
|                         class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800" |                         class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full border bg-gray-100 text-gray-800" | ||||||
|                         >{g.name}</a |                         >{g.name}</a | ||||||
|                       > |                       > | ||||||
|                     {/each} |                     {/each} | ||||||
|   | |||||||
| @@ -112,7 +112,7 @@ | |||||||
|     "create-a-new-scanstation": "Neue Station erstellen", |     "create-a-new-scanstation": "Neue Station erstellen", | ||||||
|     "create-a-new-statsclient": "Neuen Statsclient erstellen", |     "create-a-new-statsclient": "Neuen Statsclient erstellen", | ||||||
|     "create-a-new-team": "Erstelle ein neues Team", |     "create-a-new-team": "Erstelle ein neues Team", | ||||||
|     "create-a-new-track": "Neuen Track erstellen", |     "create-a-new-track": "Neue Laufstrecke erstellen", | ||||||
|     "create-a-new-user": "Neuen Benutzer anlegen", |     "create-a-new-user": "Neuen Benutzer anlegen", | ||||||
|     "create-a-new-user-group": "Erstelle eine neue Gruppe", |     "create-a-new-user-group": "Erstelle eine neue Gruppe", | ||||||
|     "create-and-generate-pdf": "Erstellen und PDF herunterladen", |     "create-and-generate-pdf": "Erstellen und PDF herunterladen", | ||||||
| @@ -120,7 +120,7 @@ | |||||||
|     "create-bulk-cards": "Blankokarten erstellen", |     "create-bulk-cards": "Blankokarten erstellen", | ||||||
|     "create-organization": "Organisation erstellen", |     "create-organization": "Organisation erstellen", | ||||||
|     "create-team": "Team erstellen", |     "create-team": "Team erstellen", | ||||||
|     "create-track": "Track erstellen", |     "create-track": "Laufstrecke erstellen", | ||||||
|     "create-user": "Benutzer anlegen", |     "create-user": "Benutzer anlegen", | ||||||
|     "create-without-pdf": "Ohne PDF erstellen", |     "create-without-pdf": "Ohne PDF erstellen", | ||||||
|     "created-blanco-cards": "Blankokarten wurden erstellt", |     "created-blanco-cards": "Blankokarten wurden erstellt", | ||||||
| @@ -454,20 +454,20 @@ | |||||||
|     "total-paid-amount": "Gezahlt", |     "total-paid-amount": "Gezahlt", | ||||||
|     "total-scans": "Scans", |     "total-scans": "Scans", | ||||||
|     "total_donation_amount_in_eur": "Gesamtbetrag in €", |     "total_donation_amount_in_eur": "Gesamtbetrag in €", | ||||||
|     "track": "Track", |     "track": "Laufstrecke", | ||||||
|     "track-added": "Track hinzugefügt", |     "track-added": "Laufstrecke hinzugefügt", | ||||||
|     "track-data-is-being-loaded": "Trackdaten werden geladen", |     "track-data-is-being-loaded": "Laufstrecke wird geladen", | ||||||
|     "track-deleted": "Track gelöscht", |     "track-deleted": "Laufstrecke gelöscht", | ||||||
|     "track-is-being-added": "Track wird hinzugefügt...", |     "track-is-being-added": "Laufstrecke wird hinzugefügt...", | ||||||
|     "track-is-being-deleted": "Track wird gelöscht", |     "track-is-being-deleted": "Laufstrecke wird gelöscht", | ||||||
|     "track-is-being-updated": "Track wird aktualisiert...", |     "track-is-being-updated": "Laufstrecke wird aktualisiert...", | ||||||
|     "track-length-in-m": "Tracklänge (in Metern)", |     "track-length-in-m": "Laufstrecke in Metern", | ||||||
|     "track-length-must-be-greater-than-0": "Die Länge muss größer als 0 (Meter) sein", |     "track-length-must-be-greater-than-0": "Die Länge muss größer als 0 (Meter) sein", | ||||||
|     "track-name": "Trackname", |     "track-name": "Name der Laufstrecke", | ||||||
|     "track-name-must-not-be-empty": "Der Name muss angegeben werden", |     "track-name-must-not-be-empty": "Der Name muss angegeben werden", | ||||||
|     "track-updated": "Track aktualisiert", |     "track-updated": "Laufstrecke aktualisiert", | ||||||
|     "track-was-updated": "Track wurde aktualisiert", |     "track-was-updated": "Laufstrecke wurde aktualisiert", | ||||||
|     "tracks": "Tracks", |     "tracks": "Laufstrecken", | ||||||
|     "unpaid": "Offen", |     "unpaid": "Offen", | ||||||
|     "update-card": "Karte aktualisieren", |     "update-card": "Karte aktualisieren", | ||||||
|     "update-password": "Passwort ändern", |     "update-password": "Passwort ändern", | ||||||
|   | |||||||
| @@ -1,3 +1,7 @@ | |||||||
| @tailwind base; | @tailwind base; | ||||||
| @tailwind components; | @tailwind components; | ||||||
|  | .activenav { | ||||||
|  |     @apply bg-gray-300; | ||||||
|  |     @apply text-black; | ||||||
|  | } | ||||||
| @tailwind utilities; | @tailwind utilities; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user