'Inhoud is verplicht']); exit; } $stmt = $db->prepare(" INSERT INTO brainstorm_cards (session_id, content, category, color, author_name, votes) VALUES (?, ?, ?, ?, ?, 0) "); $stmt->execute([$sessionId, $content, $category, $color, $user['name']]); $cardId = (int)$db->lastInsertId(); echo json_encode([ 'success' => true, 'card' => [ 'id' => $cardId, 'content' => $content, 'category' => $category, 'color' => $color, 'author_name' => $user['name'], 'votes' => 0, 'converted_to_roadmap_item_id' => null ] ]); exit; } // 2. Stemmen / Upvote op kaart (met bescherming tegen oneindig stemmen) if ($action === 'vote_card') { $data = json_decode(file_get_contents('php://input'), true); $cardId = (int)($data['card_id'] ?? 0); if (!isset($_SESSION['voted_cards'])) { $_SESSION['voted_cards'] = []; } if (in_array($cardId, $_SESSION['voted_cards'])) { $stmtVotes = $db->prepare("SELECT votes FROM brainstorm_cards WHERE id = ?"); $stmtVotes->execute([$cardId]); $votes = (int)$stmtVotes->fetchColumn(); echo json_encode(['success' => false, 'error' => 'U heeft al op deze kaart gestemd.', 'votes' => $votes]); exit; } $_SESSION['voted_cards'][] = $cardId; $stmt = $db->prepare("UPDATE brainstorm_cards SET votes = votes + 1 WHERE id = ?"); $stmt->execute([$cardId]); $stmtVotes = $db->prepare("SELECT votes FROM brainstorm_cards WHERE id = ?"); $stmtVotes->execute([$cardId]); $votes = (int)$stmtVotes->fetchColumn(); echo json_encode(['success' => true, 'votes' => $votes]); exit; } // 3. Kaart verwijderen (met autorisatiecontrole: auteur, sessie-eigenaar of beheerder) if ($action === 'delete_card') { $data = json_decode(file_get_contents('php://input'), true); $cardId = (int)($data['card_id'] ?? 0); $stmtCheck = $db->prepare(" SELECT c.*, s.created_by_id as session_owner_id FROM brainstorm_cards c JOIN brainstorm_sessions s ON c.session_id = s.id WHERE c.id = ? "); $stmtCheck->execute([$cardId]); $card = $stmtCheck->fetch(); if (!$card) { echo json_encode(['error' => 'Kaart niet gevonden']); exit; } $isAuthor = ($card['author_name'] === $user['name']); $isSessionOwner = ((int)$card['session_owner_id'] === (int)$user['id']); $isAdmin = ($user['role'] === 'ADMIN'); if (!$isAuthor && !$isSessionOwner && !$isAdmin) { http_response_code(403); echo json_encode(['error' => 'Geen toestemming om deze kaart te verwijderen.']); exit; } $stmt = $db->prepare("DELETE FROM brainstorm_cards WHERE id = ?"); $stmt->execute([$cardId]); echo json_encode(['success' => true]); exit; } // 3b. Kaart verplaatsen naar andere categorie/lane (Drag & Drop) if ($action === 'move_card') { $data = json_decode(file_get_contents('php://input'), true); $cardId = (int)($data['card_id'] ?? 0); $category = trim($data['category'] ?? ''); $validCategories = ['Ideeën', 'Knelpunten', 'Oplossingen', 'Quick Wins']; if (!$cardId || !in_array($category, $validCategories, true)) { echo json_encode(['error' => 'Ongeldige kaart of categorie']); exit; } // Bepaal kleur behorend bij de nieuwe categorie $colorMap = [ 'Ideeën' => 'amber', 'Knelpunten' => 'rose', 'Oplossingen' => 'teal', 'Quick Wins' => 'indigo' ]; $newColor = $colorMap[$category] ?? 'amber'; $stmt = $db->prepare("UPDATE brainstorm_cards SET category = ?, color = ? WHERE id = ?"); $stmt->execute([$category, $newColor, $cardId]); echo json_encode([ 'success' => true, 'card_id' => $cardId, 'category' => $category, 'color' => $newColor ]); exit; } // 4. Omzetten naar Roadmap! if ($action === 'convert_to_roadmap') { $data = json_decode(file_get_contents('php://input'), true); $cardIds = $data['card_ids'] ?? []; $quarter = $data['quarter'] ?? 'Q3'; $type = $data['type'] ?? 'FEATURE'; $priority = $data['priority'] ?? 'MEDIUM'; $dueDate = !empty($data['due_date']) ? $data['due_date'] : null; if (empty($cardIds) || !is_array($cardIds)) { echo json_encode(['error' => 'Selecteer ten minste één kaart om om te zetten.']); exit; } $db->beginTransaction(); $convertedCount = 0; foreach ($cardIds as $cardId) { $cardId = (int)$cardId; $stmtCard = $db->prepare("SELECT * FROM brainstorm_cards WHERE id = ?"); $stmtCard->execute([$cardId]); $card = $stmtCard->fetch(); if ($card) { // Maak titel (eerste zin of max 80 tekens) $firstLine = explode("\n", trim($card['content']))[0]; $title = mb_substr($firstLine, 0, 80); $stmtRoadmap = $db->prepare(" INSERT INTO roadmap_items (title, description, type, status, quarter, priority, progress, due_date, origin_brainstorm_card_id, created_by_id) VALUES (?, ?, ?, 'PLANNED', ?, ?, 0, ?, ?, ?) "); $stmtRoadmap->execute([ $title, $card['content'], $type, $quarter, $priority, $dueDate, $cardId, $user['id'] ]); $roadmapId = (int)$db->lastInsertId(); // Koppel terug aan brainstorm kaart $stmtUpdateCard = $db->prepare("UPDATE brainstorm_cards SET converted_to_roadmap_item_id = ? WHERE id = ?"); $stmtUpdateCard->execute([$roadmapId, $cardId]); $convertedCount++; } } $db->commit(); echo json_encode([ 'success' => true, 'message' => "{$convertedCount} brainstorm items succesvol omgezet naar de Roadmap!", 'converted_count' => $convertedCount ]); exit; } echo json_encode(['error' => 'Onbekende actie']); } catch (Exception $e) { if ($db->inTransaction()) $db->rollBack(); http_response_code(500); echo json_encode(['error' => $e->getMessage()]); }