@@ -600,6 +599,26 @@
const current = sel.value;
sel.innerHTML = ADMIN.categories.map(c => `
`).join('');
if (current) sel.value = current;
+ updateAdminSubcategories();
+ }
+
+ function updateAdminSubcategories(checked = []) {
+ const catId = document.getElementById('postCategory').value;
+ const cat = ADMIN.categories.find(c => c.id === catId);
+ const subs = cat?.subcategories || [];
+ const group = document.getElementById('adminSubcatGroup');
+ const box = document.getElementById('adminSubcatCheckboxes');
+ if (!subs.length) { group.style.display = 'none'; box.innerHTML = ''; return; }
+ group.style.display = '';
+ box.innerHTML = subs.map(s => `
+
`).join('');
+ }
+
+ function getCheckedSubcategories() {
+ return [...document.querySelectorAll('#adminSubcatCheckboxes input[type=checkbox]:checked')].map(cb => cb.value);
}
// ===========================
@@ -645,11 +664,13 @@
let editingId = null;
async function savePost() {
- const title = document.getElementById('postTitle').value.trim();
- const emoji = document.getElementById('postEmoji').value.trim() || '🍽️';
- const category = document.getElementById('postCategory').value;
- const author = document.getElementById('postAuthor').value.trim();
- const desc = document.getElementById('postDesc').value.trim();
+ const title = document.getElementById('postTitle').value.trim();
+ const category = document.getElementById('postCategory').value;
+ const subcategory = getCheckedSubcategories();
+ const cat = ADMIN.categories.find(c => c.id === category);
+ const emoji = cat?.emoji || '📝';
+ const author = document.getElementById('postAuthor').value.trim();
+ const desc = document.getElementById('postDesc').value.trim();
if (!title) { showToast(at('no_title')); return; }
@@ -658,7 +679,7 @@
document.getElementById('postImg2').value.trim(),
document.getElementById('postImg3').value.trim(),
].filter(Boolean);
- const post = { title, emoji, category, author, desc, images, type: currentType };
+ const post = { title, emoji, category, subcategory, author, desc, images, type: currentType };
if (currentType === 'recipe') {
post.time = document.getElementById('postTime').value.trim();
@@ -698,9 +719,11 @@
editingId = id;
document.getElementById('formTitle').textContent = at('form_edit');
document.getElementById('postTitle').value = p.title;
- document.getElementById('postEmoji').value = p.emoji;
document.getElementById('postCategory').value = p.category;
document.getElementById('postAuthor').value = p.author || '';
+ // Load subcategory checkboxes with existing values
+ const existingSubs = Array.isArray(p.subcategory) ? p.subcategory : (p.subcategory ? [p.subcategory] : []);
+ updateAdminSubcategories(existingSubs);
document.getElementById('postDesc').value = p.desc || '';
setAdmImgPreview(1, p.images?.[0] || '');
setAdmImgPreview(2, p.images?.[1] || '');
@@ -735,8 +758,8 @@
function resetForm() {
editingId = null;
document.getElementById('postTitle').value = '';
- document.getElementById('postEmoji').value = '';
document.getElementById('postAuthor').value = '';
+ updateAdminSubcategories([]);
document.getElementById('postDesc').value = '';
document.getElementById('postTime').value = '';
document.getElementById('postServings').value = '';
diff --git a/api.php b/api.php
index dba6175..6394c2d 100644
--- a/api.php
+++ b/api.php
@@ -60,15 +60,19 @@ function defaultCategories(): array {
['id' => 'kasvis', 'fi' => 'Kasvis'],
['id' => 'vegaaniset', 'fi' => 'Vegaaniset'],
['id' => 'jalkiruuat', 'fi' => 'Jälkiruuat'],
+ ['id' => 'muut', 'fi' => 'Muut'],
]],
['id' => 'knitting', 'fi' => 'Neulominen', 'en' => 'Knitting', 'emoji' => '🧶',
'subcategories' => [
['id' => 'aloittelijoille', 'fi' => 'Aloittelijoille'],
['id' => 'vaatteet', 'fi' => 'Vaatteet'],
['id' => 'kodin_tekstiilit','fi' => 'Kodin tekstiilit'],
+ ['id' => 'muut', 'fi' => 'Muut'],
]],
['id' => 'tips', 'fi' => 'Vinkit', 'en' => 'Tips', 'emoji' => '💡',
- 'subcategories' => []],
+ 'subcategories' => [
+ ['id' => 'muut', 'fi' => 'Muut'],
+ ]],
];
}
@@ -316,15 +320,25 @@ function getOrInitCategories(): array {
return $cats;
}
$cats = readData('categories.json', []);
- // Merge in subcategories if existing file doesn't have them yet
+ // Merge in subcategories (and new ones) from defaults if missing
$defaults = defaultCategories();
$defaultMap = [];
foreach ($defaults as $d) { $defaultMap[$d['id']] = $d; }
$changed = false;
foreach ($cats as &$cat) {
- if (!isset($cat['subcategories']) && isset($defaultMap[$cat['id']]['subcategories'])) {
- $cat['subcategories'] = $defaultMap[$cat['id']]['subcategories'];
+ $defSubs = $defaultMap[$cat['id']]['subcategories'] ?? [];
+ if (!isset($cat['subcategories'])) {
+ $cat['subcategories'] = $defSubs;
$changed = true;
+ } else {
+ // Add any new subcategory ids from defaults that don't exist yet
+ $existingIds = array_column($cat['subcategories'], 'id');
+ foreach ($defSubs as $ds) {
+ if (!in_array($ds['id'], $existingIds)) {
+ $cat['subcategories'][] = $ds;
+ $changed = true;
+ }
+ }
}
}
unset($cat);
diff --git a/script.js b/script.js
index 38fd810..80cb9e5 100644
--- a/script.js
+++ b/script.js
@@ -177,7 +177,7 @@ function renderCards() {
? `

`
: `
${p.emoji}
`;
return `
-
+
${cardImgHTML}
${getCategoryLabel(p.category)}
@@ -237,8 +237,9 @@ function filterPosts() {
const cards = document.querySelectorAll('.recipe-card');
let visible = 0;
cards.forEach(card => {
- const matchesCat = currentFilter === 'all' || card.dataset.category === currentFilter;
- const matchesSub = currentSubFilter === 'all' || card.dataset.subcategory === currentSubFilter;
+ const matchesCat = currentFilter === 'all' || card.dataset.category === currentFilter;
+ const postSubs = (card.dataset.subcategory || '').split(',').filter(Boolean);
+ const matchesSub = currentSubFilter === 'all' || postSubs.includes(currentSubFilter);
const title = (card.querySelector('h3')?.textContent || '').toLowerCase();
const desc = (card.querySelector('p:not(.card-author)')?.textContent || '').toLowerCase();
const subLbl = (card.dataset.subcategory || '').toLowerCase();
@@ -526,7 +527,8 @@ async function submitPublicPost() {
}
const category = document.getElementById('sub-category').value;
- const subcategory = document.getElementById('sub-subcategory')?.value || '';
+ const subVal = document.getElementById('sub-subcategory')?.value || '';
+ const subcategory = subVal ? [subVal] : [];
const cat = APP.categories.find(c => c.id === category);
const emoji = cat?.emoji || '📝';
const author = document.getElementById('sub-author').value.trim() || 'Vieras';