feat: KoePi oeffentlicher Link bekommt eigenes PWA-Manifest (Dickens Prospekte, eigener Startpunkt)

This commit is contained in:
2026-07-18 21:14:22 +02:00
parent 8ff1fd630b
commit e172cbe085
2 changed files with 38 additions and 0 deletions

View File

@@ -873,6 +873,32 @@ router.post('/share-link/disable', authenticate, (req, res) => {
res.json({ ok: true }); res.json({ ok: true });
}); });
// GET /public/:token/manifest.json eigenes PWA-Manifest für die öffentliche
// Prospekt-Seite: eigener Name ("Dickens Prospekte") und eigener start_url,
// damit die installierte App direkt wieder auf der öffentlichen Seite landet
// statt auf dem normalen Login der Haupt-App.
router.get('/public/:token/manifest.json', (req, res) => {
const active = getShareToken();
if (!active || req.params.token !== active) return res.status(404).json({ error: 'Nicht gefunden' });
res.setHeader('Content-Type', 'application/manifest+json');
res.json({
name: 'Dickens Prospekte',
short_name: 'Prospekte',
description: 'Wöchentliche Prospekte',
start_url: `/kp/${req.params.token}`,
scope: `/kp/${req.params.token}`,
display: 'standalone',
orientation: 'portrait',
background_color: '#0f1117',
theme_color: '#0f1117',
icons: [
{ src: '/favicon.svg', type: 'image/svg+xml', sizes: 'any', purpose: 'any maskable' },
{ src: '/icon-192.png', type: 'image/png', sizes: '192x192' },
{ src: '/icon-512.png', type: 'image/png', sizes: '512x512' },
],
});
});
// GET /public/:token/offers öffentlich, nur Cache, kein Login // GET /public/:token/offers öffentlich, nur Cache, kein Login
router.get('/public/:token/offers', publicRateLimit, async (req, res) => { router.get('/public/:token/offers', publicRateLimit, async (req, res) => {
const active = getShareToken(); const active = getShareToken();

View File

@@ -4093,6 +4093,18 @@ function PublicKoepi({ token }) {
const [invalid, setInvalid] = useState(false); const [invalid, setInvalid] = useState(false);
const BASE = '/api/tools/koepi/public/' + token; const BASE = '/api/tools/koepi/public/' + token;
// Eigenes PWA-Manifest (eigener Name "Dickens Prospekte", eigener
// start_url) statt des normalen App-Manifests — damit eine über diesen
// Link installierte App direkt wieder hier landet, nicht beim Login
useEffect(() => {
document.title = 'Dickens Prospekte';
let link = document.querySelector('link[rel="manifest"]');
const original = link?.getAttribute('href');
if (!link) { link = document.createElement('link'); link.rel = 'manifest'; document.head.appendChild(link); }
link.setAttribute('href', `${BASE}/manifest.json`);
return () => { if (link && original) link.setAttribute('href', original); };
}, [token]);
useEffect(() => { useEffect(() => {
fetch(BASE + '/prospekte') fetch(BASE + '/prospekte')
.then(async r => { if (!r.ok) throw new Error(); return r.json(); }) .then(async r => { if (!r.ok) throw new Error(); return r.json(); })