154 lines
5.1 KiB
Svelte
154 lines
5.1 KiB
Svelte
<script>
|
|
import { uploadLogo, getLicenseStatus, uploadLicense } from "../../lib/api";
|
|
import { addToast } from "../../lib/stores";
|
|
import { onMount } from "svelte";
|
|
|
|
let fileInput;
|
|
let previewSrc = "/api/logo?t=" + Date.now();
|
|
let uploading = false;
|
|
let licenseStatus = null;
|
|
let licFile;
|
|
|
|
onMount(async () => {
|
|
loadLicense();
|
|
});
|
|
|
|
async function loadLicense() {
|
|
try {
|
|
licenseStatus = await getLicenseStatus();
|
|
} catch (e) {}
|
|
}
|
|
|
|
async function handleLicenseUpload() {
|
|
if (!licFile.files[0]) return;
|
|
try {
|
|
await uploadLicense(licFile.files[0]);
|
|
addToast("Lizenzdatei hochgeladen", "success");
|
|
loadLicense();
|
|
} catch (e) {
|
|
addToast(e.message, "error");
|
|
}
|
|
}
|
|
|
|
async function handleFileChange(e) {
|
|
const file = e.target.files[0];
|
|
if (!file) return;
|
|
|
|
if (!file.type.startsWith("image/")) {
|
|
addToast("Bitte nur Bilder hochladen", "warning");
|
|
return;
|
|
}
|
|
|
|
uploading = true;
|
|
try {
|
|
await uploadLogo(file);
|
|
addToast("Logo aktualisiert", "success");
|
|
const timestamp = Date.now();
|
|
previewSrc = `/api/logo?t=${timestamp}`;
|
|
|
|
window.dispatchEvent(new Event("logo-updated"));
|
|
} catch (err) {
|
|
addToast(err.message, "error");
|
|
} finally {
|
|
uploading = false;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div class="card bg-base-100 shadow-xl border border-base-200 max-w-2xl">
|
|
<div class="card-body">
|
|
<h3 class="card-title text-lg mb-4">Schuleinstellungen</h3>
|
|
|
|
<div class="form-control w-full">
|
|
<label class="label">
|
|
<span class="label-text font-bold">Schul-Logo</span>
|
|
<span class="label-text-alt"
|
|
>Wird im Login und Dashboard angezeigt</span
|
|
>
|
|
</label>
|
|
|
|
<div class="flex items-center gap-6 mt-2">
|
|
<div
|
|
class="avatar placeholder border border-base-300 rounded-lg p-1 bg-base-200"
|
|
>
|
|
<div class="w-24 h-24 rounded-lg">
|
|
<img
|
|
src={previewSrc}
|
|
alt="Logo"
|
|
on:error={(e) => (e.target.style.display = "none")}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<input
|
|
type="file"
|
|
accept="image/png, image/jpeg"
|
|
class="file-input file-input-bordered file-input-primary w-full max-w-xs"
|
|
bind:this={fileInput}
|
|
on:change={handleFileChange}
|
|
disabled={uploading}
|
|
/>
|
|
<div class="text-xs text-base-content/50 mt-2">
|
|
Empfohlen: PNG mit transparentem Hintergrund.<br />
|
|
Max. 2MB.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card bg-base-100 shadow-xl border border-base-200 max-w-2xl mt-8">
|
|
<div class="card-body">
|
|
<h3 class="card-title text-lg mb-4">Lizenzierung</h3>
|
|
|
|
{#if licenseStatus}
|
|
<div
|
|
class="stats stats-vertical lg:stats-horizontal shadow mb-4 border border-base-200"
|
|
>
|
|
<div class="stat">
|
|
<div class="stat-title">Status</div>
|
|
<div
|
|
class="stat-value text-lg {licenseStatus.is_valid
|
|
? 'text-success'
|
|
: 'text-error'}"
|
|
>
|
|
{licenseStatus.is_valid ? "Aktiv" : "Ungültig"}
|
|
</div>
|
|
<div class="stat-desc">{licenseStatus.message}</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-title">Schule</div>
|
|
<div class="stat-value text-lg">
|
|
{licenseStatus.school_name || "-"}
|
|
</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-title">Gültig bis</div>
|
|
<div class="stat-value text-lg">
|
|
{licenseStatus.expires_at || "-"}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
|
|
<div class="form-control w-full">
|
|
<label class="label">
|
|
<span class="label-text font-bold"
|
|
>Lizenzdatei einspielen (.lic)</span
|
|
>
|
|
</label>
|
|
<div class="flex gap-4">
|
|
<input
|
|
type="file"
|
|
accept=".lic"
|
|
class="file-input file-input-bordered w-full"
|
|
bind:this={licFile}
|
|
/>
|
|
<button class="btn btn-primary" on:click={handleLicenseUpload}
|
|
>Hochladen</button
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|