Linux spg1.cloudpowerdns.com 5.14.0-611.34.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Feb 18 05:51:10 EST 2026 x86_64
LiteSpeed
Server IP : 176.9.63.151 & Your IP : 216.73.217.60
Domains :
Cant Read [ /etc/named.conf ]
User : fastear1
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
home /
fastear1 /
.trash /
public /
Delete
Unzip
Name
Size
Permission
Date
Action
data
[ DIR ]
drwxr-xr-x
2025-09-15 23:22
uploads
[ DIR ]
drwxr-xr-x
2025-09-15 18:00
COMPLETE_SETUP_GUIDE.md
5.02
KB
-rw-r--r--
2025-09-15 23:45
DATABASE_SETUP.md
2.84
KB
-rw-r--r--
2025-09-15 23:41
FIX_ACCESS_DENIED.md
2.36
KB
-rw-r--r--
2025-09-16 00:07
MIGRATION_SUMMARY.md
4.28
KB
-rw-r--r--
2025-09-15 23:45
NEXT_STEPS.md
2.18
KB
-rw-r--r--
2025-09-15 23:45
PHPMYADMIN_SETUP_GUIDE.md
3.61
KB
-rw-r--r--
2025-09-15 23:43
QUICK_FIX_INSTRUCTIONS.md
1.99
KB
-rw-r--r--
2025-09-16 00:09
admin-dashboard.html
25.26
KB
-rw-r--r--
2025-09-15 17:29
admin-login.html
5.25
KB
-rw-r--r--
2025-09-15 02:24
admin-profile.html
24.21
KB
-rw-r--r--
2025-09-15 17:43
analytics.html
25.08
KB
-rw-r--r--
2025-09-15 16:13
check_mysql.php
1.33
KB
-rw-r--r--
2025-09-15 23:44
cleanup_duplicates.php
1.46
KB
-rw-r--r--
2025-09-15 23:08
complete_workflow_test.php
4.46
KB
-rw-r--r--
2025-09-15 23:22
create_test_user.php
1.15
KB
-rw-r--r--
2025-09-15 23:20
database.php
4.29
KB
-rw-r--r--
2025-09-15 23:43
database_mysql.php
9.98
KB
-rw-r--r--
2025-09-16 00:08
db_config.php
587
B
-rw-r--r--
2025-09-16 00:07
demo-enhanced.html
45.46
KB
-rw-r--r--
2025-09-15 01:43
deposit.html
10.83
KB
-rw-r--r--
2025-09-15 17:08
error_log
825
B
-rw-r--r--
2025-10-04 15:48
fastearnads.sql
6.12
KB
-rw-r--r--
2025-09-15 23:39
fastearnads_tables_only.sql
5.96
KB
-rw-r--r--
2025-09-16 00:07
final_test.php
4.73
KB
-rw-r--r--
2025-09-15 23:29
import_database.bat
1.03
KB
-rw-r--r--
2025-09-15 23:45
index.php
50.11
KB
-rw-r--r--
2025-09-15 23:40
manage-ads.html
25.39
KB
-rw-r--r--
2025-09-15 16:12
manage-users.html
42.4
KB
-rw-r--r--
2025-09-15 16:54
manage-withdraws.html
49.19
KB
-rw-r--r--
2025-09-15 15:54
migrate_data.php
1.6
KB
-rw-r--r--
2025-09-15 23:40
simple-login.html
1.19
KB
-rw-r--r--
2025-09-15 02:08
start_mysql.bat
948
B
-rw-r--r--
2025-09-15 23:45
test_admin_approval.php
3.55
KB
-rw-r--r--
2025-09-15 23:21
test_connection_with_user.php
1.9
KB
-rw-r--r--
2025-09-15 19:19
test_db_connection.php
1.54
KB
-rw-r--r--
2025-09-15 23:41
test_deposit_fix.php
2.88
KB
-rw-r--r--
2025-09-15 23:09
test_frontend.html
3.49
KB
-rw-r--r--
2025-09-15 23:22
test_user_activity_history.php
2.96
KB
-rw-r--r--
2025-09-15 23:21
user-ads.html
18.36
KB
-rw-r--r--
2025-09-15 14:39
user-dashboard.html
47.77
KB
-rw-r--r--
2025-09-15 23:26
user-login.html
5.78
KB
-rw-r--r--
2025-09-15 02:27
user-profile.html
33.93
KB
-rw-r--r--
2025-09-15 18:33
user-register.html
7.56
KB
-rw-r--r--
2025-09-15 02:27
user-transactions.html
31.83
KB
-rw-r--r--
2025-09-15 22:58
user-withdraw.html
29.48
KB
-rw-r--r--
2025-09-15 21:52
user-withdrawals.html
29.17
KB
-rw-r--r--
2025-09-15 21:51
waiting-approval.html
5.46
KB
-rw-r--r--
2025-09-15 03:23
Save
Rename
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Dashboard - FastEarnAds</title> <script src="https://cdn.tailwindcss.com"></script> <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script> </head> <body class="bg-gray-50" x-data="dashboardData()" x-init="loadData()"> <!-- Header --> <header class="bg-white shadow-sm border-b border-gray-200"> <div class="max-w-7xl mx-auto px-3 sm:px-4 py-3 sm:py-4"> <div class="flex items-center justify-between"> <div class="flex items-center space-x-2 sm:space-x-4"> <div class="w-8 h-8 sm:w-10 sm:h-10 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-lg flex items-center justify-center"> <svg class="w-4 h-4 sm:w-6 sm:h-6 text-white" fill="currentColor" viewBox="0 0 20 20"> <path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/> </svg> </div> <div> <h1 class="text-lg sm:text-xl font-bold text-gray-900">FastEarnAds</h1> <p class="text-xs sm:text-sm text-gray-600 hidden sm:block">Welcome back!</p> </div> </div> <div class="flex items-center space-x-2 sm:space-x-4"> <a href="/user/profile" class="p-1.5 sm:p-2 text-gray-600 hover:text-gray-800 hover:bg-gray-100 rounded-lg transition-colors" title="Profile Settings"> <svg class="w-4 h-4 sm:w-5 sm:h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/> </svg> </a> <div class="text-right"> <p class="text-xs sm:text-sm font-medium text-gray-900">User</p> <p class="text-xs text-gray-600">$<span x-text="userBalance">0.00</span></p> </div> <form action="/user/logout" method="POST" class="inline"> <button type="submit" class="text-gray-600 hover:text-gray-800 p-1 sm:p-2 rounded-lg hover:bg-gray-100 transition-colors" title="Logout"> <svg class="w-4 h-4 sm:w-5 sm:h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/> </svg> </button> </form> </div> </div> </div> </header> <!-- Admin Impersonation Banner --> <div x-show="isAdminImpersonating" x-cloak class="bg-gradient-to-r from-orange-500 to-red-500 text-white px-3 sm:px-4 py-2 sm:py-3 shadow-md"> <div class="max-w-7xl mx-auto flex flex-col sm:flex-row items-start sm:items-center justify-between gap-2 sm:gap-0"> <div class="flex items-start sm:items-center space-x-2 sm:space-x-3"> <svg class="w-4 h-4 sm:w-5 sm:h-5 text-white mt-0.5 sm:mt-0 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"/> </svg> <div> <p class="font-semibold text-xs sm:text-sm">🔒 Admin Mode: You are viewing this account as an administrator</p> <p class="text-orange-100 text-xs hidden sm:block">All actions performed will be logged for security purposes</p> </div> </div> <button @click="returnToAdminPanel()" class="bg-white bg-opacity-20 hover:bg-opacity-30 text-white font-medium px-3 sm:px-4 py-1.5 sm:py-2 rounded-lg transition-colors flex items-center space-x-1 sm:space-x-2 text-xs sm:text-sm w-full sm:w-auto justify-center mt-2 sm:mt-0"> <svg class="w-3 h-3 sm:w-4 sm:h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 15l-3-3m0 0l3-3m-3 3h8M3 12a9 9 0 1118 0 9 9 0 01-18 0z"/> </svg> <span>Return to Admin Panel</span> </button> </div> </div> <!-- Main Content --> <div class="max-w-7xl mx-auto px-3 sm:px-4 py-4 sm:py-8"> <!-- Welcome Section --> <div class="bg-gradient-to-r from-green-400 via-blue-500 to-purple-600 rounded-xl sm:rounded-2xl p-4 sm:p-8 text-white mb-4 sm:mb-8 shadow-lg"> <div class="flex flex-col lg:flex-row items-start lg:items-center justify-between gap-4"> <div class="w-full lg:w-auto"> <h2 class="text-xl sm:text-2xl lg:text-3xl font-bold mb-1 sm:mb-2 flex items-center"> 🎉 Congratulations! <div class="ml-2 sm:ml-3 w-6 h-6 sm:w-8 sm:h-8 bg-white bg-opacity-20 rounded-full flex items-center justify-center flex-shrink-0"> <svg class="w-3 h-3 sm:w-5 sm:h-5 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/> </svg> </div> </h2> <p class="text-green-100 mb-3 sm:mb-4 text-sm sm:text-base lg:text-lg">Your deposit has been approved and your account is now active!</p> <div class="flex flex-col sm:flex-row sm:items-center space-y-2 sm:space-y-0 sm:space-x-4"> <div class="flex items-center space-x-2"> <svg class="w-4 h-4 sm:w-5 sm:h-5 text-green-200 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 002 2v8a2 2 0 002 2z"/> </svg> <span class="text-xs sm:text-sm text-green-100">Start watching ads and earning money instantly</span> </div> </div> </div> <div class="w-full lg:w-auto lg:text-right"> <div class="bg-white bg-opacity-20 backdrop-blur-sm rounded-xl p-4 sm:p-6 border border-white border-opacity-30"> <p class="text-xs sm:text-sm text-green-100 mb-1 sm:mb-2 text-center lg:text-left">Current Balance</p> <p class="text-2xl sm:text-3xl lg:text-4xl font-bold text-white text-center lg:text-left">$<span x-text="userBalance">0.00</span></p> <div class="mt-2 sm:mt-3 flex items-center justify-center lg:justify-start space-x-2"> <div class="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div> <span class="text-xs text-green-200">Account Active</span> </div> </div> </div> </div> </div> <!-- Stats Cards --> <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-6 mb-4 sm:mb-8"> <div class="bg-white rounded-xl p-4 sm:p-6 shadow-sm border hover:shadow-md transition-shadow duration-200"> <div class="flex items-center justify-between"> <div> <p class="text-xs sm:text-sm font-medium text-gray-600 mb-1">Ads Watched</p> <p class="text-2xl sm:text-3xl font-bold text-gray-900" x-text="stats.adsWatched">0</p> <div class="mt-1 sm:mt-2 flex items-center"> <div class="w-2 h-2 bg-blue-500 rounded-full mr-2"></div> <span class="text-xs text-blue-600 font-medium">Total Views</span> </div> </div> <div class="w-10 h-10 sm:w-14 sm:h-14 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl flex items-center justify-center shadow-lg"> <svg class="w-5 h-5 sm:w-7 sm:h-7 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 002 2v8a2 2 0 002 2z"/> </svg> </div> </div> </div> <div class="bg-white rounded-xl p-4 sm:p-6 shadow-sm border hover:shadow-md transition-shadow duration-200"> <div class="flex items-center justify-between"> <div> <p class="text-xs sm:text-sm font-medium text-gray-600 mb-1">Total Earned</p> <p class="text-2xl sm:text-3xl font-bold text-green-600">$<span x-text="stats.totalEarned">0.00</span></p> <div class="mt-1 sm:mt-2 flex items-center"> <div class="w-2 h-2 bg-green-500 rounded-full mr-2"></div> <span class="text-xs text-green-600 font-medium">All Time</span> </div> </div> <div class="w-10 h-10 sm:w-14 sm:h-14 bg-gradient-to-br from-green-500 to-green-600 rounded-xl flex items-center justify-center shadow-lg"> <svg class="w-5 h-5 sm:w-7 sm:h-7 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1"/> </svg> </div> </div> </div> <div class="bg-white rounded-xl p-4 sm:p-6 shadow-sm border hover:shadow-md transition-shadow duration-200 sm:col-span-2 lg:col-span-1"> <div class="flex items-center justify-between"> <div> <p class="text-xs sm:text-sm font-medium text-gray-600 mb-1">Available Ads</p> <p class="text-2xl sm:text-3xl font-bold text-purple-600" x-text="stats.availableAds">0</p> <div class="mt-1 sm:mt-2 flex items-center"> <div class="w-2 h-2 bg-purple-500 rounded-full mr-2 animate-pulse"></div> <span class="text-xs text-purple-600 font-medium">Ready to Watch</span> </div> </div> <div class="w-10 h-10 sm:w-14 sm:h-14 bg-gradient-to-br from-purple-500 to-purple-600 rounded-xl flex items-center justify-center shadow-lg"> <svg class="w-5 h-5 sm:w-7 sm:h-7 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H9a2 2 0 00-2 2z"/> </svg> </div> </div> </div> </div> <!-- Quick Actions --> <div class="grid grid-cols-1 lg:grid-cols-3 gap-4 sm:gap-8"> <!-- Watch Ads & Earn - Overview --> <div class="bg-white rounded-xl shadow-sm border"> <div class="p-4 sm:p-6 border-b border-gray-200"> <h3 class="text-base sm:text-lg font-semibold text-gray-900">Watch Ads & Earn</h3> <p class="text-xs sm:text-sm text-gray-600 mt-1">Click on ads to start earning</p> </div> <div class="p-4 sm:p-6"> <div class="grid grid-cols-1 gap-3 sm:gap-4 mb-4 sm:mb-6"> <div class="bg-blue-50 p-3 sm:p-4 rounded-lg text-center"> <h4 class="text-xs sm:text-sm font-medium text-blue-900">Today's Earnings</h4> <p class="text-xl sm:text-2xl font-bold text-blue-600">$<span x-text="stats.totalEarned">0.00</span></p> </div> <div class="bg-green-50 p-3 sm:p-4 rounded-lg text-center"> <h4 class="text-xs sm:text-sm font-medium text-green-900">Ads Watched</h4> <p class="text-xl sm:text-2xl font-bold text-green-600" x-text="stats.adsWatched">0</p> </div> <div class="bg-purple-50 p-3 sm:p-4 rounded-lg text-center"> <h4 class="text-xs sm:text-sm font-medium text-purple-900">Available Ads</h4> <p class="text-xl sm:text-2xl font-bold text-purple-600" x-text="stats.availableAds">0</p> </div> </div> <div class="text-center"> <p class="text-xs sm:text-sm text-gray-600 mb-3 sm:mb-4">Start watching ads to earn money instantly!</p> <a href="/user/ads" class="inline-flex items-center bg-blue-600 text-white px-4 sm:px-6 py-2 sm:py-3 rounded-lg hover:bg-blue-700 transition-colors font-medium text-sm sm:text-base w-full sm:w-auto justify-center"> <svg class="w-4 h-4 sm:w-5 sm:h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 002 2v8a2 2 0 002 2z"></path> </svg> Watch Ads Now </a> </div> </div> </div> <!-- Withdraw Earnings - Overview --> <div class="bg-white rounded-xl shadow-sm border"> <div class="p-4 sm:p-6 border-b border-gray-200"> <h3 class="text-base sm:text-lg font-semibold text-gray-900">Withdraw Earnings</h3> <p class="text-xs sm:text-sm text-gray-600 mt-1">Request withdraw when enabled by admin</p> </div> <div class="p-4 sm:p-6"> <div class="mb-4 sm:mb-6"> <div class="bg-green-50 p-3 sm:p-4 rounded-lg text-center"> <h4 class="text-xs sm:text-sm font-medium text-green-900">Available Balance</h4> <p class="text-2xl sm:text-3xl font-bold text-green-600">$<span x-text="parseFloat(userBalance).toFixed(2)">0.00</span></p> </div> </div> <div class="text-center"> <p class="text-xs sm:text-sm text-gray-600 mb-3 sm:mb-4">Withdraw your earnings using various payment methods</p> <a href="/user/withdrawals" class="inline-flex items-center bg-green-600 text-white px-4 sm:px-6 py-2 sm:py-3 rounded-lg hover:bg-green-700 transition-colors font-medium text-sm sm:text-base w-full sm:w-auto justify-center"> <svg class="w-4 h-4 sm:w-5 sm:h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1"></path> </svg> Withdraw Now </a> </div> <!-- Status Display --> <div class="mt-4 sm:mt-6 pt-4 sm:pt-6 border-t"> <div x-show="withdrawEnabled" class="text-center"> <span class="inline-flex items-center px-2 sm:px-3 py-1 rounded-full text-xs sm:text-sm font-medium bg-green-100 text-green-800"> <svg class="w-3 h-3 sm:w-4 sm:h-4 mr-1" fill="currentColor" viewBox="0 0 20 20"> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path> </svg> Withdrawals Enabled </span> </div> <div x-show="!withdrawEnabled" class="text-center"> <span class="inline-flex items-center px-2 sm:px-3 py-1 rounded-full text-xs sm:text-sm font-medium bg-yellow-100 text-yellow-800"> <svg class="w-3 h-3 sm:w-4 sm:h-4 mr-1" fill="currentColor" viewBox="0 0 20 20"> <path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path> </svg> Coming Soon </span> </div> </div> </div> </div> <!-- Recent Activity --> <div class="bg-white rounded-xl shadow-sm border"> <div class="p-4 sm:p-6 border-b border-gray-200"> <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-2"> <div> <h3 class="text-base sm:text-lg font-semibold text-gray-900 flex items-center"> <svg class="w-4 h-4 sm:w-5 sm:h-5 mr-2 text-indigo-600" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H9a2 2 0 00-2 2z"/> </svg> Recent Activity </h3> <p class="text-xs sm:text-sm text-gray-600 mt-1">Your latest 3 transactions</p> </div> <a href="/user-transactions.html" class="text-xs sm:text-sm text-indigo-600 hover:text-indigo-700 font-medium flex items-center justify-center sm:justify-start"> View All <svg class="w-3 h-3 sm:w-4 sm:h-4 ml-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/> </svg> </a> </div> </div> <div class="p-4 sm:p-6"> <div class="space-y-3 sm:space-y-4"> <template x-for="activity in recentActivity" :key="activity.id"> <div class="flex items-center justify-between p-3 sm:p-4 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors"> <div class="flex items-center space-x-3"> <!-- Activity Icon --> <div class="w-8 h-8 sm:w-10 sm:h-10 rounded-full flex items-center justify-center flex-shrink-0" :class="{ 'bg-green-100 text-green-600': activity.type === 'deposit' || activity.type === 'ad_watch', 'bg-blue-100 text-blue-600': activity.type === 'ad_click', 'bg-yellow-100 text-yellow-600': activity.type === 'withdraw_pending', 'bg-red-100 text-red-600': activity.type === 'withdraw_rejected', 'bg-purple-100 text-purple-600': activity.type === 'withdraw_approved', 'bg-orange-100 text-orange-600': activity.type === 'withdraw_refund', 'bg-indigo-100 text-indigo-600': activity.type === 'withdraw_request', 'bg-gray-100 text-gray-600': !activity.type || activity.type === 'activity' }"> <!-- Deposit Icon --> <svg x-show="activity.type === 'deposit'" class="w-4 h-4 sm:w-5 sm:h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/> </svg> <!-- Ad Click Icon --> <svg x-show="activity.type === 'ad_click' || activity.type === 'ad_watch'" class="w-4 h-4 sm:w-5 sm:h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"/> </svg> <!-- Withdraw Request Submit Icon --> <svg x-show="activity.type === 'withdraw_request'" class="w-4 h-4 sm:w-5 sm:h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/> </svg> <!-- Withdraw Pending Icon --> <svg x-show="activity.type === 'withdraw_pending'" class="w-4 h-4 sm:w-5 sm:h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/> </svg> <!-- Withdraw Rejected Icon --> <svg x-show="activity.type === 'withdraw_rejected'" class="w-4 h-4 sm:w-5 sm:h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/> </svg> <!-- Withdraw Approved Icon --> <svg x-show="activity.type === 'withdraw_approved'" class="w-4 h-4 sm:w-5 sm:h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/> </svg> <!-- Withdraw Refund Icon --> <svg x-show="activity.type === 'withdraw_refund'" class="w-4 h-4 sm:w-5 sm:h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"/> </svg> <!-- Default Activity Icon --> <svg x-show="!activity.type || activity.type === 'activity'" class="w-4 h-4 sm:w-5 sm:h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/> </svg> </div> <!-- Activity Details --> <div class="min-w-0 flex-1"> <p class="text-xs sm:text-sm font-medium text-gray-900 truncate" x-text="activity.description"></p> <p class="text-xs text-gray-500" x-text="activity.time"></p> </div> </div> <!-- Amount --> <div class="text-right flex-shrink-0"> <span class="text-xs sm:text-sm font-bold" :class="{ 'text-green-600': activity.amount && !activity.amount.includes('-'), 'text-red-600': activity.amount && activity.amount.includes('-'), 'text-gray-500': !activity.amount }" x-text="activity.amount || '--'"> </span> </div> </div> </template> <div x-show="recentActivity.length === 0" class="text-center py-8 sm:py-12"> <div class="w-12 h-12 sm:w-16 sm:h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-3 sm:mb-4"> <svg class="w-6 h-6 sm:w-8 sm:h-8 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H9a2 2 0 00-2 2z"/> </svg> </div> <h4 class="text-base sm:text-lg font-medium text-gray-900 mb-1 sm:mb-2">No Activity Yet</h4> <p class="text-xs sm:text-sm text-gray-500 mb-3 sm:mb-4">Start watching ads to see your earnings here</p> <a href="/user/ads" class="inline-flex items-center text-indigo-600 hover:text-indigo-700 font-medium text-xs sm:text-sm"> <svg class="w-3 h-3 sm:w-4 sm:h-4 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"/> </svg> Watch Your First Ad </a> </div> </div> </div> </div> </div> </div> <script> function dashboardData() { return { userBalance: 0.00, withdrawEnabled: false, enabledMethods: [], isAdminImpersonating: false, showConfirmModal: false, confirmModalTitle: '', confirmModalMessage: '', confirmModalAction: null, confirmModalIcon: '', confirmModalColor: '', stats: { adsWatched: 0, totalEarned: 0.00, availableAds: 0 }, availableAds: [], recentActivity: [], async loadData() { // Check if admin is impersonating await this.checkAdminImpersonation(); try { // Load available ads from admin const adsResponse = await fetch('/user/available-ads'); if (adsResponse.ok) { this.availableAds = await adsResponse.json(); this.stats.availableAds = this.availableAds.length; } else { // If no ads API, show empty - no sample ads this.availableAds = []; this.stats.availableAds = 0; } // Load user stats const statsResponse = await fetch('/user/stats'); if (statsResponse.ok) { const statsData = await statsResponse.json(); this.userBalance = parseFloat(statsData.balance || 0).toFixed(2); this.stats.adsWatched = statsData.adsWatched || 0; this.stats.totalEarned = parseFloat(statsData.totalEarned || 0).toFixed(2); } // Load withdraw status const withdrawResponse = await fetch('/user/withdraw-status'); if (withdrawResponse.ok) { const withdrawData = await withdrawResponse.json(); this.withdrawEnabled = withdrawData.withdrawEnabled; // Extract method names from the response this.enabledMethods = (withdrawData.enabledMethods || []).map(method => method.name || method); this.userBalance = parseFloat(withdrawData.userBalance || 0).toFixed(2); } // Load recent activity const activityResponse = await fetch('/user/activity-history'); if (activityResponse.ok) { const activityData = await activityResponse.json(); // Process and format activity data - limit to 3 most recent this.recentActivity = activityData.slice(0, 3).map(activity => ({ id: activity.id, description: this.formatActivityDescription(activity), time: this.formatActivityTime(activity.created_at), amount: this.formatActivityAmount(activity), type: activity.type || 'activity' })); } } catch (error) { console.error('Error loading dashboard data:', error); // Keep everything at zero - no sample data this.initializeEmptyState(); } }, async checkAdminImpersonation() { try { const response = await fetch('/user/check-admin-impersonation'); if (response.ok) { const result = await response.json(); this.isAdminImpersonating = result.isImpersonating || false; } } catch (error) { console.log('Admin impersonation check failed'); this.isAdminImpersonating = false; } }, async returnToAdminPanel() { this.showProfessionalConfirm( '🔒 Return to Admin Panel', 'Are you sure you want to return to the admin panel? This will end the user impersonation session and restore your admin privileges.', () => this.performReturnToAdmin(), 'info' ); }, async performReturnToAdmin() { try { const response = await fetch('/admin/return-from-impersonation', { method: 'POST', headers: { 'Content-Type': 'application/json' } }); if (response.ok) { window.location.href = '/admin/manage-users'; } else { this.showProfessionalConfirm( '❌ Return Failed', 'Error returning to admin panel. Please try logging out and back in.', () => {}, 'danger' ); } } catch (error) { console.error('Error returning to admin panel:', error); this.showProfessionalConfirm( '🚨 Network Error', 'Network error occurred. Please try again or refresh the page.', () => {}, 'danger' ); } }, initializeEmptyState() { this.userBalance = 0.00; this.withdrawEnabled = false; this.enabledMethods = []; this.stats = { adsWatched: 0, totalEarned: 0.00, availableAds: 0 }; this.availableAds = []; this.recentActivity = []; // Still check for withdraw methods this.checkWithdrawStatus(); }, loadSampleData() { // Start with zero balance and stats this.userBalance = 0.00; this.stats = { adsWatched: 0, totalEarned: 0.00, availableAds: 0 }; // No sample ads - only show what admin adds this.availableAds = []; // No fake activity - user starts fresh this.recentActivity = []; // Check for withdraw methods automatically this.checkWithdrawStatus(); }, async checkWithdrawStatus() { try { const response = await fetch('/user/withdraw-status'); if (response.ok) { const withdrawData = await response.json(); this.withdrawEnabled = withdrawData.withdrawEnabled; // Extract method names from the response this.enabledMethods = (withdrawData.enabledMethods || []).map(method => method.name || method); } } catch (error) { console.log('Withdraw status check failed, will show as unavailable'); this.withdrawEnabled = false; this.enabledMethods = []; } }, async watchAd(ad) { // Confirm user wants to watch the ad if (!confirm(`Watch "${ad.title}" for $${ad.reward}?\nDuration: ${ad.duration} seconds`)) { return; } try { // Open ad in new window const adWindow = window.open(ad.url, '_blank', 'width=800,height=600'); // Simulate ad watching timer let timeLeft = ad.duration; const timer = setInterval(() => { console.log(`Ad timer: ${timeLeft} seconds remaining`); timeLeft--; if (timeLeft <= 0) { clearInterval(timer); this.completeAdWatch(ad); } }, 1000); // Show countdown in current window alert(`Ad opened in new window! Watch for ${ad.duration} seconds to earn $${ad.reward}`); } catch (error) { console.error('Error watching ad:', error); alert('Error opening ad. Please try again.'); } }, async completeAdWatch(ad) { try { // Send completion to server const response = await fetch('/user/watch-ad', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ ad_id: ad.id, reward: ad.reward, duration: ad.duration }) }); if (response.ok) { const result = await response.json(); // Update local stats this.userBalance = parseFloat((this.userBalance + ad.reward).toFixed(2)); this.stats.adsWatched += 1; this.stats.totalEarned = parseFloat((this.stats.totalEarned + ad.reward).toFixed(2)); // Add to recent activity this.recentActivity.unshift({ id: Date.now(), description: `Watched ${ad.title}`, time: 'Just now', amount: ad.reward.toFixed(2) }); alert(`🎉 Congratulations! You earned $${ad.reward.toFixed(2)}!\nNew Balance: $${this.userBalance.toFixed(2)}`); } else { alert('Error recording ad completion. Please try again.'); } } catch (error) { console.error('Error completing ad watch:', error); alert('Network error. Please check your connection.'); } }, formatActivityDescription(activity) { if (activity.type === 'ad_watch') { return 'Watched ad and earned reward'; } else if (activity.type === 'withdraw_request') { return 'Withdraw request submitted'; } else if (activity.type === 'withdraw_refund') { return 'Withdraw rejected - amount refunded'; } return activity.description || 'Activity'; }, showProfessionalConfirm(title, message, action, iconType = 'warning') { this.confirmModalTitle = title; this.confirmModalMessage = message; this.confirmModalAction = action; // Set icon and color based on type switch (iconType) { case 'success': this.confirmModalIcon = '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>'; this.confirmModalColor = 'bg-gradient-to-r from-green-500 to-emerald-600'; break; case 'danger': this.confirmModalIcon = '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"/>'; this.confirmModalColor = 'bg-gradient-to-r from-red-500 to-pink-600'; break; case 'info': this.confirmModalIcon = '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 15l-3-3m0 0l3-3m-3 3h8M3 12a9 9 0 1118 0 9 9 0 01-18 0z"/>'; this.confirmModalColor = 'bg-gradient-to-r from-purple-500 to-indigo-600'; break; default: // warning this.confirmModalIcon = '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"/>'; this.confirmModalColor = 'bg-gradient-to-r from-orange-500 to-red-500'; } this.showConfirmModal = true; }, closeConfirmModal() { this.showConfirmModal = false; this.confirmModalAction = null; }, executeConfirmAction() { if (this.confirmModalAction) { this.confirmModalAction(); } this.closeConfirmModal(); }, formatActivityTime(timestamp) { const date = new Date(timestamp); const now = new Date(); const diffMs = now - date; const diffMins = Math.floor(diffMs / 60000); const diffHours = Math.floor(diffMins / 60); const diffDays = Math.floor(diffHours / 24); if (diffMins < 1) return 'Just now'; if (diffMins < 60) return `${diffMins} minute${diffMins > 1 ? 's' : ''} ago`; if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`; if (diffDays < 7) return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`; return date.toLocaleDateString(); }, formatActivityAmount(activity) { // For ad watch activities, use reward field instead of amount let amount = activity.amount || '0.00'; if (activity.type === 'ad_watch' && activity.reward) { amount = activity.reward; } if (!amount) return ''; const formattedAmount = Math.abs(parseFloat(amount)).toFixed(2); return amount < 0 ? `-$${formattedAmount}` : `+$${formattedAmount}`; } } } </script> <!-- Professional Confirmation Modal for User Dashboard --> <div x-show="showConfirmModal" x-cloak class="fixed inset-0 z-[70] flex items-center justify-center px-4 py-6"> <div class="fixed inset-0 bg-black bg-opacity-50 backdrop-blur-sm transition-opacity" x-show="showConfirmModal" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" @click.stop="closeConfirmModal()"></div> <div class="relative bg-white rounded-2xl shadow-2xl max-w-md w-full mx-auto" x-show="showConfirmModal" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0 scale-95 translate-y-4" x-transition:enter-end="opacity-100 scale-100 translate-y-0" x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100 scale-100 translate-y-0" x-transition:leave-end="opacity-0 scale-95 translate-y-4"> <!-- Header --> <div :class="confirmModalColor" class="text-white px-6 py-4 rounded-t-2xl"> <div class="flex items-center space-x-3"> <div class="w-10 h-10 bg-white bg-opacity-20 rounded-full flex items-center justify-center"> <svg class="w-6 h-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor" x-html="confirmModalIcon"> </svg> </div> <h3 class="text-lg font-bold" x-text="confirmModalTitle">Confirm Action</h3> </div> </div> <!-- Content --> <div class="p-6"> <p class="text-gray-700 text-sm leading-relaxed" x-text="confirmModalMessage">Are you sure you want to proceed with this action?</p> </div> <!-- Footer --> <div class="bg-gray-50 px-6 py-4 rounded-b-2xl border-t border-gray-200"> <div class="flex space-x-3"> <button @click.stop="closeConfirmModal()" class="flex-1 px-4 py-2 bg-gray-300 text-gray-700 rounded-lg hover:bg-gray-400 transition-colors font-medium"> Cancel </button> <button @click.stop="executeConfirmAction()" :class="confirmModalColor" class="flex-1 px-4 py-2 text-white rounded-lg hover:opacity-90 transition-all font-medium"> Confirm </button> </div> </div> </div> </div> </body> </html>