feat: add favorites panel to meal generator, remove redundant Another one button

- Add clickable favorites counter with expandable panel
- Render saved recipes list with remove button
- Remove duplicate 'Another one' button (Generate already covers it)
- Sync favorite button state when removing from panel
This commit is contained in:
emil
2026-05-13 00:25:09 +03:00
commit 8f11c5af43
161 changed files with 14023 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect width="32" height="32" rx="8" fill="#534AB7"/>
<text x="16" y="22" font-size="16" font-family="monospace" font-weight="bold" text-anchor="middle" fill="white">#</text>
</svg>

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

+24
View File
@@ -0,0 +1,24 @@
{
"name": "Randify — Random Value Generators",
"short_name": "Randify",
"description": "Simple tools for raffles, games, and everything that needs randomness.",
"start_url": "/",
"display": "standalone",
"background_color": "#09090b",
"theme_color": "#534AB7",
"orientation": "portrait-primary",
"scope": "/",
"lang": "en",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
+4
View File
@@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://randify.pro/sitemap-index.xml
+56
View File
@@ -0,0 +1,56 @@
const CACHE_NAME = "randify-v1";
self.addEventListener("install", (event) => {
self.skipWaiting();
});
self.addEventListener("activate", (event) => {
event.waitUntil(self.clients.claim());
});
self.addEventListener("fetch", (event) => {
const { request } = event;
const isNavigate = request.mode === "navigate";
const isSameOrigin = new URL(request.url).origin === self.location.origin;
if (!isSameOrigin) {
return;
}
if (isNavigate) {
// Network-first for HTML pages: fresh content when online,
// fallback to cache when offline.
event.respondWith(
fetch(request)
.then((response) => {
if (response && response.status === 200) {
const clone = response.clone();
caches.open(CACHE_NAME).then((cache) => cache.put(request, clone));
}
return response;
})
.catch(() => caches.match(request)),
);
} else {
// Cache-first for static assets (JS, CSS, SVG, fonts, etc.)
event.respondWith(
caches.match(request).then((cached) => {
if (cached) {
return cached;
}
return fetch(request).then((response) => {
if (
!response ||
response.status !== 200 ||
response.type !== "basic"
) {
return response;
}
const clone = response.clone();
caches.open(CACHE_NAME).then((cache) => cache.put(request, clone));
return response;
});
}),
);
}
});
+8
View File
@@ -0,0 +1,8 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
Verification: dd9dad039a139021
</body>
</html>