Skip to content

Commit 11f1e3d

Browse files
Merge pull request #10 from nitrique/feature/json-translations
feature(translations): add translations
2 parents 047c19d + baa2715 commit 11f1e3d

File tree

7 files changed

+341
-168
lines changed

7 files changed

+341
-168
lines changed

.traefik.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ testData:
88
enabled: true
99
maxEntries: 100
1010
sessionTime: 1m
11-
queuePageFile: queue-page.html
11+
queuePageFile: "/var/public/queue-page.html"
12+
queueTranslationsFile: "/var/public/translations.json"
1213
useCookies: true
1314
cookieName: queue-manager-id

docker-compose.yml

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
# docker-compose.yml
2-
version: "3.6"
3-
41
services:
52
traefik:
6-
image: traefik:v3.3.4
7-
container_name: traefik
3+
image: traefik:v3.6
84
command:
95
- --log.level=INFO
106
- --api
@@ -21,34 +17,54 @@ services:
2117
volumes:
2218
- /var/run/docker.sock:/var/run/docker.sock
2319
- ./:/plugins-local/src/github.com/hhftechnology/traefik-queue-manager
24-
labels:
25-
- traefik.http.middlewares.queuemanager.plugin.queuemanager.enabled=true
26-
- traefik.http.middlewares.queuemanager.plugin.queuemanager.queuePageFile=/plugins-local/src/github.com/hhftechnology/traefik-queue-manager/queue-page.html
27-
- traefik.http.middlewares.queuemanager.plugin.queuemanager.maxEntries=5
28-
- traefik.http.middlewares.queuemanager.plugin.queuemanager.sessionTime=1m
29-
- traefik.http.middlewares.queuemanager.plugin.queuemanager.purgeTime=5m
30-
- traefik.http.middlewares.queuemanager.plugin.queuemanager.useCookies=true
31-
- traefik.http.middlewares.queuemanager.plugin.queuemanager.cookieName=queue-manager-id
32-
- traefik.http.middlewares.queuemanager.plugin.queuemanager.refreshInterval=30
33-
- traefik.http.middlewares.queuemanager.plugin.queuemanager.debug=true
20+
- ./public:/var/public
3421

3522
whoami:
3623
image: traefik/whoami
37-
container_name: whoami-service
3824
depends_on:
3925
- traefik
4026
networks:
4127
- traefik-network
42-
deploy:
43-
replicas: 3
28+
volumes:
29+
- ./:/plugins-local/src/github.com/hhftechnology/traefik-queue-manager
4430
labels:
4531
- traefik.enable=true
46-
- traefik.http.routers.whoami.rule=Host(`whoami.local`)
32+
- traefik.http.routers.whoami.rule=Host(`localhost`)
4733
- traefik.http.routers.whoami.entrypoints=web
4834
- traefik.http.routers.whoami.service=whoami-service
4935
- traefik.http.services.whoami-service.loadbalancer.server.port=80
50-
- traefik.http.routers.whoami.middlewares=queuemanager
36+
- traefik.http.routers.whoami.middlewares=qm1
37+
- traefik.http.middlewares.qm1.plugin.queuemanager.enabled=true
38+
- traefik.http.middlewares.qm1.plugin.queuemanager.maxEntries=1
39+
- traefik.http.middlewares.qm1.plugin.queuemanager.sessionTime=1m
40+
- traefik.http.middlewares.qm1.plugin.queuemanager.purgeTime=5m
41+
- traefik.http.middlewares.qm1.plugin.queuemanager.useCookies=true
42+
- traefik.http.middlewares.qm1.plugin.queuemanager.cookieName=queue-manager-id
43+
- traefik.http.middlewares.qm1.plugin.queuemanager.refreshInterval=30
44+
- traefik.http.middlewares.qm1.plugin.queuemanager.debug=true
45+
46+
nginx:
47+
image: nginx
48+
depends_on:
49+
- traefik
50+
networks:
51+
- traefik-network
52+
labels:
53+
- traefik.enable=true
54+
- traefik.http.routers.service2.rule=Host(`127.0.0.1`)
55+
- traefik.http.routers.service2.entrypoints=web
56+
- traefik.http.routers.service2.service=nginx-service
57+
- traefik.http.services.nginx-service.loadbalancer.server.port=80
58+
- traefik.http.routers.service2.middlewares=qm2
59+
- traefik.http.middlewares.qm2.plugin.queuemanager.enabled=true
60+
- traefik.http.middlewares.qm2.plugin.queuemanager.maxEntries=2
61+
- traefik.http.middlewares.qm2.plugin.queuemanager.sessionTime=1m
62+
- traefik.http.middlewares.qm2.plugin.queuemanager.purgeTime=5m
63+
- traefik.http.middlewares.qm2.plugin.queuemanager.useCookies=true
64+
- traefik.http.middlewares.qm2.plugin.queuemanager.cookieName=queue-manager-id
65+
- traefik.http.middlewares.qm2.plugin.queuemanager.refreshInterval=30
66+
- traefik.http.middlewares.qm2.plugin.queuemanager.debug=true
5167

