From 5352f398875313d7931508da4657a964ccbb2f75 Mon Sep 17 00:00:00 2001 From: jeremy bayse Date: Mon, 3 Aug 2026 11:03:37 +0200 Subject: [PATCH] Make SuiviCPT an installable PWA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds what iOS/Android need to treat the site as an installable app from Safari's "Add to Home Screen": a manifest.json, apple-touch-icon set generated from the existing logo mark (scripts/generate-icons.mjs, sharp as a dev dependency), and the apple-mobile-web-app-* meta tags iOS Safari requires since it ignores manifest.json entirely. The service worker is deliberately minimal — this app shows live financial data, so navigations always hit the network first. It only caches enough to serve offline.html when there's no connection, not a full offline-first app shell. Co-Authored-By: Claude Sonnet 5 --- package-lock.json | 612 ++++++++++++++++++++ package.json | 1 + public/icons/apple-touch-icon-152.png | Bin 0 -> 3922 bytes public/icons/apple-touch-icon-167.png | Bin 0 -> 4309 bytes public/icons/apple-touch-icon.png | Bin 0 -> 4728 bytes public/icons/icon-192.png | Bin 0 -> 5186 bytes public/icons/icon-512.png | Bin 0 -> 18927 bytes public/icons/icon-maskable-512.png | Bin 0 -> 16802 bytes public/manifest.json | 32 + public/offline.html | 50 ++ public/sw.js | 33 ++ resources/views/layouts/app.blade.php | 1 + resources/views/layouts/guest.blade.php | 1 + resources/views/partials/pwa-meta.blade.php | 18 + scripts/generate-icons.mjs | 40 ++ 15 files changed, 788 insertions(+) create mode 100644 public/icons/apple-touch-icon-152.png create mode 100644 public/icons/apple-touch-icon-167.png create mode 100644 public/icons/apple-touch-icon.png create mode 100644 public/icons/icon-192.png create mode 100644 public/icons/icon-512.png create mode 100644 public/icons/icon-maskable-512.png create mode 100644 public/manifest.json create mode 100644 public/offline.html create mode 100644 public/sw.js create mode 100644 resources/views/partials/pwa-meta.blade.php create mode 100644 scripts/generate-icons.mjs diff --git a/package-lock.json b/package-lock.json index 0f61414..1d9ed11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "concurrently": "^9.0.1", "laravel-vite-plugin": "^1.2.0", "postcss": "^8.4.31", + "sharp": "^0.35.3", "tailwindcss": "^3.1.0", "vite": "^6.0.11" } @@ -32,6 +33,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", @@ -474,6 +486,533 @@ "node": ">=18" } }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz", + "integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.3.2" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz", + "integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.3.2" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz", + "integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.3" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz", + "integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz", + "integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz", + "integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz", + "integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz", + "integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz", + "integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz", + "integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz", + "integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz", + "integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz", + "integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz", + "integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.3.2" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz", + "integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.3.2" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz", + "integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.3.2" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz", + "integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.3.2" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz", + "integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.3.2" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz", + "integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.3.2" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz", + "integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.3.2" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz", + "integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.3.2" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz", + "integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==", + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.1" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz", + "integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/sharp-wasm32": "0.35.3" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz", + "integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz", + "integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz", + "integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -1382,6 +1921,16 @@ "node": ">=0.4.0" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -2450,6 +2999,69 @@ "tslib": "^2.1.0" } }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz", + "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.1.0", + "detect-libc": "^2.1.2", + "semver": "^7.8.5" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.35.3", + "@img/sharp-darwin-x64": "0.35.3", + "@img/sharp-freebsd-wasm32": "0.35.3", + "@img/sharp-libvips-darwin-arm64": "1.3.2", + "@img/sharp-libvips-darwin-x64": "1.3.2", + "@img/sharp-libvips-linux-arm": "1.3.2", + "@img/sharp-libvips-linux-arm64": "1.3.2", + "@img/sharp-libvips-linux-ppc64": "1.3.2", + "@img/sharp-libvips-linux-riscv64": "1.3.2", + "@img/sharp-libvips-linux-s390x": "1.3.2", + "@img/sharp-libvips-linux-x64": "1.3.2", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.2", + "@img/sharp-libvips-linuxmusl-x64": "1.3.2", + "@img/sharp-linux-arm": "0.35.3", + "@img/sharp-linux-arm64": "0.35.3", + "@img/sharp-linux-ppc64": "0.35.3", + "@img/sharp-linux-riscv64": "0.35.3", + "@img/sharp-linux-s390x": "0.35.3", + "@img/sharp-linux-x64": "0.35.3", + "@img/sharp-linuxmusl-arm64": "0.35.3", + "@img/sharp-linuxmusl-x64": "0.35.3", + "@img/sharp-webcontainers-wasm32": "0.35.3", + "@img/sharp-win32-arm64": "0.35.3", + "@img/sharp-win32-ia32": "0.35.3", + "@img/sharp-win32-x64": "0.35.3" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, "node_modules/shell-quote": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.9.0.tgz", diff --git a/package.json b/package.json index cd60955..ced959f 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "concurrently": "^9.0.1", "laravel-vite-plugin": "^1.2.0", "postcss": "^8.4.31", + "sharp": "^0.35.3", "tailwindcss": "^3.1.0", "vite": "^6.0.11" }, diff --git a/public/icons/apple-touch-icon-152.png b/public/icons/apple-touch-icon-152.png new file mode 100644 index 0000000000000000000000000000000000000000..ea6c1a9ea2e05ffe9d388b6a7462e66f3626a787 GIT binary patch literal 3922 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 literal 0 HcmV?d00001 diff --git a/public/icons/icon-192.png b/public/icons/icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd1da6f95238fb9cd6cc0c1a1071f7df9d320d5 GIT binary patch literal 5186 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 literal 0 HcmV?d00001 diff --git a/public/icons/icon-maskable-512.png b/public/icons/icon-maskable-512.png new file mode 100644 index 0000000000000000000000000000000000000000..f1bb33c0b41031c6b0e88a84f2071c2647844906 GIT binary patch literal 16802 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 X1sp^7r>=xUz(1v%s`A;_jokkSTNn9@ literal 0 HcmV?d00001 diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..f7cf9c7 --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,32 @@ +{ + "name": "SuiviCPT", + "short_name": "SuiviCPT", + "description": "Suivi budgétaire et transactions pour le foyer", + "start_url": "/dashboard", + "scope": "/", + "display": "standalone", + "orientation": "portrait", + "background_color": "#f5ead8", + "theme_color": "#c67139", + "lang": "fr", + "icons": [ + { + "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/public/offline.html b/public/offline.html new file mode 100644 index 0000000..f6cf2e5 --- /dev/null +++ b/public/offline.html @@ -0,0 +1,50 @@ + + + + + + SuiviCPT — Hors ligne + + + +
+
+ + + + + +
+

