jitware commited on
Commit
9d7e09e
·
verified ·
1 Parent(s): 7d0332d

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +396 -19
  3. prompts.txt +1 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Offerte Programma
3
- emoji: 📈
4
- colorFrom: gray
5
- colorTo: red
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
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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