Updated dependencies. Moved email assets from base64 to attachments to improve support in Gmail. Implemented custom email branding support. Implemented custom print branding support. Moved image assets to email/kiosk directory. Implemented kiosk dark mode logo support. Updated README.md

This commit is contained in:
Glenn de Haan
2025-12-02 18:42:35 +01:00
parent 4e3ca28f7a
commit 24bfbedc42
10 changed files with 107 additions and 16 deletions

View File

@@ -617,6 +617,41 @@ Heres what each variable represents:
> PRINTERS: 'pdf,192.168.1.10,192.168.1.11'
> ```
### Custom Branding (Logo)
You can customize the appearance of the pdf and ESC/POS print layout by providing your own branding assets, including:
* `logo.png` — Logo used in the print header
To do this, use Docker volume mappings to mount your custom assets into the `/print` directory inside the container.
The application will use these files (if present) instead of the default ones.
> **If you provide custom branding for printed vouchers, make sure your logo closely match the original application logos size, aspect ratio, and color space.** This helps ensure the layout prints correctly and avoids color shifts or misalignment in the final output.
#### Example
Suppose you have your custom images in a local directory called `branding/`:
```
branding/
└── logo.png
```
You can configure this using Docker Compose:
```yaml
services:
unifi-voucher-site:
image: glenndehaan/unifi-voucher-site:latest
ports:
- "3000:3000"
environment:
KIOSK_ENABLED: 'true'
KIOSK_VOUCHER_TYPES: '480,1,,,;'
volumes:
- ./branding:/print
```
### Usage
#### PDF
@@ -677,6 +712,41 @@ Heres what each variable represents:
These settings allow the application to connect to your SMTP server and send emails on your behalf.
### Custom Branding (Logo)
You can customize the appearance of the email by providing your own branding assets, including:
* `logo.png` — Logo used in the email header
To do this, use Docker volume mappings to mount your custom assets into the `/email` directory inside the container.
The application will use these files (if present) instead of the default ones.
> We recommend to keep the logo at a maximum height of 75px, to prevent layout shifts
#### Example
Suppose you have your custom images in a local directory called `branding/`:
```
branding/
└── logo.png
```
You can configure this using Docker Compose:
```yaml
services:
unifi-voucher-site:
image: glenndehaan/unifi-voucher-site:latest
ports:
- "3000:3000"
environment:
KIOSK_ENABLED: 'true'
KIOSK_VOUCHER_TYPES: '480,1,,,;'
volumes:
- ./branding:/email
```
### Usage
Once the SMTP environment variables are configured, the email feature will be available within the UniFi Voucher Site interface. After generating a voucher, you will see an option to send the voucher via email. Enter the recipient's email address, and the application will send the voucher details directly to their inbox.
@@ -760,9 +830,14 @@ KIOSK_VOUCHER_TYPES: '480,1,,,;'
### Custom Branding (Logo and Background)
You can customize the appearance of the kiosk page by providing your own `logo.png` and `bg.jpg` images.
You can customize the appearance of the kiosk page by providing your own branding assets, including:
To do this, use Docker volume mappings to mount your custom assets to the `/kiosk` directory inside the container. The application will use these files (if present) instead of the default ones.
* `logo.png` — Logo used in light mode
* `logo_dark.png` — Logo used in dark mode
* `bg.jpg` — Background image
To do this, use Docker volume mappings to mount your custom assets into the `/kiosk` directory inside the container.
The application will use these files (if present) instead of the default ones.
#### Example
@@ -771,6 +846,7 @@ Suppose you have your custom images in a local directory called `branding/`:
```
branding/
├── logo.png
├── logo_dark.png
└── bg.jpg
```
@@ -789,7 +865,8 @@ services:
- ./branding:/kiosk
```
> **Note:** Ensure `logo.png` and `bg.jpg` are valid image files. Both are optional — only override the ones you want to customize.
> **Note:** All branding files are optional — provide only the ones you want to override.
> Ensure `logo.png`, `logo_dark.png`, and `bg.jpg` are valid image files.
### Usage

View File

