pdo = $connection->getPdo(); } public function index(Request $request, Response $response): string { $type = $request->get('type', ''); $search = $request->get('search', ''); $status = $request->get('status', ''); $page = max(1, (int)$request->get('page', 1)); $perPage = 20; $offset = ($page - 1) * $perPage; $where = ['o.deleted_at IS NULL']; $params = []; if ($type) { $where[] = 'o.type = ?'; $params[] = $type; } if ($status) { $where[] = 'o.status = ?'; $params[] = $status; } if ($search) { $where[] = '(o.title LIKE ? OR o.description LIKE ?)'; $params[] = "%{$search}%"; $params[] = "%{$search}%"; } $whereClause = implode(' AND ', $where); $stmt = $this->pdo->prepare("SELECT COUNT(*) FROM opportunities o WHERE {$whereClause}"); $stmt->execute($params); $total = (int)$stmt->fetchColumn(); $stmt = $this->pdo->prepare( "SELECT o.*, org.name as org_name, GROUP_CONCAT(DISTINCT t.name) as tag_names FROM opportunities o LEFT JOIN organizations org ON org.id = o.organization_id LEFT JOIN opportunity_tags ot ON ot.opportunity_id = o.id LEFT JOIN tags t ON t.id = ot.tag_id WHERE {$whereClause} GROUP BY o.id ORDER BY o.score DESC, o.created_at DESC LIMIT ? OFFSET ?" ); $stmt->execute(array_merge($params, [$perPage, $offset])); $opportunities = $stmt->fetchAll(); // Get type counts for sidebar $typeCounts = $this->pdo->query( "SELECT type, COUNT(*) as count FROM opportunities WHERE deleted_at IS NULL GROUP BY type" )->fetchAll(PDO::FETCH_KEY_PAIR); return $this->render('admin/opportunities/index', [ 'opportunities' => $opportunities, 'total' => $total, 'page' => $page, 'perPage' => $perPage, 'type' => $type, 'status' => $status, 'search' => $search, 'typeCounts' => $typeCounts, 'types' => ['grant', 'competition', 'demo_day', 'event', 'partnership', 'investment', 'other'], 'statuses' => ['active', 'closed', 'expired'], ], 'admin'); } public function show(Request $request, Response $response, int $id): string { $stmt = $this->pdo->prepare( "SELECT o.*, org.name as org_name, org.type as org_type, org.website_url as org_website, GROUP_CONCAT(DISTINCT t.name) as tag_names FROM opportunities o LEFT JOIN organizations org ON org.id = o.organization_id LEFT JOIN opportunity_tags ot ON ot.opportunity_id = o.id LEFT JOIN tags t ON t.id = ot.tag_id WHERE o.id = ? AND o.deleted_at IS NULL GROUP BY o.id" ); $stmt->execute([$id]); $opportunity = $stmt->fetch(); if (!$opportunity) { $response->redirect('/admin/opportunities'); return ''; } // Get applications $stmt = $this->pdo->prepare("SELECT * FROM applications WHERE opportunity_id = ? AND deleted_at IS NULL ORDER BY created_at DESC"); $stmt->execute([$id]); $applications = $stmt->fetchAll(); return $this->render('admin/opportunities/show', [ 'opportunity' => $opportunity, 'applications' => $applications, ], 'admin'); } }