Spaces:
Running
Running
Add 3 files
Browse files- README.md +7 -5
- index.html +396 -19
- prompts.txt +1 -0
README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: static
|
7 |
pinned: false
|
|
|
|
|
8 |
---
|
9 |
|
10 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: offerte-programma
|
3 |
+
emoji: 🐳
|
4 |
+
colorFrom: yellow
|
5 |
+
colorTo: purple
|
6 |
sdk: static
|
7 |
pinned: false
|
8 |
+
tags:
|
9 |
+
- deepsite
|
10 |
---
|
11 |
|
12 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
index.html
CHANGED
@@ -1,19 +1,396 @@
|
|
1 |
-
<!
|
2 |
-
<html>
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="nl">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>Offerte Generator</title>
|
7 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
8 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
9 |
+
<style>
|
10 |
+
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap');
|
11 |
+
|
12 |
+
body {
|
13 |
+
font-family: 'Roboto', sans-serif;
|
14 |
+
}
|
15 |
+
|
16 |
+
.a4-container {
|
17 |
+
width: 210mm;
|
18 |
+
min-height: 297mm;
|
19 |
+
margin: 0 auto;
|
20 |
+
background: white;
|
21 |
+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
22 |
+
position: relative;
|
23 |
+
}
|
24 |
+
|
25 |
+
.a4-content {
|
26 |
+
padding: 20mm;
|
27 |
+
}
|
28 |
+
|
29 |
+
.logo-placeholder {
|
30 |
+
width: 150px;
|
31 |
+
height: 80px;
|
32 |
+
background-color: #f3f4f6;
|
33 |
+
display: flex;
|
34 |
+
align-items: center;
|
35 |
+
justify-content: center;
|
36 |
+
color: #9ca3af;
|
37 |
+
border: 1px dashed #d1d5db;
|
38 |
+
}
|
39 |
+
|
40 |
+
.article-row {
|
41 |
+
transition: all 0.2s ease;
|
42 |
+
}
|
43 |
+
|
44 |
+
.article-row:hover {
|
45 |
+
background-color: #f9fafb;
|
46 |
+
}
|
47 |
+
|
48 |
+
.remove-article {
|
49 |
+
opacity: 0;
|
50 |
+
transition: opacity 0.2s ease;
|
51 |
+
}
|
52 |
+
|
53 |
+
.article-row:hover .remove-article {
|
54 |
+
opacity: 1;
|
55 |
+
}
|
56 |
+
|
57 |
+
@media print {
|
58 |
+
body * {
|
59 |
+
visibility: hidden;
|
60 |
+
}
|
61 |
+
.a4-container, .a4-container * {
|
62 |
+
visibility: visible;
|
63 |
+
}
|
64 |
+
.a4-container {
|
65 |
+
position: absolute;
|
66 |
+
left: 0;
|
67 |
+
top: 0;
|
68 |
+
width: 100%;
|
69 |
+
box-shadow: none;
|
70 |
+
}
|
71 |
+
.no-print {
|
72 |
+
display: none !important;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
</style>
|
76 |
+
</head>
|
77 |
+
<body class="bg-gray-100 p-4">
|
78 |
+
<div class="container mx-auto">
|
79 |
+
<h1 class="text-3xl font-bold text-center mb-8 text-gray-800">Offerte Generator</h1>
|
80 |
+
|
81 |
+
<div class="flex flex-col lg:flex-row gap-8">
|
82 |
+
<!-- Formulier -->
|
83 |
+
<div class="w-full lg:w-1/3 bg-white p-6 rounded-lg shadow-md no-print">
|
84 |
+
<h2 class="text-xl font-semibold mb-4 text-gray-700">Offertegegevens</h2>
|
85 |
+
|
86 |
+
<div class="space-y-4">
|
87 |
+
<div>
|
88 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Bedrijfsnaam</label>
|
89 |
+
<input type="text" id="company-name" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
90 |
+
</div>
|
91 |
+
|
92 |
+
<div>
|
93 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Klantnaam</label>
|
94 |
+
<input type="text" id="customer-name" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
95 |
+
</div>
|
96 |
+
|
97 |
+
<div>
|
98 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Offertenummer</label>
|
99 |
+
<input type="text" id="quote-number" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" value="Q-2023-001">
|
100 |
+
</div>
|
101 |
+
|
102 |
+
<div>
|
103 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Datum</label>
|
104 |
+
<input type="date" id="quote-date" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
105 |
+
</div>
|
106 |
+
|
107 |
+
<div>
|
108 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Vervaldatum</label>
|
109 |
+
<input type="date" id="expiry-date" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
110 |
+
</div>
|
111 |
+
|
112 |
+
<div class="pt-4 border-t border-gray-200">
|
113 |
+
<h3 class="text-lg font-medium text-gray-700 mb-2">Artikelen</h3>
|
114 |
+
|
115 |
+
<div id="articles-container">
|
116 |
+
<!-- Artikelen worden hier toegevoegd -->
|
117 |
+
</div>
|
118 |
+
|
119 |
+
<button id="add-article" class="mt-2 w-full bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-md transition duration-200">
|
120 |
+
Artikel toevoegen
|
121 |
+
</button>
|
122 |
+
</div>
|
123 |
+
</div>
|
124 |
+
|
125 |
+
<div class="mt-6 flex gap-2">
|
126 |
+
<button id="generate-pdf" class="flex-1 bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded-md transition duration-200">
|
127 |
+
Download als Afbeelding
|
128 |
+
</button>
|
129 |
+
<button id="print-quote" class="flex-1 bg-gray-500 hover:bg-gray-600 text-white py-2 px-4 rounded-md transition duration-200 no-print">
|
130 |
+
Afdrukken
|
131 |
+
</button>
|
132 |
+
</div>
|
133 |
+
</div>
|
134 |
+
|
135 |
+
<!-- Offerte preview -->
|
136 |
+
<div class="w-full lg:w-2/3 flex justify-center">
|
137 |
+
<div id="quote-preview" class="a4-container">
|
138 |
+
<div class="a4-content">
|
139 |
+
<!-- Header -->
|
140 |
+
<div class="flex justify-between items-start mb-8">
|
141 |
+
<div class="logo-placeholder">
|
142 |
+
Logo hier
|
143 |
+
</div>
|
144 |
+
|
145 |
+
<div class="text-right">
|
146 |
+
<h1 id="preview-company-name" class="text-2xl font-bold text-gray-800">Bedrijfsnaam</h1>
|
147 |
+
<p class="text-gray-600">Offerte</p>
|
148 |
+
</div>
|
149 |
+
</div>
|
150 |
+
|
151 |
+
<!-- Klantgegevens -->
|
152 |
+
<div class="mb-8">
|
153 |
+
<div class="bg-gray-100 p-4 rounded-md">
|
154 |
+
<h2 class="font-medium text-gray-700 mb-2">Aan:</h2>
|
155 |
+
<p id="preview-customer-name" class="text-gray-800">Klantnaam</p>
|
156 |
+
</div>
|
157 |
+
</div>
|
158 |
+
|
159 |
+
<!-- Offerte details -->
|
160 |
+
<div class="flex justify-between mb-8">
|
161 |
+
<div>
|
162 |
+
<p class="text-gray-600"><span class="font-medium">Offertenummer:</span> <span id="preview-quote-number">Q-2023-001</span></p>
|
163 |
+
<p class="text-gray-600"><span class="font-medium">Datum:</span> <span id="preview-quote-date">01-01-2023</span></p>
|
164 |
+
<p class="text-gray-600"><span class="font-medium">Vervaldatum:</span> <span id="preview-expiry-date">15-01-2023</span></p>
|
165 |
+
</div>
|
166 |
+
</div>
|
167 |
+
|
168 |
+
<!-- Artikellijst -->
|
169 |
+
<div class="mb-8">
|
170 |
+
<table class="w-full border-collapse">
|
171 |
+
<thead>
|
172 |
+
<tr class="bg-gray-100">
|
173 |
+
<th class="text-left py-2 px-4 border border-gray-200 font-medium text-gray-700">Omschrijving</th>
|
174 |
+
<th class="text-right py-2 px-4 border border-gray-200 font-medium text-gray-700">Aantal</th>
|
175 |
+
<th class="text-right py-2 px-4 border border-gray-200 font-medium text-gray-700">Prijs</th>
|
176 |
+
<th class="text-right py-2 px-4 border border-gray-200 font-medium text-gray-700">Totaal</th>
|
177 |
+
</tr>
|
178 |
+
</thead>
|
179 |
+
<tbody id="preview-articles">
|
180 |
+
<!-- Artikelen worden hier toegevoegd -->
|
181 |
+
<tr>
|
182 |
+
<td colspan="4" class="py-4 text-center text-gray-500">Voeg artikelen toe</td>
|
183 |
+
</tr>
|
184 |
+
</tbody>
|
185 |
+
<tfoot>
|
186 |
+
<tr>
|
187 |
+
<td colspan="3" class="text-right py-2 px-4 border border-gray-200 font-medium text-gray-700">Subtotaal</td>
|
188 |
+
<td id="subtotal" class="text-right py-2 px-4 border border-gray-200">€0.00</td>
|
189 |
+
</tr>
|
190 |
+
<tr>
|
191 |
+
<td colspan="3" class="text-right py-2 px-4 border border-gray-200 font-medium text-gray-700">BTW (21%)</td>
|
192 |
+
<td id="vat" class="text-right py-2 px-4 border border-gray-200">€0.00</td>
|
193 |
+
</tr>
|
194 |
+
<tr class="bg-gray-100">
|
195 |
+
<td colspan="3" class="text-right py-2 px-4 border border-gray-200 font-bold text-gray-700">Totaal</td>
|
196 |
+
<td id="total" class="text-right py-2 px-4 border border-gray-200 font-bold">€0.00</td>
|
197 |
+
</tr>
|
198 |
+
</tfoot>
|
199 |
+
</table>
|
200 |
+
</div>
|
201 |
+
|
202 |
+
<!-- Opmerkingen -->
|
203 |
+
<div class="mb-8">
|
204 |
+
<h2 class="font-medium text-gray-700 mb-2">Opmerkingen</h2>
|
205 |
+
<p class="text-gray-600">Deze offerte is geldig tot de vervaldatum. Betaling binnen 14 dagen na facturering.</p>
|
206 |
+
</div>
|
207 |
+
|
208 |
+
<!-- Handtekening -->
|
209 |
+
<div class="mt-16">
|
210 |
+
<div class="pt-8 border-t border-gray-200 w-1/3">
|
211 |
+
<p class="text-gray-600">Handtekening</p>
|
212 |
+
</div>
|
213 |
+
</div>
|
214 |
+
</div>
|
215 |
+
</div>
|
216 |
+
</div>
|
217 |
+
</div>
|
218 |
+
</div>
|
219 |
+
|
220 |
+
<script>
|
221 |
+
document.addEventListener('DOMContentLoaded', function() {
|
222 |
+
// Stel vandaag in als standaarddatum
|
223 |
+
const today = new Date();
|
224 |
+
document.getElementById('quote-date').valueAsDate = today;
|
225 |
+
|
226 |
+
// Voeg 14 dagen toe voor vervaldatum
|
227 |
+
const expiryDate = new Date();
|
228 |
+
expiryDate.setDate(today.getDate() + 14);
|
229 |
+
document.getElementById('expiry-date').valueAsDate = expiryDate;
|
230 |
+
|
231 |
+
// Update preview bij input wijzigingen
|
232 |
+
document.getElementById('company-name').addEventListener('input', updatePreview);
|
233 |
+
document.getElementById('customer-name').addEventListener('input', updatePreview);
|
234 |
+
document.getElementById('quote-number').addEventListener('input', updatePreview);
|
235 |
+
document.getElementById('quote-date').addEventListener('input', updatePreview);
|
236 |
+
document.getElementById('expiry-date').addEventListener('input', updatePreview);
|
237 |
+
|
238 |
+
// Voeg een artikel toe
|
239 |
+
document.getElementById('add-article').addEventListener('click', addArticle);
|
240 |
+
|
241 |
+
// Genereer PDF
|
242 |
+
document.getElementById('generate-pdf').addEventListener('click', generateImage);
|
243 |
+
|
244 |
+
// Afdrukken
|
245 |
+
document.getElementById('print-quote').addEventListener('click', function() {
|
246 |
+
window.print();
|
247 |
+
});
|
248 |
+
|
249 |
+
// Initialiseer preview
|
250 |
+
updatePreview();
|
251 |
+
|
252 |
+
// Voeg een standaard artikel toe
|
253 |
+
addArticle();
|
254 |
+
|
255 |
+
function updatePreview() {
|
256 |
+
document.getElementById('preview-company-name').textContent = document.getElementById('company-name').value || 'Bedrijfsnaam';
|
257 |
+
document.getElementById('preview-customer-name').textContent = document.getElementById('customer-name').value || 'Klantnaam';
|
258 |
+
document.getElementById('preview-quote-number').textContent = document.getElementById('quote-number').value || 'Q-2023-001';
|
259 |
+
|
260 |
+
const quoteDate = document.getElementById('quote-date').valueAsDate;
|
261 |
+
if (quoteDate) {
|
262 |
+
document.getElementById('preview-quote-date').textContent = formatDate(quoteDate);
|
263 |
+
}
|
264 |
+
|
265 |
+
const expiryDate = document.getElementById('expiry-date').valueAsDate;
|
266 |
+
if (expiryDate) {
|
267 |
+
document.getElementById('preview-expiry-date').textContent = formatDate(expiryDate);
|
268 |
+
}
|
269 |
+
}
|
270 |
+
|
271 |
+
function formatDate(date) {
|
272 |
+
const day = String(date.getDate()).padStart(2, '0');
|
273 |
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
274 |
+
const year = date.getFullYear();
|
275 |
+
return `${day}-${month}-${year}`;
|
276 |
+
}
|
277 |
+
|
278 |
+
function addArticle() {
|
279 |
+
const articleId = Date.now();
|
280 |
+
|
281 |
+
// Voeg artikel toe aan formulier
|
282 |
+
const articlesContainer = document.getElementById('articles-container');
|
283 |
+
const articleDiv = document.createElement('div');
|
284 |
+
articleDiv.className = 'article-row bg-gray-50 p-3 rounded-md mb-2 relative';
|
285 |
+
articleDiv.dataset.id = articleId;
|
286 |
+
articleDiv.innerHTML = `
|
287 |
+
<div class="grid grid-cols-12 gap-2">
|
288 |
+
<div class="col-span-6">
|
289 |
+
<input type="text" placeholder="Omschrijving" class="article-description w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
|
290 |
+
</div>
|
291 |
+
<div class="col-span-2">
|
292 |
+
<input type="number" placeholder="Aantal" min="1" value="1" class="article-quantity w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
|
293 |
+
</div>
|
294 |
+
<div class="col-span-2">
|
295 |
+
<input type="number" placeholder="Prijs" min="0" step="0.01" value="0.00" class="article-price w-full px-2 py-1 border border-gray-300 rounded-md text-sm">
|
296 |
+
</div>
|
297 |
+
<div class="col-span-2 flex items-center">
|
298 |
+
<span class="article-total text-sm font-medium">€0.00</span>
|
299 |
+
<button class="remove-article ml-2 text-red-500 hover:text-red-700 text-sm absolute right-2 top-1/2 transform -translate-y-1/2">
|
300 |
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
301 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
302 |
+
</svg>
|
303 |
+
</button>
|
304 |
+
</div>
|
305 |
+
</div>
|
306 |
+
`;
|
307 |
+
articlesContainer.appendChild(articleDiv);
|
308 |
+
|
309 |
+
// Voeg event listeners toe voor berekeningen
|
310 |
+
const descriptionInput = articleDiv.querySelector('.article-description');
|
311 |
+
const quantityInput = articleDiv.querySelector('.article-quantity');
|
312 |
+
const priceInput = articleDiv.querySelector('.article-price');
|
313 |
+
const totalSpan = articleDiv.querySelector('.article-total');
|
314 |
+
const removeBtn = articleDiv.querySelector('.remove-article');
|
315 |
+
|
316 |
+
descriptionInput.addEventListener('input', updateArticlesPreview);
|
317 |
+
quantityInput.addEventListener('input', updateArticleTotal);
|
318 |
+
priceInput.addEventListener('input', updateArticleTotal);
|
319 |
+
|
320 |
+
removeBtn.addEventListener('click', function() {
|
321 |
+
articleDiv.remove();
|
322 |
+
updateArticlesPreview();
|
323 |
+
});
|
324 |
+
|
325 |
+
// Initialiseer artikel total
|
326 |
+
updateArticleTotal();
|
327 |
+
|
328 |
+
function updateArticleTotal() {
|
329 |
+
const quantity = parseFloat(quantityInput.value) || 0;
|
330 |
+
const price = parseFloat(priceInput.value) || 0;
|
331 |
+
const total = quantity * price;
|
332 |
+
totalSpan.textContent = `€${total.toFixed(2)}`;
|
333 |
+
updateArticlesPreview();
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
function updateArticlesPreview() {
|
338 |
+
const articlesContainer = document.getElementById('preview-articles');
|
339 |
+
articlesContainer.innerHTML = '';
|
340 |
+
|
341 |
+
const articleRows = document.querySelectorAll('.article-row');
|
342 |
+
let subtotal = 0;
|
343 |
+
|
344 |
+
if (articleRows.length === 0) {
|
345 |
+
articlesContainer.innerHTML = `
|
346 |
+
<tr>
|
347 |
+
<td colspan="4" class="py-4 text-center text-gray-500">Voeg artikelen toe</td>
|
348 |
+
</tr>
|
349 |
+
`;
|
350 |
+
} else {
|
351 |
+
articleRows.forEach(row => {
|
352 |
+
const description = row.querySelector('.article-description').value || 'Artikel';
|
353 |
+
const quantity = parseFloat(row.querySelector('.article-quantity').value) || 0;
|
354 |
+
const price = parseFloat(row.querySelector('.article-price').value) || 0;
|
355 |
+
const total = quantity * price;
|
356 |
+
subtotal += total;
|
357 |
+
|
358 |
+
const tr = document.createElement('tr');
|
359 |
+
tr.className = 'border-b border-gray-200';
|
360 |
+
tr.innerHTML = `
|
361 |
+
<td class="py-2 px-4 border border-gray-200">${description}</td>
|
362 |
+
<td class="py-2 px-4 border border-gray-200 text-right">${quantity}</td>
|
363 |
+
<td class="py-2 px-4 border border-gray-200 text-right">€${price.toFixed(2)}</td>
|
364 |
+
<td class="py-2 px-4 border border-gray-200 text-right">€${total.toFixed(2)}</td>
|
365 |
+
`;
|
366 |
+
articlesContainer.appendChild(tr);
|
367 |
+
});
|
368 |
+
}
|
369 |
+
|
370 |
+
const vat = subtotal * 0.21;
|
371 |
+
const total = subtotal + vat;
|
372 |
+
|
373 |
+
document.getElementById('subtotal').textContent = `€${subtotal.toFixed(2)}`;
|
374 |
+
document.getElementById('vat').textContent = `€${vat.toFixed(2)}`;
|
375 |
+
document.getElementById('total').textContent = `€${total.toFixed(2)}`;
|
376 |
+
}
|
377 |
+
|
378 |
+
function generateImage() {
|
379 |
+
const quotePreview = document.getElementById('quote-preview');
|
380 |
+
|
381 |
+
html2canvas(quotePreview, {
|
382 |
+
scale: 2,
|
383 |
+
logging: false,
|
384 |
+
useCORS: true,
|
385 |
+
allowTaint: true
|
386 |
+
}).then(canvas => {
|
387 |
+
const link = document.createElement('a');
|
388 |
+
link.download = `offerte-${document.getElementById('quote-number').value || 'Q-2023-001'}.png`;
|
389 |
+
link.href = canvas.toDataURL('image/png');
|
390 |
+
link.click();
|
391 |
+
});
|
392 |
+
}
|
393 |
+
});
|
394 |
+
</script>
|
395 |
+
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=jitware/offerte-programma" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
|
396 |
+
</html>
|
prompts.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
schrijf mij een eenvoudige app in tailwind die met dezelfde opmaak van in de bijlage een eenvoudige offerte opmaakt en dit omzet in een A4 afbeelding, waarbij artikel velden kunnen worden toegevoegd in css,html, node, css tailwind
|