@@ -75,10 +75,21 @@ module.exports = {
voucher,
unifiSsid: variables.unifiSsid,
unifiSsidPassword: variables.unifiSsidPassword,
qr: await qr(),
timeConvert: time,
bytesConvert: bytes
})
}),
attachments: [
{
filename: 'logo.png',
content: fs.existsSync('/email/logo.png') ? fs.readFileSync(`/email/logo.png`) : fs.readFileSync(`${process.cwd()}/public/images/email/logo.png`),
cid: 'logo@unifi-voucher-site.com'
},
{
filename: 'qr.png',
content: await qr(true),
cid: 'qr@unifi-voucher-site.com'
}
]
}).catch((e) => {
log.error(`[Mail] Error when sending mail`);
log.error(e);

View File

@@ -1,6 +1,7 @@
/**
* Import base packages
* Import vendor modules
*/
const fs = require('fs');
const PDFDocument = require('pdfkit');
const ThermalPrinter = require('node-thermal-printer').printer;
const PrinterTypes = require('node-thermal-printer').types;
@@ -82,7 +83,7 @@ module.exports = {
doc.moveDown(1);
}
doc.image('public/images/logo_grayscale_dark.png', 75, 15, {
doc.image(fs.existsSync('/print/logo.png') ? '/print/logo.png' : `${process.cwd()}/public/images/print/logo.png`, 75, 15, {
fit: [75, 75],
align: 'center',
valign: 'center'
@@ -248,7 +249,7 @@ module.exports = {
printer.setTypeFontB();
printer.alignCenter();
printer.newLine();
await printer.printImage(`${process.cwd()}/public/images/logo_grayscale_dark.png`);
await printer.printImage(fs.existsSync('/print/logo.png') ? '/print/logo.png' : `${process.cwd()}/public/images/logo_grayscale_dark.png`);
printer.newLine();
printer.alignCenter();

8
package-lock.json generated
View File

@@ -11,7 +11,7 @@
"dependencies": {
"cookie-parser": "^1.4.7",
"ejs": "^3.1.10",
"express": "^5.2.0",
"express": "^5.2.1",
"express-locale": "^2.0.2",
"express-openid-connect": "^2.19.3",
"js-logger": "^1.6.1",
@@ -1837,9 +1837,9 @@
}
},
"node_modules/express": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/express/-/express-5.2.0.tgz",
"integrity": "sha512-XdpJDLxfztVY59X0zPI6sibRiGcxhTPXRD3IhJmjKf2jwMvkRGV1j7loB8U+heeamoU3XvihAaGRTR4aXXUN3A==",
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
"license": "MIT",
"dependencies": {
"accepts": "^2.0.0",

View File

@@ -17,7 +17,7 @@
"dependencies": {
"cookie-parser": "^1.4.7",
"ejs": "^3.1.10",
"express": "^5.2.0",
"express": "^5.2.1",
"express-locale": "^2.0.2",
"express-openid-connect": "^2.19.3",
"js-logger": "^1.6.1",

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -114,7 +114,7 @@
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;" valign="top">
<p>
<center>
<img src="https://github.com/glenndehaan/unifi-voucher-site/blob/master/public/images/icon/logo_192x192.png?raw=true" height="75px"/>
<img src="cid:logo@unifi-voucher-site.com" height="75px" alt="Logo" style="height: 75px;"/>
<br/>
<h1 style="font-weight: 400; font-size: 1.75rem; line-height: 1.2;"><%= t('title') %></h1>
</center>
@@ -134,7 +134,7 @@
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0;"><%= t('connect') %>: <span style="font-weight: bold;"><%= unifiSsid %></span> <%= t('or') %>,</p>
<% } %>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0;"><%= t('scan') %>:</p>
<img src="<%= qr %>" />
<img src="cid:qr@unifi-voucher-site.com" alt="Scan to Connect QR Code" />
</center>
<p style="font-family: sans-serif; font-size: 5px; margin: 0; margin-bottom: 5px;">&nbsp;</p>
<% } %>

View File

@@ -24,6 +24,7 @@
<meta name="theme-color" content="#139CDA">
<link rel="preload" href="<%= baseUrl %>/images/kiosk/logo.png" as="image">
<link rel="preload" href="<%= baseUrl %>/images/kiosk/logo_dark.png" as="image">
<link rel="preload" href="<%= baseUrl %>/images/kiosk/bg.jpg" as="image">
<link rel="preload" href="<%= baseUrl %>/dist/style.css" as="style">
<link href="<%= baseUrl %>/dist/style.css" rel="stylesheet">
@@ -60,7 +61,8 @@
<div class="w-full max-w-md bg-white dark:bg-gray-800 rounded-lg border border-black/5 dark:border-white/5 shadow-sm z-10 relative">
<div class="p-4 border-b border-black/5 dark:border-white/5">
<img class="mx-auto h-24 w-auto" width="48" height="48" alt="UniFi Voucher Site Logo" src="<%= baseUrl %>/images/kiosk/logo.png">
<img class="dark:hidden block mx-auto h-24 w-auto" width="48" height="48" alt="UniFi Voucher Site Logo" src="<%= baseUrl %>/images/kiosk/logo.png">
<img class="dark:block hidden mx-auto h-24 w-auto" width="48" height="48" alt="UniFi Voucher Site Logo" src="<%= baseUrl %>/images/kiosk/logo_dark.png">
<h1 class="mt-4 text-2xl font-semibold text-center text-gray-900 dark:text-white"><%= t('title') %></h1>
<% if(error) { %>