HEX
Server: Apache/2.4.65 (Debian)
System: Linux kubikelcreative 5.10.0-35-amd64 #1 SMP Debian 5.10.237-1 (2025-05-19) x86_64
User: www-data (33)
PHP: 8.4.13
Disabled: NONE
Upload Files
File: /var/www/indoadvisory_new/webapp/src/routes/settings.tsx
import { Hono } from 'hono'
import { type SiteSetting } from '../utils/database'
import { type User } from '../utils/auth'

type Bindings = {
  DB: D1Database;
}

const settings = new Hono<{ Bindings: Bindings }>()

// Settings Page
settings.get('/', async (c) => {
  try {
    const settingsList = await c.env.DB.prepare(
      'SELECT * FROM site_settings ORDER BY setting_key'
    ).all() as { results: SiteSetting[] }

    const user = c.get('user') as User

    // Convert settings array to object for easier access
    const settingsObj: { [key: string]: string } = {}
    settingsList.results.forEach(setting => {
      settingsObj[setting.setting_key] = setting.setting_value
    })

    return c.html(`
      <!DOCTYPE html>
      <html lang="id">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Pengaturan Website - Admin IndoAdvisory</title>
          <script src="https://cdn.tailwindcss.com"></script>
          <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
      </head>
      <body class="bg-gray-100">
          ${adminNavbar(user)}
          
          <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
              <div class="mb-8">
                  <h1 class="text-3xl font-bold text-gray-800">Pengaturan Website</h1>
                  <p class="text-gray-600 mt-2">Kelola informasi dasar website dan perusahaan</p>
              </div>
              
              <form id="settingsForm" action="/admin/settings" method="POST" class="space-y-8">
                  <!-- Company Information -->
                  <div class="bg-white rounded-xl shadow-lg p-8">
                      <h2 class="text-xl font-bold text-gray-800 mb-6">
                          <i class="fas fa-building mr-2 text-blue-600"></i>
                          Informasi Perusahaan
                      </h2>
                      
                      <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Nama Perusahaan</label>
                              <input 
                                  type="text" 
                                  name="company_name" 
                                  value="${settingsObj.company_name || 'IndoAdvisory'}"
                                  required 
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              />
                          </div>
                          
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Email Perusahaan</label>
                              <input 
                                  type="email" 
                                  name="company_email" 
                                  value="${settingsObj.company_email || 'info@indoadvisory.co.id'}"
                                  required 
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              />
                          </div>
                          
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Telepon</label>
                              <input 
                                  type="text" 
                                  name="company_phone" 
                                  value="${settingsObj.company_phone || '+62 21 5794 3210'}"
                                  required 
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              />
                          </div>
                          
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Website URL</label>
                              <input 
                                  type="url" 
                                  name="company_website" 
                                  value="${settingsObj.company_website || 'https://indoadvisory.co.id'}"
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              />
                          </div>
                      </div>
                      
                      <div class="mt-6">
                          <label class="block text-sm font-medium text-gray-700 mb-2">Alamat Lengkap</label>
                          <textarea 
                              name="company_address" 
                              rows="3"
                              class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              placeholder="Alamat lengkap perusahaan"
                          >${settingsObj.company_address || 'Menara Sudirman Lt. 25\\nJl. Jend. Sudirman Kav. 60\\nJakarta Selatan 12190'}</textarea>
                      </div>
                  </div>
                  
                  <!-- Website Settings -->
                  <div class="bg-white rounded-xl shadow-lg p-8">
                      <h2 class="text-xl font-bold text-gray-800 mb-6">
                          <i class="fas fa-globe mr-2 text-blue-600"></i>
                          Pengaturan Website
                      </h2>
                      
                      <div class="space-y-6">
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Judul Website</label>
                              <input 
                                  type="text" 
                                  name="site_title" 
                                  value="${settingsObj.site_title || 'IndoAdvisory - Penasihat Investasi Terpercaya'}"
                                  required 
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              />
                          </div>
                          
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Deskripsi Website</label>
                              <textarea 
                                  name="site_description" 
                                  rows="3"
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                                  placeholder="Deskripsi singkat tentang perusahaan"
                              >${settingsObj.site_description || 'Firma konsultan private equity terkemuka di Indonesia'}</textarea>
                          </div>
                          
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Bahasa Default</label>
                              <select 
                                  name="default_language" 
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              >
                                  <option value="id" ${(settingsObj.default_language || 'id') === 'id' ? 'selected' : ''}>Bahasa Indonesia</option>
                                  <option value="en" ${settingsObj.default_language === 'en' ? 'selected' : ''}>English</option>
                              </select>
                          </div>
                      </div>
                  </div>
                  
                  <!-- Hero Section Settings -->
                  <div class="bg-white rounded-xl shadow-lg p-8">
                      <h2 class="text-xl font-bold text-gray-800 mb-6">
                          <i class="fas fa-star mr-2 text-blue-600"></i>
                          Hero Section
                      </h2>
                      
                      <div class="space-y-6">
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Judul Hero (Bahasa Indonesia)</label>
                              <input 
                                  type="text" 
                                  name="hero_title_id" 
                                  value="${settingsObj.hero_title_id || 'Penasihat Private Equity Terpercaya di Indonesia'}"
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              />
                          </div>
                          
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Judul Hero (English)</label>
                              <input 
                                  type="text" 
                                  name="hero_title_en" 
                                  value="${settingsObj.hero_title_en || 'Trusted Private Equity Advisory in Indonesia'}"
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              />
                          </div>
                          
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Subtitle Hero (Bahasa Indonesia)</label>
                              <textarea 
                                  name="hero_subtitle_id" 
                                  rows="3"
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              >${settingsObj.hero_subtitle_id || 'Kami membantu perusahaan mencapai pertumbuhan berkelanjutan melalui strategi investasi yang tepat, valuasi perusahaan yang akurat, dan persiapan IPO yang komprehensif.'}</textarea>
                          </div>
                          
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Subtitle Hero (English)</label>
                              <textarea 
                                  name="hero_subtitle_en" 
                                  rows="3"
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              >${settingsObj.hero_subtitle_en || 'We help companies achieve sustainable growth through strategic investments, accurate company valuations, and comprehensive IPO preparation.'}</textarea>
                          </div>
                      </div>
                  </div>
                  
                  <!-- Statistics Settings -->
                  <div class="bg-white rounded-xl shadow-lg p-8">
                      <h2 class="text-xl font-bold text-gray-800 mb-6">
                          <i class="fas fa-chart-bar mr-2 text-blue-600"></i>
                          Statistik Perusahaan
                      </h2>
                      
                      <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Total Klien</label>
                              <input 
                                  type="number" 
                                  name="stats_clients" 
                                  value="${settingsObj.stats_clients || '150'}"
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              />
                          </div>
                          
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Total Valuasi</label>
                              <input 
                                  type="text" 
                                  name="stats_valuation" 
                                  value="${settingsObj.stats_valuation || 'Rp 2.5T'}"
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              />
                          </div>
                          
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">IPO Sukses</label>
                              <input 
                                  type="number" 
                                  name="stats_ipos" 
                                  value="${settingsObj.stats_ipos || '25'}"
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              />
                          </div>
                          
                          <div>
                              <label class="block text-sm font-medium text-gray-700 mb-2">Satisfaction Rate (%)</label>
                              <input 
                                  type="number" 
                                  name="stats_satisfaction" 
                                  value="${settingsObj.stats_satisfaction || '98'}"
                                  class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                              />
                          </div>
                      </div>
                  </div>
                  
                  <!-- Portfolio Section Settings -->
                  <div class="bg-white rounded-xl shadow-lg p-8">
                      <h2 class="text-xl font-bold text-gray-800 mb-6">
                          <i class="fas fa-eye mr-2 text-blue-600"></i>
                          Pengaturan Portfolio & Statistik
                      </h2>
                      
                      <div class="space-y-6">
                          <div class="bg-blue-50 border border-blue-200 rounded-lg p-4">
                              <div class="flex items-center justify-between">
                                  <div>
                                      <h3 class="font-semibold text-gray-800">Tampilkan Bagian Portfolio</h3>
                                      <p class="text-sm text-gray-600 mt-1">Menampilkan atau menyembunyikan seluruh bagian Portfolio & Prestasi di halaman utama</p>
                                  </div>
                                  <label class="relative inline-flex items-center cursor-pointer">
                                      <input type="checkbox" name="portfolio_section_enabled" value="1" 
                                             ${(settingsObj.portfolio_section_enabled || '1') === '1' ? 'checked' : ''}
                                             class="sr-only peer">
                                      <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
                                  </label>
                              </div>
                          </div>
                          
                          <div class="bg-green-50 border border-green-200 rounded-lg p-4">
                              <div class="flex items-center justify-between">
                                  <div>
                                      <h3 class="font-semibold text-gray-800">Tampilkan Statistik Kinerja</h3>
                                      <p class="text-sm text-gray-600 mt-1">Menampilkan atau menyembunyikan grafik dan data statistik dalam bagian portfolio</p>
                                  </div>
                                  <label class="relative inline-flex items-center cursor-pointer">
                                      <input type="checkbox" name="portfolio_statistics_enabled" value="1" 
                                             ${(settingsObj.portfolio_statistics_enabled || '1') === '1' ? 'checked' : ''}
                                             class="sr-only peer">
                                      <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-green-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-green-600"></div>
                                  </label>
                              </div>
                          </div>
                          
                          <div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
                              <h4 class="font-medium text-gray-800 mb-2">
                                  <i class="fas fa-info-circle text-yellow-600 mr-2"></i>
                                  Informasi Pengaturan
                              </h4>
                              <ul class="text-sm text-gray-600 space-y-1">
                                  <li>• <strong>Portfolio Section</strong>: Mengontrol visibilitas keseluruhan bagian "Portfolio & Prestasi"</li>
                                  <li>• <strong>Statistik Kinerja</strong>: Mengontrol tampilan grafik dan data statistik di dalam portfolio</li>
                                  <li>• Client showcase (Klien Terkini) akan tetap tampil meskipun statistik dimatikan</li>
                                  <li>• Perubahan akan terlihat langsung di halaman utama setelah disimpan</li>
                              </ul>
                          </div>
                      </div>
                  </div>
                  
                  <div class="flex justify-end space-x-4">
                      <button 
                          type="button" 
                          onclick="window.location.href='/admin/dashboard'" 
                          class="px-6 py-3 text-gray-700 bg-gray-200 rounded-lg hover:bg-gray-300 transition-colors"
                      >
                          <i class="fas fa-times mr-2"></i>
                          Batal
                      </button>
                      <button 
                          type="submit" 
                          class="px-8 py-3 bg-blue-600 text-white rounded-lg font-semibold hover:bg-blue-700 transition-colors"
                      >
                          <i class="fas fa-save mr-2"></i>
                          Simpan Pengaturan
                      </button>
                  </div>
              </form>
          </div>
          
          <script>
              document.getElementById('settingsForm').addEventListener('submit', function(e) {
                  e.preventDefault();
                  
                  const formData = new FormData(this);
                  const settings = {};
                  
                  // Handle regular form fields
                  for (let [key, value] of formData.entries()) {
                      settings[key] = value;
                  }
                  
                  // Handle unchecked checkboxes (they don't appear in formData)
                  const checkboxes = this.querySelectorAll('input[type="checkbox"]');
                  checkboxes.forEach(checkbox => {
                      if (!settings.hasOwnProperty(checkbox.name)) {
                          settings[checkbox.name] = '0';
                      }
                  });
                  
                  fetch('/admin/settings', {
                      method: 'POST',
                      headers: {
                          'Content-Type': 'application/json',
                      },
                      body: JSON.stringify(settings)
                  })
                  .then(response => response.json())
                  .then(data => {
                      if (data.success) {
                          alert('Pengaturan berhasil disimpan!');
                          window.location.reload();
                      } else {
                          alert('Terjadi kesalahan: ' + data.error);
                      }
                  })
                  .catch(error => {
                      alert('Terjadi kesalahan: ' + error.message);
                  });
              });
          </script>
      </body>
      </html>
    `)
  } catch (error) {
    return c.html(`<div>Error: ${error.message}</div>`)
  }
})

