PDF Designer

This commit is contained in:
Moritz Utcke
2024-02-23 11:51:59 +07:00
parent 06b423a22e
commit 9a92eaa92c
16 changed files with 1750 additions and 46 deletions

View File

@@ -0,0 +1,34 @@
<script lang="ts">
import DashboardAdminAusweis from "#components/Dashboard/Admin/DashboardAdminAusweis.svelte";
import DashboardAusweis from "#components/Dashboard/DashboardAusweis.svelte";
import DashboardAusweisSkeleton from "#components/Dashboard/DashboardAusweisSkeleton.svelte";
import { client } from "src/trpc";
let ausweisRequest = client.v1.benutzer.getAusweise.query({
limit: 10
});
</script>
<h1 class="text-4xl font-medium my-8">Ausweise</h1>
<div class="grid xl:grid-cols-2 grid-cols-1 gap-4">
{#await ausweisRequest}
<DashboardAusweisSkeleton></DashboardAusweisSkeleton>
<DashboardAusweisSkeleton></DashboardAusweisSkeleton>
{:then ausweise}
{#if ausweise.length == 0}
<div class="">
<h1 class="text-2xl">Es konnten keine Ausweise gefunden werden.</h1>
<p>Erstellen sie einen Verbrauchsausweis für ihr Wohngebäude <a href="/energieausweis-erstellen/verbrauchsausweis-wohnen">hier</a></p>
</div>
{:else}
{#each ausweise as ausweis}
<DashboardAdminAusweis {ausweis}></DashboardAdminAusweis>
{/each}
{/if}
{/await}
</div>

View File

@@ -0,0 +1,98 @@
<script lang="ts">
import { Designer } from "@pdfme/ui";
import { onMount } from "svelte";
import { Template, BLANK_PDF } from "@pdfme/common";
let template: Template = {
basePdf: BLANK_PDF,
schemas: [
{
},
],
};
let container: HTMLDivElement;
let designer: Designer;
onMount(() => {
designer = new Designer({ domContainer: container, template });
});
function loadBasePDF() {
if (!loadTemplateInput.files) return;
const file = loadTemplateInput.files[0];
const reader = new FileReader();
reader.onload = function (e) {
if (!e.target) return;
const basePdf = e.target.result as string;
const newTemplate = { ...template, basePdf };
designer = new Designer({ domContainer: container, template: newTemplate });
};
reader.readAsDataURL(file);
}
function addNewField() {
template = designer.getTemplate();
template.schemas[0]["new-field"] = {
type: "text",
position: { x: 0, y: 0 },
width: 10,
height: 10
};
designer.updateTemplate(template);
}
function exportTemplate() {
const template = designer.getTemplate();
const blob = new Blob([JSON.stringify(template)], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "template.json";
a.click();
}
function loadTemplate() {
const input = document.createElement("input");
input.type = "file";
input.accept = ".json";
input.onchange = function (e) {
if (!input.files) return;
const file = input.files[0];
const reader = new FileReader();
reader.onload = function (e) {
if (!e.target) return;
const template = JSON.parse(e.target.result as string) as Template;
designer = new Designer({ domContainer: container, template });
};
reader.readAsText(file);
};
input.click()
}
let loadTemplateInput: HTMLInputElement;
</script>
<header>
<button class="btn btn-secondary" on:click={() => loadTemplateInput.click()}>Change base PDF</button>
<button class="btn btn-secondary" on:click={addNewField}>Add new Field</button>
<button class="btn btn-secondary" on:click={exportTemplate}>Export</button>
<button class="btn btn-secondary" on:click={loadTemplate}>Load Template</button>
<a class="btn btn-secondary" href="/dashboard/admin/pdf-viewer">Test in Viewer</a>
<input type="file" hidden bind:this={loadTemplateInput} on:change={loadBasePDF}>
</header>
<div bind:this={container}></div>

View File

@@ -0,0 +1,95 @@
<script lang="ts">
import { Benutzer, GebaeudeStammdaten, Rechnungen, VerbrauchsausweisWohnen } from "@ibcornelsen/database/client";
import { Template } from "@pdfme/common";
import { Viewer } from "@pdfme/ui";
type AusweisData = VerbrauchsausweisWohnen & { benutzer: Benutzer, gebaeude_stammdaten: GebaeudeStammdaten, rechnungen: Rechnungen }
export let ausweise: AusweisData[];
let pdfInputs: AusweisData;
let template: Template;
let viewer: Viewer
function convertAusweisData(inputs: AusweisData): Record<string, string> {
return {
"gebaeude_stammdaten.adresse": inputs.gebaeude_stammdaten.adresse || "",
"gebaeude_stammdaten.gebaeudetyp": inputs.gebaeude_stammdaten.gebaeudetyp || "",
"gebaeude_stammdaten.baujahr_gebaeude": inputs.gebaeude_stammdaten.baujahr_gebaeude.join(", ") || "",
"gebaeude_stammdaten.baujahr_heizung": inputs.gebaeude_stammdaten.baujahr_heizung.join(", ") || "",
"gebaeude_stammdaten.plz": inputs.gebaeude_stammdaten.plz || "",
"gebaeude_stammdaten.ort": inputs.gebaeude_stammdaten.ort || "",
}
}
function loadTemplate() {
const input = document.createElement("input");
input.type = "file";
input.accept = ".json";
input.onchange = function (e) {
if (!input.files) return;
const file = input.files[0];
const reader = new FileReader();
reader.onload = async function (e) {
if (!e.target) return;
template = JSON.parse(e.target.result as string) as Template;
if (!pdfInputs) {
alert("Bitte wählen Sie einen Ausweis aus, um diesen als Basis zu verwenden.")
return
};
viewer = new Viewer({
domContainer: pdfViewerContainer,
template,
inputs: [convertAusweisData(pdfInputs)]
})
};
reader.readAsText(file);
};
input.click();
}
function changeInputs(inputs: AusweisData) {
pdfInputs = inputs;
if (!template) {
alert("Bitte laden Sie zuerst ein Template.")
return
}
viewer = new Viewer({
domContainer: pdfViewerContainer,
template,
inputs: [convertAusweisData(pdfInputs)]
})
}
let pdfViewerContainer: HTMLDivElement;
</script>
<header>
<div>
<button class="btn btn-secondary" on:click={loadTemplate}>Load Template</button>
</div>
</header>
<main class="grid grid-cols-[1fr_4fr]">
<div>
<h1>Ausweise</h1>
{#each ausweise as ausweis}
<div>
<h2 class="text-black">{ausweis.gebaeude_stammdaten.adresse}</h2>
<button class="btn btn-secondary" on:click={() => {
changeInputs(ausweis)
}}>Diesen Ausweis als Basis nehmen</button>
</div>
{/each}
</div>
<div bind:this={pdfViewerContainer}></div>
</main>