styling
This commit is contained in:
2
frontend/.gitignore
vendored
2
frontend/.gitignore
vendored
@@ -35,3 +35,5 @@ Thumbs.db
|
|||||||
!vite.config.js # Vite configuration
|
!vite.config.js # Vite configuration
|
||||||
vite.config.js.timestamp-*
|
vite.config.js.timestamp-*
|
||||||
vite.config.ts.timestamp-*
|
vite.config.ts.timestamp-*
|
||||||
|
|
||||||
|
!src/**
|
||||||
|
|||||||
@@ -1,304 +1,338 @@
|
|||||||
<script>
|
<script>
|
||||||
import { createEventDispatcher } from "svelte";
|
import { createEventDispatcher } from 'svelte';
|
||||||
import { t } from "svelte-i18n";
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
export let name;
|
export let name;
|
||||||
|
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
export let type = "text";
|
export let type = 'text';
|
||||||
|
|
||||||
/** @type {string|Number|null} */
|
/** @type {string|Number|null} */
|
||||||
export let value;
|
export let value;
|
||||||
|
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
export let placeholder = "";
|
export let placeholder = '';
|
||||||
|
|
||||||
/** @type {Number} */
|
/** @type {Number} */
|
||||||
export let rows = 4;
|
export let rows = 4;
|
||||||
|
|
||||||
/** @type {Array<{value: string | number, label: string, color?:string}>} */
|
/** @type {Array<{value: string | number, label: string, color?:string}>} */
|
||||||
export let options = [];
|
export let options = [];
|
||||||
|
|
||||||
/** @type {Boolean} */
|
/** @type {Boolean} */
|
||||||
export let required = false;
|
export let required = false;
|
||||||
|
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
export let label = "";
|
export let label = '';
|
||||||
|
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
export let otherPasswordValue = "";
|
export let otherPasswordValue = '';
|
||||||
|
|
||||||
/** @type {boolean} */
|
/** @type {boolean} */
|
||||||
export let toUpperCase = false;
|
export let toUpperCase = false;
|
||||||
|
|
||||||
/** @type {boolean} */
|
/** @type {boolean} */
|
||||||
export let checked = false;
|
export let checked = false;
|
||||||
|
|
||||||
/** @type {boolean} */
|
/** @type {boolean} */
|
||||||
export let readonly = false;
|
export let readonly = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Event} event - The input event
|
* @param {Event} event - The input event
|
||||||
*/
|
*/
|
||||||
function handleInput(event) {
|
function handleInput(event) {
|
||||||
const target = event.target;
|
const target = event.target;
|
||||||
|
|
||||||
if (target instanceof HTMLInputElement) {
|
if (target instanceof HTMLInputElement) {
|
||||||
let inputValue = target.value;
|
let inputValue = target.value;
|
||||||
if (toUpperCase) {
|
if (toUpperCase) {
|
||||||
inputValue = inputValue.toUpperCase();
|
inputValue = inputValue.toUpperCase();
|
||||||
target.value = inputValue; // Update the input field value
|
target.value = inputValue; // Update the input field value
|
||||||
}
|
}
|
||||||
value = inputValue;
|
value = inputValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the field
|
* Validates the field
|
||||||
* @param {string} name - The name of the field
|
* @param {string} name - The name of the field
|
||||||
* @param {string|Number|null} value - The value of the field
|
* @param {string|Number|null} value - The value of the field
|
||||||
* @param {Boolean} required - The requirements of the field
|
* @param {Boolean} required - The requirements of the field
|
||||||
* @returns {string|null} The error message or null if valid
|
* @returns {string|null} The error message or null if valid
|
||||||
*/
|
*/
|
||||||
function validateField(name, value, required) {
|
function validateField(name, value, required) {
|
||||||
if (
|
if (value === null || (typeof value === 'string' && !value.trim() && !required)) return null;
|
||||||
value === null ||
|
switch (name) {
|
||||||
(typeof value === "string" && !value.trim() && !required)
|
case 'membership_start_date':
|
||||||
)
|
return typeof value === 'string' && value.trim() ? null : $t('validation.date');
|
||||||
return null;
|
case 'email':
|
||||||
switch (name) {
|
return typeof value === 'string' && /^\S+@\S+\.\S+$/.test(value)
|
||||||
case "membership_start_date":
|
? null
|
||||||
return typeof value === "string" && value.trim()
|
: $t('validation.email');
|
||||||
? null
|
case 'password':
|
||||||
: $t("validation.date");
|
case 'password2':
|
||||||
case "email":
|
if (typeof value === 'string' && value.length < 8) {
|
||||||
return typeof value === "string" && /^\S+@\S+\.\S+$/.test(value)
|
return $t('validation.password');
|
||||||
? null
|
}
|
||||||
: $t("validation.email");
|
if (otherPasswordValue && value !== otherPasswordValue) {
|
||||||
case "password":
|
return $t('validation.password_match');
|
||||||
case "password2":
|
}
|
||||||
if (typeof value === "string" && value.length < 8) {
|
return null;
|
||||||
return $t("validation.password");
|
case 'phone':
|
||||||
}
|
return typeof value === 'string' && /^\+?[0-9\s()-]{7,}$/.test(value)
|
||||||
if (otherPasswordValue && value !== otherPasswordValue) {
|
? null
|
||||||
return $t("validation.password_match");
|
: $t('validation.phone');
|
||||||
}
|
case 'zip_code':
|
||||||
return null;
|
return typeof value === 'string' && /^\d{5}$/.test(value)
|
||||||
case "phone":
|
? null
|
||||||
return typeof value === "string" && /^\+?[0-9\s()-]{7,}$/.test(value)
|
: $t('validation.zip_code');
|
||||||
? null
|
case 'iban':
|
||||||
: $t("validation.phone");
|
return typeof value === 'string' && /^[A-Z]{2}\d{2}[A-Z0-9]{1,30}$/.test(value)
|
||||||
case "zip_code":
|
? null
|
||||||
return typeof value === "string" && /^\d{5}$/.test(value)
|
: $t('validation.iban');
|
||||||
? null
|
case 'bic':
|
||||||
: $t("validation.zip_code");
|
return typeof value === 'string' &&
|
||||||
case "iban":
|
/^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$/.test(value)
|
||||||
return typeof value === "string" &&
|
? null
|
||||||
/^[A-Z]{2}\d{2}[A-Z0-9]{1,30}$/.test(value)
|
: $t('validation.bic');
|
||||||
? null
|
case 'licence_number':
|
||||||
: $t("validation.iban");
|
return typeof value === 'string' && value.length == 11 ? null : $t('validation.licence');
|
||||||
case "bic":
|
|
||||||
return typeof value === "string" &&
|
|
||||||
/^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$/.test(value)
|
|
||||||
? null
|
|
||||||
: $t("validation.bic");
|
|
||||||
case "licence_number":
|
|
||||||
return typeof value === "string" && value.length == 11
|
|
||||||
? null
|
|
||||||
: $t("validation.licence");
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return typeof value === "string" && !value.trim() && required
|
return typeof value === 'string' && !value.trim() && required
|
||||||
? $t("validation.required")
|
? $t('validation.required')
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: error = validateField(name, value, required);
|
$: error = validateField(name, value, required);
|
||||||
$: selectedOption = options.find((option) => option.value == value);
|
$: selectedOption = options.find((option) => option.value == value);
|
||||||
$: selectedColor = selectedOption ? selectedOption.color : "";
|
$: selectedColor = selectedOption ? selectedOption.color : '';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="input-box {type === 'checkbox' ? 'checkbox-container' : ''}">
|
<div class="input-box {type === 'checkbox' ? 'checkbox-container' : ''}">
|
||||||
{#if type === "checkbox"}
|
{#if type === 'checkbox'}
|
||||||
<label class="form-control {readonly ? 'form-control--disabled' : ''}">
|
<label class="form-control {readonly ? 'form-control--disabled' : ''}">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
{name}
|
{name}
|
||||||
{value}
|
{value}
|
||||||
{checked}
|
{checked}
|
||||||
{readonly}
|
{readonly}
|
||||||
on:change={() => (checked = !checked)}
|
on:change={() => (checked = !checked)}
|
||||||
/>
|
/>
|
||||||
<span class="checkbox-text"> {label} </span>
|
<span class="checkbox-text"> {label} </span>
|
||||||
</label>
|
</label>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="label">{label}</span>
|
<span class="label">{label}</span>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="input-error-container">
|
<div class="input-error-container">
|
||||||
{#if error}
|
{#if error}
|
||||||
<span class="error-message">{error}</span>
|
<span class="error-message">{error}</span>
|
||||||
{/if}
|
{/if}
|
||||||
{#if type === "select"}
|
{#if type === 'select'}
|
||||||
<select
|
<select
|
||||||
{name}
|
{name}
|
||||||
bind:value
|
bind:value
|
||||||
{required}
|
{required}
|
||||||
class="input select"
|
class="input select"
|
||||||
style={selectedColor ? `color: ${selectedColor};` : ""}
|
style={selectedColor ? `color: ${selectedColor};` : ''}
|
||||||
>
|
>
|
||||||
{#each options as option}
|
{#each options as option}
|
||||||
<option value={option.value}>{option.label}</option>
|
<option value={option.value}>{option.label}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
{:else if type === "textarea"}
|
{:else if type === 'textarea'}
|
||||||
<textarea
|
<textarea
|
||||||
{name}
|
{name}
|
||||||
{placeholder}
|
{placeholder}
|
||||||
{required}
|
{required}
|
||||||
{value}
|
{value}
|
||||||
{readonly}
|
{readonly}
|
||||||
{rows}
|
{rows}
|
||||||
class="input textarea {readonly ? 'readonly' : ''}"
|
class="input textarea {readonly ? 'readonly' : ''}"
|
||||||
style="height:{rows * 1.5}em;"
|
style="height:{rows * 1.5}em;"
|
||||||
/>
|
></textarea>
|
||||||
{:else if type != "checkbox"}
|
{:else if type != 'checkbox'}
|
||||||
<input
|
<input
|
||||||
{name}
|
{name}
|
||||||
{type}
|
{type}
|
||||||
{placeholder}
|
{placeholder}
|
||||||
{readonly}
|
{readonly}
|
||||||
{value}
|
{value}
|
||||||
{required}
|
{required}
|
||||||
on:input={handleInput}
|
on:input={handleInput}
|
||||||
on:blur={handleInput}
|
on:blur={handleInput}
|
||||||
class="input {readonly ? 'readonly' : ''}"
|
class="input {readonly ? 'readonly' : ''}"
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--form-control-color: #6bff55;
|
--form-control-color: var(--green); /* Changed from #6bff55 */
|
||||||
--form-control-disabled: #959495;
|
--form-control-disabled: var(--overlay0); /* Changed from #959495 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-control {
|
.form-control {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1.5em auto;
|
grid-template-columns: 1.5em auto;
|
||||||
gap: 0.75em;
|
gap: 0.75em;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
.form-control--disabled {
|
.form-control--disabled {
|
||||||
color: var(--form-control-disabled);
|
color: var(--form-control-disabled);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="checkbox"] {
|
input[type='checkbox'] {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
background-color: var(--form-background);
|
background-color: var(--surface0);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
color: currentColor;
|
color: var(--text);
|
||||||
width: 1.75em;
|
width: 1.75em;
|
||||||
height: 1.75em;
|
height: 1.75em;
|
||||||
border: 0.15em solid currentColor;
|
border: 0.15em solid var(--overlay0);
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5em;
|
||||||
transform: translateY(-0.075em);
|
transform: translateY(-0.075em);
|
||||||
display: grid;
|
display: grid;
|
||||||
place-content: center;
|
place-content: center;
|
||||||
transition: transform 0.2s ease-in-out;
|
transition: transform 0.2s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="checkbox"]::before {
|
input[type='checkbox']::before {
|
||||||
content: "";
|
content: '';
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
|
clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
|
||||||
transform: scale(0);
|
transform: scale(0);
|
||||||
transform-origin: bottom left;
|
transform-origin: bottom left;
|
||||||
transition: 120ms transform ease-in-out;
|
transition: 120ms transform ease-in-out;
|
||||||
box-shadow: inset 1em 1em var(--form-control-color);
|
box-shadow: inset 1em 1em var(--form-control-color);
|
||||||
background-color: CanvasText;
|
background-color: var(--crust);
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="checkbox"]:checked::before {
|
input[type='checkbox']:checked::before {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="checkbox"]:hover {
|
input[type='checkbox']:hover {
|
||||||
outline: max(2px, 0.15em) solid currentColor;
|
outline: max(2px, 0.15em) solid var(--lavender);
|
||||||
outline-offset: max(2px, 0.15em);
|
outline-offset: max(2px, 0.15em);
|
||||||
transform: scale(1.3);
|
transform: scale(1.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="checkbox"]:disabled {
|
input[type='checkbox']:disabled {
|
||||||
--form-control-color: var(--form-control-disabled);
|
--form-control-color: var(--form-control-disabled);
|
||||||
color: var(--form-control-disabled);
|
color: var(--form-control-disabled);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
.readonly {
|
.readonly {
|
||||||
background-color: #ececec;
|
background-color: var(--surface0);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
color: #4f4f4f;
|
color: var(--overlay1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-container {
|
.checkbox-container {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
.checkbox-text {
|
.checkbox-text {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
.checkbox-text {
|
.checkbox-text {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.select {
|
.select {
|
||||||
padding-right: 1.5em;
|
padding-right: 1.5em;
|
||||||
}
|
background-color: var(--surface0);
|
||||||
.input-error-container {
|
}
|
||||||
display: flex;
|
.input-error-container {
|
||||||
align-items: flex-end;
|
display: flex;
|
||||||
width: 100%;
|
flex-direction: column;
|
||||||
max-width: 444px;
|
gap: 0.5rem;
|
||||||
}
|
width: 100%;
|
||||||
|
max-width: 444px;
|
||||||
|
}
|
||||||
|
|
||||||
.error-message {
|
.error-message {
|
||||||
color: #eb5424;
|
color: var(--red); /* Changed from #eb5424 */
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
margin: 0.5rem 0;
|
||||||
input,
|
}
|
||||||
textarea,
|
input,
|
||||||
select {
|
textarea,
|
||||||
width: 100%;
|
select {
|
||||||
padding: 0.5rem;
|
width: 100%;
|
||||||
border: 1px solid #ccc;
|
padding: 0.75rem 0;
|
||||||
border-radius: 4px;
|
background-color: var(--surface0);
|
||||||
color: white;
|
border: 1px solid var(--overlay0);
|
||||||
}
|
border-radius: 6px;
|
||||||
textarea {
|
color: var(--text);
|
||||||
resize: vertical;
|
transition: border-color 0.2s ease-in-out;
|
||||||
min-height: 100px;
|
}
|
||||||
}
|
|
||||||
|
input:focus,
|
||||||
|
textarea:focus,
|
||||||
|
select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--lavender);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:hover:not(:disabled),
|
||||||
|
textarea:hover:not(:disabled),
|
||||||
|
select:hover:not(:disabled) {
|
||||||
|
border-color: var(--overlay2);
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: vertical;
|
||||||
|
min-height: 100px;
|
||||||
|
}
|
||||||
|
/* Add consistent spacing between input boxes */
|
||||||
|
.input-box {
|
||||||
|
margin: 1rem 0;
|
||||||
|
padding: 0.5rem;
|
||||||
|
background-color: var(--surface0);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-box .label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
color: var(--lavender);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style select dropdown */
|
||||||
|
select option {
|
||||||
|
background-color: var(--base);
|
||||||
|
color: var(--text);
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,128 +1,155 @@
|
|||||||
<script>
|
<script>
|
||||||
import { quintOut } from "svelte/easing";
|
import { quintOut } from 'svelte/easing';
|
||||||
|
|
||||||
import { t } from "svelte-i18n";
|
import { t } from 'svelte-i18n';
|
||||||
import { createEventDispatcher } from "svelte";
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
const modal = (/** @type {Element} */ node, { duration = 300 } = {}) => {
|
const modal = (/** @type {Element} */ node, { duration = 300 } = {}) => {
|
||||||
const transform = getComputedStyle(node).transform;
|
const transform = getComputedStyle(node).transform;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
duration,
|
duration,
|
||||||
easing: quintOut,
|
easing: quintOut,
|
||||||
css: (/** @type {any} */ t, /** @type {number} */ u) => {
|
css: (/** @type {any} */ t, /** @type {number} */ u) => {
|
||||||
return `transform:
|
return `transform:
|
||||||
${transform}
|
${transform}
|
||||||
scale(${t})
|
scale(${t})
|
||||||
translateY(${u * -100}%)
|
translateY(${u * -100}%)
|
||||||
`;
|
`;
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
function closeModal() {
|
function closeModal() {
|
||||||
dispatch("close", {});
|
dispatch('close', {});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="modal-background">
|
<div class="modal-background">
|
||||||
<div
|
<div transition:modal|global={{ duration: 1000 }} class="modal" role="dialog" aria-modal="true">
|
||||||
transition:modal|global={{ duration: 1000 }}
|
<!-- svelte-ignore a11y-missing-attribute -->
|
||||||
class="modal"
|
<a
|
||||||
role="dialog"
|
title={$t('cancel')}
|
||||||
aria-modal="true"
|
class="modal-close"
|
||||||
>
|
on:click={closeModal}
|
||||||
<!-- svelte-ignore a11y-missing-attribute -->
|
role="button"
|
||||||
<a
|
tabindex="0"
|
||||||
title={$t("cancel")}
|
on:keydown={(e) => e.key == 'Enter' && closeModal()}
|
||||||
class="modal-close"
|
>
|
||||||
on:click={closeModal}
|
<svg
|
||||||
role="button"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
tabindex="0"
|
width="20"
|
||||||
on:keydown={(e) => e.key == "Enter" && closeModal()}
|
height="20"
|
||||||
>
|
viewBox="0 0 384 512"
|
||||||
<svg
|
aria-hidden="true"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
>
|
||||||
width="20"
|
<path
|
||||||
height="20"
|
d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"
|
||||||
viewBox="0 0 384 512"
|
/>
|
||||||
aria-hidden="true"
|
</svg>
|
||||||
>
|
<span class="sr-only">{$t('cancel')}</span>
|
||||||
<path
|
</a>
|
||||||
d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"
|
<div class="container">
|
||||||
/>
|
<slot />
|
||||||
</svg>
|
</div>
|
||||||
<span class="sr-only">{$t("cancel")}</span>
|
</div>
|
||||||
</a>
|
|
||||||
<div class="container">
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.modal-background {
|
.modal-background {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background: rgba(0, 0, 0, 0.9);
|
background: rgba(30, 30, 46, 0.65); /* var(--base) with 0.75 opacity */
|
||||||
z-index: 9999;
|
backdrop-filter: blur(4px); /* Optional: adds a slight blur effect */
|
||||||
display: flex;
|
z-index: 9999;
|
||||||
}
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
position: relative;
|
position: relative;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
width: 70%;
|
width: 70%;
|
||||||
box-shadow: 0 0 10px hsl(0 0% 0% / 10%);
|
background-color: var(--base);
|
||||||
transform: translate(-50%, -50%);
|
border: 1px solid var(--surface0);
|
||||||
}
|
border-radius: 8px;
|
||||||
.sr-only {
|
box-shadow: 0 4px 20px rgba(17, 17, 27, 0.5); /* var(--crust) with opacity */
|
||||||
position: absolute;
|
transform: translate(-50%, -50%);
|
||||||
width: 1px;
|
}
|
||||||
height: 1px;
|
.sr-only {
|
||||||
padding: 0;
|
position: absolute;
|
||||||
margin: -1px;
|
width: 1px;
|
||||||
overflow: hidden;
|
height: 1px;
|
||||||
clip: rect(0, 0, 0, 0);
|
padding: 0;
|
||||||
white-space: nowrap;
|
margin: -1px;
|
||||||
border-width: 0;
|
overflow: hidden;
|
||||||
}
|
clip: rect(0, 0, 0, 0);
|
||||||
@media (max-width: 990px) {
|
white-space: nowrap;
|
||||||
.modal {
|
border-width: 0;
|
||||||
width: 90%;
|
}
|
||||||
}
|
@media (max-width: 990px) {
|
||||||
}
|
.modal {
|
||||||
.modal-close {
|
width: 90%;
|
||||||
border: none;
|
}
|
||||||
}
|
}
|
||||||
|
.modal-close {
|
||||||
|
border: none;
|
||||||
|
padding: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.modal-close svg {
|
.modal-close svg {
|
||||||
display: block;
|
display: block;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
fill: rgb(14 165 233 /1);
|
transition: all 0.3s ease-in-out;
|
||||||
transition: all 0.5s;
|
fill: var(--blue); /* Using Catppuccin blue */
|
||||||
}
|
}
|
||||||
.modal-close:hover svg {
|
.modal-close:hover svg {
|
||||||
fill: rgb(225 29 72);
|
fill: var(--red); /* Using Catppuccin red */
|
||||||
transform: scale(1.5);
|
transform: scale(1.2);
|
||||||
}
|
}
|
||||||
.modal .container {
|
.modal .container {
|
||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
padding: 2rem;
|
||||||
@media (min-width: 680px) {
|
background-color: var(--base);
|
||||||
.modal .container {
|
border-radius: 8px;
|
||||||
flex-direction: column;
|
}
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
/* Scrollbar styling */
|
||||||
}
|
.modal .container::-webkit-scrollbar {
|
||||||
}
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal .container::-webkit-scrollbar-track {
|
||||||
|
background: var(--surface0);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal .container::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--surface2);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal .container::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--surface1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 680px) {
|
||||||
|
.modal .container {
|
||||||
|
flex-direction: column;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
<script>
|
<script>
|
||||||
/** @type {number | null} */
|
/** @type {number | null} */
|
||||||
export let width;
|
export let width;
|
||||||
/** @type {string | null} */
|
/** @type {string | null} */
|
||||||
export let message;
|
export let message;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="loading">
|
<div class="loading">
|
||||||
<p class="simple-loader" style={width ? `width: ${width}px` : ""} />
|
<p class="simple-loader" style={width ? `width: ${width}px` : ''}></p>
|
||||||
{#if message}
|
{#if message}
|
||||||
<p>{message}</p>
|
<p>{message}</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.loading {
|
.loading {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.loading p {
|
.loading p {
|
||||||
margin-left: 0.5rem;
|
margin-left: 0.5rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
727
frontend/src/lib/css/styles.min.css
vendored
727
frontend/src/lib/css/styles.min.css
vendored
@@ -1,46 +1,75 @@
|
|||||||
|
:root {
|
||||||
|
--rosewater: #f5e0dc;
|
||||||
|
--flamingo: #f2cdcd;
|
||||||
|
--pink: #f5c2e7;
|
||||||
|
--mauve: #cba6f7;
|
||||||
|
--red: #f38ba8;
|
||||||
|
--maroon: #eba0ac;
|
||||||
|
--peach: #fab387;
|
||||||
|
--yellow: #f9e2af;
|
||||||
|
--green: #a6e3a1;
|
||||||
|
--teal: #94e2d5;
|
||||||
|
--sky: #89dceb;
|
||||||
|
--sapphire: #74c7ec;
|
||||||
|
--blue: #89b4fa;
|
||||||
|
--lavender: #b4befe;
|
||||||
|
--text: #cdd6f4;
|
||||||
|
--subtext1: #bac2de;
|
||||||
|
--subtext0: #a6adc8;
|
||||||
|
--overlay2: #9399b2;
|
||||||
|
--overlay1: #7f849c;
|
||||||
|
--overlay0: #6c7086;
|
||||||
|
--surface2: #585b70;
|
||||||
|
--surface1: #45475a;
|
||||||
|
--surface0: #313244;
|
||||||
|
--base: #1e1e2e;
|
||||||
|
--mantle: #181825;
|
||||||
|
--crust: #11111b;
|
||||||
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Roboto Mono";
|
font-family: 'Roboto Mono';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
src: url(https://fonts.gstatic.com/s/robotomono/v22/L0xuDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_gPq_ROW9.ttf)
|
src: url(https://fonts.gstatic.com/s/robotomono/v22/L0xuDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_gPq_ROW9.ttf)
|
||||||
format("truetype");
|
format('truetype');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Roboto Mono";
|
font-family: 'Roboto Mono';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: url(https://fonts.gstatic.com/s/robotomono/v22/L0xuDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vq_ROW9.ttf)
|
src: url(https://fonts.gstatic.com/s/robotomono/v22/L0xuDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vq_ROW9.ttf)
|
||||||
format("truetype");
|
format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
padding: 0 30px;
|
padding: 0 30px;
|
||||||
background-color: black;
|
background-color: var(--base);
|
||||||
color: #9b9b9b;
|
color: var(--text);
|
||||||
font-family: "Quicksand", sans-serif;
|
font-family: 'Quicksand', sans-serif;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
margin: 5em auto 0 auto;
|
margin: 5em auto 0 auto;
|
||||||
}
|
}
|
||||||
pre,
|
pre,
|
||||||
code {
|
code {
|
||||||
display: inline;
|
display: inline;
|
||||||
font-family: "Roboto Mono", monospace;
|
font-family: 'Roboto Mono', monospace;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
font-family: "Roboto Mono", monospace;
|
font-family: 'Roboto Mono', monospace;
|
||||||
color: white;
|
color: var(--text);
|
||||||
border-style: none;
|
border-style: none;
|
||||||
height: 21px;
|
height: 21px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
h1,
|
h1,
|
||||||
h2,
|
h2,
|
||||||
@@ -48,506 +77,514 @@ h3,
|
|||||||
h4,
|
h4,
|
||||||
h5,
|
h5,
|
||||||
h6 {
|
h6 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
h2 {
|
h2 {
|
||||||
margin: 0 0 45px 0;
|
margin: 0 0 45px 0;
|
||||||
color: #fff;
|
color: var(--lavender);
|
||||||
font-size: 36px;
|
font-size: 36px;
|
||||||
}
|
}
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0 0 2rem 0;
|
margin: 0 0 2rem 0;
|
||||||
color: #fff;
|
color: var(--lavender);
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
margin: 0 0 45px;
|
margin: 0 0 45px;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
}
|
}
|
||||||
ul {
|
ul {
|
||||||
margin: 0 0 32px;
|
margin: 0 0 32px;
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
transition: border 0.2s ease-in-out;
|
transition: border 0.2s ease-in-out;
|
||||||
border-bottom: 1px solid transparent;
|
border-bottom: 1px solid transparent;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #00b7ef;
|
color: var(--blue);
|
||||||
}
|
}
|
||||||
a:hover {
|
a:hover {
|
||||||
border-bottom-color: #00b7ef;
|
border-bottom-color: var(--blue);
|
||||||
}
|
}
|
||||||
li {
|
li {
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
}
|
}
|
||||||
li strong {
|
li strong {
|
||||||
color: #fff;
|
color: var(--text);
|
||||||
}
|
}
|
||||||
.image {
|
.image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 0 32px;
|
margin: 0 0 32px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.image img {
|
.image img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.optanon-alert-box-wrapper {
|
.optanon-alert-box-wrapper {
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
.hide-mobile {
|
.hide-mobile {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@media (min-width: 680px) {
|
@media (min-width: 680px) {
|
||||||
body {
|
body {
|
||||||
margin: 8em auto 0 auto;
|
margin: 8em auto 0 auto;
|
||||||
}
|
}
|
||||||
.hide-mobile {
|
.hide-mobile {
|
||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 3em 0 0;
|
padding: 3em 0 0;
|
||||||
background: black;
|
background: var(--base);
|
||||||
}
|
}
|
||||||
.header.top-banner-open {
|
.header.top-banner-open {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
transition: all 0.2s linear;
|
transition: all 0.2s linear;
|
||||||
}
|
}
|
||||||
.header .header-container {
|
.header .header-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: calc(1200px + 10em);
|
max-width: calc(1200px + 10em);
|
||||||
height: 5em;
|
height: 5em;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
background-color: var(--base);
|
||||||
}
|
}
|
||||||
.header .header-container .header-left {
|
.header .header-container .header-left {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
.header .header-container .header-left .header-crafted-by-container {
|
.header .header-container .header-left .header-crafted-by-container {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
.header .header-container .header-left .header-crafted-by-container a {
|
.header .header-container .header-left .header-crafted-by-container a {
|
||||||
display: flex;
|
display: flex;
|
||||||
color: #9b9b9b;
|
color: var(--subtext0);
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
.header .header-container .header-left .header-crafted-by-container a img {
|
.header .header-container .header-left .header-crafted-by-container a img {
|
||||||
height: 28px;
|
height: 28px;
|
||||||
}
|
}
|
||||||
.header .header-container .header-left .header-crafted-by-container a span {
|
.header .header-container .header-left .header-crafted-by-container a span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 2px 1ch 0 0;
|
margin: 2px 1ch 0 0;
|
||||||
}
|
}
|
||||||
.header .header-container .header-left .header-crafted-by-container .auth0 {
|
.header .header-container .header-left .header-crafted-by-container .auth0 {
|
||||||
margin-left: 1ch;
|
margin-left: 1ch;
|
||||||
color: #fff;
|
color: var(--text);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.header .header-container .header-right {
|
.header .header-container .header-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
.header .header-container .header-right .header-nav-item {
|
.header .header-container .header-right .header-nav-item {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
.header .header-container .header-right .header-nav-item button {
|
.header .header-container .header-right .header-nav-item button {
|
||||||
all: unset;
|
all: unset;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.header .header-container .header-right .header-nav-item.active a,
|
.header .header-container .header-right .header-nav-item.active a,
|
||||||
.header .header-container .header-right .header-nav-item.active button {
|
.header .header-container .header-right .header-nav-item.active button {
|
||||||
color: #fff;
|
color: var(--text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header .header-container .header-right a img {
|
.header .header-container .header-right a img {
|
||||||
margin-top: -0.4rem;
|
margin-top: -0.4rem;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header .header-container .header-right .header-nav-item a,
|
.header .header-container .header-right .header-nav-item a,
|
||||||
.header .header-container .header-right .header-nav-item button {
|
.header .header-container .header-right .header-nav-item button {
|
||||||
transition: color 0.3s ease-in-out;
|
transition: color 0.3s ease-in-out;
|
||||||
display: block;
|
display: block;
|
||||||
padding: 20px 0;
|
padding: 20px 0;
|
||||||
border: none;
|
border: none;
|
||||||
color: #9b9b9b;
|
color: var(--subtext0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header .header-container .header-right .header-nav-item:hover a,
|
.header .header-container .header-right .header-nav-item:hover a,
|
||||||
.header .header-container .header-right .header-nav-item:hover button {
|
.header .header-container .header-right .header-nav-item:hover button {
|
||||||
color: #fdfff5;
|
color: var(--lavender);
|
||||||
}
|
}
|
||||||
@media (min-width: 680px) {
|
@media (min-width: 680px) {
|
||||||
.header {
|
.header {
|
||||||
padding: 3em 5rem 0;
|
padding: 3em 5rem 0;
|
||||||
}
|
}
|
||||||
.header.top-banner-open {
|
.header.top-banner-open {
|
||||||
margin-top: 48px;
|
margin-top: 48px;
|
||||||
}
|
}
|
||||||
.header .header-container {
|
.header .header-container {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
.header .header-container .header-right {
|
.header .header-container .header-right {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
.header .header-container .header-right .header-nav-item {
|
.header .header-container .header-right .header-nav-item {
|
||||||
margin-left: 26px;
|
margin-left: 26px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.button-dark {
|
.button-dark {
|
||||||
transition: border-color 0.3s ease-in-out, background-color 0.3s ease-in-out;
|
transition:
|
||||||
color: white;
|
border-color 0.3s ease-in-out,
|
||||||
text-transform: uppercase;
|
background-color 0.3s ease-in-out;
|
||||||
font-weight: 500;
|
color: white;
|
||||||
padding: 18px 28px;
|
text-transform: uppercase;
|
||||||
letter-spacing: 1px;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
padding: 18px 28px;
|
||||||
background-color: transparent;
|
letter-spacing: 1px;
|
||||||
border: 1px solid #595b5c;
|
cursor: pointer;
|
||||||
margin: 2px;
|
background-color: transparent;
|
||||||
|
border: 1px solid var(--surface1);
|
||||||
|
margin: 2px;
|
||||||
}
|
}
|
||||||
.button-dark:hover {
|
.button-dark:hover {
|
||||||
border-color: #fff;
|
border-color: var(--text);
|
||||||
}
|
}
|
||||||
.button-colorful {
|
.button-colorful {
|
||||||
transition: border-color 0.3s ease-in-out, background-color 0.3s ease-in-out;
|
transition:
|
||||||
color: white;
|
border-color 0.3s ease-in-out,
|
||||||
text-transform: uppercase;
|
background-color 0.3s ease-in-out;
|
||||||
font-weight: 500;
|
color: white;
|
||||||
padding: 18px 28px;
|
text-transform: uppercase;
|
||||||
letter-spacing: 1px;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
padding: 18px 28px;
|
||||||
background-color: #d43aff;
|
letter-spacing: 1px;
|
||||||
border: 1px solid #d43aff;
|
cursor: pointer;
|
||||||
|
background-color: var(--mauve);
|
||||||
|
border: 1px solid var(--mauve);
|
||||||
}
|
}
|
||||||
.button-colorful:hover {
|
.button-colorful:hover {
|
||||||
background-color: #c907ff;
|
background-color: #c907ff;
|
||||||
border-color: #c907ff;
|
border-color: #c907ff;
|
||||||
}
|
}
|
||||||
.button-orange {
|
.button-orange {
|
||||||
transition: border-color 0.3s ease-in-out, background-color 0.3s ease-in-out;
|
transition:
|
||||||
color: white;
|
border-color 0.3s ease-in-out,
|
||||||
text-transform: uppercase;
|
background-color 0.3s ease-in-out;
|
||||||
font-weight: 500;
|
color: white;
|
||||||
padding: 18px 28px;
|
text-transform: uppercase;
|
||||||
letter-spacing: 1px;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
padding: 18px 28px;
|
||||||
background-color: #eb5424;
|
letter-spacing: 1px;
|
||||||
border: 1px solid #eb5424;
|
cursor: pointer;
|
||||||
|
background-color: var(--peach);
|
||||||
|
border: 1px solid var(--peach);
|
||||||
}
|
}
|
||||||
.button-orange:hover {
|
.button-orange:hover {
|
||||||
background-color: #ca3f12;
|
background-color: #ca3f12;
|
||||||
border-color: #ca3f12;
|
border-color: #ca3f12;
|
||||||
}
|
}
|
||||||
.button-colorful:disabled {
|
.button-colorful:disabled {
|
||||||
transition: border-color 0.3s ease-in-out, background-color 0.3s ease-in-out;
|
transition:
|
||||||
color: white;
|
border-color 0.3s ease-in-out,
|
||||||
text-transform: uppercase;
|
background-color 0.3s ease-in-out;
|
||||||
font-weight: 500;
|
color: white;
|
||||||
padding: 18px 28px;
|
text-transform: uppercase;
|
||||||
letter-spacing: 1px;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
padding: 18px 28px;
|
||||||
background-color: #9a9a9a;
|
letter-spacing: 1px;
|
||||||
border: 1px solid #9a9a9a;
|
cursor: pointer;
|
||||||
|
background-color: var(--overlay0);
|
||||||
|
border: 1px solid var(--overlay0);
|
||||||
}
|
}
|
||||||
.hero-container {
|
.hero-container {
|
||||||
max-width: 795px;
|
max-width: 795px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin: 0 auto 70px auto;
|
margin: 0 auto 70px auto;
|
||||||
}
|
}
|
||||||
.hero-container .hero-logo {
|
.hero-container .hero-logo {
|
||||||
margin-top: 88px;
|
margin-top: 88px;
|
||||||
margin-bottom: 32px;
|
margin-bottom: 32px;
|
||||||
}
|
}
|
||||||
.hero-container .hero-subtitle {
|
.hero-container .hero-subtitle {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
margin: 0 0 45px 0;
|
margin: 0 0 45px 0;
|
||||||
}
|
}
|
||||||
.hero-container .hero-buttons-container {
|
.hero-container .hero-buttons-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
.hero-container .hero-buttons-container button {
|
.hero-container .hero-buttons-container button {
|
||||||
margin: 0 8px;
|
margin: 0 8px;
|
||||||
}
|
}
|
||||||
@media (min-width: 680px) {
|
@media (min-width: 680px) {
|
||||||
.hero-container {
|
.hero-container {
|
||||||
margin: 0 auto 140px auto;
|
margin: 0 auto 140px auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
transition: opacity 0.2s ease-in-out;
|
transition: opacity 0.2s ease-in-out;
|
||||||
color: white;
|
color: white;
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container .content {
|
.container .content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
.container .content .step-title {
|
.container .content .step-title {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 86px;
|
line-height: 86px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.container .content .step-subtitle {
|
.container .content .step-subtitle {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -5px;
|
top: -5px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 680px) {
|
@media (max-width: 680px) {
|
||||||
.container .content {
|
.container .content {
|
||||||
margin-top: 120px;
|
margin-top: 120px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 680px) {
|
@media (min-width: 680px) {
|
||||||
.container {
|
.container {
|
||||||
position: relative;
|
position: relative;
|
||||||
left: 100px;
|
left: 100px;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: calc(100% - 100px);
|
width: calc(100% - 100px);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.container .content {
|
.container .content {
|
||||||
max-width: 795px;
|
max-width: 795px;
|
||||||
}
|
}
|
||||||
.container .content .step-title {
|
.container .content .step-title {
|
||||||
font-size: 36px;
|
font-size: 36px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.input-box {
|
.input-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background-color: #2f2f2f;
|
background-color: var(--surface0);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
font-family: "Roboto Mono", monospace;
|
font-family: 'Roboto Mono', monospace;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
.input-box .label {
|
.input-box .label {
|
||||||
margin: 0 1ch 0 0;
|
margin: 0 1ch 0 0;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
.input-box .input {
|
.input-box .input {
|
||||||
background-color: #494848;
|
background-color: var(--surface1);
|
||||||
border-radius: 6px;
|
border: 3px solid var(--surface1);
|
||||||
outline: none;
|
border-radius: 6px;
|
||||||
border: 3px solid #494848;
|
outline: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 444px;
|
max-width: 444px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
@media (min-width: 680px) {
|
@media (min-width: 680px) {
|
||||||
.input-box {
|
.input-box {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.btn-container {
|
.btn-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: first baseline;
|
align-items: first baseline;
|
||||||
}
|
}
|
||||||
@media (max-width: 680px) {
|
@media (max-width: 680px) {
|
||||||
.btn-container {
|
.btn-container {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
.btn-container p {
|
.btn-container p {
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.button-group {
|
.button-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
font-family: "Roboto Mono", monospace;
|
font-family: 'Roboto Mono', monospace;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
padding: 18px 28px;
|
padding: 18px 28px;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
transition: border-color 0.3s ease-in-out, background-color 0.3s ease-in-out;
|
transition:
|
||||||
border-radius: 5px;
|
border-color 0.3s ease-in-out,
|
||||||
|
background-color 0.3s ease-in-out;
|
||||||
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn.primary {
|
.btn.primary {
|
||||||
background-color: #4361ee;
|
background-color: var(--blue);
|
||||||
border-color: #4361ee;
|
border-color: var(--blue);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn.primary:hover {
|
.btn.primary:hover {
|
||||||
background-color: #3651d4;
|
background-color: var(--sapphire);
|
||||||
border-color: #3651d4;
|
border-color: var(--sapphire);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn.danger {
|
.btn.danger {
|
||||||
background-color: #dc2626;
|
background-color: var(--red);
|
||||||
border-color: #dc2626;
|
border-color: var(--red);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn.danger:hover {
|
.btn.danger:hover {
|
||||||
background-color: #c51f1f;
|
background-color: var(--maroon);
|
||||||
border-color: #c51f1f;
|
border-color: var(--maroon);
|
||||||
}
|
}
|
||||||
.warning {
|
.warning {
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background-color: rgb(255 228 230);
|
background-color: var(--surface0);
|
||||||
border: 1px solid rgb(225 29 72);
|
border: 1px solid var(--red);
|
||||||
border-radius: 6px;
|
color: var(--red);
|
||||||
color: rgb(225 29 72);
|
border-radius: 6px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
.warning a {
|
.warning a {
|
||||||
color: rgb(225 29 72);
|
color: var(--red);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
.warning.hidden {
|
.warning.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
margin-top: 10rem;
|
margin-top: 10rem;
|
||||||
padding: 30px 40px;
|
padding: 30px 40px;
|
||||||
background: #2f3132;
|
background: var(--surface0);
|
||||||
color: #fff;
|
color: var(--text);
|
||||||
}
|
}
|
||||||
.error p {
|
.error p {
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
}
|
}
|
||||||
.error p.intro {
|
.error p.intro {
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
}
|
}
|
||||||
.error .button-colorful {
|
.error .button-colorful {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
@media (min-width: 680px) {
|
@media (min-width: 680px) {
|
||||||
.error {
|
.error {
|
||||||
padding: 65px 80px;
|
padding: 65px 80px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-branding-container {
|
.footer-branding-container {
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
margin-bottom: 73px;
|
margin-bottom: 73px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-branding-container .footer-branding {
|
.footer-branding-container .footer-branding {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
}
|
}
|
||||||
.footer-branding-container .footer-branding {
|
.footer-branding-container .footer-branding {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 30px 0 0;
|
margin: 30px 0 0;
|
||||||
}
|
}
|
||||||
.footer-branding-container .footer-branding .footer-crafted-by-container {
|
.footer-branding-container .footer-branding .footer-crafted-by-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
.footer-branding-container .footer-branding .footer-crafted-by-container span {
|
.footer-branding-container .footer-branding .footer-crafted-by-container span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 3px 1ch 0 0;
|
margin: 3px 1ch 0 0;
|
||||||
}
|
}
|
||||||
.footer-branding-container
|
.footer-branding-container
|
||||||
.footer-branding
|
.footer-branding
|
||||||
.footer-crafted-by-container
|
.footer-crafted-by-container
|
||||||
.footer-branded-crafted-img {
|
.footer-branded-crafted-img {
|
||||||
height: 28px;
|
height: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-branding-container .footer-branding .footer-copyright {
|
.footer-branding-container .footer-branding .footer-copyright {
|
||||||
color: #696969;
|
color: #696969;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
}
|
}
|
||||||
.footer-container {
|
.footer-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
color: white;
|
color: white;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 680px) {
|
@media (min-width: 680px) {
|
||||||
.footer-container {
|
.footer-container {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.simple-loader {
|
.simple-loader {
|
||||||
--b: 20px; /* border thickness */
|
--b: 20px; /* border thickness */
|
||||||
--n: 15; /* number of dashes*/
|
--n: 15; /* number of dashes*/
|
||||||
--g: 7deg; /* gap between dashes*/
|
--g: 7deg; /* gap between dashes*/
|
||||||
--c: #d43aff; /* the color */
|
--c: var(--mauve); /* Changed loader color to match theme */
|
||||||
|
|
||||||
width: 40px; /* size */
|
width: 40px; /* size */
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
padding: 1px; /* get rid of bad outlines */
|
padding: 1px; /* get rid of bad outlines */
|
||||||
background: conic-gradient(#0000, var(--c)) content-box;
|
background: conic-gradient(#0000, var(--c)) content-box;
|
||||||
--_m: /* we use +/-1deg between colors to avoid jagged edges */ repeating-conic-gradient(
|
--_m: /* we use +/-1deg between colors to avoid jagged edges */ repeating-conic-gradient(
|
||||||
#0000 0deg,
|
#0000 0deg,
|
||||||
#000 1deg calc(360deg / var(--n) - var(--g) - 1deg),
|
#000 1deg calc(360deg / var(--n) - var(--g) - 1deg),
|
||||||
#0000 calc(360deg / var(--n) - var(--g)) calc(360deg / var(--n))
|
#0000 calc(360deg / var(--n) - var(--g)) calc(360deg / var(--n))
|
||||||
),
|
),
|
||||||
radial-gradient(
|
radial-gradient(farthest-side, #0000 calc(98% - var(--b)), #000 calc(100% - var(--b)));
|
||||||
farthest-side,
|
-webkit-mask: var(--_m);
|
||||||
#0000 calc(98% - var(--b)),
|
mask: var(--_m);
|
||||||
#000 calc(100% - var(--b))
|
-webkit-mask-composite: destination-in;
|
||||||
);
|
mask-composite: intersect;
|
||||||
-webkit-mask: var(--_m);
|
animation: load 1s infinite steps(var(--n));
|
||||||
mask: var(--_m);
|
|
||||||
-webkit-mask-composite: destination-in;
|
|
||||||
mask-composite: intersect;
|
|
||||||
animation: load 1s infinite steps(var(--n));
|
|
||||||
}
|
}
|
||||||
@keyframes load {
|
@keyframes load {
|
||||||
to {
|
to {
|
||||||
transform: rotate(1turn);
|
transform: rotate(1turn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,156 +1,156 @@
|
|||||||
<script>
|
<script>
|
||||||
import Modal from "$lib/components/Modal.svelte";
|
import Modal from '$lib/components/Modal.svelte';
|
||||||
import UserEditForm from "$lib/components/UserEditForm.svelte";
|
import UserEditForm from '$lib/components/UserEditForm.svelte';
|
||||||
import { onMount } from "svelte";
|
import { onMount } from 'svelte';
|
||||||
import { page } from "$app/stores";
|
import { page } from '$app/stores';
|
||||||
import { t } from "svelte-i18n";
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
/** @type {import('./$types').ActionData} */
|
/** @type {import('./$types').ActionData} */
|
||||||
export let form;
|
export let form;
|
||||||
|
|
||||||
$: ({ user, licence_categories, subscriptions } = $page.data);
|
$: ({ user, licence_categories, subscriptions } = $page.data);
|
||||||
|
|
||||||
let showModal = false;
|
let showModal = false;
|
||||||
|
|
||||||
const open = () => (showModal = true);
|
const open = () => (showModal = true);
|
||||||
const close = () => {
|
const close = () => {
|
||||||
showModal = false;
|
showModal = false;
|
||||||
if (form) {
|
if (form) {
|
||||||
form.errors = undefined;
|
form.errors = undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
console.dir(user);
|
console.dir(user);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="hero-container">
|
<div class="hero-container">
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
{#if user.status}
|
{#if user.status}
|
||||||
<h3 class="hero-subtitle subtitle info-row">
|
<h3 class="hero-subtitle subtitle info-row">
|
||||||
<span class="label">Status:</span>
|
<span class="label">Status:</span>
|
||||||
<span class="value block-value">
|
<span class="value block-value">
|
||||||
<span
|
<span
|
||||||
>{$t(`userStatus.${user.status}`, {
|
>{$t(`userStatus.${user.status}`, {
|
||||||
default: "unknown status",
|
default: 'unknown status'
|
||||||
})}</span
|
})}</span
|
||||||
>
|
>
|
||||||
<span
|
<span>{$t(`userRole.${user.role_id}`, { default: 'unknown role' })}</span>
|
||||||
>{$t(`userRole.${user.role_id}`, { default: "unknown role" })}</span
|
</span>
|
||||||
>
|
</h3>
|
||||||
</span>
|
{/if}
|
||||||
</h3>
|
<h3 class="hero-subtitle subtitle info-row">
|
||||||
{/if}
|
<span class="label">Name:</span>
|
||||||
<h3 class="hero-subtitle subtitle info-row">
|
<span class="value">{`${user.first_name} ${user.last_name}`}</span>
|
||||||
<span class="label">Name:</span>
|
</h3>
|
||||||
<span class="value">{`${user.first_name} ${user.last_name}`}</span>
|
{#if user.email}
|
||||||
</h3>
|
<h3 class="hero-subtitle subtitle info-row">
|
||||||
{#if user.email}
|
<span class="label">Email:</span>
|
||||||
<h3 class="hero-subtitle subtitle info-row">
|
<span class="value">{user.email}</span>
|
||||||
<span class="label">Email:</span>
|
</h3>
|
||||||
<span class="value">{user.email}</span>
|
{/if}
|
||||||
</h3>
|
{#if user.address}
|
||||||
{/if}
|
<h3 class="hero-subtitle subtitle info-row">
|
||||||
{#if user.address}
|
<span class="label">Adresse:</span>
|
||||||
<h3 class="hero-subtitle subtitle info-row">
|
<span class="value block-value">
|
||||||
<span class="label">Adresse:</span>
|
<span>{user.address}</span>
|
||||||
<span class="value block-value">
|
<span>{`${user.zip_code} ${user.city}`}</span>
|
||||||
<span>{user.address}</span>
|
</span>
|
||||||
<span>{`${user.zip_code} ${user.city}`}</span>
|
</h3>
|
||||||
</span>
|
{/if}
|
||||||
</h3>
|
{#if user.phone}
|
||||||
{/if}
|
<h3 class="hero-subtitle subtitle info-row">
|
||||||
{#if user.phone}
|
<span class="label">Telefon:</span>
|
||||||
<h3 class="hero-subtitle subtitle info-row">
|
<span class="value">{user.phone}</span>
|
||||||
<span class="label">Telefon:</span>
|
</h3>
|
||||||
<span class="value">{user.phone}</span>
|
{/if}
|
||||||
</h3>
|
{#if user.date_of_birth}
|
||||||
{/if}
|
<h3 class="hero-subtitle subtitle info-row">
|
||||||
{#if user.date_of_birth}
|
<span class="label">Geburtstag:</span>
|
||||||
<h3 class="hero-subtitle subtitle info-row">
|
<span class="value">{user.date_of_birth}</span>
|
||||||
<span class="label">Geburtstag:</span>
|
</h3>
|
||||||
<span class="value">{user.date_of_birth}</span>
|
{/if}
|
||||||
</h3>
|
{#if user.notes}
|
||||||
{/if}
|
<h3 class="hero-subtitle subtitle info-row">
|
||||||
{#if user.notes}
|
<span class="label">{$t('notes')}:</span>
|
||||||
<h3 class="hero-subtitle subtitle info-row">
|
<span class="value">{user.notes}</span>
|
||||||
<span class="label">{$t("notes")}:</span>
|
</h3>
|
||||||
<span class="value">{user.notes}</span>
|
{/if}
|
||||||
</h3>
|
</div>
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="hero-buttons-container">
|
<div class="hero-buttons-container">
|
||||||
<button class="button-dark" on:click={open}>Ändern</button>
|
<button class="button-dark" on:click={open}>Ändern</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if showModal}
|
{#if showModal}
|
||||||
<Modal on:close={close}>
|
<Modal on:close={close}>
|
||||||
<UserEditForm
|
<UserEditForm {form} {user} {subscriptions} {licence_categories} on:cancel={close} />
|
||||||
{form}
|
</Modal>
|
||||||
{user}
|
|
||||||
{subscriptions}
|
|
||||||
{licence_categories}
|
|
||||||
on:cancel={close}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.hero-container .hero-subtitle:not(:last-of-type) {
|
.hero-container .hero-subtitle:not(:last-of-type) {
|
||||||
margin: 0 0 0 0;
|
margin: 0 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-container {
|
.hero-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-info {
|
.user-info {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto 1fr;
|
grid-template-columns: auto 1fr;
|
||||||
gap: 0.5rem 1rem;
|
gap: 0.5rem 1rem;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
color: var(--text);
|
||||||
|
background-color: var(--surface0);
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--surface1);
|
||||||
|
}
|
||||||
|
|
||||||
.info-row {
|
.info-row {
|
||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
}
|
color: var(--lavender);
|
||||||
|
}
|
||||||
|
|
||||||
.value {
|
.value {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
.block-value {
|
.block-value {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
color: var(--subtext0);
|
||||||
|
}
|
||||||
|
|
||||||
.hero-buttons-container {
|
.hero-buttons-container {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-info {
|
.user-info {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label,
|
.label,
|
||||||
.value {
|
.value {
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
<script>
|
<script>
|
||||||
import Modal from "$lib/components/Modal.svelte";
|
import Modal from '$lib/components/Modal.svelte';
|
||||||
import UserEditForm from "$lib/components/UserEditForm.svelte";
|
import UserEditForm from '$lib/components/UserEditForm.svelte';
|
||||||
import { t } from "svelte-i18n";
|
import { t } from 'svelte-i18n';
|
||||||
import { page } from "$app/stores";
|
import { page } from '$app/stores';
|
||||||
|
|
||||||
/** @type {import('./$types').ActionData} */
|
/** @type {import('./$types').ActionData} */
|
||||||
export let form;
|
export let form;
|
||||||
|
|
||||||
$: ({
|
$: ({
|
||||||
user,
|
user,
|
||||||
users = [],
|
users = [],
|
||||||
licence_categories = [],
|
licence_categories = [],
|
||||||
subscriptions = [],
|
subscriptions = [],
|
||||||
payments = [],
|
payments = []
|
||||||
} = $page.data);
|
} = $page.data);
|
||||||
|
|
||||||
let activeSection = "users";
|
let activeSection = 'users';
|
||||||
/** @type{App.Locals['user'] | null} */
|
/** @type{App.Locals['user'] | null} */
|
||||||
let selectedUser = null;
|
let selectedUser = null;
|
||||||
let showModal = false;
|
let showModal = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the edit modal for the selected user.
|
* Opens the edit modal for the selected user.
|
||||||
* @param {App.Locals['user'] | null} user The user to edit.
|
* @param {App.Locals['user'] | null} user The user to edit.
|
||||||
*/
|
*/
|
||||||
const openEditModal = (user) => {
|
const openEditModal = (user) => {
|
||||||
selectedUser = user;
|
selectedUser = user;
|
||||||
console.dir(selectedUser);
|
console.dir(selectedUser);
|
||||||
showModal = true;
|
showModal = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
showModal = false;
|
showModal = false;
|
||||||
selectedUser = null;
|
selectedUser = null;
|
||||||
if (form) {
|
if (form) {
|
||||||
form.errors = undefined;
|
form.errors = undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the active admin section for display
|
* sets the active admin section for display
|
||||||
* @param {string} section The new active section.
|
* @param {string} section The new active section.
|
||||||
*/
|
*/
|
||||||
const setActiveSection = (section) => {
|
const setActiveSection = (section) => {
|
||||||
activeSection = section;
|
activeSection = section;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
class="nav-link {activeSection === 'users' ? 'active' : ''}"
|
class="nav-link {activeSection === 'users' ? 'active' : ''}"
|
||||||
on:click={() => setActiveSection('users')}
|
on:click={() => setActiveSection('users')}
|
||||||
>
|
>
|
||||||
<i class="fas fa-users" />
|
<i class="fas fa-users"></i>
|
||||||
<span class="nav-badge">{users.length}</span>
|
<span class="nav-badge">{users.length}</span>
|
||||||
{$t('users')}
|
{$t('users')}
|
||||||
</button>
|
</button>
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
class="nav-link {activeSection === 'subscriptions' ? 'active' : ''}"
|
class="nav-link {activeSection === 'subscriptions' ? 'active' : ''}"
|
||||||
on:click={() => setActiveSection('subscriptions')}
|
on:click={() => setActiveSection('subscriptions')}
|
||||||
>
|
>
|
||||||
<i class="fas fa-clipboard-list" />
|
<i class="fas fa-clipboard-list"></i>
|
||||||
<span class="nav-badge">{subscriptions.length}</span>
|
<span class="nav-badge">{subscriptions.length}</span>
|
||||||
{$t('subscriptions')}
|
{$t('subscriptions')}
|
||||||
</button>
|
</button>
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
class="nav-link {activeSection === 'payments' ? 'active' : ''}"
|
class="nav-link {activeSection === 'payments' ? 'active' : ''}"
|
||||||
on:click={() => setActiveSection('payments')}
|
on:click={() => setActiveSection('payments')}
|
||||||
>
|
>
|
||||||
<i class="fas fa-credit-card" />
|
<i class="fas fa-credit-card"></i>
|
||||||
{$t('payments')}
|
{$t('payments')}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<h2>{$t('users')}</h2>
|
<h2>{$t('users')}</h2>
|
||||||
<button class="btn primary" on:click={() => openEditModal(null)}>
|
<button class="btn primary" on:click={() => openEditModal(null)}>
|
||||||
<i class="fas fa-plus" />
|
<i class="fas fa-plus"></i>
|
||||||
{$t('add_new')}
|
{$t('add_new')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -124,11 +124,11 @@
|
|||||||
</table>
|
</table>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<button class="btn primary" on:click={() => openEditModal(user)}>
|
<button class="btn primary" on:click={() => openEditModal(user)}>
|
||||||
<i class="fas fa-edit" />
|
<i class="fas fa-edit"></i>
|
||||||
{$t('edit')}
|
{$t('edit')}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn danger">
|
<button class="btn danger">
|
||||||
<i class="fas fa-trash" />
|
<i class="fas fa-trash"></i>
|
||||||
{$t('delete')}
|
{$t('delete')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<h2>{$t('subscriptions')}</h2>
|
<h2>{$t('subscriptions')}</h2>
|
||||||
<button class="btn primary" on:click={() => openEditModal(null)}>
|
<button class="btn primary" on:click={() => openEditModal(null)}>
|
||||||
<i class="fas fa-plus" />
|
<i class="fas fa-plus"></i>
|
||||||
{$t('add_new')}
|
{$t('add_new')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user