The entire skate-spots codebase was accidentally copied into src/src/ and public/public/ instead of src/ and public/ directly. This left the real src/ directory as blank MKStack template stubs, explaining why the landing page showed the default template instead of SkateSpots. Changes made: - Copied all files from src/src/ up to src/ (App.tsx, AppRouter.tsx, main.tsx, all pages, components, hooks, contexts, lib, i18n, test) - Copied all files from public/public/ up to public/ (images, manifest, etc.) - Deleted src/src/ and public/public/ nested directories - Removed HelloWorld.tsx template stub from pages/ - Retained the previously fixed index.css (Tailwind v3 directives) Full skate-spots feature set is now active: - All 30+ routes (map, events, spots, coaches, marketplace, wallet, etc.) - NWCProvider, LanguageProvider, PWAInstallPrompt, AmberCallbackHandler - Skate community relays (goskatespots.nostr1.com, wotr.relatr.xyz, etc.) - Outfit Variable font, Amber pre-check in main.tsx - All hooks (useSkateSpots, useCoaches, useZaps, etc.) - i18n support (en/es) Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
139 lines
4.9 KiB
HTML
139 lines
4.9 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Generate SkateSpots Icons</title>
|
|
</head>
|
|
<body>
|
|
<h1>SkateSpots Icon Generator</h1>
|
|
<p>Right-click each icon below and "Save image as..." to download:</p>
|
|
|
|
<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; max-width: 800px;">
|
|
<div>
|
|
<canvas id="icon72" width="72" height="72"></canvas>
|
|
<p>icon-72.png (72x72)</p>
|
|
</div>
|
|
<div>
|
|
<canvas id="icon96" width="96" height="96"></canvas>
|
|
<p>icon-96.png (96x96)</p>
|
|
</div>
|
|
<div>
|
|
<canvas id="icon128" width="128" height="128"></canvas>
|
|
<p>icon-128.png (128x128)</p>
|
|
</div>
|
|
<div>
|
|
<canvas id="icon144" width="144" height="144"></canvas>
|
|
<p>icon-144.png (144x144)</p>
|
|
</div>
|
|
<div>
|
|
<canvas id="icon152" width="152" height="152"></canvas>
|
|
<p>icon-152.png (152x152)</p>
|
|
</div>
|
|
<div>
|
|
<canvas id="icon192" width="192" height="192"></canvas>
|
|
<p>icon-192.png (192x192)</p>
|
|
</div>
|
|
<div>
|
|
<canvas id="icon384" width="384" height="384"></canvas>
|
|
<p>icon-384.png (384x384)</p>
|
|
</div>
|
|
<div>
|
|
<canvas id="icon512" width="512" height="512"></canvas>
|
|
<p>icon-512.png (512x512)</p>
|
|
</div>
|
|
<div>
|
|
<canvas id="logo" width="32" height="32"></canvas>
|
|
<p>logo.png (32x32)</p>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function drawIcon(canvas) {
|
|
const ctx = canvas.getContext('2d');
|
|
const size = canvas.width;
|
|
|
|
// Black background
|
|
ctx.fillStyle = '#000000';
|
|
ctx.fillRect(0, 0, size, size);
|
|
|
|
// Gradient circle background
|
|
const gradient = ctx.createLinearGradient(0, 0, size, size);
|
|
gradient.addColorStop(0, '#ff0040');
|
|
gradient.addColorStop(0.5, '#ff6600');
|
|
gradient.addColorStop(1, '#ccff00');
|
|
|
|
ctx.fillStyle = gradient;
|
|
ctx.beginPath();
|
|
ctx.arc(size/2, size/2, size/2, 0, Math.PI * 2);
|
|
ctx.fill();
|
|
|
|
// Draw map pin icon in white
|
|
ctx.fillStyle = '#ffffff';
|
|
ctx.strokeStyle = '#ffffff';
|
|
ctx.lineWidth = size * 0.04;
|
|
|
|
// Pin shape
|
|
const centerX = size / 2;
|
|
const centerY = size / 2.2;
|
|
const radius = size * 0.25;
|
|
|
|
ctx.beginPath();
|
|
ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
|
|
ctx.fill();
|
|
|
|
// Pin point
|
|
ctx.beginPath();
|
|
ctx.moveTo(centerX - radius * 0.5, centerY + radius);
|
|
ctx.lineTo(centerX, centerY + radius * 2);
|
|
ctx.lineTo(centerX + radius * 0.5, centerY + radius);
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
|
|
// Inner circle
|
|
ctx.fillStyle = '#000000';
|
|
ctx.beginPath();
|
|
ctx.arc(centerX, centerY, radius * 0.5, 0, Math.PI * 2);
|
|
ctx.fill();
|
|
}
|
|
|
|
// Generate all sizes
|
|
['icon72', 'icon96', 'icon128', 'icon144', 'icon152', 'icon192', 'icon384', 'icon512', 'logo'].forEach(id => {
|
|
const canvas = document.getElementById(id);
|
|
drawIcon(canvas);
|
|
});
|
|
|
|
// Auto-download function
|
|
function downloadAllIcons() {
|
|
const icons = [
|
|
{ id: 'icon72', name: 'icon-72.png' },
|
|
{ id: 'icon96', name: 'icon-96.png' },
|
|
{ id: 'icon128', name: 'icon-128.png' },
|
|
{ id: 'icon144', name: 'icon-144.png' },
|
|
{ id: 'icon152', name: 'icon-152.png' },
|
|
{ id: 'icon192', name: 'icon-192.png' },
|
|
{ id: 'icon384', name: 'icon-384.png' },
|
|
{ id: 'icon512', name: 'icon-512.png' },
|
|
{ id: 'logo', name: 'logo.png' },
|
|
];
|
|
|
|
icons.forEach((icon, index) => {
|
|
setTimeout(() => {
|
|
const canvas = document.getElementById(icon.id);
|
|
canvas.toBlob(blob => {
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = icon.name;
|
|
a.click();
|
|
URL.revokeObjectURL(url);
|
|
});
|
|
}, index * 500);
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<br><br>
|
|
<button onclick="downloadAllIcons()" style="padding: 12px 24px; background: #ff0040; color: white; border: none; border-radius: 8px; font-weight: bold; cursor: pointer;">
|
|
Download All Icons
|
|
</button>
|
|
</body>
|
|
</html>
|