5268
networks:
5369
traefik-network:
54-
driver: bridge
70+
driver: bridge

queue-page.html renamed to public/queue-page.html

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>Service Queue - Please Wait</title>
6+
<title>[[.Translations.PageTitle]]</title>
77

8-
<meta http-equiv="refresh" content="[[.RefreshInterval]];url=./"> <meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate, max-age=0, s-maxage=0">
8+
<meta http-equiv="refresh" content="[[.QueueData.RefreshInterval]];url=./"> <meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate, max-age=0, s-maxage=0">
99
<meta http-equiv="Pragma" content="no-cache">
1010
<meta http-equiv="Expires" content="0"> <style>
1111
body {
@@ -49,7 +49,7 @@
4949
}
5050
.progress-bar {
5151
height: 28px; /* Taller progress bar */
52-
width: [[.ProgressPercentage]]%; /* Dynamically set width */
52+
width: [[.QueueData.ProgressPercentage]]%; /* Dynamically set width */
5353
background: linear-gradient(90deg, #007bff, #0056b3); /* Blue gradient */
5454
border-radius: 8px; /* Match container's rounding */
5555
text-align: center;
@@ -98,7 +98,7 @@
9898
font-size: 0.8em;
9999
color: #444;
100100
word-break: break-all;
101-
display: [[if .DebugInfo]]block[[else]]none[[end]]; /* Conditional display */
101+
display: [[if .QueueData.DebugInfo]]block[[else]]none[[end]]; /* Conditional display */
102102
}
103103
.debug-info pre {
104104
white-space: pre-wrap; /* Allow wrapping for long debug lines */
@@ -123,39 +123,37 @@
123123
</head>
124124
<body>
125125
<div class="container">
126-
<div class="spinner"></div> <h1>You're in the Queue</h1>
127-
<p>Our services are currently experiencing high demand. Your patience is appreciated. You will be automatically redirected when it's your turn.</p>
126+
<div class="spinner"></div> <h1>[[.Translations.Title]]</h1>
127+
<p>[[.Translations.Introduction]]</p>
128128

129129
<div class="progress-container">
130-
<div class="progress-bar">[[.ProgressPercentage]]%</div>
130+
<div class="progress-bar">[[.QueueData.ProgressPercentage]]%</div>
131131
</div>
132132

133133
<div class="info-grid">
134134
<div class="info-box">
135-
<strong>Your Position</strong>
136-
<p>[[.Position]] / [[.QueueSize]]</p>
135+
<strong>[[.Translations.YourPosition]]</strong>
136+
<p>[[.QueueData.Position]] / [[.QueueData.QueueSize]]</p>
137137
</div>
138138
<div class="info-box">
139-
<strong>Estimated Wait Time</strong>
140-
<p>~[[.EstimatedWaitTime]] min(s)</p>
139+
<strong>[[.Translations.ETA]]</strong>
140+
<p>~[[.QueueData.EstimatedWaitTime]] [[.Translations.Mins]]</p>
141141
</div>
142142
</div>
143143

144-
<p>[[.Message]]</p>
145-
146144
<div class="countdown-message">
147-
This page will automatically refresh in <strong id="countdown">[[.RefreshInterval]]</strong> seconds.
145+
[[ printf .Translations.RefreshTime .QueueData.RefreshInterval | safeHtml ]]
148146
</div>
149147

150148
<div class="debug-info">
151149
<strong>Debug Information:</strong>
152-
<pre>[[.DebugInfo]]</pre>
150+
<pre>[[.QueueData.DebugInfo]]</pre>
153151
</div>
154152
</div>
155153

156154
<script>
157155
document.addEventListener('DOMContentLoaded', function() {
158-
let countdownSeconds = parseInt("[[.RefreshInterval]]", 10);
156+
let countdownSeconds = parseInt("[[.QueueData.RefreshInterval]]", 10);
159157
const countdownElement = document.getElementById('countdown');
160158

161159
if (countdownElement) {
@@ -183,7 +181,7 @@
183181
setTimeout(function() {
184182
const cleanUrl = window.location.pathname;
185183
window.location.href = cleanUrl + (cleanUrl.includes('?') ? '&' : '?') + 't_fallback=' + new Date().getTime();
186-
}, (parseInt("[[.RefreshInterval]]", 10) -1) * 1000); // 1 second before meta refresh
184+
}, (parseInt("[[.QueueData.RefreshInterval]]", 10) -1) * 1000); // 1 second before meta refresh
187185
});
188186
</script>
189187
</body>

public/translations.json

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"en": {
3+
"pageTitle": "Service Queue - Please Wait",
4+
"title": "You're in the Queue",
5+
"introduction": "Our services are currently experiencing high demand. Your patience is appreciated. You will be automatically redirected when it's your turn.",
6+
"yourPosition": "Your Position",
7+
"eta": "Estimated Wait Time",
8+
"refreshTime": "This page will automatically refresh in <span id=\"countdown\">%d</span> seconds",
9+
"mins": "min(s)"
10+
},
11+
"fr": {
12+
"pageTitle": "File d’attente - Veuillez patienter",
13+
"title": "Vous êtes dans la file d'attente",
14+
"introduction": "Nos services rencontrent actuellement une forte demande. Merci pour votre patience. Vous serez automatiquement redirigé lorsque ce sera votre tour.",
15+
"yourPosition": "Votre position",
16+
"eta": "Temps d’attente estimé",
17+
"refreshTime": "Cette page se rafraîchira automatiquement dans <span id=\"countdown\">%d</span> secondes",
18+
"mins": "min(s)"
19+
},
20+
"es": {
21+
"pageTitle": "Cola de servicio - Por favor espere",
22+
"title": "Estás en la cola",
23+
"introduction": "Nuestros servicios están experimentando una alta demanda. Agradecemos tu paciencia. Serás redirigido automáticamente cuando sea tu turno.",
24+
"yourPosition": "Tu posición",
25+
"eta": "Tiempo de espera estimado",
26+
"refreshTime": "Esta página se actualizará automáticamente en <span id=\"countdown\">%d</span> segundos",
27+
"mins": "min(s)"
28+
},
29+
"de": {
30+
"pageTitle": "Warteschlange - Bitte warten",
31+
"title": "Sie befinden sich in der Warteschlange",
32+
"introduction": "Unsere Dienste verzeichnen derzeit eine hohe Nachfrage. Vielen Dank für Ihre Geduld. Sie werden automatisch weitergeleitet, wenn Sie an der Reihe sind.",
33+
"yourPosition": "Ihre Position",
34+
"eta": "Geschätzte Wartezeit",
35+
"refreshTime": "Diese Seite wird in <span id=\"countdown\">%d</span> Sekunden automatisch aktualisiert",
36+
"mins": "min(s)"
37+
},
38+
"pt": {
39+
"pageTitle": "Fila de serviço - Por favor, aguarde",
40+
"title": "Você está na fila",
41+
"introduction": "Nossos serviços estão com alta demanda no momento. Agradecemos sua paciência. Você será redirecionado automaticamente quando for a sua vez.",
42+
"yourPosition": "Sua posição",
43+
"eta": "Tempo de espera estimado",
44+
"refreshTime": "Esta página será atualizada automaticamente em <span id=\"countdown\">%d</span> segundos",
45+
"mins": "min(s)"
46+
},
47+
"it": {
48+
"pageTitle": "Coda del servizio - Attendere prego",
49+
"title": "Sei in coda",
50+
"introduction": "I nostri servizi stanno riscontrando un'alta domanda. Ti ringraziamo per la pazienza. Verrai reindirizzato automaticamente quando sarà il tuo turno.",
51+
"yourPosition": "La tua posizione",
52+
"eta": "Tempo di attesa stimato",
53+
"refreshTime": "Questa pagina si aggiornerà automaticamente tra <span id=\"countdown\">%d</span> secondi",
54+
"mins": "min(s)"
55+
}
56+
}

0 commit comments

Comments
 (0)