diff --git a/app/Controllers/AIController.php b/app/Controllers/AIController.php
new file mode 100644
index 0000000..a5570b8
--- /dev/null
+++ b/app/Controllers/AIController.php
@@ -0,0 +1,38 @@
+ 'Message is empty']);
+ return;
+ }
+
+ require_once __DIR__ . '/../../ai/LocalAIApi.php';
+
+ $systemPrompt = "You are a helpful assistant for " . get_setting('site_name', 'ApkNusa') . ", an APK downloader and tech blog site. Provide concise and accurate information about Android apps, games, and technology. Be youthful and professional.";
+
+ $resp = \LocalAIApi::createResponse([
+ 'input' => [
+ ['role' => 'system', 'content' => $systemPrompt],
+ ['role' => 'user', 'content' => $userMessage],
+ ],
+ ]);
+
+ if (!empty($resp['success'])) {
+ $text = \LocalAIApi::extractText($resp);
+ echo json_encode(['reply' => $text]);
+ } else {
+ echo json_encode(['error' => 'AI Assistant is currently unavailable.']);
+ }
+ }
+}
diff --git a/app/Controllers/AdminController.php b/app/Controllers/AdminController.php
index e1eb15b..de176de 100644
--- a/app/Controllers/AdminController.php
+++ b/app/Controllers/AdminController.php
@@ -54,11 +54,18 @@ class AdminController extends Controller {
'total_downloads' => $this->getTotalDownloads(),
'total_users' => $db->query("SELECT COUNT(*) FROM users")->fetchColumn(),
'pending_withdrawals' => $db->query("SELECT COUNT(*) FROM withdrawals WHERE status = 'pending'")->fetchColumn(),
- 'recent_apks' => array_slice($apkService->getAllApks(), 0, 5)
+ 'recent_apks' => array_slice($apkService->getAllApks(), 0, 5),
+ 'referral_stats' => $this->getReferralStats()
];
$this->view('admin/dashboard', $stats);
}
+private function getReferralStats() {
+ $db = db_pdo();
+ $stmt = $db->query("SELECT DATE(created_at) as date, COUNT(*) as count FROM referral_downloads WHERE created_at > DATE_SUB(NOW(), INTERVAL 7 DAY) GROUP BY DATE(created_at) ORDER BY date ASC");
+ return $stmt->fetchAll();
+ }
+
private function getTotalDownloads() {
$db = db_pdo();
return $db->query("SELECT SUM(total_downloads) FROM apks")->fetchColumn() ?: 0;
@@ -239,6 +246,7 @@ class AdminController extends Controller {
$this->checkAuth();
$settings = [
'site_name' => get_setting('site_name'),
+ 'contact_email' => get_setting('contact_email'),
'site_icon' => get_setting('site_icon'),
'site_favicon' => get_setting('site_favicon'),
'meta_description' => get_setting('meta_description'),
@@ -251,6 +259,7 @@ class AdminController extends Controller {
'github_url' => get_setting('github_url'),
'telegram_url' => get_setting('telegram_url'),
'whatsapp_url' => get_setting('whatsapp_url'),
+ 'maintenance_mode' => get_setting('maintenance_mode'),
];
$this->view('admin/settings', ['settings' => $settings]);
}
@@ -260,7 +269,7 @@ class AdminController extends Controller {
$db = db_pdo();
$fields = [
- 'site_name', 'meta_description', 'meta_keywords', 'head_js', 'body_js',
+ 'site_name', 'contact_email', 'meta_description', 'meta_keywords', 'head_js', 'body_js',
'facebook_url', 'twitter_url', 'instagram_url', 'github_url', 'telegram_url', 'whatsapp_url'
];
foreach ($fields as $field) {
diff --git a/app/Controllers/ContactController.php b/app/Controllers/ContactController.php
new file mode 100644
index 0000000..6853220
--- /dev/null
+++ b/app/Controllers/ContactController.php
@@ -0,0 +1,45 @@
+view('contact', [
+ 'title' => __('contact_us') . ' - ' . get_setting('site_name', 'ApkNusa')
+ ]);
+ }
+
+ public function submit() {
+ $name = $_POST['name'] ?? '';
+ $email = $_POST['email'] ?? '';
+ $subject = $_POST['subject'] ?? 'New Contact Message';
+ $message = $_POST['message'] ?? '';
+
+ if (empty($name) || empty($email) || empty($message)) {
+ $_SESSION['error'] = 'All fields are required.';
+ $this->redirect('/contact');
+ }
+
+ if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['error'] = 'Invalid email address.';
+ $this->redirect('/contact');
+ }
+
+ require_once __DIR__ . '/../../mail/MailService.php';
+
+ $res = \MailService::sendContactMessage($name, $email, $message, null, $subject);
+
+ if (!empty($res['success'])) {
+ $_SESSION['success'] = 'Your message has been sent successfully!';
+ } else {
+ $_SESSION['error'] = 'Failed to send message. Please try again later.';
+ // Log error if needed: error_log($res['error']);
+ }
+
+ $this->redirect('/contact');
+ }
+}
diff --git a/app/Controllers/NewsletterController.php b/app/Controllers/NewsletterController.php
new file mode 100644
index 0000000..244062d
--- /dev/null
+++ b/app/Controllers/NewsletterController.php
@@ -0,0 +1,33 @@
+ 'Please provide a valid email address.']);
+ return;
+ }
+
+ $db = db_pdo();
+ try {
+ $stmt = $db->prepare("INSERT INTO newsletter_subscribers (email) VALUES (?)");
+ $stmt->execute([$email]);
+ echo json_encode(['success' => 'Thank you for subscribing!']);
+ } catch (\PDOException $e) {
+ if ($e->getCode() == 23000) { // Duplicate entry
+ echo json_encode(['success' => 'You are already subscribed!']);
+ } else {
+ echo json_encode(['error' => 'An error occurred. Please try again.']);
+ }
+ }
+ }
+}
diff --git a/app/Controllers/SitemapController.php b/app/Controllers/SitemapController.php
index 4c8f913..1bdd17d 100644
--- a/app/Controllers/SitemapController.php
+++ b/app/Controllers/SitemapController.php
@@ -38,10 +38,21 @@ class SitemapController extends Controller {
echo '';
}
+ // Blog Posts
+ $posts = $db->query("SELECT * FROM posts WHERE status = 'published'")->fetchAll();
+ foreach ($posts as $post) {
+ echo '