@cenk1cenk2/md-printer 2.20.12 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +332 -48
  2. package/dist/_virtual/_@oxc-project_runtime@0.153.0/helpers/esm/decorate.mjs +1 -2
  3. package/dist/_virtual/_@oxc-project_runtime@0.153.0/helpers/esm/decorateMetadata.mjs +1 -2
  4. package/dist/_virtual/_@oxc-project_runtime@0.153.0/helpers/esm/decorateParam.mjs +8 -0
  5. package/dist/commands/index.mjs +136 -257
  6. package/dist/components/Date.svelte +1 -0
  7. package/dist/components/Markdown.svelte +20 -0
  8. package/dist/components/Nodes.svelte +32 -0
  9. package/dist/components/Page.svelte +20 -0
  10. package/dist/components/PageBreak.svelte +5 -0
  11. package/dist/components/PageNumber.svelte +1 -0
  12. package/dist/components/SignatureBlock.svelte +56 -0
  13. package/dist/components/Title.svelte +1 -0
  14. package/dist/components/TotalPages.svelte +1 -0
  15. package/dist/components/index.ts +8 -0
  16. package/dist/constants/file.constants.mjs +1 -8
  17. package/dist/constants/index.mjs +3 -4
  18. package/dist/constants/template.constants.mjs +48 -10
  19. package/dist/interfaces/commands/index.mjs +1 -1
  20. package/dist/interfaces/commands/run.interface.mjs +1 -1
  21. package/dist/interfaces/index.mjs +1 -1
  22. package/dist/interfaces/markdown.interface.mjs +1 -0
  23. package/dist/interfaces/renderer.interface.mjs +1 -0
  24. package/dist/interfaces/session.interface.mjs +1 -0
  25. package/dist/interfaces/signature.interface.mjs +1 -0
  26. package/dist/interfaces/template.interface.mjs +1 -0
  27. package/dist/services/i18n.service.mjs +4 -8
  28. package/dist/services/index.mjs +13 -2
  29. package/dist/services/loopback.mjs +18 -0
  30. package/dist/services/markdown.service.mjs +123 -0
  31. package/dist/services/printer.module.mjs +41 -0
  32. package/dist/services/printer.service.mjs +171 -0
  33. package/dist/services/renderer/browser.mjs +41 -0
  34. package/dist/services/renderer/browser.service.mjs +56 -0
  35. package/dist/services/renderer/renderer.service.mjs +198 -0
  36. package/dist/services/session/Preview.svelte +238 -0
  37. package/dist/services/session/preview.service.mjs +187 -0
  38. package/dist/services/session/session.service.mjs +115 -0
  39. package/dist/services/signature/adapters/a-trust.adapter.mjs +106 -0
  40. package/dist/services/signature/adapters/a-trust.html +77 -0
  41. package/dist/services/signature/index.mjs +4 -0
  42. package/dist/services/signature/signature.adapter.mjs +4 -0
  43. package/dist/services/signature/signature.service.mjs +95 -0
  44. package/dist/services/template/Document.svelte +21 -0
  45. package/dist/services/template/Margin.svelte +15 -0
  46. package/dist/services/template/assets.mjs +127 -0
  47. package/dist/services/template/render.entry.ts +32 -0
  48. package/dist/services/template/svelte.plugin.mjs +66 -0
  49. package/dist/services/template/template.service.mjs +211 -0
  50. package/oclif.manifest.json +64 -33
  51. package/package.json +70 -35
  52. package/templates/default/Template.svelte +83 -0
  53. package/templates/default/settings.json +1 -3
  54. package/templates/invoice/Template.svelte +247 -0
  55. package/templates/invoice/components/Client.svelte +42 -0
  56. package/templates/invoice/components/Company.svelte +41 -0
  57. package/templates/invoice/components/Items.svelte +66 -0
  58. package/templates/invoice/components/Notes.svelte +21 -0
  59. package/templates/invoice/components/Payment.svelte +25 -0
  60. package/templates/invoice/components/Signature.svelte +34 -0
  61. package/templates/invoice/components/Totals.svelte +47 -0
  62. package/templates/invoice/i18n/de.yaml +6 -0
  63. package/templates/invoice/i18n/en.yaml +6 -0
  64. package/templates/invoice/round.js +2 -0
  65. package/templates/invoice/settings.json +1 -4
  66. package/templates/kilic.dev/Template.svelte +102 -0
  67. package/templates/kilic.dev/settings.json +1 -3
  68. package/templates/mail/Template.svelte +166 -0
  69. package/templates/mail/settings.json +1 -3
  70. package/dist/hooks/not-found.hook.mjs +0 -7
  71. package/dist/hooks/update-notifier.hook.mjs +0 -7
  72. package/dist/interfaces/pupeteer.mjs +0 -1
  73. package/templates/default/main.css +0 -73
  74. package/templates/invoice/.gitignore +0 -1
  75. package/templates/invoice/footer.html +0 -18
  76. package/templates/invoice/tailwind.css +0 -164
  77. package/templates/invoice/template.html.j2 +0 -189
  78. package/templates/kilic.dev/footer.html +0 -26
  79. package/templates/kilic.dev/header.html +0 -16
  80. package/templates/kilic.dev/main.css +0 -74
  81. package/templates/mail/.gitignore +0 -1
  82. package/templates/mail/tailwind.css +0 -145
  83. package/templates/mail/template.html.j2 +0 -14
