my personal site
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update package-lock.json and enhance admin and ads landing HTML

- Removed unused @cloudflare/workers-types from package-lock.json.
- Updated miniflare and wrangler versions in package-lock.json for improved compatibility.
- Refactored ad item handling in admin-html.ts to normalize data and provide default values for missing fields.
- Added new CSS styles and specifications for ad formats in ads-landing-html.ts to improve layout and clarity.

+69 -22
+12
.assetsignore
··· 1 + # Exclude subprojects and dependencies from asset upload 2 + gymtracker/ 3 + node_modules/ 4 + .wrangler/ 5 + .git/ 6 + 7 + # Build output 8 + dist/ 9 + 10 + # OS and misc 11 + .DS_Store 12 + *.log
+8 -17
gymtracker/package-lock.json
··· 124 124 "node": ">=16" 125 125 } 126 126 }, 127 - "node_modules/@cloudflare/workers-types": { 128 - "version": "4.20260317.1", 129 - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260317.1.tgz", 130 - "integrity": "sha512-+G4eVwyCpm8Au1ex8vQBCuA9wnwqetz4tPNRoB/53qvktERWBRMQnrtvC1k584yRE3emMThtuY0gWshvSJ++PQ==", 131 - "dev": true, 132 - "license": "MIT OR Apache-2.0", 133 - "optional": true, 134 - "peer": true 135 - }, 136 127 "node_modules/@cspotcode/source-map-support": { 137 128 "version": "0.8.1", 138 129 "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", ··· 1285 1276 } 1286 1277 }, 1287 1278 "node_modules/miniflare": { 1288 - "version": "4.20260317.1", 1289 - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260317.1.tgz", 1290 - "integrity": "sha512-A3csI1HXEIfqe3oscgpoRMHdYlkReQKPH/g5JE53vFSjoM6YIAOGAzyDNeYffwd9oQkPWDj9xER8+vpxei8klA==", 1279 + "version": "4.20260317.2", 1280 + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260317.2.tgz", 1281 + "integrity": "sha512-qNL+yWAFMX6fr0pWU6Lx1vNpPobpnDSF1V8eunIckWvoIQl8y1oBjL2RJFEGY3un+l3f9gwW9dirDPP26usYJQ==", 1291 1282 "dev": true, 1292 1283 "license": "MIT", 1293 1284 "dependencies": { ··· 1461 1452 } 1462 1453 }, 1463 1454 "node_modules/wrangler": { 1464 - "version": "4.76.0", 1465 - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.76.0.tgz", 1466 - "integrity": "sha512-Wan+CU5a0tu4HIxGOrzjNbkmxCT27HUmzrMj6kc7aoAnjSLv50Ggcn2Ant7wNQrD6xW3g31phKupZJgTZ8wZfQ==", 1455 + "version": "4.77.0", 1456 + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.77.0.tgz", 1457 + "integrity": "sha512-E2Gm69+K++BFd3QvoWjC290RPQj1vDOUotA++sNHmtKPb7EP6C8Qv+1D5Ii73tfZtyNgakpqHlh8lBBbVWTKAQ==", 1467 1458 "dev": true, 1468 1459 "license": "MIT OR Apache-2.0", 1469 1460 "dependencies": { ··· 1471 1462 "@cloudflare/unenv-preset": "2.16.0", 1472 1463 "blake3-wasm": "2.1.5", 1473 1464 "esbuild": "0.27.3", 1474 - "miniflare": "4.20260317.1", 1465 + "miniflare": "4.20260317.2", 1475 1466 "path-to-regexp": "6.3.0", 1476 1467 "unenv": "2.0.0-rc.24", 1477 1468 "workerd": "1.20260317.1" ··· 1481 1472 "wrangler2": "bin/wrangler.js" 1482 1473 }, 1483 1474 "engines": { 1484 - "node": ">=20.0.0" 1475 + "node": ">=20.3.0" 1485 1476 }, 1486 1477 "optionalDependencies": { 1487 1478 "fsevents": "~2.3.2"
+10 -5
gymtracker/src/admin-html.ts
··· 751 751 if (!item || typeof item !== 'object') { console.warn('Admin: skipping malformed ad at index', i); return; } 752 752 const id = item.id; 753 753 if (!id || typeof id !== 'string') { console.warn('Admin: skipping ad without valid id at index', i); return; } 754 - if (typeof item.sponsor !== 'string' || typeof item.headline !== 'string' || typeof item.cta !== 'string') { 755 - console.warn('Admin: skipping ad with missing required fields at index', i); 756 - return; 757 - } 758 - result.push(item); 754 + const normalized = { 755 + ...item, 756 + id: id.trim(), 757 + sponsor: typeof item.sponsor === 'string' && item.sponsor.trim() ? item.sponsor : '(no sponsor)', 758 + headline: typeof item.headline === 'string' && item.headline.trim() ? item.headline : '(no headline)', 759 + cta: typeof item.cta === 'string' && item.cta.trim() ? item.cta : 'Learn more', 760 + active: typeof item.active === 'boolean' ? item.active : false, 761 + tier: typeof item.tier === 'string' && item.tier.trim() ? item.tier.toLowerCase() : 'banner', 762 + }; 763 + result.push(normalized); 759 764 }); 760 765 return result; 761 766 }
+33
gymtracker/src/ads-landing-html.ts
··· 352 352 margin-bottom: 4px; 353 353 } 354 354 .format-card-desc { font-size: 0.875rem; color: var(--muted); line-height: 1.6; } 355 + .format-specs { 356 + margin-top: 14px; 357 + padding-top: 12px; 358 + border-top: 1px solid var(--border); 359 + font-size: 0.8125rem; 360 + color: var(--text-mid); 361 + line-height: 1.65; 362 + } 363 + .format-specs dt { 364 + font-weight: 600; 365 + color: var(--text); 366 + margin-top: 8px; 367 + } 368 + .format-specs dt:first-child { margin-top: 0; } 369 + .format-specs dd { margin: 2px 0 0; } 355 370 356 371 /* ── Exclusive callout ─────────────────────────────────── */ 357 372 .exclusive-callout { ··· 1239 1254 <div class="format-card-info"> 1240 1255 <div class="format-card-name">Text</div> 1241 1256 <div class="format-card-desc">Sponsor name, headline, subline, and a CTA. No image needed.</div> 1257 + <dl class="format-specs"> 1258 + <dt>Assets</dt> 1259 + <dd>Sponsor name, headline, subline (optional), CTA. Optional logo (20×20px).</dd> 1260 + <dt>Image</dt> 1261 + <dd>None required.</dd> 1262 + </dl> 1242 1263 </div> 1243 1264 </div> 1244 1265 <div class="format-card"> ··· 1255 1276 <div class="format-card-info"> 1256 1277 <div class="format-card-name">Banner</div> 1257 1278 <div class="format-card-desc">An image plus a short block of copy. Standard placement in the feed.</div> 1279 + <dl class="format-specs"> 1280 + <dt>Banner image</dt> 1281 + <dd>1200×628px (landscape). JPG or PNG, max 2MB.</dd> 1282 + <dt>Copy</dt> 1283 + <dd>Headline, subline (optional), CTA. Optional logo (20×20px).</dd> 1284 + </dl> 1258 1285 </div> 1259 1286 </div> 1260 1287 <div class="format-card"> ··· 1271 1298 <div class="format-card-info"> 1272 1299 <div class="format-card-name">Feature</div> 1273 1300 <div class="format-card-desc">Taller image and more room for copy. The largest format available.</div> 1301 + <dl class="format-specs"> 1302 + <dt>Feature image</dt> 1303 + <dd>1080×1350px (4:5 portrait). JPG or PNG, max 2MB.</dd> 1304 + <dt>Copy</dt> 1305 + <dd>Headline, subline (optional), CTA. Optional logo (20×20px). More room for subline.</dd> 1306 + </dl> 1274 1307 </div> 1275 1308 </div> 1276 1309 </div>
+6
workers/gymtracker-ads-api/package-lock.json
··· 1 + { 2 + "name": "gymtracker-ads-api", 3 + "lockfileVersion": 3, 4 + "requires": true, 5 + "packages": {} 6 + }