Logo, emoji pois lomakkeesta, alikategoria-bugifi

- logo.svg: SVG-tekstilogo (sydän + tykkää kursiivillaa + .fi cream)
  korvaa emoji+h1-yhdistelmän; .logo-svg CSS-luokka headeriin
- index.html: emoji-kenttä poistettu julkaisulomakkeesta;
  kategoria-select ilman erillistä paria
- script.js: emoji haetaan automaattisesti kategoriasta, ei lomakkeen
  kentästä; sub-emoji poistettu reset-listalta
- api.php: seed_categories-toiminto päivittää categories.json:n
  uusilla subcategories-tiedoilla
- admin.html: seedPosts() kutsuu myös seed_categories ensin →
  alikategoriat toimivat nyt heti "Lataa esimerkkisisältö" -napin jälkeen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 01:52:09 +02:00
parent f98aa72ca0
commit 416db62e5c
6 changed files with 35 additions and 15 deletions

View File

@@ -425,13 +425,15 @@
// LOGIN // LOGIN
// =========================== // ===========================
async function seedPosts() { async function seedPosts() {
if (!confirm('Tämä korvaa KAIKKI nykyiset julkaisut oletussisällöllä (30 julkaisua). Jatketaanko?')) return; if (!confirm('Tämä korvaa KAIKKI nykyiset julkaisut ja kategoriat oletussisällöllä. Jatketaanko?')) return;
// Seed categories first (needed for subcategories to work)
await apiPost('seed_categories', {});
const data = await apiPost('seed_posts', {}); const data = await apiPost('seed_posts', {});
if (data.ok) { if (data.ok) {
const postsData = await apiGet('posts'); const postsData = await apiGet('posts');
ADMIN.posts = postsData.posts || []; ADMIN.posts = postsData.posts || [];
renderPostList(); renderPostList();
showToast('✅ Ladattu ' + data.count + ' julkaisua!'); showToast('✅ Ladattu ' + data.count + ' julkaisua + kategoriat päivitetty!');
} else { } else {
showToast('⚠️ ' + (data.error || 'Virhe')); showToast('⚠️ ' + (data.error || 'Virhe'));
} }

View File

@@ -418,6 +418,12 @@ switch ($action) {
writeData('posts.json', $posts); writeData('posts.json', $posts);
ok(['count' => count($posts)]); ok(['count' => count($posts)]);
case 'seed_categories':
if (!isAdmin()) err('Unauthorized', 403);
$cats = defaultCategories();
writeData('categories.json', $cats);
ok(['count' => count($cats)]);
case 'admin_login': case 'admin_login':
if (($body['password'] ?? '') === ADMIN_PASSWORD) { if (($body['password'] ?? '') === ADMIN_PASSWORD) {
$_SESSION['tykkaafi_admin'] = true; $_SESSION['tykkaafi_admin'] = true;

View File

@@ -12,8 +12,7 @@
<header> <header>
<div class="header-inner"> <div class="header-inner">
<div class="logo"> <div class="logo">
<span class="logo-icon">🍳</span> <img src="logo.svg" alt="tykkää.fi" class="logo-svg" />
<h1>tykkää.fi</h1>
</div> </div>
<p class="tagline" data-i18n="tagline"></p> <p class="tagline" data-i18n="tagline"></p>
<nav> <nav>
@@ -106,15 +105,9 @@
<input type="text" id="sub-title" placeholder="esim. Mummon mustikkapiirakka" maxlength="100" /> <input type="text" id="sub-title" placeholder="esim. Mummon mustikkapiirakka" maxlength="100" />
</div> </div>
<div class="form-row"> <div class="form-group">
<div class="form-group"> <label>Kategoria</label>
<label>Kategoria</label> <select id="sub-category"></select>
<select id="sub-category"></select>
</div>
<div class="form-group">
<label>Emoji</label>
<input type="text" id="sub-emoji" placeholder="🍽️" maxlength="4" />
</div>
</div> </div>
<div class="form-group"> <div class="form-group">

17
logo.svg Normal file
View File

@@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 252 62" width="252" height="62" role="img" aria-label="tykkää.fi">
<!-- Heart -->
<path fill="#e07b39" d="M14,5.5 C14,0.5 7.5,-3 3.5,1 C-0.5,-3 -7,0.5 -7,5.5 C-7,12 3.5,20.5 3.5,20.5 C3.5,20.5 14,12 14,5.5Z" transform="translate(9,18)"/>
<!-- tykkää -->
<text x="36" y="46"
font-family="Georgia, 'Times New Roman', serif"
font-style="italic"
font-size="44"
fill="#ffffff"
letter-spacing="-0.5">tykkää</text>
<!-- .fi -->
<text x="196" y="46"
font-family="Georgia, 'Times New Roman', serif"
font-style="italic"
font-size="34"
fill="#e8c9a8">.fi</text>
</svg>

After

Width:  |  Height:  |  Size: 701 B

View File

@@ -507,8 +507,9 @@ async function submitPublicPost() {
return; return;
} }
const emoji = document.getElementById('sub-emoji').value.trim() || '📝';
const category = document.getElementById('sub-category').value; const category = document.getElementById('sub-category').value;
const cat = APP.categories.find(c => c.id === category);
const emoji = cat?.emoji || '📝';
const author = document.getElementById('sub-author').value.trim() || 'Vieras'; const author = document.getElementById('sub-author').value.trim() || 'Vieras';
const desc = document.getElementById('sub-desc').value.trim(); const desc = document.getElementById('sub-desc').value.trim();
const images = [ const images = [
@@ -551,7 +552,7 @@ async function submitPublicPost() {
renderCategoryFilters(); renderCategoryFilters();
// Reset form fields // Reset form fields
['sub-title','sub-emoji','sub-author','sub-desc','sub-img1','sub-img2','sub-img3', ['sub-title','sub-author','sub-desc','sub-img1','sub-img2','sub-img3',
'sub-time','sub-servings','sub-ingredients','sub-steps','sub-body'].forEach(id => { 'sub-time','sub-servings','sub-ingredients','sub-steps','sub-body'].forEach(id => {
const el = document.getElementById(id); const el = document.getElementById(id);
if (el) el.value = ''; if (el) el.value = '';

View File

@@ -51,6 +51,7 @@ header {
} }
.logo-icon { font-size: 2.4rem; } .logo-icon { font-size: 2.4rem; }
.logo-svg { height: 52px; width: auto; display: block; }
header h1 { header h1 {
font-size: 2.4rem; font-size: 2.4rem;