@@ -0,0 +1,166 @@
1
+ <script>
2
+ import { Page } from '@cenk1cenk2/md-printer/components'
3
+
4
+ let { content } = $props()
5
+ </script>
6
+
7
+ <svelte:head>
8
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
9
+ <meta charset="UTF-8" />
10
+ </svelte:head>
11
+
12
+ <Page>
13
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -- markdown input is trusted, same as the document itself -->
14
+ <div class="leading-tight prose">{@html content}</div>
15
+ </Page>
16
+
17
+ <style lang="postcss">
18
+ @import '@fontsource/montserrat/latin-400.css';
19
+ @import '@fontsource/montserrat/latin-ext-400.css';
20
+ @import '@fontsource/montserrat/latin-700.css';
21
+ @import '@fontsource/montserrat/latin-ext-700.css';
22
+
23
+ @import 'tailwindcss';
24
+ @plugin '@tailwindcss/typography';
25
+
26
+ @theme {
27
+ --font-sans: 'Montserrat';
28
+ --font-serif: 'Montserrat';
29
+ --font-weight-semibold: 700;
30
+ --font-weight-bold: 800;
31
+ --font-weight-extrabold: 900;
32
+ --color-primary-500: #cd0043;
33
+ --color-gray-50: oklch(98.5% 0.002 247.839);
34
+ --color-gray-100: #abb2bf;
35
+ --color-gray-200: #979eab;
36
+ --color-gray-300: #7c8a9d;
37
+ --color-gray-400: #5c6370;
38
+ --color-gray-500: #4b5263;
39
+ --color-gray-600: #2c333d;
40
+ --color-gray-700: #22282f;
41
+ --color-gray-800: #1e2127;
42
+ --color-gray-900: #17191e;
43
+ --color-gray-950: oklch(13% 0.028 261.692);
44
+ }
45
+
46
+ *,
47
+ ::after,
48
+ ::before,
49
+ ::backdrop,
50
+ ::file-selector-button {
51
+ border-color: var(--color-gray-200, currentcolor);
52
+ }
53
+
54
+ body {
55
+ font-family: var(--font-sans);
56
+ }
57
+
58
+ address {
59
+ @apply text-sm;
60
+ }
61
+
62
+ /* Typography styles converted from config */
63
+ .prose a {
64
+ text-decoration: none;
65
+ }
66
+
67
+ .prose h1 {
68
+ font-weight: 800;
69
+ padding-top: 0.1875rem;
70
+ /* 0.75 * 0.25rem */
71
+ padding-bottom: 0.1875rem;
72
+ margin-bottom: 0;
73
+ margin-top: 0;
74
+ border-width: 0;
75
+ }
76
+
77
+ .prose h2 {
78
+ font-weight: 800;
79
+ padding-top: 0.125rem;
80
+ /* 0.5 * 0.25rem */
81
+ padding-bottom: 0.125rem;
82
+ margin-bottom: 0;
83
+ margin-top: 0;
84
+ border-width: 0;
85
+ }
86
+
87
+ .prose h3 {
88
+ font-weight: 700;
89
+ padding-top: 0.0625rem;
90
+ /* 0.25 * 0.25rem */
91
+ padding-bottom: 0.0625rem;
92
+ margin-bottom: 0;
93
+ margin-top: 0;
94
+ border-width: 0;
95
+ }
96
+
97
+ p {
98
+ margin: 0.1em 0em;
99
+ }
100
+
101
+ .prose blockquote {
102
+ font-weight: 400;
103
+ color: var(--color-gray-600);
104
+ font-style: normal;
105
+ quotes: '\201C' '\201D' '\2018' '\2019';
106
+ }
107
+
108
+ .prose blockquote p:first-of-type::before {
109
+ content: '';
110
+ }
111
+
112
+ .prose blockquote p:last-of-type::after {
113
+ content: '';
114
+ }
115
+
116
+ .prose ul > li {
117
+ padding-left: 1em;
118
+ text-align: left;
119
+ }
120
+
121
+ .prose ol > li {
122
+ padding-left: 1em;
123
+ text-align: left;
124
+ }
125
+
126
+ .prose ol > li::before {
127
+ top: calc(0.875em - 0.1em);
128
+ }
129
+
130
+ .prose ul > li::before {
131
+ top: calc(0.875em - 0.1em);
132
+ }
133
+
134
+ html {
135
+ font-size: 12px;
136
+ }
137
+
138
+ .page-break {
139
+ page-break-after: always;
140
+ }
141
+
142
+ .text-vertical {
143
+ text-orientation: upright;
144
+ writing-mode: vertical-lr;
145
+ display: flex;
146
+ flex-direction: column;
147
+ justify-content: center;
148
+ @apply p-4;
149
+ }
150
+
151
+ table th {
152
+ @apply bg-gray-700 text-white;
153
+ }
154
+
155
+ table tr {
156
+ border-top: 0;
157
+ @apply even:bg-gray-50;
158
+ }
159
+
160
+ table th,
161
+ table td,
162
+ table tr {
163
+ border: 0;
164
+ padding: 0.5em 0.5em;
165
+ }
166
+ </style>
@@ -1,7 +1,5 @@
1
1
  {
2
- "body_class": [],
3
- "highlight_style": "atom-one-dark",
4
- "pdf_options": {
2
+ "pdfOptions": {
5
3
  "format": "A4",
6
4
  "margin": "0",
7
5
  "printBackground": true
@@ -1,7 +0,0 @@
1
- import { notFoundHook } from "@cenk1cenk2/oclif-common";
2
-
3
- //#region src/hooks/not-found.hook.ts
4
- var not_found_hook_default = notFoundHook;
5
-
6
- //#endregion
7
- export { not_found_hook_default as default };
@@ -1,7 +0,0 @@
1
- import { updateNotifierHook } from "@cenk1cenk2/oclif-common";
2
-
3
- //#region src/hooks/update-notifier.hook.ts
4
- var update_notifier_hook_default = updateNotifierHook;
5
-
6
- //#endregion
7
- export { update_notifier_hook_default as default };
@@ -1 +0,0 @@
1
- export { };
@@ -1,73 +0,0 @@
1
- @import url(https://unpkg.com/github-markdown-css/github-markdown-light.css);
2
- @import url('https://fonts.bunny.net/css?family=montserrat:100,200,300,400,500,600,700,800,900&display=swap');
3
- @import url(https://fonts.googleapis.com/css2?family=Roboto+Mono);
4
-
5
- .markdown-body {
6
- font-size: 11px;
7
- font-family: 'Montserrat', sans-serif;
8
- }
9
-
10
- .markdown-body h1,
11
- .markdown-body h2 {
12
- font-weight: 800;
13
- }
14
-
15
- .markdown-body h3,
16
- .markdown-body h4,
17
- .markdown-body h5,
18
- .markdown-body h6,
19
- .markdown-body strong,
20
- .markdown-body b {
21
- font-weight: 700;
22
- }
23
-
24
- .page-break {
25
- page-break-after: always;
26
- }
27
-
28
- .markdown-body pre > code {
29
- white-space: pre-wrap;
30
- padding: 0;
31
- margin: 0;
32
-
33
- font-family: 'Roboto Mono', monospace;
34
- }
35
-
36
- .markdown-body .document-title-header {
37
- height: 500px;
38
- margin: auto auto;
39
- padding-top: 50%;
40
- page-break-after: always;
41
- border-bottom: 0;
42
- font-size: 2.5em;
43
- }
44
-
45
- .markdown-body pre {
46
- background-color: #1e2127;
47
- padding: 12px 8px;
48
- }
49
-
50
- .markdown-body output pre {
51
- margin-top: -36px;
52
- background-color: #1e2127;
53
- border-top-left-radius: 0;
54
- border-top-right-radius: 0;
55
- border-top-color: #38404b;
56
- border-top-width: 2px;
57
- border-top-style: solid;
58
- }
59
-
60
- .markdown-body output::before {
61
- padding: 4px 16px;
62
- position: relative;
63
- top: -24px;
64
- border-top-left-radius: 4px;
65
- border-top-right-radius: 4px;
66
- color: #a0a0a0;
67
- background-color: #1e2127;
68
- content: '> output';
69
- font-size: 0.85em;
70
- border-top-color: #38404b;
71
- border-top-width: 2px;
72
- border-top-style: solid;
73
- }
@@ -1 +0,0 @@
1
- /main.css
@@ -1,18 +0,0 @@
1
- <style>
2
- footer {
3
- margin: 0 auto;
4
- text-align: center;
5
- font-size: 8px;
6
- color: #38404b;
7
- width: 100%;
8
- padding-top: 8px;
9
- margin-bottom: -8px;
10
- }
11
- </style>
12
- <footer>
13
- <div>
14
- <span class="title"></span>
15
- -
16
- <b> <span class="pageNumber"></span>/<span class="totalPages"></span> </b>
17
- </div>
18
- </footer>
@@ -1,164 +0,0 @@
1
- @import url('https://fonts.bunny.net/css?family=montserrat:100,200,300,400,500,600,700,800,900&display=swap');
2
-
3
- @import 'tailwindcss';
4
- @plugin '@tailwindcss/typography';
5
-
6
- @theme {
7
- --font-sans: 'Montserrat';
8
- --font-serif: 'Montserrat';
9
- --font-weight-semibold: 700;
10
- --font-weight-bold: 800;
11
- --font-weight-extrabold: 900;
12
- --color-primary-500: #cd0043;
13
- --color-gray-50: oklch(98.5% 0.002 247.839);
14
- --color-gray-100: #abb2bf;
15
- --color-gray-200: #979eab;
16
- --color-gray-300: #7c8a9d;
17
- --color-gray-400: #5c6370;
18
- --color-gray-500: #4b5263;
19
- --color-gray-600: #2c333d;
20
- --color-gray-700: #22282f;
21
- --color-gray-800: #1e2127;
22
- --color-gray-900: #17191e;
23
- --color-gray-950: oklch(13% 0.028 261.692);
24
- }
25
-
26
- *,
27
- ::after,
28
- ::before,
29
- ::backdrop,
30
- ::file-selector-button {
31
- border-color: var(--color-gray-200, currentcolor);
32
- }
33
-
34
- body {
35
- font-family: var(--font-sans);
36
- }
37
-
38
- address {
39
- @apply text-sm;
40
- white-space: pre-line;
41
- }
42
-
43
- /* Typography styles converted from config */
44
- .prose a {
45
- text-decoration: none;
46
- }
47
-
48
- .prose h1 {
49
- font-weight: 800;
50
- padding-top: 0.1875rem;
51
- /* 0.75 * 0.25rem */
52
- padding-bottom: 0.1875rem;
53
- margin-bottom: 0;
54
- margin-top: 0;
55
- border-width: 0;
56
- }
57
-
58
- .prose h2 {
59
- font-weight: 800;
60
- padding-top: 0.125rem;
61
- /* 0.5 * 0.25rem */
62
- padding-bottom: 0.125rem;
63
- margin-bottom: 0;
64
- margin-top: 0;
65
- border-width: 0;
66
- }
67
-
68
- .prose h3 {
69
- font-weight: 700;
70
- padding-top: 0.0625rem;
71
- /* 0.25 * 0.25rem */
72
- padding-bottom: 0.0625rem;
73
- margin-bottom: 0;
74
- margin-top: 0;
75
- border-width: 0;
76
- }
77
-
78
- p {
79
- margin: 0.1em 0em;
80
- }
81
-
82
- .prose blockquote {
83
- font-weight: 400;
84
- color: var(--color-gray-600);
85
- font-style: normal;
86
- quotes: '\201C' '\201D' '\2018' '\2019';
87
- }
88
-
89
- .prose blockquote p:first-of-type::before {
90
- content: '';
91
- }
92
-
93
- .prose blockquote p:last-of-type::after {
94
- content: '';
95
- }
96
-
97
- .prose ul > li {
98
- padding-left: 1em;
99
- text-align: left;
100
- }
101
-
102
- .prose ol > li {
103
- padding-left: 1em;
104
- text-align: left;
105
- }
106
-
107
- .prose ol > li::before {
108
- top: calc(0.875em - 0.1em);
109
- }
110
-
111
- .prose ul > li::before {
112
- top: calc(0.875em - 0.1em);
113
- }
114
-
115
- html {
116
- font-size: 12px;
117
- }
118
-
119
- .page-break {
120
- page-break-after: always;
121
- }
122
-
123
- .text-vertical {
124
- text-orientation: upright;
125
- writing-mode: vertical-lr;
126
- display: flex;
127
- flex-direction: column;
128
- justify-content: center;
129
- @apply p-4;
130
- }
131
-
132
- /* md-to-pdf ships github-markdown-css, which sets `table { display: block }` for horizontal
133
- * scrolling. That collapses rows into an anonymous max-content box, so column widths are ignored. */
134
- table {
135
- display: table;
136
- width: 100%;
137
- }
138
-
139
- table th {
140
- @apply bg-gray-700 text-white;
141
- }
142
-
143
- table tr {
144
- border-top: 0;
145
- break-inside: avoid;
146
- }
147
-
148
- /* zebra rows only pay off over many rows, so striping is opt-in; the short key/value
149
- * tables use hairline row dividers instead and stay quieter beside the items table.
150
- * The reset is needed because md-to-pdf's markdown.css stripes every table itself. */
151
- table tr:nth-child(even) {
152
- background-color: transparent;
153
- }
154
-
155
- table.striped tr:nth-child(even) {
156
- @apply bg-gray-50;
157
- }
158
-
159
- table th,
160
- table td,
161
- table tr {
162
- border: 0;
163
- padding: 0.5em 0.5em;
164
- }
@@ -1,189 +0,0 @@
1
- <!--
2
- vim: ft=htmldjango
3
- -->
4
- <!DOCTYPE html>
5
- <html lang="{{ language }}">
6
-
7
- <head>
8
- <meta charset="UTF-8">
9
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
10
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
- <title>{{ t('meta.title') }}</title>
12
- </head>
13
-
14
- <body>
15
- <div class="max-w-full leading-tight prose grid">
16
- <section id="header" class="relative grid grid-cols-12">
17
- <img src="https://main.s3.kilic.dev/html/icon.png" alt="logo"
18
- class="absolute h-40 top-1/2 left-1/2 -translate-x-1/2 -translate-y-[62%] drop-shadow-lg drop-shadow-gray-900 z-10">
19
- <div class="col-span-1 flex flex-col justify-center text-lg font-extrabold text-gray-100">
20
- <p class="text-vertical">{{ t('sections.from') }}</p>
21
- </div>
22
- <div class="col-start-2 col-span-5 flex flex-col justify-start p-4 pt-10 mr-12">
23
- <h1>{{ company.name }}</h1>
24
- <h3>{{ company.tax_number }}</h3>
25
- <address>{{ company.address | trim }}</address>
26
- <div class="flex flex-col text-sm">
27
- {% if company.phone %}
28
- <a href="tel:{{ company.phone }}">{{ company.phone }}</a>
29
- {% endif %}
30
- {% if company.email %}
31
- <a href="mailto:{{ company.email }}">{{ company.email }}</a>
32
- {% endif %}
33
- {% if company.website %}
34
- <a href="{{ company.website }}">{{ company.website }}</a>
35
- {% endif %}
36
- </div>
37
- </div>
38
- <div class="col-span-6 bg-gray-900 rounded-bl-4xl flex flex-col justify-center text-center">
39
- <p class="p-4 font-bold text-white text-6xl">{{ t('invoice') }}</p>
40
- </div>
41
- </section>
42
- <section id="client" class="grid grid-cols-12">
43
- <div class="col-span-1 flex flex-col justify-center text-lg font-extrabold text-gray-100">
44
- <p class="text-vertical">{{ t('sections.to') }}</p>
45
- </div>
46
- <div class="col-span-5 flex flex-col justify-start p-4">
47
- <h2>{{ client.name }}</h2>
48
- {% if client.tax_number %}
49
- <h3>{{ client.tax_number }}</h3>
50
- {% endif %}
51
- <address>{{ client.address | trim }}</address>
52
- </div>
53
- <div class="col-span-6 flex items-center justify-center text-xs py-4 pl-4 pr-16">
54
- <div class="w-full overflow-hidden rounded-xl border-y-2 shadow-md shadow-gray-300 border-gray-900!">
55
- <table class="w-full table-auto my-0!">
56
- <tbody>
57
- <tr>
58
- <td class="w-[30%] text-left align-middle font-bold">{{ t('fields.date') }}</td>
59
- <td class="w-[70%] text-right align-middle font-semibold">{{ date }}</td>
60
- </tr>
61
- <tr>
62
- <td class="w-[30%] text-left align-middle font-bold border-t! border-t-gray-100/30!">{{ t('fields.id') }}</td>
63
- <td class="w-[70%] text-right align-middle font-semibold border-t! border-t-gray-100/30!">{{ id }}</td>
64
- </tr>
65
- </tbody>
66
- </table>
67
- </div>
68
- </div>
69
- </section>
70
- <section id="items" class="grid grid-cols-12">
71
- <div class="col-span-12 px-16 py-4">
72
- <div class="overflow-hidden rounded-xl border-y-2 shadow-md shadow-gray-300 border-gray-900!">
73
- <table class="striped w-full table-auto my-0!">
74
- <thead class="border-b-1 border-b-gray-900! border-x-2 border-x-gray-900!">
75
- <tr>
76
- <th scope="col" class="w-md text-center">
77
- {{ t('table.description') }}
78
- </th>
79
- <th scope="col" class="w-[10%] text-center">
80
- {{ t('table.quantity') }}
81
- </th>
82
- <th scope="col" class="w-[10%] text-center">
83
- {{ t('table.price') }}
84
- </th>
85
- <th scope="col" class="w-[10%] text-center">
86
- {{ t('table.subtotal') }}
87
- </th>
88
- <th scope="col" class="w-[10%] text-center">
89
- {{ t('table.tax') }}
90
- </th>
91
- <th scope="col" class="w-[14%] font-semibold text-center">
92
- {{ t('table.total') }}
93
- </th>
94
- </tr>
95
- </thead>
96
- <tbody>
97
- {% set calculated_subtotal = 0 %}
98
- {% set calculated_tax = 0 %}
99
- {% for item in items %}
100
- <tr>
101
- <td class="text-left align-middle">{{ item.description }}</td>
102
- <td class="text-center align-middle">{{ item.quantity }} {{ item.unit }}</td>
103
- <td class="text-center align-middle">{{ item.price }}{{ currency }}</td>
104
- {% set calculated_item_subtotal = item.quantity * item.price %}
105
- <td class="text-center align-middle">{{ calculated_item_subtotal | round(2) }}{{ currency }}</td>
106
- {% set calculated_item_tax = calculated_item_subtotal * item.tax / 100 %}
107
- {% set calculated_tax = calculated_tax + calculated_item_tax %}
108
- <td class="text-center align-middle">
109
- {% if calculated_item_tax > 0 %}
110
- <div class="flex flex-row items-center">
111
- <span
112
- class="w-8 shrink-0 mr-1 py-px rounded-full text-center text-[0.50rem] font-semibold bg-gray-700 text-white">{{ item.tax }}%</span>
113
- <span>{{ calculated_item_tax | round(2) }}{{ currency }}</span>
114
- </div>
115
- {% else %}
116
- <span class="font-semibold">—</span>
117
- {% endif %}
118
- </td>
119
- {% set calculated_item_total = calculated_item_subtotal + calculated_item_tax %}
120
- <td class="font-semibold text-right align-middle">{{ calculated_item_total | round(2) }}{{ currency }}</td>
121
- </tr>
122
- {% set calculated_subtotal = calculated_subtotal + calculated_item_subtotal %}
123
- {% endfor %}
124
- </tbody>
125
- </table>
126
- </div>
127
- </div>
128
- </section>
129
- <section id="payment" class="grid grid-cols-12">
130
- <div class="col-span-1 flex flex-col justify-center text-lg font-extrabold text-gray-100 bg-gray-900">
131
- <p class="text-vertical">{{ t('sections.payment') }}</p>
132
- </div>
133
- <div
134
- class="col-span-5 flex flex-col p-4 ml-[-1px] pl-5 justify-center bg-gray-700 rounded-r-4xl text-white">
135
- <span>{{ payment.bank }}</span>
136
- <address>{{ payment.address | trim }}</address>
137
- <span>{{ payment.bic }}</span>
138
- <span>{{ payment.routing }}</span>
139
- <span class="mt-4 font-semibold">{{ payment.name }}</span>
140
- <span class="font-semibold">{{ payment.iban }}</span>
141
- </div>
142
- <div class="col-span-1"></div>
143
- <div class="col-span-5 flex flex-col justify-center m-8 mr-16">
144
- <div class="w-full overflow-hidden rounded-xl border-y-2 shadow-md shadow-gray-300 border-gray-900!">
145
- <table class="w-full table-auto my-0!">
146
- <tbody>
147
- <tr>
148
- <td class="w-[55%] text-left align-middle font-semibold">{{ t('summary.subtotal') }}</td>
149
- <td class="w-[45%] text-right align-middle font-semibold">{{ calculated_subtotal | round(2) }}{{ currency }}</td>
150
- </tr>
151
- <tr>
152
- <td class="w-[55%] text-left align-middle font-semibold border-t! border-t-gray-100/30!">{{ t('summary.tax') }}</td>
153
- <td class="w-[45%] text-right align-middle font-semibold border-t! border-t-gray-100/30!">
154
- {% if calculated_tax > 0 %}
155
- {{ calculated_tax | round(2) }}{{ currency }}
156
- {% else %}
157
- —
158
- {% endif %}
159
- </td>
160
- </tr>
161
- {% set calculated_total = calculated_subtotal + calculated_tax %}
162
- <tr>
163
- <td class="w-[55%] text-left align-middle font-bold text-primary-500 border-t-2! border-t-primary-500!">{{ t('summary.total') }}</td>
164
- <td class="w-[45%] text-right align-middle font-bold text-primary-500 border-t-2! border-t-primary-500!">
165
- {{ calculated_total | round(2) }}{{ currency }}
166
- </td>
167
- </tr>
168
- </tbody>
169
- </table>
170
- </div>
171
- </div>
172
- </section>
173
- <section id="footer" class="grid grid-cols-12">
174
- <div class="col-span-1 flex flex-col justify-center text-lg font-extrabold text-gray-100">
175
- <p class="text-vertical">{{ t('sections.notes') }}</p>
176
- </div>
177
- <div class="col-span-5 flex flex-col p-4 text-sm leading-tight prose">
178
- {{ content | safe }}<br />
179
- </div>
180
- <div class="col-span-1"></div>
181
- <div
182
- class="col-span-5 flex flex-col justify-end text-center m-8 mr-16 p-4 pb-0 border-2 border-gray-50! rounded-xl text-xs text-gray-100 h-36">
183
- <p>{{ t('signature') }}</p>
184
- </div>
185
- </section>
186
- </div>
187
- </body>
188
-
189
- </html>
@@ -1,26 +0,0 @@
1
- <style>
2
- footer {
3
- margin: 0 auto;
4
- text-align: center;
5
- font-size: 8px;
6
- color: #38404b;
7
- width: 100%;
8
- border-top: 1px solid #efefef;
9
- padding-top: 8px;
10
- }
11
- </style>
12
- <footer>
13
- <div>
14
- <img
15
- height="8px"
16
- src="data:image/png;base64,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"
17
- alt="logo"
18
- />
19
-
20
- <span>kilic.dev</span>
21
- -
22
- <span class="title"></span>
23
- -
24
- <span class="pageNumber"></span>/<span class="totalPages"></span>
25
- </div>
26
- </footer>