mirror of
				https://github.com/Theodor-Springmann-Stiftung/musenalm.git
				synced 2025-11-04 12:15:32 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			232 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			232 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
{{ $model := . }}
 | 
						|
 | 
						|
 | 
						|
<script src="/assets/js/qrcode.min.js"></script>
 | 
						|
 | 
						|
<script type="module">
 | 
						|
  const qrElement = document.getElementById('qr');
 | 
						|
  const tokenElement = document.getElementById('token');
 | 
						|
  const accessUrl = "{{ $model.access_url }}";
 | 
						|
 | 
						|
  /**
 | 
						|
   * @param {number} timeout - Maximum time to wait in milliseconds.
 | 
						|
   * @param {number} interval - How often to check in milliseconds.
 | 
						|
   * @returns {Promise<Function>} Resolves with the QRCode constructor when available.
 | 
						|
   */
 | 
						|
  function getQRCodeWhenAvailable(timeout = 5000, interval = 100) {
 | 
						|
    return new Promise((resolve, reject) => {
 | 
						|
      let elapsedTime = 0;
 | 
						|
      const checkInterval = setInterval(() => {
 | 
						|
        if (typeof window.QRCode === 'function') {
 | 
						|
          clearInterval(checkInterval);
 | 
						|
          resolve(window.QRCode); // Resolve with the QRCode object/function
 | 
						|
        } else {
 | 
						|
          elapsedTime += interval;
 | 
						|
          if (elapsedTime >= timeout) {
 | 
						|
            clearInterval(checkInterval);
 | 
						|
            console.error('Timed out waiting for QRCode to become available.');
 | 
						|
            reject(new Error('QRCode not available after ' + timeout + 'ms. Check if qrcode.min.js is loaded correctly and sets window.QRCode.'));
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }, interval);
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
	// INFO: We have to wait for the QRCode object to be available. It's messy.
 | 
						|
  async function genQRCode() {
 | 
						|
		const QRCode = await getQRCodeWhenAvailable();
 | 
						|
		if (qrElement && accessUrl && qrElement.innerHTML.trim() === '') {
 | 
						|
			new QRCode(qrElement, {
 | 
						|
				text: accessUrl,
 | 
						|
				width: 1280,
 | 
						|
				height: 1280,
 | 
						|
				colorDark: "#000000",
 | 
						|
				colorLight: "#ffffff",
 | 
						|
				correctLevel: QRCode.CorrectLevel.H
 | 
						|
			});
 | 
						|
			setTimeout(() => {
 | 
						|
				qrElement.classList.remove('hidden');
 | 
						|
			}, 20);
 | 
						|
		}
 | 
						|
  }
 | 
						|
 | 
						|
  genQRCode();
 | 
						|
	if (tokenElement) {
 | 
						|
		tokenElement.addEventListener('focus', (ev) => {
 | 
						|
			ev.preventDefault();
 | 
						|
			tokenElement.select();
 | 
						|
		});
 | 
						|
		tokenElement.addEventListener('mousedown', (ev) => {
 | 
						|
			ev.preventDefault();
 | 
						|
			tokenElement.select();
 | 
						|
		});
 | 
						|
		tokenElement.addEventListener('mouseup', (ev) => {
 | 
						|
			ev.preventDefault();
 | 
						|
			tokenElement.select();
 | 
						|
		});
 | 
						|
  }
 | 
						|
</script>
 | 
						|
 | 
						|
<div class="flex container-normal bg-slate-100 mx-auto !pt-36 px-8">
 | 
						|
	<div class="flex-col w-full">
 | 
						|
		{{ if $model.redirect_url }}
 | 
						|
			<a href="{{ $model.redirect_url }}" class="text-gray-700 hover:text-slate-950">
 | 
						|
				<i class="ri-arrow-left-s-line"></i> Zurück
 | 
						|
			</a>
 | 
						|
		{{ else }}
 | 
						|
			<a href="/" class="text-gray-700 hover:text-slate-950">
 | 
						|
				<i class="ri-arrow-left-s-line"></i> Startseite
 | 
						|
			</a>
 | 
						|
		{{ end }}
 | 
						|
		<h1 class="text-2xl self-baseline w-full mt-6 mb-2 font-bold text-slate-900">
 | 
						|
			Nutzer einladen
 | 
						|
		</h1>
 | 
						|
		<div class="text-sm text-slate-600 !hyphens-auto mb-6 max-w-[60ch]">
 | 
						|
			<i class="ri-question-line"></i>
 | 
						|
			Mit diesem Link können neue Accounts registriert werden. Geben Sie den Link an Personen
 | 
						|
			weiter, die Sie einladen möchten.
 | 
						|
		</div>
 | 
						|
	</div>
 | 
						|
</div>
 | 
						|
 | 
						|
<div class="user-invites flex container-normal mx-auto px-8 mt-4">
 | 
						|
	<div class="flex flex-row w-full">
 | 
						|
		<div class="flex-col max-w-xl w-full">
 | 
						|
			<!-- QR Code -->
 | 
						|
			<div class="mb-4 p-4 border rounded-xs hidden" id="qr"></div>
 | 
						|
 | 
						|
			<!-- Access URL and Token -->
 | 
						|
			<div class="mb-6 flex flex-col">
 | 
						|
				<div class="flex flex-row">
 | 
						|
					<input
 | 
						|
						type="text"
 | 
						|
						name="token"
 | 
						|
						id="token"
 | 
						|
						class="w-full text-center border border-slate-300 rounded-xs
 | 
						|
					focus:border-slate-500 focus:ring-slate-500 p-1 px-2 overflow-ellipsis"
 | 
						|
						value="{{ $model.access_url }}"
 | 
						|
						deactive
 | 
						|
						readonly />
 | 
						|
					<tool-tip position="top">
 | 
						|
						<div class="data-tip font-bold hidden">Kopieren</div>
 | 
						|
						<button
 | 
						|
							type="button"
 | 
						|
							class="ml-2 inline-flex justify-center py-2 px-3 border border-transparent
 | 
						|
					rounded-xs
 | 
						|
					shadow-sm text-sm font-medium text-white bg-slate-700 hover:bg-slate-800 cursor-pointer
 | 
						|
					focus:outline-none no-underline
 | 
						|
					focus:ring-2 focus:ring-offset-2 focus:ring-slate-500"
 | 
						|
							onclick="navigator.clipboard.writeText('{{ $model.access_url }}')">
 | 
						|
							<i class="ri-file-copy-line"></i>
 | 
						|
						</button>
 | 
						|
					</tool-tip>
 | 
						|
					<tool-tip position="top">
 | 
						|
						<div class="data-tip font-bold hidden">In neuem Fenster öffnen</div>
 | 
						|
						<a
 | 
						|
							href="{{ $model.relative_url }}"
 | 
						|
							target="_blank"
 | 
						|
							class="ml-2 inline-flex justify-center py-2 px-3 border border-transparent
 | 
						|
					rounded-xs
 | 
						|
					shadow-sm text-sm font-medium text-white bg-slate-700 hover:bg-slate-800 cursor-pointer
 | 
						|
					focus:outline-none no-underline
 | 
						|
					focus:ring-2 focus:ring-offset-2 focus:ring-slate-500">
 | 
						|
							<i class="ri-external-link-line"></i>
 | 
						|
						</a>
 | 
						|
					</tool-tip>
 | 
						|
					<form class="" method="POST">
 | 
						|
						<input
 | 
						|
							type="hidden"
 | 
						|
							name="csrf_nonce"
 | 
						|
							id="csrf_nonce"
 | 
						|
							required
 | 
						|
							value="{{ $model.csrf_nonce }}" />
 | 
						|
						<input
 | 
						|
							type="hidden"
 | 
						|
							name="csrf_token"
 | 
						|
							id="csrf_token"
 | 
						|
							required
 | 
						|
							value="{{ $model.csrf_token }}" />
 | 
						|
						<div class="col-span-9 flex flex-row items-center justify-center">
 | 
						|
							<tool-tip position="top">
 | 
						|
								<div class="data-tip font-bold hidden">Link invalidieren</div>
 | 
						|
								<button
 | 
						|
									type="submit"
 | 
						|
									class="ml-2 inline-flex justify-center py-2 px-3 border border-transparent
 | 
						|
					rounded-xs
 | 
						|
					shadow-sm text-sm font-medium text-white bg-slate-700 hover:bg-slate-800 cursor-pointer
 | 
						|
					focus:outline-none no-underline
 | 
						|
					focus:ring-2 focus:ring-offset-2 focus:ring-slate-500">
 | 
						|
									<i class="ri-loop-left-line"></i>
 | 
						|
								</button>
 | 
						|
							</tool-tip>
 | 
						|
						</div>
 | 
						|
					</form>
 | 
						|
				</div>
 | 
						|
				<div class="text-right text-slate-400 mb-1 mt-3">
 | 
						|
					Gültig bis
 | 
						|
					{{ $model.validUntil }}
 | 
						|
				</div>
 | 
						|
			</div>
 | 
						|
			<!-- End of Access URL and Token -->
 | 
						|
		</div>
 | 
						|
		<!-- End of First Column -->
 | 
						|
 | 
						|
		<!-- Second column -->
 | 
						|
		<div class="ml-12 flex flex-col">
 | 
						|
			<!-- User Role Chooser -->
 | 
						|
			<div class="user-chooser flex flex-col gap-y-3">
 | 
						|
				<a
 | 
						|
					href="/user/management/access/User?redirectTo={{ $model.redirect_url }}"
 | 
						|
					{{ if eq $model.role "User" }}aria-current="page"{{ end }}>
 | 
						|
					Benutzer
 | 
						|
				</a>
 | 
						|
				{{ if eq $model.role "User" }}
 | 
						|
					<div class="max-w-[60ch] text-sm text-blue-600 flex flex-row gap-x-2 hyphens-auto">
 | 
						|
						<div>
 | 
						|
							<i class="ri-error-warning-line"></i>
 | 
						|
						</div>
 | 
						|
						<div>
 | 
						|
							Benutzer können private Felder und Datensätze einsehen, aber nicht bearbeiten oder
 | 
						|
							löschen.
 | 
						|
						</div>
 | 
						|
					</div>
 | 
						|
				{{- end -}}
 | 
						|
				<a
 | 
						|
					href="/user/management/access/Editor?redirectTo={{ $model.redirect_url }}"
 | 
						|
					{{ if eq $model.role "Editor" }}aria-current="page"{{ end }}>
 | 
						|
					Redakteur
 | 
						|
				</a>
 | 
						|
				{{- if eq $model.role "Editor" -}}
 | 
						|
					<div class="max-w-[60ch] text-sm text-orange-600 flex flex-row gap-x-2 hyphens-auto">
 | 
						|
						<div>
 | 
						|
							<i class="ri-error-warning-line"></i>
 | 
						|
						</div>
 | 
						|
						<div>
 | 
						|
							Redakteure können alle Felder und Datensätze der Datenbank einsehen, bearbeiten oder
 | 
						|
							löschen.
 | 
						|
						</div>
 | 
						|
					</div>
 | 
						|
				{{- end -}}
 | 
						|
				<a
 | 
						|
					href="/user/management/access/Admin?redirectTo={{ $model.redirect_url }}"
 | 
						|
					{{ if eq $model.role "Admin" }}aria-current="page"{{ end }}>
 | 
						|
					Admin
 | 
						|
				</a>
 | 
						|
				{{- if eq $model.role "Admin" -}}
 | 
						|
					<div class="max-w-[60ch] text-sm text-red-600 flex flex-row gap-x-2 hyphens-auto">
 | 
						|
						<div>
 | 
						|
							<i class="ri-error-warning-line"></i>
 | 
						|
						</div>
 | 
						|
						<div>
 | 
						|
							Administratoren können alle Felder und Datensätze einsehen, bearbeiten oder löschen.
 | 
						|
							Administratoren können Passwörter setzen, Nutzer einladen und deaktivieren.
 | 
						|
						</div>
 | 
						|
					</div>
 | 
						|
				{{- end -}}
 | 
						|
			</div>
 | 
						|
			<!-- End of User Role Chooser -->
 | 
						|
		</div>
 | 
						|
		<!-- End of second column -->
 | 
						|
	</div>
 | 
						|
</div>
 |