Skip to content

Commit d2b08fe

Browse files
authored
fix(title): show app version in footer and normalize em/en dashes (#86) (#88)
- footer.line1 interpolates the runtime app version (GET /api/version with package.json fallback) and uses a regular hyphen instead of an em dash. - Remove remaining em/en dashes from i18n prose (es/en/zh-CN) so the app shows no smart dashes anywhere. - Add scripts/check-dashes.mjs that fails on U+2013/U+2014 in index.html, the PWA manifest and i18n translations; wired into 'npm run lint' and a new 'npm run check:dashes' script. Co-authored-by: gnacho <hnacho@proton.me>
1 parent 734090d commit d2b08fe

7 files changed

Lines changed: 52 additions & 14 deletions

File tree

‎app/package.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
"scripts": {
77
"dev": "vite",
88
"build": "tsc -b && vite build",
9-
"lint": "eslint . && node scripts/theme-audit.mjs",
9+
"lint": "eslint . && node scripts/theme-audit.mjs && node scripts/check-dashes.mjs",
1010
"format": "prettier --write .",
11+
"check:dashes": "node scripts/check-dashes.mjs",
1112
"check:bundlesize": "node scripts/check-bundle-size.mjs",
1213
"test:e2e": "playwright test",
1314
"preview": "vite preview"

‎app/scripts/check-dashes.mjs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Falla si aparecen em dash (U+2014) o en dash (U+2013) en prosa visible de la
2+
// app: index.html, manifest PWA y las traducciones i18n (regresión #55/#86).
3+
import { execSync } from 'node:child_process'
4+
5+
const TARGETS = ['index.html', 'public/manifest.webmanifest', 'src/i18n']
6+
const out = execSync(`grep -rnP '[\\x{2013}\\x{2014}]' ${TARGETS.join(' ')} || true`).toString()
7+
const bad = out.split('\n').filter((l) => l)
8+
if (bad.length) {
9+
console.error('Em/en dashes (—/–) en texto visible de la app:\n' + bad.join('\n'))
10+
process.exit(1)
11+
}
12+
console.log('check-dashes OK: sin em/en dashes en index.html, manifest e i18n')

‎app/src/components/Footer.tsx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { useTranslation } from 'react-i18next';
22
import { useInstall } from '@/hooks/useInstall';
3+
import { useAppVersion } from '@/hooks/useAppVersion';
34
import { numLocale } from '@/i18n';
45

56
export default function Footer() {
67
const { t } = useTranslation();
78
const install = useInstall();
9+
const version = useAppVersion();
810

911
// Resumen de la instalación desde la topología (issue #37): sin nombres de
1012
// marca hardcodeados. "N inversores · Batería X kWh" (batería opcional).
@@ -13,7 +15,7 @@ export default function Footer() {
1315
return (
1416
<footer className="mx-auto w-full max-w-[1440px] px-4 pb-6 pt-2 lg:px-6">
1517
<div className="flex flex-col items-center justify-between gap-2 border-t border-app pt-4 text-xs text-faint sm:flex-row">
16-
<p>{t('footer.line1')}</p>
18+
<p>{t('footer.line1', { version })}</p>
1719
<p>{installLine ?? t('footer.line2')}</p>
1820
</div>
1921
</footer>

‎app/src/hooks/useAppVersion.ts‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { useEffect, useState } from 'react';
2+
import { apiFetch } from '@/data/api-client';
3+
import pkg from '../../package.json';
4+
5+
// Versión de la app: /api/version en runtime (fuente del server, refleja lo
6+
// desplegado) con fallback a la versión embebida en el bundle (package.json).
7+
export function useAppVersion(): string {
8+
const [version, setVersion] = useState(pkg.version);
9+
10+
useEffect(() => {
11+
let alive = true;
12+
apiFetch<{ version?: string }>('/api/version')
13+
.then((res) => {
14+
if (alive && res?.version) setVersion(res.version);
15+
})
16+
.catch(() => {});
17+
return () => {
18+
alive = false;
19+
};
20+
}, []);
21+
22+
return version;
23+
}

‎app/src/i18n/locales/en/translation.json‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
"temperature": "Temperature",
139139
"autonomy": "Est. autonomy",
140140
"socTitle": "State of charge · today",
141-
"socSubtitle": "0–100 % · dashed night projection",
141+
"socSubtitle": "0-100 % · dashed night projection",
142142
"socAria": "Battery state of charge throughout the day",
143143
"socFull": "Battery full {{time}}",
144144
"chargeStart": "Charge start {{time}}",
@@ -336,7 +336,7 @@
336336
"privacy": "100% private · 0% cloud",
337337
"checkUpdates": "Check for updates",
338338
"checking": "Checking…",
339-
"upToDate": "You're up to date — v{{version}} is the latest version",
339+
"upToDate": "You're up to date - v{{version}} is the latest version",
340340
"updateAvailable": "New version available: v{{version}}",
341341
"viewRelease": "What's new",
342342
"updateNow": "Update now",
@@ -535,7 +535,7 @@
535535
}
536536
},
537537
"footer": {
538-
"line1": "Helios · Solar Monitor — local data via Home Assistant",
538+
"line1": "Helios · Solar Monitor {{version}} - local data via Home Assistant",
539539
"line2": "Local installation · data via Home Assistant"
540540
},
541541
"stub": {
@@ -580,7 +580,7 @@
580580
}
581581
},
582582
"demo": {
583-
"banner": "Demo mode — changes are not applied to the system",
583+
"banner": "Demo mode - changes are not applied to the system",
584584
"exit": "Exit demo"
585585
},
586586
"audit": {

‎app/src/i18n/locales/es/translation.json‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
"temperature": "Temperatura",
139139
"autonomy": "Autonomía est.",
140140
"socTitle": "Estado de carga · hoy",
141-
"socSubtitle": "0–100 % · proyección nocturna discontinua",
141+
"socSubtitle": "0-100 % · proyección nocturna discontinua",
142142
"socAria": "Estado de carga de la batería a lo largo del día",
143143
"socFull": "Batería llena {{time}}",
144144
"chargeStart": "Inicio de carga {{time}}",
@@ -336,7 +336,7 @@
336336
"privacy": "100% privado · 0% nube",
337337
"checkUpdates": "Comprobar actualizaciones",
338338
"checking": "Comprobando…",
339-
"upToDate": "Estás al día — v{{version}} es la última versión",
339+
"upToDate": "Estás al día - v{{version}} es la última versión",
340340
"updateAvailable": "Nueva versión disponible: v{{version}}",
341341
"viewRelease": "Ver novedades",
342342
"updateNow": "Actualizar ahora",
@@ -535,7 +535,7 @@
535535
}
536536
},
537537
"footer": {
538-
"line1": "Helios · Monitor Solar — datos locales vía Home Assistant",
538+
"line1": "Helios · Monitor Solar {{version}} - datos locales vía Home Assistant",
539539
"line2": "Instalación local · datos vía Home Assistant"
540540
},
541541
"stub": {
@@ -580,7 +580,7 @@
580580
}
581581
},
582582
"demo": {
583-
"banner": "Modo demo — los cambios no se aplican al sistema",
583+
"banner": "Modo demo - los cambios no se aplican al sistema",
584584
"exit": "Salir del demo"
585585
},
586586
"audit": {

‎app/src/i18n/locales/zh-CN/translation.json‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
"temperature": "温度",
139139
"autonomy": "预计续航",
140140
"socTitle": "充电状态 · 今天",
141-
"socSubtitle": "0–100 % · 夜间预测为虚线",
141+
"socSubtitle": "0-100 % · 夜间预测为虚线",
142142
"socAria": "全天电池充电状态",
143143
"socFull": "电池已充满 {{time}}",
144144
"chargeStart": "开始充电 {{time}}",
@@ -334,7 +334,7 @@
334334
"privacy": "100% 私密 · 0% 云",
335335
"checkUpdates": "检查更新",
336336
"checking": "检查中…",
337-
"upToDate": "已是最新版本 — v{{version}} 是最新版",
337+
"upToDate": "已是最新版本 - v{{version}} 是最新版",
338338
"updateAvailable": "有新版本可用:v{{version}}",
339339
"viewRelease": "查看更新",
340340
"updateNow": "立即更新",
@@ -532,7 +532,7 @@
532532
}
533533
},
534534
"footer": {
535-
"line1": "Helios · 太阳能监控 — 通过 Home Assistant 本地获取数据",
535+
"line1": "Helios · 太阳能监控 {{version}} - 通过 Home Assistant 本地获取数据",
536536
"line2": "本地安装 · 通过 Home Assistant 获取数据"
537537
},
538538
"stub": {
@@ -577,7 +577,7 @@
577577
}
578578
},
579579
"demo": {
580-
"banner": "演示模式 — 更改不会应用到系统",
580+
"banner": "演示模式 - 更改不会应用到系统",
581581
"exit": "退出演示"
582582
},
583583
"audit": {

0 commit comments

Comments
 (0)