From cf7361f735720471e0a1254e3408c924c56f4e66 Mon Sep 17 00:00:00 2001 From: luciano Date: Wed, 29 Apr 2026 22:03:19 +0200 Subject: [PATCH] =?UTF-8?q?feat(web):=20PWA=20=E2=80=94=20manifest,=20icon?= =?UTF-8?q?e,=20meta=20iOS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - src/app/manifest.ts (Next 14 file convention) → /manifest.webmanifest - public/icons/icon.svg + icon-maskable.svg (vettoriali, palette editoriale) - scripts/generate-icons.mjs (sharp): genera icon-192/512.png, apple-touch-icon-180.png, icon-maskable-512.png, badge-72.png - layout.tsx: viewport con themeColor light/dark, manifest link, appleWebApp meta (capable + title), icons (svg + png + apple touch) - .eslintrc: ignora scripts Node out-of-project; lint-staged: .mjs format-only Display standalone, lang it, theme #221d18 (ink) / bg #f6f0df (carta). Sblocca "Installa app" su Chrome/Edge/Android e "Aggiungi alla Home" su iOS Safari — quest'ultimo è pre-requisito per ricevere le push su iOS. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/web/.eslintrc.cjs | 2 + apps/web/package.json | 5 +- apps/web/public/icons/apple-touch-icon.png | Bin 0 -> 4887 bytes apps/web/public/icons/badge-72.png | Bin 0 -> 1183 bytes apps/web/public/icons/icon-192.png | Bin 0 -> 5265 bytes apps/web/public/icons/icon-512.png | Bin 0 -> 18991 bytes apps/web/public/icons/icon-maskable-512.png | Bin 0 -> 13207 bytes apps/web/public/icons/icon-maskable.svg | 8 ++++ apps/web/public/icons/icon.svg | 16 +++++++ apps/web/scripts/generate-icons.mjs | 28 ++++++++++++ apps/web/src/app/[locale]/layout.tsx | 27 ++++++++++- apps/web/src/app/manifest.ts | 48 ++++++++++++++++++++ package.json | 4 +- pnpm-lock.yaml | Bin 323653 -> 332940 bytes 14 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 apps/web/public/icons/apple-touch-icon.png create mode 100644 apps/web/public/icons/badge-72.png create mode 100644 apps/web/public/icons/icon-192.png create mode 100644 apps/web/public/icons/icon-512.png create mode 100644 apps/web/public/icons/icon-maskable-512.png create mode 100644 apps/web/public/icons/icon-maskable.svg create mode 100644 apps/web/public/icons/icon.svg create mode 100644 apps/web/scripts/generate-icons.mjs create mode 100644 apps/web/src/app/manifest.ts diff --git a/apps/web/.eslintrc.cjs b/apps/web/.eslintrc.cjs index a9910da..d4596a4 100644 --- a/apps/web/.eslintrc.cjs +++ b/apps/web/.eslintrc.cjs @@ -5,5 +5,7 @@ module.exports = { ignorePatterns: [ // Service worker servito al browser: out-of-project per il TS parser. 'public/**/*.js', + // Script Node ESM: out-of-project per il TS parser. + 'scripts/**/*.mjs', ], }; diff --git a/apps/web/package.json b/apps/web/package.json index 29f11ef..683e6df 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -35,13 +35,14 @@ "devDependencies": { "@ketopath/eslint-config": "workspace:*", "@ketopath/tsconfig": "workspace:*", + "@playwright/test": "^1.45.3", "@types/node": "^20.12.7", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "autoprefixer": "^10.4.19", "eslint-config-next": "^14.2.5", "postcss": "^8.4.39", - "tailwindcss": "^3.4.4", - "@playwright/test": "^1.45.3" + "sharp": "^0.34.5", + "tailwindcss": "^3.4.4" } } diff --git a/apps/web/public/icons/apple-touch-icon.png b/apps/web/public/icons/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..af39111c228a8f27496b099db489d1fa2568b343 GIT binary patch literal 4887 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 literal 0 HcmV?d00001 diff --git a/apps/web/public/icons/badge-72.png b/apps/web/public/icons/badge-72.png new file mode 100644 index 0000000000000000000000000000000000000000..f0599921e978b3cc45635c3c11ab54974459ef49 GIT binary patch literal 1183 zcmV;Q1YrA#P)oQAtEWRCt{2n)_3XQ5eVl8SaEyQMyn>g~)A~j4=koFd?JN5Th{} zxul61_lgveHlwH%>5gicEmDatR;|mp<#rhM*RMIR=JmeYw%cyI?JLg@&ksBAb58I1 zyx-^hoO7l@dZq(~u15xg2#(IAKnM^cKnl2W0f)$)cT|v#RX~{*b@mCr{NegVz3yCf&-zxcp4SO*|IUu z>MN0ZH5Gx=yk+@w1E=E5sW<^3&uea|!tMMF?2q0KXQyGZTw~!qNrmm<>xFTO0i>5i z?A{&X%kl-if7NI*KQbaz%;jKyer@kDcgNNZ;@q?Seemc(5jx*K#pid;f`UTVESLRl z{$Ugc=t_E`_>%sMAhNd9?7=@0MOOJ9kRbVR7!o^JjH?{_9%@Vs>v6bHNSm$%h@b!?D+?Nk6$^mraTAKKB z!L$5~=J2wcA2dUF`G(rEUeA3saO?#aH$ID%X$C^@$=I$*Z zX&w(=n*Ri#j@B9k1^9Hq`O~HB0jS{mMH!&<)Dy}F)YepufT>OY`s1@!xqviPw*)Z!_ni{?X3-vij>YelwfVxlbeqGm z86Yor72H%#;_roX1Mp7QU=u*Rm6sG`3On-GFCO8+y?jK3trefUjvI;0O9^&?V^akk zjo%~lg9UT^@wTJB&wzY9Cm?*&nm--U%?0B|4HZ5}$f6*`?c0U+7LDED*c6bS>5y>z zV7K!Y|LXQK>HY|tcd?`shq^&}rF}?%^b&YUC*%4AX+SGT-xd7CE`>BF&=)VYwFF2n zfs~vOZxy8fLP7ejIG1=>*r!-hZUX{PwmMl{1V49~$~9CHzg;wSZJLpGN&%O*$ejVv2{W+5Fu*x5yyzF_mRGMsuZ|(AR6C)r-@dJ%p5*u1E{^M0;gk z{{i~;u?;JhE|4v_vOL%1n5>Myijy7@qIX5$`Lp|C-uF*hEL$>9me-qGNMmt1#7_Xk zqbw%e{(x@gToShV{IqVkSm)8huzL9tL`8(BZ5TySp(3D$OzZBg2lPKL{OD{&Q%(xBl^7iDJG4<`1PG)cMkNME`wtyf836(*h*61wJcv2o xjLD=K0RkzAQHjCPo8K6Bnl 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 literal 0 HcmV?d00001 diff --git a/apps/web/public/icons/icon-512.png b/apps/web/public/icons/icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..26a5c7a7de10f6012732139b1e3f66e1ded813ce GIT binary patch literal 18991 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 literal 0 HcmV?d00001 diff --git a/apps/web/public/icons/icon-maskable-512.png b/apps/web/public/icons/icon-maskable-512.png new file mode 100644 index 0000000000000000000000000000000000000000..aeb43a65eaea18a13c6a110769c79716084c4002 GIT binary patch literal 13207 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 literal 0 HcmV?d00001 diff --git a/apps/web/public/icons/icon-maskable.svg b/apps/web/public/icons/icon-maskable.svg new file mode 100644 index 0000000..7881962 --- /dev/null +++ b/apps/web/public/icons/icon-maskable.svg @@ -0,0 +1,8 @@ + + + + + + KP. + + diff --git a/apps/web/public/icons/icon.svg b/apps/web/public/icons/icon.svg new file mode 100644 index 0000000..7a08148 --- /dev/null +++ b/apps/web/public/icons/icon.svg @@ -0,0 +1,16 @@ + + + + + + + + + KETOPATH + + + KP. + + + una keto italiana + diff --git a/apps/web/scripts/generate-icons.mjs b/apps/web/scripts/generate-icons.mjs new file mode 100644 index 0000000..5a67c66 --- /dev/null +++ b/apps/web/scripts/generate-icons.mjs @@ -0,0 +1,28 @@ +// Genera i PNG dell'icona PWA a partire dalle SVG sorgente. +// Eseguilo dopo aver modificato icon.svg / icon-maskable.svg. +// +// pnpm --filter @ketopath/web exec node scripts/generate-icons.mjs + +import { readFile, writeFile } from 'node:fs/promises'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; +import sharp from 'sharp'; + +const here = path.dirname(fileURLToPath(import.meta.url)); +const PUBLIC_ICONS = path.join(here, '..', 'public', 'icons'); + +const targets = [ + { src: 'icon.svg', out: 'icon-192.png', size: 192 }, + { src: 'icon.svg', out: 'icon-512.png', size: 512 }, + { src: 'icon.svg', out: 'apple-touch-icon.png', size: 180 }, + { src: 'icon-maskable.svg', out: 'icon-maskable-512.png', size: 512 }, + { src: 'icon-maskable.svg', out: 'badge-72.png', size: 72 }, +]; + +for (const t of targets) { + const svg = await readFile(path.join(PUBLIC_ICONS, t.src)); + const png = await sharp(svg, { density: 384 }).resize(t.size, t.size).png().toBuffer(); + await writeFile(path.join(PUBLIC_ICONS, t.out), png); + // eslint-disable-next-line no-console + console.info(`✓ ${t.out} (${t.size}×${t.size})`); +} diff --git a/apps/web/src/app/[locale]/layout.tsx b/apps/web/src/app/[locale]/layout.tsx index 3d93b9c..61d9b42 100644 --- a/apps/web/src/app/[locale]/layout.tsx +++ b/apps/web/src/app/[locale]/layout.tsx @@ -1,4 +1,4 @@ -import type { Metadata } from 'next'; +import type { Metadata, Viewport } from 'next'; import { Fraunces, Inter_Tight, JetBrains_Mono } from 'next/font/google'; import { notFound } from 'next/navigation'; import { NextIntlClientProvider } from 'next-intl'; @@ -35,6 +35,16 @@ export function generateStaticParams() { return locales.map((locale) => ({ locale })); } +export const viewport: Viewport = { + themeColor: [ + { media: '(prefers-color-scheme: light)', color: '#f6f0df' }, + { media: '(prefers-color-scheme: dark)', color: '#221d18' }, + ], + width: 'device-width', + initialScale: 1, + // Su iOS standalone mode mantiene il colore della status bar coerente. +}; + export async function generateMetadata({ params: { locale }, }: { @@ -44,6 +54,21 @@ export async function generateMetadata({ return { title: t('title'), description: t('description'), + manifest: '/manifest.webmanifest', + applicationName: 'KetoPath', + appleWebApp: { + capable: true, + title: 'KetoPath', + statusBarStyle: 'default', + }, + icons: { + icon: [ + { url: '/icons/icon.svg', type: 'image/svg+xml' }, + { url: '/icons/icon-192.png', sizes: '192x192', type: 'image/png' }, + { url: '/icons/icon-512.png', sizes: '512x512', type: 'image/png' }, + ], + apple: [{ url: '/icons/apple-touch-icon.png', sizes: '180x180', type: 'image/png' }], + }, }; } diff --git a/apps/web/src/app/manifest.ts b/apps/web/src/app/manifest.ts new file mode 100644 index 0000000..03f9ea3 --- /dev/null +++ b/apps/web/src/app/manifest.ts @@ -0,0 +1,48 @@ +// Web App Manifest (Next.js 14 file convention). +// Servito a /manifest.webmanifest. PRD §5.6 — installabile su iOS/Android per +// abilitare le notifiche push sui dispositivi mobili (vedi ADR 0003). + +import type { MetadataRoute } from 'next'; + +export default function manifest(): MetadataRoute.Manifest { + return { + name: 'KetoPath — Una keto italiana', + short_name: 'KetoPath', + description: + 'Chetogenica e digiuno intermittente personalizzati: piani settimanali, lista spesa, notifiche.', + lang: 'it', + start_url: '/', + scope: '/', + display: 'standalone', + orientation: 'portrait', + background_color: '#f6f0df', + theme_color: '#221d18', + categories: ['health', 'lifestyle', 'food'], + icons: [ + { + src: '/icons/icon.svg', + sizes: 'any', + type: 'image/svg+xml', + purpose: 'any', + }, + { + src: '/icons/icon-192.png', + sizes: '192x192', + type: 'image/png', + purpose: 'any', + }, + { + src: '/icons/icon-512.png', + sizes: '512x512', + type: 'image/png', + purpose: 'any', + }, + { + src: '/icons/icon-maskable-512.png', + sizes: '512x512', + type: 'image/png', + purpose: 'maskable', + }, + ], + }; +} diff --git a/package.json b/package.json index 2e3d9df..4450ec4 100644 --- a/package.json +++ b/package.json @@ -47,11 +47,11 @@ "@vitest/coverage-v8": "^1.6.0" }, "lint-staged": { - "*.{ts,tsx,jsx,cjs,mjs}": [ + "*.{ts,tsx,jsx,cjs}": [ "eslint --fix --max-warnings=0", "prettier --write" ], - "*.js": [ + "*.{js,mjs}": [ "prettier --write" ], "*.{json,md,yml,yaml,css}": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad52f21c67cef92e9e1cf89b818827e2926262d2..d8afb9eda897f940cc5699d09e950dfbfe424203 100644 GIT binary patch delta 6846 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 YfgkrDin^xp;rNG_t{%t#eE&N3|7WP0`Tzg` delta 546 zcmeBKDRT6I@CH84$@|4hCmYC>ZGOrr%LV7$6bWbFTp$zA2ol+BAjg`}tTAP~#uUbK z`F7tejN5&;FzpuKe)APE>wx3^?I zjwIkaeWfM~|MWB~G-d0ZnboJqSu1SdC>ik{MvHi%#z{XXc-NU7e*JNy=yXIt`XpNCMzc*@+|oRv|js#)=oK zUQv(_ry{9uoW9qQnSFYcBQxLh_c|;Skfb1f+5TFW<+0#&U}W-b|7y?jamI9DY)Veg O-ohffz5Ol=t2qFi<)69$