Pas de connexion

+

SuiviCPT a besoin d'internet pour afficher tes données à jour.

+ +
+ + diff --git a/public/sw.js b/public/sw.js new file mode 100644 index 0000000..b31fdd4 --- /dev/null +++ b/public/sw.js @@ -0,0 +1,33 @@ +// Minimal service worker: exists only to satisfy PWA installability criteria +// and give a usable offline fallback. Deliberately not a full offline-first +// cache — this app shows live financial data, so navigations always go to +// the network first; only the built Vite assets and the offline page are +// cached, never HTML page content. +const CACHE = 'suivicpt-shell-v1'; +const OFFLINE_URL = '/offline.html'; + +self.addEventListener('install', (event) => { + event.waitUntil( + caches.open(CACHE).then((cache) => cache.add(OFFLINE_URL)) + ); + self.skipWaiting(); +}); + +self.addEventListener('activate', (event) => { + event.waitUntil( + caches.keys().then((keys) => + Promise.all(keys.filter((key) => key !== CACHE).map((key) => caches.delete(key))) + ) + ); + self.clients.claim(); +}); + +self.addEventListener('fetch', (event) => { + if (event.request.mode !== 'navigate') { + return; + } + + event.respondWith( + fetch(event.request).catch(() => caches.match(OFFLINE_URL)) + ); +}); diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 2f4ca9a..1edab01 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -8,6 +8,7 @@ {{ config('app.name', 'Laravel') }} @include('partials.theme-script') + @include('partials.pwa-meta') diff --git a/resources/views/layouts/guest.blade.php b/resources/views/layouts/guest.blade.php index a9859cb..6b40cdf 100644 --- a/resources/views/layouts/guest.blade.php +++ b/resources/views/layouts/guest.blade.php @@ -8,6 +8,7 @@ {{ config('app.name', 'Laravel') }} @include('partials.theme-script') + @include('partials.pwa-meta') diff --git a/resources/views/partials/pwa-meta.blade.php b/resources/views/partials/pwa-meta.blade.php new file mode 100644 index 0000000..6cfd529 --- /dev/null +++ b/resources/views/partials/pwa-meta.blade.php @@ -0,0 +1,18 @@ + + + +{{-- iOS Safari ignores manifest.json entirely — it needs its own tags to + treat the site as an installable, standalone app. --}} + + + + + + + + + diff --git a/scripts/generate-icons.mjs b/scripts/generate-icons.mjs new file mode 100644 index 0000000..b973888 --- /dev/null +++ b/scripts/generate-icons.mjs @@ -0,0 +1,40 @@ +import sharp from 'sharp'; +import { mkdirSync } from 'fs'; + +const BRAND = '#c67139'; +const MARK = '#fff8ee'; + +function svgIcon({ size, markScale }) { + const r = (316 / 2) * markScale; + const cx = size / 2; + const cy = size / 2; + const scale = (size * markScale) / 316; + + return ` + + + + + + + +`; +} + +mkdirSync('public/icons', { recursive: true }); + +const targets = [ + { file: 'public/icons/apple-touch-icon.png', size: 180, markScale: 0.68 }, + { file: 'public/icons/apple-touch-icon-152.png', size: 152, markScale: 0.68 }, + { file: 'public/icons/apple-touch-icon-167.png', size: 167, markScale: 0.68 }, + { file: 'public/icons/icon-192.png', size: 192, markScale: 0.68 }, + { file: 'public/icons/icon-512.png', size: 512, markScale: 0.68 }, + { file: 'public/icons/icon-maskable-512.png', size: 512, markScale: 0.55 }, +]; + +for (const t of targets) { + await sharp(Buffer.from(svgIcon(t))) + .png() + .toFile(t.file); + console.log(`wrote ${t.file}`); +}