// Save Settings
settings.post('/', async (c) => {
  try {
    const settingsData = await c.req.json()
    
    // Update each setting
    for (const [key, value] of Object.entries(settingsData)) {
      await c.env.DB.prepare(`
        INSERT INTO site_settings (setting_key, setting_value, updated_at) 
        VALUES (?, ?, ?) 
        ON CONFLICT(setting_key) 
        DO UPDATE SET setting_value = ?, updated_at = ?
      `).bind(key, value, new Date().toISOString(), value, new Date().toISOString()).run()
    }
    
    return c.json({ success: true })
  } catch (error) {
    return c.json({ error: error.message }, 500)
  }
})

// Admin Navbar Component
function adminNavbar(user: User): string {
  return `
    <nav class="bg-white shadow-lg border-b">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
            <div class="flex justify-between items-center h-16">
                <div class="flex items-center">
                    <h1 class="text-xl font-bold text-gray-800">
                        <i class="fas fa-chart-line text-blue-600 mr-2"></i>
                        IndoAdvisory Admin
                    </h1>
                </div>
                
                <div class="hidden md:flex items-center space-x-6">
                    <a href="/admin/dashboard" class="text-gray-700 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium">
                        <i class="fas fa-tachometer-alt mr-1"></i>
                        Dashboard
                    </a>
                    <a href="/admin/articles" class="text-gray-700 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium">
                        <i class="fas fa-newspaper mr-1"></i>
                        Artikel
                    </a>
                    <a href="/admin/inquiries" class="text-gray-700 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium">
                        <i class="fas fa-envelope mr-1"></i>
                        Inquiry
                    </a>
                    <a href="/admin/team" class="text-gray-700 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium">
                        <i class="fas fa-users mr-1"></i>
                        Tim
                    </a>
                    <a href="/admin/settings" class="text-blue-600 font-semibold px-3 py-2 rounded-md text-sm font-medium">
                        <i class="fas fa-cog mr-1"></i>
                        Settings
                    </a>
                    <a href="/" target="_blank" class="text-gray-700 hover:text-blue-600 px-3 py-2 rounded-md text-sm font-medium">
                        <i class="fas fa-external-link-alt mr-1"></i>
                        Lihat Website
                    </a>
                </div>
                
                <div class="flex items-center">
                    <span class="text-gray-700 mr-4">
                        <i class="fas fa-user mr-1"></i>
                        ${user.name}
                    </span>
                    <a href="/admin/logout" class="text-red-600 hover:text-red-700 px-3 py-2 rounded-md text-sm font-medium">
                        <i class="fas fa-sign-out-alt mr-1"></i>
                        Logout
                    </a>
                </div>
            </div>
        </div>
    </nav>
  `
}

export default settings