= $t['no_cases'] ?>
+ + + = $t['clear_search'] ?> + +diff --git a/checkout.php b/checkout.php index 1c48f7f..0172862 100644 --- a/checkout.php +++ b/checkout.php @@ -36,6 +36,7 @@ $donation_id = $pdo->lastInsertId(); // Thawani Checkout Session Request $payload = [ 'client_reference_id' => (string)$donation_id, + 'mode' => 'payment', 'products' => [ [ 'name' => $case['title_en'], @@ -51,9 +52,7 @@ $payload = [ ] ]; -// In a real scenario, we'd use CURL to call Thawani API. -// Since we don't have real keys, we'll mock the redirect or show a simulation. - +// Check if keys are default/empty if (THAWANI_SECRET_KEY === 'rRQ26GcsZ60u9Y9v9876543210' || empty(THAWANI_SECRET_KEY)) { // Simulation Mode ?> @@ -82,22 +81,42 @@ if (THAWANI_SECRET_KEY === 'rRQ26GcsZ60u9Y9v9876543210' || empty(THAWANI_SECRET_ exit; } -// REAL CURL CALL (if keys were valid) -/* +// REAL CURL CALL $ch = curl_init(THAWANI_API_URL . '/checkout/session'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', - 'Thawani-Api-Key: ' . THAWANI_SECRET_KEY + 'thawani-api-key: ' . THAWANI_SECRET_KEY ]); $response = curl_exec($ch); -$data = json_decode($response, true); -if (isset($data['data']['session_id'])) { - $session_id = $data['data']['session_id']; - header("Location: https://checkout.thawani.om/pay/" . $session_id . "?key=" . THAWANI_PUBLISHABLE_KEY); -} else { - echo "Thawani Error: " . ($data['description'] ?? 'Unknown error'); +$err = curl_error($ch); +curl_close($ch); + +if ($err) { + die("CURL Error: " . $err); +} + +$data = json_decode($response, true); + +if (isset($data['success']) && $data['success'] === true && isset($data['data']['session_id'])) { + $session_id = $data['data']['session_id']; + + // Save session_id to donation record + $stmt = $pdo->prepare("UPDATE donations SET transaction_id = ? WHERE id = ?"); + $stmt->execute([$session_id, $donation_id]); + + $checkout_url = (THAWANI_ENV === 'sandbox') + ? "https://uatcheckout.thawani.om/pay/" . $session_id . "?key=" . THAWANI_PUBLISHABLE_KEY + : "https://checkout.thawani.om/pay/" . $session_id . "?key=" . THAWANI_PUBLISHABLE_KEY; + + header("Location: " . $checkout_url); + exit; +} else { + echo "
"; + print_r($data); + echo ""; + echo "Go Back"; } -*/ \ No newline at end of file diff --git a/index.php b/index.php index 82482e7..83618c2 100644 --- a/index.php +++ b/index.php @@ -20,7 +20,7 @@ $texts = [ 'lang_code' => 'ar', 'hero_title' => 'Make a Real Impact Today', 'hero_sub' => 'Choose a campaign from our trusted categories and help change lives in minutes.', - 'no_cases' => 'No active cases found for this category.', + 'no_cases' => 'No active cases found matching your criteria.', 'admin_panel' => 'Admin Panel', 'modal_title' => 'Make a Donation', 'modal_amount' => 'Amount (OMR)', @@ -28,6 +28,14 @@ $texts = [ 'modal_email' => 'Your Email', 'modal_phone' => 'Phone Number', 'modal_submit' => 'Proceed to Payment', + 'top_priority' => 'Top Priority', + 'urgent' => 'Urgent', + 'featured' => 'Featured', + 'search_placeholder' => 'Search for a case...', + 'search_btn' => 'Search', + 'new_badge' => 'NEW', + 'monthly_giving' => 'Join our monthly giving circle', + 'clear_search' => 'Clear Search', ], 'ar' => [ 'title' => 'ادعم قضية', @@ -41,7 +49,7 @@ $texts = [ 'lang_code' => 'en', 'hero_title' => 'أحدث تأثيراً حقيقياً اليوم', 'hero_sub' => 'اختر حملة من فئاتنا الموثوقة وساعد في تغيير الأرواح في دقائق.', - 'no_cases' => 'لا توجد حالات نشطة لهذه الفئة.', + 'no_cases' => 'لم يتم العثور على حالات نشطة تطابق بحثك.', 'admin_panel' => 'لوحة التحكم', 'modal_title' => 'تبرع الآن', 'modal_amount' => 'المبلغ (ريال عماني)', @@ -49,6 +57,14 @@ $texts = [ 'modal_email' => 'البريد الإلكتروني', 'modal_phone' => 'رقم الهاتف', 'modal_submit' => 'الانتقال للدفع', + 'top_priority' => 'أولوية قصوى', + 'urgent' => 'عاجل', + 'featured' => 'مميز', + 'search_placeholder' => 'ابحث عن حالة...', + 'search_btn' => 'بحث', + 'new_badge' => 'جديد', + 'monthly_giving' => 'انضم إلى دائرة العطاء الشهري', + 'clear_search' => 'مسح البحث', ] ]; @@ -59,16 +75,36 @@ $pdo = db(); $profile = $pdo->query("SELECT * FROM org_profile LIMIT 1")->fetch(); $categories = $pdo->query("SELECT * FROM categories")->fetchAll(); $selected_cat = $_GET['cat'] ?? 'all'; +$search_query = trim($_GET['search'] ?? ''); +// Fetch featured/top priority cases separately for the "ads" section +$featured_cases = $pdo->query("SELECT c.*, cat.name_en as cat_name_en, cat.name_ar as cat_name_ar + FROM cases c + LEFT JOIN categories cat ON c.category_id = cat.id + WHERE c.status = 'active' AND (c.importance = 'top_priority' OR c.importance = 'urgent') + ORDER BY c.importance = 'top_priority' DESC, c.id DESC LIMIT 5")->fetchAll(); + +$params = []; $sql = "SELECT c.*, cat.name_en as cat_name_en, cat.name_ar as cat_name_ar FROM cases c LEFT JOIN categories cat ON c.category_id = cat.id WHERE c.status = 'active'"; + if ($selected_cat !== 'all') { - $sql .= " AND c.category_id = " . (int)$selected_cat; + $sql .= " AND c.category_id = :cat"; + $params['cat'] = (int)$selected_cat; } + +if ($search_query !== '') { + $sql .= " AND (c.title_en LIKE :search OR c.title_ar LIKE :search OR c.desc_en LIKE :search OR c.desc_ar LIKE :search)"; + $params['search'] = "%$search_query%"; +} + $sql .= " ORDER BY CASE WHEN c.importance = 'top_priority' THEN 1 WHEN c.importance = 'urgent' THEN 2 ELSE 3 END, c.id DESC"; -$cases = $pdo->query($sql)->fetchAll(); + +$stmt = $pdo->prepare($sql); +$stmt->execute($params); +$cases = $stmt->fetchAll(); // Project meta $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? $t['subtitle']; @@ -149,8 +185,64 @@ function safe_truncate($text, $limit = 120) { margin-inline-end: 12px; } + /* Ads/Featured Section Styles */ + .ads-container { + background: #fff; + border-bottom: 1px solid #e5e7eb; + padding: 10px 0; + overflow: hidden; + } + + .ads-scroller { + display: flex; + align-items: center; + gap: 20px; + overflow-x: auto; + scrollbar-width: none; + -ms-overflow-style: none; + } + .ads-scroller::-webkit-scrollbar { + display: none; + } + + .ad-item { + display: flex; + align-items: center; + background: #f9fafb; + border: 1px solid #e5e7eb; + border-radius: 9999px; + padding: 4px 16px 4px 6px; + white-space: nowrap; + font-size: 0.875rem; + color: var(--text-main); + text-decoration: none; + transition: all 0.2s; + cursor: pointer; + } + + .ad-item:hover { + border-color: var(--primary-color); + background: #fff; + color: var(--primary-color); + } + + .ad-badge { + background: #ef4444; + color: #fff; + font-size: 0.7rem; + font-weight: 800; + padding: 4px 10px; + border-radius: 9999px; + margin-inline-end: 10px; + text-transform: uppercase; + } + + .ad-title { + font-weight: 600; + } + .hero { - padding: 4rem 0; + padding: 4rem 0 3rem 0; background: #fff; border-bottom: 1px solid #e5e7eb; text-align: center; @@ -168,9 +260,53 @@ function safe_truncate($text, $limit = 120) { font-size: 1.125rem; color: var(--text-muted); max-width: 600px; + margin: 0 auto 2rem auto; + } + + .search-container { + max-width: 500px; margin: 0 auto; } + .search-box { + display: flex; + background: #f3f4f6; + border-radius: 9999px; + padding: 6px; + border: 1px solid #e5e7eb; + transition: border-color 0.3s, background 0.3s; + } + + .search-box:focus-within { + border-color: var(--primary-color); + background: #fff; + box-shadow: 0 0 0 4px rgba(5, 150, 105, 0.1); + } + + .search-box input { + border: none; + background: transparent; + padding: 0.5rem 1.5rem; + flex-grow: 1; + outline: none; + font-size: 0.9375rem; + } + + .search-btn { + background: var(--primary-color); + color: #fff; + border: none; + border-radius: 9999px; + padding: 0.5rem 1.5rem; + font-weight: 600; + font-size: 0.875rem; + transition: background 0.2s; + } + + .search-btn:hover { + background: var(--primary-hover); + } + .cat-tabs { margin-bottom: 2rem; display: flex; @@ -204,7 +340,7 @@ function safe_truncate($text, $limit = 120) { border-radius: 16px; overflow: hidden; border: 1px solid #e5e7eb; - transition: transform 0.2s, box-shadow 0.2s; + transition: transform 0.2s, box-shadow 0.2s, border-color 0.3s; height: 100%; display: flex; flex-direction: column; @@ -338,27 +474,68 @@ function safe_truncate($text, $limit = 120) { + +
= $t['hero_sub'] ?>
+ += $t['no_cases'] ?>
+ + + = $t['clear_search'] ?> + +