diff --git a/api.php b/api.php index 95635c9..db42875 100644 --- a/api.php +++ b/api.php @@ -1912,6 +1912,100 @@ switch ($action) { echo json_encode(['success' => true]); break; + // ---------- OHJEET (GUIDES) ---------- + case 'guides': + requireAuth(); + $companyId = requireCompany(); + echo json_encode(dbLoadGuides($companyId)); + break; + + case 'guide': + requireAuth(); + requireCompany(); + $id = $_GET['id'] ?? ''; + $guide = dbLoadGuide($id); + if (!$guide) { http_response_code(404); echo json_encode(['error' => 'Ohjetta ei löydy']); exit; } + echo json_encode($guide); + break; + + case 'guide_save': + requireAuth(); + requireAdmin(); + $companyId = requireCompany(); + if ($method !== 'POST') break; + $input = json_decode(file_get_contents('php://input'), true); + $isNew = empty($input['id']); + $guide = [ + 'id' => $input['id'] ?? generateId(), + 'category_id' => $input['category_id'] ?? null, + 'title' => trim($input['title'] ?? ''), + 'content' => $input['content'] ?? '', + 'tags' => trim($input['tags'] ?? ''), + 'author' => $isNew ? currentUser() : ($input['author'] ?? currentUser()), + 'pinned' => !empty($input['pinned']), + 'luotu' => $isNew ? date('Y-m-d H:i:s') : ($input['luotu'] ?? date('Y-m-d H:i:s')), + 'muokattu' => $isNew ? null : date('Y-m-d H:i:s'), + 'muokkaaja' => $isNew ? '' : currentUser(), + ]; + if (empty($guide['title'])) { + http_response_code(400); + echo json_encode(['error' => 'Otsikko vaaditaan']); + exit; + } + dbSaveGuide($companyId, $guide); + dbAddLog($companyId, currentUser(), $isNew ? 'guide_create' : 'guide_update', $guide['id'], $guide['title'], ($isNew ? 'Loi' : 'Muokkasi') . ' ohjeen'); + echo json_encode($guide); + break; + + case 'guide_delete': + requireAuth(); + requireAdmin(); + $companyId = requireCompany(); + if ($method !== 'POST') break; + $input = json_decode(file_get_contents('php://input'), true); + $id = $input['id'] ?? ''; + $guide = dbLoadGuide($id); + dbDeleteGuide($id); + dbAddLog($companyId, currentUser(), 'guide_delete', $id, $guide ? $guide['title'] : '', 'Poisti ohjeen'); + echo json_encode(['success' => true]); + break; + + case 'guide_categories': + requireAuth(); + $companyId = requireCompany(); + echo json_encode(dbLoadGuideCategories($companyId)); + break; + + case 'guide_category_save': + requireAuth(); + requireAdmin(); + $companyId = requireCompany(); + if ($method !== 'POST') break; + $input = json_decode(file_get_contents('php://input'), true); + $cat = [ + 'id' => $input['id'] ?? generateId(), + 'nimi' => trim($input['nimi'] ?? ''), + 'sort_order' => (int)($input['sort_order'] ?? 0), + ]; + if (empty($cat['nimi'])) { + http_response_code(400); + echo json_encode(['error' => 'Kategorian nimi vaaditaan']); + exit; + } + dbSaveGuideCategory($companyId, $cat); + echo json_encode($cat); + break; + + case 'guide_category_delete': + requireAuth(); + requireAdmin(); + $companyId = requireCompany(); + if ($method !== 'POST') break; + $input = json_decode(file_get_contents('php://input'), true); + dbDeleteGuideCategory($input['id'] ?? ''); + echo json_encode(['success' => true]); + break; + // ---------- ARCHIVE ---------- case 'archived_customers': requireAuth(); diff --git a/db.php b/db.php index 68e46bd..085a3a4 100644 --- a/db.php +++ b/db.php @@ -419,6 +419,32 @@ function initDatabase(): void { FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE, INDEX idx_company_customer (company_id, customer_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", + + "CREATE TABLE IF NOT EXISTS guide_categories ( + id VARCHAR(20) PRIMARY KEY, + company_id VARCHAR(50) NOT NULL, + nimi VARCHAR(255) NOT NULL, + sort_order INT DEFAULT 0, + FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE, + INDEX idx_company (company_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", + + "CREATE TABLE IF NOT EXISTS guides ( + id VARCHAR(20) PRIMARY KEY, + company_id VARCHAR(50) NOT NULL, + category_id VARCHAR(20) DEFAULT NULL, + title VARCHAR(500) NOT NULL, + content LONGTEXT, + tags VARCHAR(500) DEFAULT '', + author VARCHAR(100) DEFAULT '', + pinned TINYINT(1) DEFAULT 0, + luotu DATETIME, + muokattu DATETIME NULL, + muokkaaja VARCHAR(100) DEFAULT '', + FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE, + INDEX idx_company (company_id), + INDEX idx_category (category_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", ]; foreach ($tables as $i => $sql) { @@ -951,6 +977,70 @@ function dbDeleteIpam(string $id): void { _dbExecute("DELETE FROM ipam WHERE id = ?", [$id]); } +// ==================== OHJEET (GUIDES) ==================== + +function dbLoadGuideCategories(string $companyId): array { + return _dbFetchAll("SELECT * FROM guide_categories WHERE company_id = ? ORDER BY sort_order, nimi", [$companyId]); +} + +function dbSaveGuideCategory(string $companyId, array $cat): void { + _dbExecute(" + INSERT INTO guide_categories (id, company_id, nimi, sort_order) + VALUES (?, ?, ?, ?) + ON DUPLICATE KEY UPDATE nimi = VALUES(nimi), sort_order = VALUES(sort_order) + ", [$cat['id'], $companyId, $cat['nimi'] ?? '', $cat['sort_order'] ?? 0]); +} + +function dbDeleteGuideCategory(string $catId): void { + _dbExecute("DELETE FROM guide_categories WHERE id = ?", [$catId]); +} + +function dbLoadGuides(string $companyId): array { + $rows = _dbFetchAll(" + SELECT g.*, gc.nimi AS category_name + FROM guides g + LEFT JOIN guide_categories gc ON g.category_id = gc.id + WHERE g.company_id = ? + ORDER BY g.pinned DESC, g.muokattu DESC, g.luotu DESC + ", [$companyId]); + foreach ($rows as &$r) { + $r['pinned'] = (bool)$r['pinned']; + } + return $rows; +} + +function dbLoadGuide(string $guideId): ?array { + $rows = _dbFetchAll(" + SELECT g.*, gc.nimi AS category_name + FROM guides g + LEFT JOIN guide_categories gc ON g.category_id = gc.id + WHERE g.id = ? + ", [$guideId]); + if (empty($rows)) return null; + $r = $rows[0]; + $r['pinned'] = (bool)$r['pinned']; + return $r; +} + +function dbSaveGuide(string $companyId, array $g): void { + _dbExecute(" + INSERT INTO guides (id, company_id, category_id, title, content, tags, author, pinned, luotu, muokattu, muokkaaja) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + category_id = VALUES(category_id), title = VALUES(title), content = VALUES(content), + tags = VALUES(tags), pinned = VALUES(pinned), muokattu = VALUES(muokattu), muokkaaja = VALUES(muokkaaja) + ", [ + $g['id'], $companyId, !empty($g['category_id']) ? $g['category_id'] : null, + $g['title'] ?? '', $g['content'] ?? '', $g['tags'] ?? '', + $g['author'] ?? '', $g['pinned'] ? 1 : 0, + $g['luotu'] ?? date('Y-m-d H:i:s'), $g['muokattu'] ?? null, $g['muokkaaja'] ?? '' + ]); +} + +function dbDeleteGuide(string $guideId): void { + _dbExecute("DELETE FROM guides WHERE id = ?", [$guideId]); +} + // ==================== LIIDIT ==================== function dbLoadLeads(string $companyId): array { diff --git a/index.html b/index.html index aceea91..8d7a880 100644 --- a/index.html +++ b/index.html @@ -81,6 +81,7 @@ + @@ -325,6 +326,107 @@ + +