Upload 99 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- jweb/1a/about.html +394 -0
- jweb/1a/assets/api/booking_handler.php +92 -0
- jweb/1a/assets/api/callback.php +51 -0
- jweb/1a/assets/api/notifications.php +20 -0
- jweb/1a/assets/api/subscribe.php +62 -0
- jweb/1a/assets/api/testimonials.php +37 -0
- jweb/1a/assets/api/vehicles.php +20 -0
- jweb/1a/assets/config.php +17 -0
- jweb/1a/assets/css/1b.css +78 -0
- jweb/1a/assets/css/1c.css +47 -0
- jweb/1a/assets/css/1d.css +33 -0
- jweb/1a/assets/css/1e.css +85 -0
- jweb/1a/assets/db.php +13 -0
- jweb/1a/assets/models/Subscription.php +68 -0
- jweb/1a/assets/sample_data.php +120 -0
- jweb/1a/contact.html +430 -0
- jweb/1a/gallery.html +926 -0
- jweb/1a/services.html +855 -0
- jweb/ac1/assets/css/st.css +191 -0
- jweb/ac1/assets/css/sty.css +759 -0
- jweb/ac1/assets/css/style.css +89 -0
- jweb/ac1/assets/css/styles.css +195 -0
- jweb/ac1/assets/database/db.sql +86 -0
- jweb/ac1/assets/database/jm.sql +930 -0
- jweb/ac1/assets/database/mdb.sql +936 -0
- jweb/ac1/assets/images +1 -0
- jweb/ac1/assets/js/script.js +14 -0
- jweb/ac1/assets/js/scripts.js +29 -0
- jweb/ac1/check_session.php +24 -0
- jweb/ac1/config.php +14 -0
- jweb/ac1/db.php +111 -0
- jweb/ac1/home.html +692 -0
- jweb/ac1/inde.php +341 -0
- jweb/ac1/index.html +626 -0
- jweb/ac1/login.php +110 -0
- jweb/ac1/login_form.php +38 -0
- jweb/ac1/logout.php +52 -0
- jweb/ac1/setup_database.php +108 -0
- jweb/ac1/shake it.html +1313 -0
- jweb/ac1/signup.php +162 -0
- jweb/ac1/src/admin/admin-approval.php +190 -0
- jweb/ac1/src/admin/payments.php +77 -0
- jweb/ac1/src/api/agent-functions.php +156 -0
- jweb/ac1/src/api/agent_claim.php +195 -0
- jweb/ac1/src/api/check_session.php +24 -0
- jweb/ac1/src/api/config.php +13 -0
- jweb/ac1/src/api/db.php +233 -0
- jweb/ac1/src/api/deposit.php +52 -0
- jweb/ac1/src/api/fetch_tokens.php +25 -0
- jweb/ac1/src/api/generate-package-page.php +456 -0
jweb/1a/about.html
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>About - Japanese Motors</title>
|
| 7 |
+
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 8 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
+
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
|
| 10 |
+
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
|
| 11 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 12 |
+
<script src="https://unpkg.com/feather-icons"></script>
|
| 13 |
+
<link rel="stylesheet" href="assets/css/1d.css">
|
| 14 |
+
</head>
|
| 15 |
+
<body class="bg-gray-100 font-sans">
|
| 16 |
+
<!-- Navigation -->
|
| 17 |
+
<nav class="bg-white shadow-lg fixed w-full z-10">
|
| 18 |
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
| 19 |
+
<div class="flex justify-between h-16">
|
| 20 |
+
<div class="flex items-center">
|
| 21 |
+
<a href="about.html" class="flex-shrink-0 flex items-center">
|
| 22 |
+
<i data-feather="zap" class="h-8 w-8 text-red-500"></i>
|
| 23 |
+
<span class="ml-2 text-xl font-bold text-gray-900">JAPANESE MOTORS</span>
|
| 24 |
+
</a>
|
| 25 |
+
</div>
|
| 26 |
+
<div class="hidden md:flex items-center space-x-8">
|
| 27 |
+
<a href="../index.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Home</a>
|
| 28 |
+
<a href="gallery.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Inventory</a>
|
| 29 |
+
<a href="services.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Services</a>
|
| 30 |
+
<a href="about.html" class="nav-link text-red-500 px-3 py-2 rounded-md text-sm font-medium">About</a>
|
| 31 |
+
<a href="contact.html" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">Contact</a>
|
| 32 |
+
</div>
|
| 33 |
+
<div class="md:hidden flex items-center">
|
| 34 |
+
<button class="text-gray-500 hover:text-gray-900 focus:outline-none">
|
| 35 |
+
<i data-feather="menu"></i>
|
| 36 |
+
</button>
|
| 37 |
+
</div>
|
| 38 |
+
</div>
|
| 39 |
+
</div>
|
| 40 |
+
</nav>
|
| 41 |
+
|
| 42 |
+
<!-- Hero Section -->
|
| 43 |
+
<div class="relative pt-32 pb-20 bg-gray-900">
|
| 44 |
+
<div class="absolute inset-0 bg-black opacity-50"></div>
|
| 45 |
+
<div class="absolute inset-0 bg-center bg-cover" style="background-image: url('https://images.unsplash.com/photo-1566478985091-c2f6d2a45c0e?ixlib=rb-4.0.3&auto=format&fit=crop&w=1600&q=80');"></div>
|
| 46 |
+
<div class="container mx-auto px-4 relative">
|
| 47 |
+
<div class="text-center">
|
| 48 |
+
<h1 class="text-4xl font-bold text-white mb-4" data-aos="fade-up">Our Story</h1>
|
| 49 |
+
<p class="text-xl text-gray-300 max-w-2xl mx-auto" data-aos="fade-up" data-aos-delay="100">Dedicated to Japanese automotive excellence for over two decades</p>
|
| 50 |
+
</div>
|
| 51 |
+
</div>
|
| 52 |
+
</div>
|
| 53 |
+
|
| 54 |
+
<!-- Introduction -->
|
| 55 |
+
<section class="py-16 bg-white">
|
| 56 |
+
<div class="container mx-auto px-4">
|
| 57 |
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
|
| 58 |
+
<div data-aos="fade-right">
|
| 59 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-6">Welcome to Japanese Motors</h2>
|
| 60 |
+
<p class="text-gray-600 mb-6">Since 1999, Japanese Motors has been the premier destination for enthusiasts and collectors of Japanese performance vehicles. What began as a small specialty import business has grown into a comprehensive automotive destination offering sales, service, and restoration of the finest Japanese cars.</p>
|
| 61 |
+
<p class="text-gray-600 mb-6">Our passion for Japanese engineering excellence drives everything we do. From the legendary Nissan Skyline GT-R to the timeless Toyota Supra, we understand the unique character and performance potential of each vehicle we work with.</p>
|
| 62 |
+
<div class="flex items-center space-x-4">
|
| 63 |
+
<div class="flex items-center">
|
| 64 |
+
<i data-feather="award" class="text-red-500 mr-2"></i>
|
| 65 |
+
<span class="font-medium">2000+ Vehicles Sold</span>
|
| 66 |
+
</div>
|
| 67 |
+
<div class="flex items-center">
|
| 68 |
+
<i data-feather="users" class="text-red-500 mr-2"></i>
|
| 69 |
+
<span class="font-medium">1500+ Happy Clients</span>
|
| 70 |
+
</div>
|
| 71 |
+
</div>
|
| 72 |
+
</div>
|
| 73 |
+
<div data-aos="fade-left">
|
| 74 |
+
<img src="https://images.unsplash.com/photo-1580273916550-e323be2ae537?ixlib=rb-4.0.3&auto=format&fit=crop&w=1000&q=80" alt="Japanese Motors Showroom" class="rounded-lg shadow-lg w-full">
|
| 75 |
+
</div>
|
| 76 |
+
</div>
|
| 77 |
+
</div>
|
| 78 |
+
</section>
|
| 79 |
+
|
| 80 |
+
<!-- Our History -->
|
| 81 |
+
<section class="py-16 bg-gray-100">
|
| 82 |
+
<div class="container mx-auto px-4">
|
| 83 |
+
<div class="text-center mb-12">
|
| 84 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-4">Our History</h2>
|
| 85 |
+
<div class="w-20 h-1 bg-red-500 mx-auto"></div>
|
| 86 |
+
<p class="mt-4 text-gray-600 max-w-2xl mx-auto">A journey of passion for Japanese automotive excellence</p>
|
| 87 |
+
</div>
|
| 88 |
+
|
| 89 |
+
<div class="max-w-4xl mx-auto">
|
| 90 |
+
<div class="relative">
|
| 91 |
+
<!-- Timeline item 1 -->
|
| 92 |
+
<div class="mb-12 flex items-start" data-aos="fade-up">
|
| 93 |
+
<div class="bg-red-500 rounded-full h-12 w-12 flex items-center justify-center text-white font-bold z-10 mr-6">1999</div>
|
| 94 |
+
<div class="flex-1">
|
| 95 |
+
<h3 class="text-xl font-bold text-gray-800 mb-2">Foundation</h3>
|
| 96 |
+
<p class="text-gray-600">Japanese Motors was founded by Takashi Yamamoto with a vision to bring exceptional Japanese performance vehicles to enthusiasts worldwide. Started as a small import operation in Tokyo.</p>
|
| 97 |
+
</div>
|
| 98 |
+
</div>
|
| 99 |
+
|
| 100 |
+
<!-- Timeline item 2 -->
|
| 101 |
+
<div class="mb-12 flex items-start" data-aos="fade-up" data-aos-delay="100">
|
| 102 |
+
<div class="bg-red-500 rounded-full h-12 w-12 flex items-center justify-center text-white font-bold z-10 mr-6">2005</div>
|
| 103 |
+
<div class="flex-1">
|
| 104 |
+
<h3 class="text-xl font-bold text-gray-800 mb-2">First Showroom</h3>
|
| 105 |
+
<p class="text-gray-600">Opened our first dedicated showroom in Osaka, allowing customers to experience vehicles firsthand. Expanded inventory to include rare JDM models.</p>
|
| 106 |
+
</div>
|
| 107 |
+
</div>
|
| 108 |
+
|
| 109 |
+
<!-- Timeline item 3 -->
|
| 110 |
+
<div class="mb-12 flex items-start" data-aos="fade-up" data-aos-delay="200">
|
| 111 |
+
<div class="bg-red-500 rounded-full h-12 w-12 flex items-center justify-center text-white font-bold z-10 mr-6">2012</div>
|
| 112 |
+
<div class="flex-1">
|
| 113 |
+
<h3 class="text-xl font-bold text-gray-800 mb-2">Service Department</h3>
|
| 114 |
+
<p class="text-gray-600">Launched our state-of-the-art service center with factory-trained technicians specializing in Japanese performance vehicles. Became an authorized service provider for multiple brands.</p>
|
| 115 |
+
</div>
|
| 116 |
+
</div>
|
| 117 |
+
|
| 118 |
+
<!-- Timeline item 4 -->
|
| 119 |
+
<div class="mb-12 flex items-start" data-aos="fade-up" data-aos-delay="300">
|
| 120 |
+
<div class="bg-red-500 rounded-full h-12 w-12 flex items-center justify-center text-white font-bold z-10 mr-6">2018</div>
|
| 121 |
+
<div class="flex-1">
|
| 122 |
+
<h3 class="text-xl font-bold text-gray-800 mb-2">Global Expansion</h3>
|
| 123 |
+
<p class="text-gray-600">Established international shipping partnerships, enabling us to serve customers across North America, Europe, and Australia. Featured in multiple automotive publications.</p>
|
| 124 |
+
</div>
|
| 125 |
+
</div>
|
| 126 |
+
|
| 127 |
+
<!-- Timeline item 5 -->
|
| 128 |
+
<div class="flex items-start" data-aos="fade-up" data-aos-delay="400">
|
| 129 |
+
<div class="bg-red-500 rounded-full h-12 w-12 flex items-center justify-center text-white font-bold z-10 mr-6">2023</div>
|
| 130 |
+
<div class="flex-1">
|
| 131 |
+
<h3 class="text-xl font-bold text-gray-800 mb-2">Digital Innovation</h3>
|
| 132 |
+
<p class="text-gray-600">Launched virtual showroom and online concierge services. Celebrated 24 years of excellence in the Japanese automotive industry with over 2,000 vehicles delivered to enthusiasts worldwide.</p>
|
| 133 |
+
</div>
|
| 134 |
+
</div>
|
| 135 |
+
</div>
|
| 136 |
+
</div>
|
| 137 |
+
</div>
|
| 138 |
+
</section>
|
| 139 |
+
|
| 140 |
+
<!-- Our Values -->
|
| 141 |
+
<section class="py-16 bg-white">
|
| 142 |
+
<div class="container mx-auto px-4">
|
| 143 |
+
<div class="text-center mb-12">
|
| 144 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-4">Our Values</h2>
|
| 145 |
+
<div class="w-20 h-1 bg-red-500 mx-auto"></div>
|
| 146 |
+
<p class="mt-4 text-gray-600 max-w-2xl mx-auto">The principles that guide everything we do</p>
|
| 147 |
+
</div>
|
| 148 |
+
|
| 149 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
|
| 150 |
+
<div class="value-card text-center p-6 rounded-lg bg-gray-50 transition duration-300" data-aos="fade-up">
|
| 151 |
+
<div class="value-icon bg-red-100 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4 transition duration-300">
|
| 152 |
+
<i data-feather="check-circle" class="w-8 h-8 text-red-500"></i>
|
| 153 |
+
</div>
|
| 154 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Quality</h3>
|
| 155 |
+
<p class="text-gray-600">We are committed to delivering the highest quality vehicles and services, with meticulous attention to detail in everything we do.</p>
|
| 156 |
+
</div>
|
| 157 |
+
|
| 158 |
+
<div class="value-card text-center p-6 rounded-lg bg-gray-50 transition duration-300" data-aos="fade-up" data-aos-delay="100">
|
| 159 |
+
<div class="value-icon bg-red-100 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4 transition duration-300">
|
| 160 |
+
<i data-feather="shield" class="w-8 h-8 text-red-500"></i>
|
| 161 |
+
</div>
|
| 162 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Integrity</h3>
|
| 163 |
+
<p class="text-gray-600">We believe in transparency and honesty, building trust through clear communication and ethical business practices.</p>
|
| 164 |
+
</div>
|
| 165 |
+
|
| 166 |
+
<div class="value-card text-center p-6 rounded-lg bg-gray-50 transition duration-300" data-aos="fade-up" data-aos-delay="200">
|
| 167 |
+
<div class="value-icon bg-red-100 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4 transition duration-300">
|
| 168 |
+
<i data-feather="heart" class="w-8 h-8 text-red-500"></i>
|
| 169 |
+
</div>
|
| 170 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Passion</h3>
|
| 171 |
+
<p class="text-gray-600">Our team shares a genuine passion for Japanese automotive culture, which drives our dedication to excellence.</p>
|
| 172 |
+
</div>
|
| 173 |
+
|
| 174 |
+
<div class="value-card text-center p-6 rounded-lg bg-gray-50 transition duration-300" data-aos="fade-up" data-aos-delay="300">
|
| 175 |
+
<div class="value-icon bg-red-100 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4 transition duration-300">
|
| 176 |
+
<i data-feather="users" class="w-8 h-8 text-red-500"></i>
|
| 177 |
+
</div>
|
| 178 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Community</h3>
|
| 179 |
+
<p class="text-gray-600">We foster a vibrant community of Japanese car enthusiasts through events, knowledge sharing, and mutual appreciation.</p>
|
| 180 |
+
</div>
|
| 181 |
+
</div>
|
| 182 |
+
</div>
|
| 183 |
+
</section>
|
| 184 |
+
|
| 185 |
+
<!-- Our Team -->
|
| 186 |
+
<section class="py-16 bg-gray-100">
|
| 187 |
+
<div class="container mx-auto px-4">
|
| 188 |
+
<div class="text-center mb-12">
|
| 189 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-4">Meet Our Team</h2>
|
| 190 |
+
<div class="w-20 h-1 bg-red-500 mx-auto"></div>
|
| 191 |
+
<p class="mt-4 text-gray-600 max-w-2xl mx-auto">Experts passionate about Japanese automotive excellence</p>
|
| 192 |
+
</div>
|
| 193 |
+
|
| 194 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
| 195 |
+
<div class="team-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300" data-aos="fade-up">
|
| 196 |
+
<img src="https://images.unsplash.com/photo-1560250097-0b93528c311a?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80" alt="Takashi Yamamoto" class="w-full h-64 object-cover">
|
| 197 |
+
<div class="p-6">
|
| 198 |
+
<h3 class="text-xl font-bold text-gray-800 mb-1">Takashi Yamamoto</h3>
|
| 199 |
+
<p class="text-red-500 mb-4">Founder & CEO</p>
|
| 200 |
+
<p class="text-gray-600 mb-4">With over 30 years in the automotive industry, Takashi's vision established Japanese Motors as a global leader in JDM vehicles.</p>
|
| 201 |
+
<div class="flex space-x-3">
|
| 202 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="linkedin" class="w-5 h-5"></i></a>
|
| 203 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="twitter" class="w-5 h-5"></i></a>
|
| 204 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="mail" class="w-5 h-5"></i></a>
|
| 205 |
+
</div>
|
| 206 |
+
</div>
|
| 207 |
+
</div>
|
| 208 |
+
|
| 209 |
+
<div class="team-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300" data-aos="fade-up" data-aos-delay="100">
|
| 210 |
+
<img src="https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80" alt="Yuki Tanaka" class="w-full h-64 object-cover">
|
| 211 |
+
<div class="p-6">
|
| 212 |
+
<h3 class="text-xl font-bold text-gray-800 mb-1">Yuki Tanaka</h3>
|
| 213 |
+
<p class="text-red-500 mb-4">Head of Sales</p>
|
| 214 |
+
<p class="text-gray-600 mb-4">Yuki's expertise in JDM vehicles and customer service ensures our clients find their perfect Japanese performance vehicle.</p>
|
| 215 |
+
<div class="flex space-x-3">
|
| 216 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="linkedin" class="w-5 h-5"></i></a>
|
| 217 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="twitter" class="w-5 h-5"></i></a>
|
| 218 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="mail" class="w-5 h-5"></i></a>
|
| 219 |
+
</div>
|
| 220 |
+
</div>
|
| 221 |
+
</div>
|
| 222 |
+
|
| 223 |
+
<div class="team-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300" data-aos="fade-up" data-aos-delay="200">
|
| 224 |
+
<img src="https://images.unsplash.com/photo-1611439699130-d68968717092?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80" alt="Kenji Sato" class="w-full h-64 object-cover">
|
| 225 |
+
<div class="p-6">
|
| 226 |
+
<h3 class="text-xl font-bold text-gray-800 mb-1">Kenji Sato</h3>
|
| 227 |
+
<p class="text-red-500 mb-4">Master Technician</p>
|
| 228 |
+
<p class="text-gray-600 mb-4">Kenji brings 25 years of technical expertise specializing in Nissan GT-R and Toyota Supra performance modifications.</p>
|
| 229 |
+
<div class="flex space-x-3">
|
| 230 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="linkedin" class="w-5 h-5"></i></a>
|
| 231 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="twitter" class="w-5 h-5"></i></a>
|
| 232 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="mail" class="w-5 h-5"></i></a>
|
| 233 |
+
</div>
|
| 234 |
+
</div>
|
| 235 |
+
</div>
|
| 236 |
+
</div>
|
| 237 |
+
</div>
|
| 238 |
+
</section>
|
| 239 |
+
|
| 240 |
+
<!-- Testimonials -->
|
| 241 |
+
<section class="py-16 bg-white">
|
| 242 |
+
<div class="container mx-auto px-4">
|
| 243 |
+
<div class="text-center mb-12">
|
| 244 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-4">What Our Clients Say</h2>
|
| 245 |
+
<div class="w-20 h-1 bg-red-500 mx-auto"></div>
|
| 246 |
+
<p class="mt-4 text-gray-600 max-w-2xl mx-auto">Hear from enthusiasts who have experienced the Japanese Motors difference</p>
|
| 247 |
+
</div>
|
| 248 |
+
|
| 249 |
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
| 250 |
+
<div class="bg-gray-50 p-6 rounded-lg" data-aos="fade-up">
|
| 251 |
+
<div class="flex items-center mb-4">
|
| 252 |
+
<div class="text-red-500 mr-2">
|
| 253 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 254 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 255 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 256 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 257 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 258 |
+
</div>
|
| 259 |
+
</div>
|
| 260 |
+
<p class="text-gray-600 mb-4">"Japanese Motors helped me import my dream R34 GT-R from Japan. Their expertise made the process smooth and worry-free. The car was even better than described!"</p>
|
| 261 |
+
<div class="flex items-center">
|
| 262 |
+
<div class="w-12 h-12 rounded-full bg-gray-300 mr-3 overflow-hidden">
|
| 263 |
+
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-4.0.3&auto=format&fit=crop&w=100&q=80" alt="Michael Chen" class="w-full h-full object-cover">
|
| 264 |
+
</div>
|
| 265 |
+
<div>
|
| 266 |
+
<h4 class="font-bold text-gray-800">Michael Chen</h4>
|
| 267 |
+
<p class="text-gray-500">California, USA</p>
|
| 268 |
+
</div>
|
| 269 |
+
</div>
|
| 270 |
+
</div>
|
| 271 |
+
|
| 272 |
+
<div class="bg-gray-50 p-6 rounded-lg" data-aos="fade-up" data-aos-delay="100">
|
| 273 |
+
<div class="flex items-center mb-4">
|
| 274 |
+
<div class="text-red-500 mr-2">
|
| 275 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 276 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 277 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 278 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 279 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 280 |
+
</div>
|
| 281 |
+
</div>
|
| 282 |
+
<p class="text-gray-600 mb-4">"The team at Japanese Motors transformed my FD RX-7 with their performance upgrades. Their knowledge of rotary engines is unmatched. Absolutely thrilled with the results!"</p>
|
| 283 |
+
<div class="flex items-center">
|
| 284 |
+
<div class="w-12 h-12 rounded-full bg-gray-300 mr-3 overflow-hidden">
|
| 285 |
+
<img src="https://images.unsplash.com/photo-1544005313-94ddf0286df2?ixlib=rb-4.0.3&auto=format&fit=crop&w=100&q=80" alt="Sarah Johnson" class="w-full h-full object-cover">
|
| 286 |
+
</div>
|
| 287 |
+
<div>
|
| 288 |
+
<h4 class="font-bold text-gray-800">Sarah Johnson</h4>
|
| 289 |
+
<p class="text-gray-500">London, UK</p>
|
| 290 |
+
</div>
|
| 291 |
+
</div>
|
| 292 |
+
</div>
|
| 293 |
+
|
| 294 |
+
<div class="bg-gray-50 p-6 rounded-lg" data-aos="fade-up" data-aos-delay="200">
|
| 295 |
+
<div class="flex items-center mb-4">
|
| 296 |
+
<div class="text-red-500 mr-2">
|
| 297 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 298 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 299 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 300 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 301 |
+
<i data-feather="star" class="w-5 h-5 fill-current"></i>
|
| 302 |
+
</div>
|
| 303 |
+
</div>
|
| 304 |
+
<p class="text-gray-600 mb-4">"I've been dealing with Japanese Motors for over 10 years. Their after-sales service and support are exceptional. They truly care about their customers beyond the initial sale."</p>
|
| 305 |
+
<div class="flex items-center">
|
| 306 |
+
<div class="w-12 h-12 rounded-full bg-gray-300 mr-3 overflow-hidden">
|
| 307 |
+
<img src="https://images.unsplash.com/photo-1552058544-f2b08422138a?ixlib=rb-4.0.3&auto=format&fit=crop&w=100&q=80" alt="David Müller" class="w-full h-full object-cover">
|
| 308 |
+
</div>
|
| 309 |
+
<div>
|
| 310 |
+
<h4 class="font-bold text-gray-800">David Müller</h4>
|
| 311 |
+
<p class="text-gray-500">Berlin, Germany</p>
|
| 312 |
+
</div>
|
| 313 |
+
</div>
|
| 314 |
+
</div>
|
| 315 |
+
</div>
|
| 316 |
+
</div>
|
| 317 |
+
</section>
|
| 318 |
+
|
| 319 |
+
<!-- Call to Action -->
|
| 320 |
+
<section class="py-16 bg-red-500 text-white">
|
| 321 |
+
<div class="container mx-auto px-4 text-center">
|
| 322 |
+
<h2 class="text-3xl font-bold mb-6">Experience the Japanese Motors Difference</h2>
|
| 323 |
+
<p class="text-xl mb-8 max-w-2xl mx-auto">Join our community of enthusiasts and discover why we're the trusted name in Japanese performance vehicles.</p>
|
| 324 |
+
<div class="flex flex-col sm:flex-row justify-center gap-4">
|
| 325 |
+
<a href="gallery.html" class="bg-white text-red-500 px-8 py-3 rounded-md font-bold transition duration-300 hover:bg-gray-100">
|
| 326 |
+
Browse Inventory
|
| 327 |
+
</a>
|
| 328 |
+
<a href="contact.html" class="border-2 border-white text-white px-8 py-3 rounded-md font-bold transition duration-300 hover:bg-white hover:text-red-500">
|
| 329 |
+
Contact Us
|
| 330 |
+
</a>
|
| 331 |
+
</div>
|
| 332 |
+
</div>
|
| 333 |
+
</section>
|
| 334 |
+
|
| 335 |
+
<!-- Footer -->
|
| 336 |
+
<footer class="bg-gray-900 text-white py-12">
|
| 337 |
+
<div class="container mx-auto px-4">
|
| 338 |
+
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
| 339 |
+
<div>
|
| 340 |
+
<h3 class="text-xl font-bold mb-4">Japanese Motors</h3>
|
| 341 |
+
<p class="text-gray-400">Premium Japanese performance vehicles imported directly from Japan.</p>
|
| 342 |
+
</div>
|
| 343 |
+
<div>
|
| 344 |
+
<h3 class="text-lg font-bold mb-4">Quick Links</h3>
|
| 345 |
+
<ul class="space-y-2">
|
| 346 |
+
<li><a href="../index.html" class="text-gray-400 hover:text-red-500">Home</a></li>
|
| 347 |
+
<li><a href="gallery.html" class="text-gray-400 hover:text-red-500">Inventory</a></li>
|
| 348 |
+
<li><a href="services.html" class="text-gray-400 hover:text-red-500">Services</a></li>
|
| 349 |
+
<li><a href="about.html" class="text-gray-400 hover:text-red-500">About Us</a></li>
|
| 350 |
+
<li><a href="contact.html" class="text-gray-400 hover:text-red-500">Contact</a></li>
|
| 351 |
+
</ul>
|
| 352 |
+
</div>
|
| 353 |
+
<div>
|
| 354 |
+
<h3 class="text-lg font-bold mb-4">Contact Info</h3>
|
| 355 |
+
<ul class="space-y-2">
|
| 356 |
+
<li class="flex items-center">
|
| 357 |
+
<i data-feather="map-pin" class="mr-2 w-4 h-4"></i>
|
| 358 |
+
<span class="text-gray-400">123 Automotive Way, Tokyo, Japan</span>
|
| 359 |
+
</li>
|
| 360 |
+
<li class="flex items-center">
|
| 361 |
+
<i data-feather="phone" class="mr-2 w-4 h-4"></i>
|
| 362 |
+
<span class="text-gray-400">+81 3 1234 5678</span>
|
| 363 |
+
</li>
|
| 364 |
+
<li class="flex items-center">
|
| 365 |
+
<i data-feather="mail" class="mr-2 w-4 h-4"></i>
|
| 366 |
+
<span class="text-gray-400">info@japanesemotors.com</span>
|
| 367 |
+
</li>
|
| 368 |
+
</ul>
|
| 369 |
+
</div>
|
| 370 |
+
<div>
|
| 371 |
+
<h3 class="text-lg font-bold mb-4">Follow Us</h3>
|
| 372 |
+
<div class="flex space-x-4">
|
| 373 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="facebook" class="w-6 h-6"></i></a>
|
| 374 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="instagram" class="w-6 h-6"></i></a>
|
| 375 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="twitter" class="w-6 h-6"></i></a>
|
| 376 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="youtube" class="w-6 h-6"></i></a>
|
| 377 |
+
</div>
|
| 378 |
+
</div>
|
| 379 |
+
</div>
|
| 380 |
+
<div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-400">
|
| 381 |
+
<p>© 2023 Japanese Motors. All rights reserved.</p>
|
| 382 |
+
</div>
|
| 383 |
+
</div>
|
| 384 |
+
</footer>
|
| 385 |
+
|
| 386 |
+
<script>
|
| 387 |
+
// Initialize Feather Icons and AOS
|
| 388 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 389 |
+
feather.replace();
|
| 390 |
+
AOS.init();
|
| 391 |
+
});
|
| 392 |
+
</script>
|
| 393 |
+
</body>
|
| 394 |
+
</html>
|
jweb/1a/assets/api/booking_handler.php
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Database configuration
|
| 3 |
+
$host = '127.0.0.1';
|
| 4 |
+
$dbname = 'jweb';
|
| 5 |
+
$username = 'root';
|
| 6 |
+
$password = 'YourStrongPassword123';
|
| 7 |
+
|
| 8 |
+
// Enable error reporting for debugging
|
| 9 |
+
error_reporting(E_ALL);
|
| 10 |
+
ini_set('display_errors', 1);
|
| 11 |
+
|
| 12 |
+
header('Content-Type: application/json');
|
| 13 |
+
|
| 14 |
+
// Create database connection
|
| 15 |
+
try {
|
| 16 |
+
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
|
| 17 |
+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
| 18 |
+
} catch (PDOException $e) {
|
| 19 |
+
echo json_encode(['status' => 'error', 'message' => 'Database connection failed: ' . $e->getMessage()]);
|
| 20 |
+
exit;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
// Process form submission
|
| 24 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
| 25 |
+
// Validate required fields
|
| 26 |
+
$required_fields = ['customer_name', 'email', 'phone', 'vehicle_make', 'vehicle_model', 'service_type', 'service_name'];
|
| 27 |
+
|
| 28 |
+
foreach ($required_fields as $field) {
|
| 29 |
+
if (empty($_POST[$field])) {
|
| 30 |
+
echo json_encode(['status' => 'error', 'message' => "Please fill in all required fields. Missing: $field"]);
|
| 31 |
+
exit;
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
// Sanitize input data
|
| 36 |
+
$customer_name = filter_var($_POST['customer_name'], FILTER_SANITIZE_STRING);
|
| 37 |
+
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
|
| 38 |
+
$phone = filter_var($_POST['phone'], FILTER_SANITIZE_STRING);
|
| 39 |
+
$vehicle_make = filter_var($_POST['vehicle_make'], FILTER_SANITIZE_STRING);
|
| 40 |
+
$vehicle_model = filter_var($_POST['vehicle_model'], FILTER_SANITIZE_STRING);
|
| 41 |
+
$vehicle_year = !empty($_POST['vehicle_year']) ? filter_var($_POST['vehicle_year'], FILTER_SANITIZE_NUMBER_INT) : null;
|
| 42 |
+
$service_type = filter_var($_POST['service_type'], FILTER_SANITIZE_STRING);
|
| 43 |
+
$service_name = filter_var($_POST['service_name'], FILTER_SANITIZE_STRING);
|
| 44 |
+
$preferred_date = !empty($_POST['preferred_date']) ? $_POST['preferred_date'] : null;
|
| 45 |
+
$preferred_time = !empty($_POST['preferred_time']) ? $_POST['preferred_time'] : null;
|
| 46 |
+
$message = !empty($_POST['message']) ? filter_var($_POST['message'], FILTER_SANITIZE_STRING) : null;
|
| 47 |
+
|
| 48 |
+
// Validate email
|
| 49 |
+
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
| 50 |
+
echo json_encode(['status' => 'error', 'message' => 'Please provide a valid email address']);
|
| 51 |
+
exit;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
// Insert data into database
|
| 55 |
+
try {
|
| 56 |
+
$stmt = $pdo->prepare("INSERT INTO service_bookings
|
| 57 |
+
(customer_name, email, phone, vehicle_make, vehicle_model, vehicle_year,
|
| 58 |
+
service_type, service_name, preferred_date, preferred_time, message)
|
| 59 |
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
| 60 |
+
|
| 61 |
+
$stmt->execute([
|
| 62 |
+
$customer_name,
|
| 63 |
+
$email,
|
| 64 |
+
$phone,
|
| 65 |
+
$vehicle_make,
|
| 66 |
+
$vehicle_model,
|
| 67 |
+
$vehicle_year,
|
| 68 |
+
$service_type,
|
| 69 |
+
$service_name,
|
| 70 |
+
$preferred_date,
|
| 71 |
+
$preferred_time,
|
| 72 |
+
$message
|
| 73 |
+
]);
|
| 74 |
+
|
| 75 |
+
// Get the booking ID
|
| 76 |
+
$booking_id = $pdo->lastInsertId();
|
| 77 |
+
|
| 78 |
+
// Send confirmation email (optional)
|
| 79 |
+
// $this->sendConfirmationEmail($email, $customer_name, $service_name, $booking_id);
|
| 80 |
+
|
| 81 |
+
echo json_encode([
|
| 82 |
+
'status' => 'success',
|
| 83 |
+
'message' => 'Your booking has been submitted successfully! We will contact you shortly to confirm your appointment.',
|
| 84 |
+
'booking_id' => $booking_id
|
| 85 |
+
]);
|
| 86 |
+
|
| 87 |
+
} catch (PDOException $e) {
|
| 88 |
+
echo json_encode(['status' => 'error', 'message' => 'Failed to save booking: ' . $e->getMessage()]);
|
| 89 |
+
}
|
| 90 |
+
} else {
|
| 91 |
+
echo json_encode(['status' => 'error', 'message' => 'Invalid request method']);
|
| 92 |
+
}
|
jweb/1a/assets/api/callback.php
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// callback.php
|
| 3 |
+
require_once 'config.php';
|
| 4 |
+
|
| 5 |
+
header('Access-Control-Allow-Origin: *');
|
| 6 |
+
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
|
| 7 |
+
header('Access-Control-Allow-Headers: Content-Type');
|
| 8 |
+
|
| 9 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
| 10 |
+
try {
|
| 11 |
+
$pdo = getDBConnection();
|
| 12 |
+
|
| 13 |
+
$name = filter_var($_POST['name'], FILTER_SANITIZE_STRING);
|
| 14 |
+
$phone = filter_var($_POST['phone'], FILTER_SANITIZE_STRING);
|
| 15 |
+
$preferredTime = filter_var($_POST['time'], FILTER_SANITIZE_STRING);
|
| 16 |
+
|
| 17 |
+
if (empty($name) || empty($phone)) {
|
| 18 |
+
echo json_encode(['success' => false, 'message' => 'Name and phone are required']);
|
| 19 |
+
exit;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
// Insert callback request
|
| 23 |
+
$stmt = $pdo->prepare("INSERT INTO callback_requests (name, phone, preferred_time) VALUES (:name, :phone, :preferred_time)");
|
| 24 |
+
$stmt->execute([
|
| 25 |
+
':name' => $name,
|
| 26 |
+
':phone' => $phone,
|
| 27 |
+
':preferred_time' => $preferredTime
|
| 28 |
+
]);
|
| 29 |
+
|
| 30 |
+
// Send email notification to admin
|
| 31 |
+
$to = 'info@japanesemotors.com';
|
| 32 |
+
$subject = 'New Callback Request - Japanese Motors';
|
| 33 |
+
$message = "A new callback request has been received:\n\n";
|
| 34 |
+
$message .= "Name: $name\n";
|
| 35 |
+
$message .= "Phone: $phone\n";
|
| 36 |
+
$message .= "Preferred Time: $preferredTime\n\n";
|
| 37 |
+
$message .= "Please contact the client as soon as possible.";
|
| 38 |
+
$headers = 'From: no-reply@japanesemotors.com' . "\r\n" .
|
| 39 |
+
'Reply-To: no-reply@japanesemotors.com' . "\r\n" .
|
| 40 |
+
'X-Mailer: PHP/' . phpversion();
|
| 41 |
+
|
| 42 |
+
mail($to, $subject, $message, $headers);
|
| 43 |
+
|
| 44 |
+
echo json_encode(['success' => true, 'message' => 'Callback request submitted successfully! We will contact you soon.']);
|
| 45 |
+
} catch(PDOException $e) {
|
| 46 |
+
echo json_encode(['success' => false, 'message' => 'Request failed: ' . $e->getMessage()]);
|
| 47 |
+
}
|
| 48 |
+
} else {
|
| 49 |
+
echo json_encode(['success' => false, 'message' => 'Invalid request method']);
|
| 50 |
+
}
|
| 51 |
+
?>
|
jweb/1a/assets/api/notifications.php
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// notifications.php
|
| 3 |
+
require_once 'config.php';
|
| 4 |
+
|
| 5 |
+
header('Access-Control-Allow-Origin: *');
|
| 6 |
+
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
|
| 7 |
+
header('Access-Control-Allow-Headers: Content-Type');
|
| 8 |
+
|
| 9 |
+
try {
|
| 10 |
+
$pdo = getDBConnection();
|
| 11 |
+
|
| 12 |
+
// Get all notifications
|
| 13 |
+
$stmt = $pdo->query("SELECT * FROM notifications ORDER BY created_at DESC LIMIT 5");
|
| 14 |
+
$notifications = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
| 15 |
+
|
| 16 |
+
echo json_encode(['success' => true, 'data' => $notifications]);
|
| 17 |
+
} catch(PDOException $e) {
|
| 18 |
+
echo json_encode(['success' => false, 'message' => 'Error fetching notifications: ' . $e->getMessage()]);
|
| 19 |
+
}
|
| 20 |
+
?>
|
jweb/1a/assets/api/subscribe.php
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Enable error reporting for debugging
|
| 3 |
+
ini_set('display_errors', 1);
|
| 4 |
+
ini_set('display_startup_errors', 1);
|
| 5 |
+
error_reporting(E_ALL);
|
| 6 |
+
|
| 7 |
+
header('Content-Type: application/json');
|
| 8 |
+
header('Access-Control-Allow-Origin: *');
|
| 9 |
+
header('Access-Control-Allow-Methods: POST');
|
| 10 |
+
header('Access-Control-Allow-Headers: Access-Control-Allow-Headers, Content-Type, Access-Control-Allow-Methods, Authorization, X-Requested-With');
|
| 11 |
+
|
| 12 |
+
// Simulate database connection (replace with your actual database code)
|
| 13 |
+
$subscriptionsFile = '../models/Subscription.php';
|
| 14 |
+
|
| 15 |
+
// Initialize subscriptions file if it doesn't exist
|
| 16 |
+
if (!file_exists($subscriptionsFile)) {
|
| 17 |
+
file_put_contents($subscriptionsFile, json_encode([]));
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
// Get POST data
|
| 21 |
+
$email = $_POST['email'] ?? '';
|
| 22 |
+
$notification_opt_in = isset($_POST['notification_opt_in']) ? (bool)$_POST['notification_opt_in'] : false;
|
| 23 |
+
|
| 24 |
+
// Validate email
|
| 25 |
+
if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
| 26 |
+
http_response_code(400);
|
| 27 |
+
echo json_encode(['message' => 'Please provide a valid email address.']);
|
| 28 |
+
exit;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
// Read existing subscriptions
|
| 32 |
+
$subscriptions = json_decode(file_get_contents($subscriptionsFile), true);
|
| 33 |
+
|
| 34 |
+
// Check if email already exists
|
| 35 |
+
foreach ($subscriptions as $sub) {
|
| 36 |
+
if ($sub['email'] === $email) {
|
| 37 |
+
http_response_code(409);
|
| 38 |
+
echo json_encode(['message' => 'This email is already subscribed.']);
|
| 39 |
+
exit;
|
| 40 |
+
}
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
// Add new subscription
|
| 44 |
+
$newSubscription = [
|
| 45 |
+
'email' => $email,
|
| 46 |
+
'notification_opt_in' => $notification_opt_in,
|
| 47 |
+
'subscribed_at' => date('Y-m-d H:i:s'),
|
| 48 |
+
'active' => true
|
| 49 |
+
];
|
| 50 |
+
|
| 51 |
+
$subscriptions[] = $newSubscription;
|
| 52 |
+
|
| 53 |
+
// Save subscriptions
|
| 54 |
+
if (file_put_contents($subscriptionsFile, json_encode($subscriptions, JSON_PRETTY_PRINT))) {
|
| 55 |
+
http_response_code(200);
|
| 56 |
+
echo json_encode(['message' => 'Successfully subscribed to our newsletter!']);
|
| 57 |
+
} else {
|
| 58 |
+
http_response_code(500);
|
| 59 |
+
echo json_encode(['message' => 'Subscription failed. Please try again.']);
|
| 60 |
+
}
|
| 61 |
+
exit;
|
| 62 |
+
?>
|
jweb/1a/assets/api/testimonials.php
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// testimonials.php
|
| 3 |
+
require_once 'config.php';
|
| 4 |
+
|
| 5 |
+
header('Access-Control-Allow-Origin: *');
|
| 6 |
+
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
|
| 7 |
+
header('Access-Control-Allow-Headers: Content-Type');
|
| 8 |
+
try {
|
| 9 |
+
$pdo = getDBConnection();
|
| 10 |
+
|
| 11 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'like') {
|
| 12 |
+
// Handle like action
|
| 13 |
+
$testimonialId = filter_var($_POST['id'], FILTER_VALIDATE_INT);
|
| 14 |
+
|
| 15 |
+
if ($testimonialId) {
|
| 16 |
+
$stmt = $pdo->prepare("UPDATE testimonials SET helpful_count = helpful_count + 1 WHERE id = :id");
|
| 17 |
+
$stmt->execute([':id' => $testimonialId]);
|
| 18 |
+
|
| 19 |
+
// Get updated count
|
| 20 |
+
$stmt = $pdo->prepare("SELECT helpful_count FROM testimonials WHERE id = :id");
|
| 21 |
+
$stmt->execute([':id' => $testimonialId]);
|
| 22 |
+
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
| 23 |
+
|
| 24 |
+
echo json_encode(['success' => true, 'count' => $result['helpful_count']]);
|
| 25 |
+
exit;
|
| 26 |
+
}
|
| 27 |
+
} else {
|
| 28 |
+
// Get all testimonials
|
| 29 |
+
$stmt = $pdo->query("SELECT * FROM testimonials ORDER BY created_at DESC");
|
| 30 |
+
$testimonials = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
| 31 |
+
|
| 32 |
+
echo json_encode(['success' => true, 'data' => $testimonials]);
|
| 33 |
+
}
|
| 34 |
+
} catch(PDOException $e) {
|
| 35 |
+
echo json_encode(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
|
| 36 |
+
}
|
| 37 |
+
?>
|
jweb/1a/assets/api/vehicles.php
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// vehicles.php
|
| 3 |
+
require_once 'config.php';
|
| 4 |
+
|
| 5 |
+
header('Access-Control-Allow-Origin: *');
|
| 6 |
+
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
|
| 7 |
+
header('Access-Control-Allow-Headers: Content-Type');
|
| 8 |
+
|
| 9 |
+
try {
|
| 10 |
+
$pdo = getDBConnection();
|
| 11 |
+
|
| 12 |
+
// Get all vehicles
|
| 13 |
+
$stmt = $pdo->query("SELECT * FROM vehicles ORDER BY created_at DESC");
|
| 14 |
+
$vehicles = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
| 15 |
+
|
| 16 |
+
echo json_encode(['success' => true, 'data' => $vehicles]);
|
| 17 |
+
} catch(PDOException $e) {
|
| 18 |
+
echo json_encode(['success' => false, 'message' => 'Error fetching vehicles: ' . $e->getMessage()]);
|
| 19 |
+
}
|
| 20 |
+
?>
|
jweb/1a/assets/config.php
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// config.php
|
| 3 |
+
define('DB_HOST', '127.0.0.1');
|
| 4 |
+
define('DB_NAME', 'jweb');
|
| 5 |
+
define('DB_USER', 'root');
|
| 6 |
+
define('DB_PASS', 'YourStrongPassword123');
|
| 7 |
+
|
| 8 |
+
function getDBConnection() {
|
| 9 |
+
try {
|
| 10 |
+
$pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASS);
|
| 11 |
+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
| 12 |
+
return $pdo;
|
| 13 |
+
} catch(PDOException $e) {
|
| 14 |
+
die("Database connection failed: " . $e->getMessage());
|
| 15 |
+
}
|
| 16 |
+
}
|
| 17 |
+
?>
|
jweb/1a/assets/css/1b.css
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.car-card:hover {
|
| 2 |
+
transform: translateY(-5px);
|
| 3 |
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
| 4 |
+
}
|
| 5 |
+
.nav-link:hover {
|
| 6 |
+
color: #ef4444;
|
| 7 |
+
}
|
| 8 |
+
.floating-chat {
|
| 9 |
+
position: fixed;
|
| 10 |
+
bottom: 20px;
|
| 11 |
+
right: 20px;
|
| 12 |
+
z-index: 1000;
|
| 13 |
+
}
|
| 14 |
+
.sticky-contact {
|
| 15 |
+
position: fixed;
|
| 16 |
+
bottom: 20px;
|
| 17 |
+
left: 20px;
|
| 18 |
+
z-index: 1000;
|
| 19 |
+
}
|
| 20 |
+
.vr-container {
|
| 21 |
+
position: relative;
|
| 22 |
+
overflow: hidden;
|
| 23 |
+
padding-top: 56.25%; /* 16:9 Aspect Ratio */
|
| 24 |
+
}
|
| 25 |
+
.vr-iframe {
|
| 26 |
+
position: absolute;
|
| 27 |
+
top: 0;
|
| 28 |
+
left: 0;
|
| 29 |
+
bottom: 0;
|
| 30 |
+
right: 0;
|
| 31 |
+
width: 100%;
|
| 32 |
+
height: 100%;
|
| 33 |
+
border: none;
|
| 34 |
+
}
|
| 35 |
+
.modal {
|
| 36 |
+
display: none;
|
| 37 |
+
position: fixed;
|
| 38 |
+
top: 0;
|
| 39 |
+
left: 0;
|
| 40 |
+
width: 100%;
|
| 41 |
+
height: 100%;
|
| 42 |
+
background-color: rgba(0, 0, 0, 0.8);
|
| 43 |
+
z-index: 1000;
|
| 44 |
+
overflow-y: auto;
|
| 45 |
+
}
|
| 46 |
+
.modal-content {
|
| 47 |
+
background-color: white;
|
| 48 |
+
margin: 5% auto;
|
| 49 |
+
padding: 20px;
|
| 50 |
+
width: 90%;
|
| 51 |
+
max-width: 1000px;
|
| 52 |
+
border-radius: 8px;
|
| 53 |
+
position: relative;
|
| 54 |
+
}
|
| 55 |
+
.close-modal {
|
| 56 |
+
position: absolute;
|
| 57 |
+
top: 15px;
|
| 58 |
+
right: 15px;
|
| 59 |
+
font-size: 24px;
|
| 60 |
+
cursor: pointer;
|
| 61 |
+
z-index: 1001;
|
| 62 |
+
}
|
| 63 |
+
.motor-type-btn.active {
|
| 64 |
+
background-color: #ef4444;
|
| 65 |
+
color: white;
|
| 66 |
+
}
|
| 67 |
+
.car-image {
|
| 68 |
+
cursor: pointer;
|
| 69 |
+
transition: transform 0.3s ease;
|
| 70 |
+
}
|
| 71 |
+
.car-image:hover {
|
| 72 |
+
transform: scale(1.03);
|
| 73 |
+
}
|
| 74 |
+
.pagination-btn.active {
|
| 75 |
+
background-color: #ef4444;
|
| 76 |
+
color: white;
|
| 77 |
+
border-color: #ef4444;
|
| 78 |
+
}
|
jweb/1a/assets/css/1c.css
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.contact-card:hover {
|
| 2 |
+
transform: translateY(-5px);
|
| 3 |
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
| 4 |
+
}
|
| 5 |
+
.nav-link:hover {
|
| 6 |
+
color: #ef4444;
|
| 7 |
+
}
|
| 8 |
+
.floating-chat {
|
| 9 |
+
position: fixed;
|
| 10 |
+
bottom: 20px;
|
| 11 |
+
right: 20px;
|
| 12 |
+
z-index: 1000;
|
| 13 |
+
}
|
| 14 |
+
.sticky-contact {
|
| 15 |
+
position: fixed;
|
| 16 |
+
bottom: 20px;
|
| 17 |
+
left: 20px;
|
| 18 |
+
z-index: 1000;
|
| 19 |
+
}
|
| 20 |
+
.contact-method:hover {
|
| 21 |
+
background-color: #fef2f2;
|
| 22 |
+
transform: translateX(5px);
|
| 23 |
+
}
|
| 24 |
+
.form-input:focus {
|
| 25 |
+
border-color: #ef4444;
|
| 26 |
+
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.2);
|
| 27 |
+
}
|
| 28 |
+
.chat-bubble {
|
| 29 |
+
position: relative;
|
| 30 |
+
background: #f3f4f6;
|
| 31 |
+
border-radius: 18px;
|
| 32 |
+
padding: 12px 16px;
|
| 33 |
+
max-width: 70%;
|
| 34 |
+
}
|
| 35 |
+
.chat-bubble:after {
|
| 36 |
+
content: '';
|
| 37 |
+
position: absolute;
|
| 38 |
+
left: 0;
|
| 39 |
+
top: 50%;
|
| 40 |
+
width: 0;
|
| 41 |
+
height: 0;
|
| 42 |
+
border: 10px solid transparent;
|
| 43 |
+
border-right-color: #f3f4f6;
|
| 44 |
+
border-left: 0;
|
| 45 |
+
margin-top: -10px;
|
| 46 |
+
margin-left: -10px;
|
| 47 |
+
}
|
jweb/1a/assets/css/1d.css
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.team-card:hover {
|
| 2 |
+
transform: translateY(-5px);
|
| 3 |
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
| 4 |
+
}
|
| 5 |
+
.nav-link:hover {
|
| 6 |
+
color: #ef4444;
|
| 7 |
+
}
|
| 8 |
+
.floating-chat {
|
| 9 |
+
position: fixed;
|
| 10 |
+
bottom: 20px;
|
| 11 |
+
right: 20px;
|
| 12 |
+
z-index: 1000;
|
| 13 |
+
}
|
| 14 |
+
.sticky-contact {
|
| 15 |
+
position: fixed;
|
| 16 |
+
bottom: 20px;
|
| 17 |
+
left: 20px;
|
| 18 |
+
z-index: 1000;
|
| 19 |
+
}
|
| 20 |
+
.timeline-item:before {
|
| 21 |
+
content: '';
|
| 22 |
+
position: absolute;
|
| 23 |
+
left: 0;
|
| 24 |
+
top: 0;
|
| 25 |
+
height: 100%;
|
| 26 |
+
width: 2px;
|
| 27 |
+
background-color: #ef4444;
|
| 28 |
+
}
|
| 29 |
+
.value-card:hover .value-icon {
|
| 30 |
+
transform: scale(1.1);
|
| 31 |
+
background-color: #ef4444;
|
| 32 |
+
color: white;
|
| 33 |
+
}
|
jweb/1a/assets/css/1e.css
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.service-card:hover {
|
| 2 |
+
transform: translateY(-5px);
|
| 3 |
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
| 4 |
+
}
|
| 5 |
+
.nav-link:hover {
|
| 6 |
+
color: #ef4444;
|
| 7 |
+
}
|
| 8 |
+
.floating-chat {
|
| 9 |
+
position: fixed;
|
| 10 |
+
bottom: 20px;
|
| 11 |
+
right: 20px;
|
| 12 |
+
z-index: 1000;
|
| 13 |
+
}
|
| 14 |
+
.sticky-contact {
|
| 15 |
+
position: fixed;
|
| 16 |
+
bottom: 20px;
|
| 17 |
+
left: 20px;
|
| 18 |
+
z-index: 1000;
|
| 19 |
+
}
|
| 20 |
+
.service-tab.active {
|
| 21 |
+
background-color: #ef4444;
|
| 22 |
+
color: white;
|
| 23 |
+
}
|
| 24 |
+
.service-content {
|
| 25 |
+
display: none;
|
| 26 |
+
}
|
| 27 |
+
.service-content.active {
|
| 28 |
+
display: block;
|
| 29 |
+
}
|
| 30 |
+
.accordion-content {
|
| 31 |
+
max-height: 0;
|
| 32 |
+
overflow: hidden;
|
| 33 |
+
transition: max-height 0.3s ease-out;
|
| 34 |
+
}
|
| 35 |
+
.accordion-item.active .accordion-content {
|
| 36 |
+
max-height: 500px;
|
| 37 |
+
}
|
| 38 |
+
.accordion-item.active .accordion-button i {
|
| 39 |
+
transform: rotate(180deg);
|
| 40 |
+
}
|
| 41 |
+
/* Modal styles */
|
| 42 |
+
.modal-overlay {
|
| 43 |
+
display: none;
|
| 44 |
+
position: fixed;
|
| 45 |
+
top: 0;
|
| 46 |
+
left: 0;
|
| 47 |
+
right: 0;
|
| 48 |
+
bottom: 0;
|
| 49 |
+
background-color: rgba(0, 0, 0, 0.75);
|
| 50 |
+
z-index: 1000;
|
| 51 |
+
align-items: center;
|
| 52 |
+
justify-content: center;
|
| 53 |
+
}
|
| 54 |
+
.modal-overlay.active {
|
| 55 |
+
display: flex;
|
| 56 |
+
}
|
| 57 |
+
.modal-container {
|
| 58 |
+
background-color: white;
|
| 59 |
+
border-radius: 0.5rem;
|
| 60 |
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
| 61 |
+
width: 90%;
|
| 62 |
+
max-width: 600px;
|
| 63 |
+
max-height: 90vh;
|
| 64 |
+
overflow-y: auto;
|
| 65 |
+
}
|
| 66 |
+
/* Notification styles */
|
| 67 |
+
.notification {
|
| 68 |
+
position: fixed;
|
| 69 |
+
top: 1rem;
|
| 70 |
+
right: 1rem;
|
| 71 |
+
padding: 1rem;
|
| 72 |
+
border-radius: 0.5rem;
|
| 73 |
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
| 74 |
+
z-index: 1100;
|
| 75 |
+
display: flex;
|
| 76 |
+
align-items: center;
|
| 77 |
+
max-width: 400px;
|
| 78 |
+
display: none;
|
| 79 |
+
}
|
| 80 |
+
.notification.success {
|
| 81 |
+
background-color: #10B981;
|
| 82 |
+
}
|
| 83 |
+
.notification.error {
|
| 84 |
+
background-color: #EF4444;
|
| 85 |
+
}
|
jweb/1a/assets/db.php
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
$host = "127.0.0.1";
|
| 3 |
+
$dbname = "motors";
|
| 4 |
+
$username = "root";
|
| 5 |
+
$password = "YourStrongPassword123";
|
| 6 |
+
|
| 7 |
+
try {
|
| 8 |
+
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password);
|
| 9 |
+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
| 10 |
+
} catch (PDOException $e) {
|
| 11 |
+
die("DB Connection failed: " . $e->getMessage());
|
| 12 |
+
}
|
| 13 |
+
?>
|
jweb/1a/assets/models/Subscription.php
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
class Subscription {
|
| 3 |
+
private $conn;
|
| 4 |
+
private $table_name = "subscriptions";
|
| 5 |
+
|
| 6 |
+
public $id;
|
| 7 |
+
public $email;
|
| 8 |
+
public $notification_opt_in;
|
| 9 |
+
public $subscribed_at;
|
| 10 |
+
public $unsubscribed_at;
|
| 11 |
+
public $is_active;
|
| 12 |
+
|
| 13 |
+
public function __construct($db) {
|
| 14 |
+
$this->conn = $db;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
public function subscribe() {
|
| 18 |
+
$query = "INSERT INTO " . $this->table_name . "
|
| 19 |
+
SET email=:email, notification_opt_in=:notification_opt_in, is_active=1";
|
| 20 |
+
|
| 21 |
+
$stmt = $this->conn->prepare($query);
|
| 22 |
+
|
| 23 |
+
$this->email = htmlspecialchars(strip_tags($this->email));
|
| 24 |
+
|
| 25 |
+
$stmt->bindParam(":email", $this->email);
|
| 26 |
+
$stmt->bindParam(":notification_opt_in", $this->notification_opt_in);
|
| 27 |
+
|
| 28 |
+
if ($stmt->execute()) {
|
| 29 |
+
return true;
|
| 30 |
+
}
|
| 31 |
+
return false;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
public function unsubscribe($email) {
|
| 35 |
+
$query = "UPDATE " . $this->table_name . "
|
| 36 |
+
SET is_active=0, unsubscribed_at=NOW()
|
| 37 |
+
WHERE email=:email";
|
| 38 |
+
|
| 39 |
+
$stmt = $this->conn->prepare($query);
|
| 40 |
+
|
| 41 |
+
$email = htmlspecialchars(strip_tags($email));
|
| 42 |
+
$stmt->bindParam(":email", $email);
|
| 43 |
+
|
| 44 |
+
if ($stmt->execute()) {
|
| 45 |
+
return true;
|
| 46 |
+
}
|
| 47 |
+
return false;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
public function checkSubscription($email) {
|
| 51 |
+
$query = "SELECT is_active FROM " . $this->table_name . "
|
| 52 |
+
WHERE email = :email";
|
| 53 |
+
|
| 54 |
+
$stmt = $this->conn->prepare($query);
|
| 55 |
+
|
| 56 |
+
$email = htmlspecialchars(strip_tags($email));
|
| 57 |
+
$stmt->bindParam(":email", $email);
|
| 58 |
+
|
| 59 |
+
$stmt->execute();
|
| 60 |
+
|
| 61 |
+
if ($stmt->rowCount() > 0) {
|
| 62 |
+
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
| 63 |
+
return $row['is_active'];
|
| 64 |
+
}
|
| 65 |
+
return false;
|
| 66 |
+
}
|
| 67 |
+
}
|
| 68 |
+
?>
|
jweb/1a/assets/sample_data.php
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// sample_data.php
|
| 3 |
+
require_once 'config.php';
|
| 4 |
+
|
| 5 |
+
try {
|
| 6 |
+
$pdo = getDBConnection();
|
| 7 |
+
|
| 8 |
+
// Insert sample vehicles
|
| 9 |
+
$vehicles = [
|
| 10 |
+
[
|
| 11 |
+
'name' => 'Nissan GT-R',
|
| 12 |
+
'model_year' => 2023,
|
| 13 |
+
'location' => 'Tokyo',
|
| 14 |
+
'description' => 'The legendary Godzilla with 565HP twin-turbo V6 engine.',
|
| 15 |
+
'price' => 112000.00,
|
| 16 |
+
'image_url' => 'http://static.photos/automotive/640x360/1',
|
| 17 |
+
'status' => 'new'
|
| 18 |
+
],
|
| 19 |
+
[
|
| 20 |
+
'name' => 'Toyota Supra',
|
| 21 |
+
'model_year' => 2023,
|
| 22 |
+
'location' => 'Osaka',
|
| 23 |
+
'description' => 'The iconic sports car returns with 382HP turbocharged inline-6.',
|
| 24 |
+
'price' => 52000.00,
|
| 25 |
+
'image_url' => 'http://static.photos/automotive/640x360/2',
|
| 26 |
+
'status' => 'used'
|
| 27 |
+
],
|
| 28 |
+
[
|
| 29 |
+
'name' => 'Honda NSX',
|
| 30 |
+
'model_year' => 2023,
|
| 31 |
+
'location' => 'Yokohama',
|
| 32 |
+
'description' => '573HP hybrid supercar with cutting-edge technology.',
|
| 33 |
+
'price' => 169000.00,
|
| 34 |
+
'image_url' => 'http://static.photos/automotive/640x360/3',
|
| 35 |
+
'status' => 'limited'
|
| 36 |
+
]
|
| 37 |
+
];
|
| 38 |
+
|
| 39 |
+
$stmt = $pdo->prepare("INSERT INTO vehicles (name, model_year, location, description, price, image_url, status) VALUES (?, ?, ?, ?, ?, ?, ?)");
|
| 40 |
+
|
| 41 |
+
foreach ($vehicles as $vehicle) {
|
| 42 |
+
$stmt->execute([
|
| 43 |
+
$vehicle['name'],
|
| 44 |
+
$vehicle['model_year'],
|
| 45 |
+
$vehicle['location'],
|
| 46 |
+
$vehicle['description'],
|
| 47 |
+
$vehicle['price'],
|
| 48 |
+
$vehicle['image_url'],
|
| 49 |
+
$vehicle['status']
|
| 50 |
+
]);
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
// Insert sample testimonials
|
| 54 |
+
$testimonials = [
|
| 55 |
+
[
|
| 56 |
+
'client_name' => 'Michael R.',
|
| 57 |
+
'client_photo' => 'http://static.photos/people/200x200/1',
|
| 58 |
+
'rating' => 5,
|
| 59 |
+
'content' => '"The team at Japanese Motors made importing my dream GT-R from Japan seamless. The car arrived in perfect condition, exactly as described. Their attention to detail is unmatched."',
|
| 60 |
+
'helpful_count' => 32
|
| 61 |
+
],
|
| 62 |
+
[
|
| 63 |
+
'client_name' => 'Sarah K.',
|
| 64 |
+
'client_photo' => 'http://static.photos/people/200x200/2',
|
| 65 |
+
'rating' => 5,
|
| 66 |
+
'content' => '"I was hesitant about importing a car internationally, but Japanese Motors guided me through every step. My Supra is flawless and I saved thousands compared to local dealers."',
|
| 67 |
+
'helpful_count' => 28
|
| 68 |
+
]
|
| 69 |
+
];
|
| 70 |
+
|
| 71 |
+
$stmt = $pdo->prepare("INSERT INTO testimonials (client_name, client_photo, rating, content, helpful_count) VALUES (?, ?, ?, ?, ?)");
|
| 72 |
+
|
| 73 |
+
foreach ($testimonials as $testimonial) {
|
| 74 |
+
$stmt->execute([
|
| 75 |
+
$testimonial['client_name'],
|
| 76 |
+
$testimonial['client_photo'],
|
| 77 |
+
$testimonial['rating'],
|
| 78 |
+
$testimonial['content'],
|
| 79 |
+
$testimonial['helpful_count']
|
| 80 |
+
]);
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
// Insert sample notifications
|
| 84 |
+
$notifications = [
|
| 85 |
+
[
|
| 86 |
+
'title' => 'Price drop on Nissan GT-R',
|
| 87 |
+
'message' => 'Special discount available this week only',
|
| 88 |
+
'type' => 'price_drop',
|
| 89 |
+
'icon' => 'dollar-sign'
|
| 90 |
+
],
|
| 91 |
+
[
|
| 92 |
+
'title' => 'New arrivals from Japan',
|
| 93 |
+
'message' => 'Fresh inventory just arrived from our Tokyo warehouse',
|
| 94 |
+
'type' => 'new_arrival',
|
| 95 |
+
'icon' => 'truck'
|
| 96 |
+
],
|
| 97 |
+
[
|
| 98 |
+
'title' => 'Limited time offer ending soon',
|
| 99 |
+
'message' => 'Don\'t miss our exclusive financing rates',
|
| 100 |
+
'type' => 'limited_offer',
|
| 101 |
+
'icon' => 'clock'
|
| 102 |
+
]
|
| 103 |
+
];
|
| 104 |
+
|
| 105 |
+
$stmt = $pdo->prepare("INSERT INTO notifications (title, message, type, icon) VALUES (?, ?, ?, ?)");
|
| 106 |
+
|
| 107 |
+
foreach ($notifications as $notification) {
|
| 108 |
+
$stmt->execute([
|
| 109 |
+
$notification['title'],
|
| 110 |
+
$notification['message'],
|
| 111 |
+
$notification['type'],
|
| 112 |
+
$notification['icon']
|
| 113 |
+
]);
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
echo "Sample data inserted successfully!";
|
| 117 |
+
} catch(PDOException $e) {
|
| 118 |
+
echo "Error inserting sample data: " . $e->getMessage();
|
| 119 |
+
}
|
| 120 |
+
?>
|
jweb/1a/contact.html
ADDED
|
@@ -0,0 +1,430 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Contact - Japanese Motors</title>
|
| 7 |
+
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 8 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
+
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
|
| 10 |
+
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
|
| 11 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 12 |
+
<script src="https://unpkg.com/feather-icons"></script>
|
| 13 |
+
<link rel="stylesheet" href="assets/css/1c.css">
|
| 14 |
+
</head>
|
| 15 |
+
<body class="bg-gray-100 font-sans">
|
| 16 |
+
<!-- Navigation -->
|
| 17 |
+
<nav class="bg-white shadow-lg fixed w-full z-10">
|
| 18 |
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
| 19 |
+
<div class="flex justify-between h-16">
|
| 20 |
+
<div class="flex items-center">
|
| 21 |
+
<a href="contact.html" class="flex-shrink-0 flex items-center">
|
| 22 |
+
<i data-feather="zap" class="h-8 w-8 text-red-500"></i>
|
| 23 |
+
<span class="ml-2 text-xl font-bold text-gray-900">JAPANESE MOTORS</span>
|
| 24 |
+
</a>
|
| 25 |
+
</div>
|
| 26 |
+
<div class="hidden md:flex items-center space-x-8">
|
| 27 |
+
<a href="../index.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Home</a>
|
| 28 |
+
<a href="gallery.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Inventory</a>
|
| 29 |
+
<a href="services.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Services</a>
|
| 30 |
+
<a href="about.html" class="nav-link text-red-500 px-3 py-2 rounded-md text-sm font-medium">About</a>
|
| 31 |
+
<a href="contact.html" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">Contact</a>
|
| 32 |
+
</div>
|
| 33 |
+
<div class="md:hidden flex items-center">
|
| 34 |
+
<button class="text-gray-500 hover:text-gray-900 focus:outline-none">
|
| 35 |
+
<i data-feather="menu"></i>
|
| 36 |
+
</button>
|
| 37 |
+
</div>
|
| 38 |
+
</div>
|
| 39 |
+
</div>
|
| 40 |
+
</nav>
|
| 41 |
+
|
| 42 |
+
<!-- Hero Section -->
|
| 43 |
+
<div class="relative pt-32 pb-20 bg-gray-900">
|
| 44 |
+
<div class="absolute inset-0 bg-black opacity-50"></div>
|
| 45 |
+
<div class="absolute inset-0 bg-center bg-cover" style="background-image: url('https://images.unsplash.com/photo-1568605117036-5fe5e7bab0b7?ixlib=rb-4.0.3&auto=format&fit=crop&w=1600&q=80');"></div>
|
| 46 |
+
<div class="container mx-auto px-4 relative">
|
| 47 |
+
<div class="text-center">
|
| 48 |
+
<h1 class="text-4xl font-bold text-white mb-4" data-aos="fade-up">Contact Us</h1>
|
| 49 |
+
<p class="text-xl text-gray-300 max-w-2xl mx-auto" data-aos="fade-up" data-aos-delay="100">Get in touch with our team for any inquiries about our vehicles or services</p>
|
| 50 |
+
</div>
|
| 51 |
+
</div>
|
| 52 |
+
</div>
|
| 53 |
+
|
| 54 |
+
<!-- Contact Methods -->
|
| 55 |
+
<section class="py-16 bg-white">
|
| 56 |
+
<div class="container mx-auto px-4">
|
| 57 |
+
<div class="text-center mb-12">
|
| 58 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-4">How Would You Like to Reach Us?</h2>
|
| 59 |
+
<div class="w-20 h-1 bg-red-500 mx-auto"></div>
|
| 60 |
+
<p class="mt-4 text-gray-600 max-w-2xl mx-auto">Choose your preferred method of communication</p>
|
| 61 |
+
</div>
|
| 62 |
+
|
| 63 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
| 64 |
+
<!-- WhatsApp -->
|
| 65 |
+
<div class="contact-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6 text-center" data-aos="fade-up">
|
| 66 |
+
<div class="bg-green-100 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4">
|
| 67 |
+
<i data-feather="message-circle" class="w-8 h-8 text-green-600"></i>
|
| 68 |
+
</div>
|
| 69 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">WhatsApp</h3>
|
| 70 |
+
<p class="text-gray-600 mb-4">Chat with us directly on WhatsApp for quick responses</p>
|
| 71 |
+
<a href="https://wa.me/254756709823" class="bg-green-500 hover:bg-green-600 text-white px-6 py-2 rounded-md font-medium transition duration-300 inline-flex items-center">
|
| 72 |
+
<i data-feather="message-circle" class="w-4 h-4 mr-2"></i> Start Chat
|
| 73 |
+
</a>
|
| 74 |
+
</div>
|
| 75 |
+
|
| 76 |
+
<!-- Live Chat -->
|
| 77 |
+
<div class="contact-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6 text-center" data-aos="fade-up" data-aos-delay="100">
|
| 78 |
+
<div class="bg-blue-100 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4">
|
| 79 |
+
<i data-feather="message-square" class="w-8 h-8 text-blue-600"></i>
|
| 80 |
+
</div>
|
| 81 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Live Chat</h3>
|
| 82 |
+
<p class="text-gray-600 mb-4">Chat with our sales team in real-time</p>
|
| 83 |
+
<button class="bg-blue-500 hover:bg-blue-600 text-white px-6 py-2 rounded-md font-medium transition duration-300 inline-flex items-center" onclick="openChat()">
|
| 84 |
+
<i data-feather="message-square" class="w-4 h-4 mr-2"></i> Start Chat
|
| 85 |
+
</button>
|
| 86 |
+
</div>
|
| 87 |
+
|
| 88 |
+
<!-- Email -->
|
| 89 |
+
<div class="contact-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6 text-center" data-aos="fade-up" data-aos-delay="200">
|
| 90 |
+
<div class="bg-red-100 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4">
|
| 91 |
+
<i data-feather="mail" class="w-8 h-8 text-red-600"></i>
|
| 92 |
+
</div>
|
| 93 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Email</h3>
|
| 94 |
+
<p class="text-gray-600 mb-4">Send us an email and we'll respond within 24 hours</p>
|
| 95 |
+
<a href="mailto:info@japanesemotors.com" class="bg-red-500 hover:bg-red-600 text-white px-6 py-2 rounded-md font-medium transition duration-300 inline-flex items-center">
|
| 96 |
+
<i data-feather="mail" class="w-4 h-4 mr-2"></i> Send Email
|
| 97 |
+
</a>
|
| 98 |
+
</div>
|
| 99 |
+
|
| 100 |
+
<!-- Phone -->
|
| 101 |
+
<div class="contact-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6 text-center" data-aos="fade-up" data-aos-delay="300">
|
| 102 |
+
<div class="bg-purple-100 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4">
|
| 103 |
+
<i data-feather="phone" class="w-8 h-8 text-purple-600"></i>
|
| 104 |
+
</div>
|
| 105 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Phone</h3>
|
| 106 |
+
<p class="text-gray-600 mb-4">Call us directly to speak with our team</p>
|
| 107 |
+
<a href="tel:+254756709823" class="bg-purple-500 hover:bg-purple-600 text-white px-6 py-2 rounded-md font-medium transition duration-300 inline-flex items-center">
|
| 108 |
+
<i data-feather="phone" class="w-4 h-4 mr-2"></i> Call Now
|
| 109 |
+
</a>
|
| 110 |
+
</div>
|
| 111 |
+
</div>
|
| 112 |
+
</div>
|
| 113 |
+
</section>
|
| 114 |
+
|
| 115 |
+
<!-- Contact Form & Info -->
|
| 116 |
+
<section class="py-16 bg-gray-100">
|
| 117 |
+
<div class="container mx-auto px-4">
|
| 118 |
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-12">
|
| 119 |
+
<!-- Contact Form -->
|
| 120 |
+
<div class="bg-white rounded-lg shadow-md p-8" data-aos="fade-right">
|
| 121 |
+
<h2 class="text-2xl font-bold text-gray-800 mb-6">Send Us a Message</h2>
|
| 122 |
+
<form id="contactForm" class="space-y-6">
|
| 123 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
| 124 |
+
<div>
|
| 125 |
+
<label for="firstName" class="block text-sm font-medium text-gray-700 mb-1">First Name</label>
|
| 126 |
+
<input type="text" id="firstName" name="firstName" class="form-input w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500" required>
|
| 127 |
+
</div>
|
| 128 |
+
<div>
|
| 129 |
+
<label for="lastName" class="block text-sm font-medium text-gray-700 mb-1">Last Name</label>
|
| 130 |
+
<input type="text" id="lastName" name="lastName" class="form-input w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500" required>
|
| 131 |
+
</div>
|
| 132 |
+
</div>
|
| 133 |
+
<div>
|
| 134 |
+
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email Address</label>
|
| 135 |
+
<input type="email" id="email" name="email" class="form-input w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500" required>
|
| 136 |
+
</div>
|
| 137 |
+
<div>
|
| 138 |
+
<label for="phone" class="block text-sm font-medium text-gray-700 mb-1">Phone Number</label>
|
| 139 |
+
<input type="tel" id="phone" name="phone" class="form-input w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500">
|
| 140 |
+
</div>
|
| 141 |
+
<div>
|
| 142 |
+
<label for="subject" class="block text-sm font-medium text-gray-700 mb-1">Subject</label>
|
| 143 |
+
<select id="subject" name="subject" class="form-input w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500" required>
|
| 144 |
+
<option value="">Select a subject</option>
|
| 145 |
+
<option value="vehicle-inquiry">Vehicle Inquiry</option>
|
| 146 |
+
<option value="test-drive">Schedule Test Drive</option>
|
| 147 |
+
<option value="service-appointment">Service Appointment</option>
|
| 148 |
+
<option value="parts-inquiry">Parts Inquiry</option>
|
| 149 |
+
<option value="general">General Question</option>
|
| 150 |
+
<option value="other">Other</option>
|
| 151 |
+
</select>
|
| 152 |
+
</div>
|
| 153 |
+
<div>
|
| 154 |
+
<label for="message" class="block text-sm font-medium text-gray-700 mb-1">Message</label>
|
| 155 |
+
<textarea id="message" name="message" rows="5" class="form-input w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500" required></textarea>
|
| 156 |
+
</div>
|
| 157 |
+
<div>
|
| 158 |
+
<button type="submit" class="w-full bg-red-500 hover:bg-red-600 text-white py-3 px-4 rounded-md font-medium transition duration-300">
|
| 159 |
+
Send Message
|
| 160 |
+
</button>
|
| 161 |
+
</div>
|
| 162 |
+
</form>
|
| 163 |
+
</div>
|
| 164 |
+
|
| 165 |
+
<!-- Contact Information -->
|
| 166 |
+
<div data-aos="fade-left">
|
| 167 |
+
<h2 class="text-2xl font-bold text-gray-800 mb-6">Contact Information</h2>
|
| 168 |
+
<div class="space-y-6">
|
| 169 |
+
<div class="flex items-start">
|
| 170 |
+
<div class="bg-red-100 p-3 rounded-full mr-4">
|
| 171 |
+
<i data-feather="map-pin" class="w-6 h-6 text-red-500"></i>
|
| 172 |
+
</div>
|
| 173 |
+
<div>
|
| 174 |
+
<h3 class="text-lg font-bold text-gray-800 mb-1">Address</h3>
|
| 175 |
+
<p class="text-gray-600">123 Automotive Way, Chuo-ku<br>Tokyo, Japan 104-0061</p>
|
| 176 |
+
</div>
|
| 177 |
+
</div>
|
| 178 |
+
|
| 179 |
+
<div class="flex items-start">
|
| 180 |
+
<div class="bg-red-100 p-3 rounded-full mr-4">
|
| 181 |
+
<i data-feather="phone" class="w-6 h-6 text-red-500"></i>
|
| 182 |
+
</div>
|
| 183 |
+
<div>
|
| 184 |
+
<h3 class="text-lg font-bold text-gray-800 mb-1">Phone</h3>
|
| 185 |
+
<p class="text-gray-600">+254 756 709 823</p>
|
| 186 |
+
<p class="text-sm text-gray-500">Mon-Fri: 9:00 AM - 7:00 PM</p>
|
| 187 |
+
<p class="text-sm text-gray-500">Sat: 10:00 AM - 5:00 PM</p>
|
| 188 |
+
</div>
|
| 189 |
+
</div>
|
| 190 |
+
|
| 191 |
+
<div class="flex items-start">
|
| 192 |
+
<div class="bg-red-100 p-3 rounded-full mr-4">
|
| 193 |
+
<i data-feather="mail" class="w-6 h-6 text-red-500"></i>
|
| 194 |
+
</div>
|
| 195 |
+
<div>
|
| 196 |
+
<h3 class="text-lg font-bold text-gray-800 mb-1">Email</h3>
|
| 197 |
+
<p class="text-gray-600">info@japanesemotors.com</p>
|
| 198 |
+
<p class="text-gray-600">sales@japanesemotors.com</p>
|
| 199 |
+
<p class="text-gray-600">service@japanesemotors.com</p>
|
| 200 |
+
</div>
|
| 201 |
+
</div>
|
| 202 |
+
|
| 203 |
+
<div class="flex items-start">
|
| 204 |
+
<div class="bg-red-100 p-3 rounded-full mr-4">
|
| 205 |
+
<i data-feather="clock" class="w-6 h-6 text-red-500"></i>
|
| 206 |
+
</div>
|
| 207 |
+
<div>
|
| 208 |
+
<h3 class="text-lg font-bold text-gray-800 mb-1">Business Hours</h3>
|
| 209 |
+
<p class="text-gray-600">Monday - Friday: 9:00 AM - 7:00 PM</p>
|
| 210 |
+
<p class="text-gray-600">Saturday: 10:00 AM - 5:00 PM</p>
|
| 211 |
+
<p class="text-gray-600">Sunday: Closed</p>
|
| 212 |
+
</div>
|
| 213 |
+
</div>
|
| 214 |
+
</div>
|
| 215 |
+
|
| 216 |
+
<div class="mt-8">
|
| 217 |
+
<h3 class="text-lg font-bold text-gray-800 mb-4">Follow Us</h3>
|
| 218 |
+
<div class="flex space-x-4">
|
| 219 |
+
<a href="#" class="bg-gray-800 text-white p-3 rounded-full hover:bg-red-500 transition duration-300">
|
| 220 |
+
<i data-feather="facebook" class="w-5 h-5"></i>
|
| 221 |
+
</a>
|
| 222 |
+
<a href="#" class="bg-gray-800 text-white p-3 rounded-full hover:bg-red-500 transition duration-300">
|
| 223 |
+
<i data-feather="instagram" class="w-5 h-5"></i>
|
| 224 |
+
</a>
|
| 225 |
+
<a href="#" class="bg-gray-800 text-white p-3 rounded-full hover:bg-red-500 transition duration-300">
|
| 226 |
+
<i data-feather="twitter" class="w-5 h-5"></i>
|
| 227 |
+
</a>
|
| 228 |
+
<a href="#" class="bg-gray-800 text-white p-3 rounded-full hover:bg-red-500 transition duration-300">
|
| 229 |
+
<i data-feather="youtube" class="w-5 h-5"></i>
|
| 230 |
+
</a>
|
| 231 |
+
<a href="https://wa.me/254756709823" class="bg-gray-800 text-white p-3 rounded-full hover:bg-green-500 transition duration-300">
|
| 232 |
+
<i data-feather="message-circle" class="w-5 h-5"></i>
|
| 233 |
+
</a>
|
| 234 |
+
</div>
|
| 235 |
+
</div>
|
| 236 |
+
</div>
|
| 237 |
+
</div>
|
| 238 |
+
</div>
|
| 239 |
+
</section>
|
| 240 |
+
|
| 241 |
+
<!-- FAQ Section -->
|
| 242 |
+
<section class="py-16 bg-white">
|
| 243 |
+
<div class="container mx-auto px-4">
|
| 244 |
+
<div class="text-center mb-12">
|
| 245 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-4">Frequently Asked Questions</h2>
|
| 246 |
+
<div class="w-20 h-1 bg-red-500 mx-auto"></div>
|
| 247 |
+
<p class="mt-4 text-gray-600 max-w-2xl mx-auto">Quick answers to common questions about contacting us</p>
|
| 248 |
+
</div>
|
| 249 |
+
|
| 250 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-4xl mx-auto">
|
| 251 |
+
<div class="bg-gray-50 p-6 rounded-lg">
|
| 252 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">What's the best way to reach you quickly?</h3>
|
| 253 |
+
<p class="text-gray-600">For the fastest response, use our WhatsApp chat or call us directly during business hours. We typically respond to WhatsApp messages within minutes.</p>
|
| 254 |
+
</div>
|
| 255 |
+
|
| 256 |
+
<div class="bg-gray-50 p-6 rounded-lg">
|
| 257 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Do you respond to inquiries after hours?</h3>
|
| 258 |
+
<p class="text-gray-600">Yes! We monitor WhatsApp and email after business hours and will respond to urgent inquiries. For non-urgent matters, we'll respond the next business day.</p>
|
| 259 |
+
</div>
|
| 260 |
+
|
| 261 |
+
<div class="bg-gray-50 p-6 rounded-lg">
|
| 262 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Can I schedule a test drive online?</h3>
|
| 263 |
+
<p class="text-gray-600">Absolutely! Use our contact form and select "Schedule Test Drive" as your subject. We'll contact you within 24 hours to confirm your appointment.</p>
|
| 264 |
+
</div>
|
| 265 |
+
|
| 266 |
+
<div class="bg-gray-50 p-6 rounded-lg">
|
| 267 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Do you ship vehicles internationally?</h3>
|
| 268 |
+
<p class="text-gray-600">Yes, we ship vehicles worldwide. Contact our sales team via email or WhatsApp to discuss shipping options to your location.</p>
|
| 269 |
+
</div>
|
| 270 |
+
</div>
|
| 271 |
+
</div>
|
| 272 |
+
</section>
|
| 273 |
+
|
| 274 |
+
<!-- Map Section -->
|
| 275 |
+
<section class="py-16 bg-gray-100">
|
| 276 |
+
<div class="container mx-auto px-4">
|
| 277 |
+
<div class="text-center mb-12">
|
| 278 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-4">Visit Our Showroom</h2>
|
| 279 |
+
<div class="w-20 h-1 bg-red-500 mx-auto"></div>
|
| 280 |
+
<p class="mt-4 text-gray-600 max-w-2xl mx-auto">Come see our collection of Japanese performance vehicles in person</p>
|
| 281 |
+
</div>
|
| 282 |
+
|
| 283 |
+
<div class="bg-white rounded-lg shadow-md overflow-hidden" data-aos="fade-up">
|
| 284 |
+
<div class="aspect-w-16 aspect-h-9">
|
| 285 |
+
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d12965.464075717876!2d139.767125!3d35.681236!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x0!2zMzXCsDQwJzUyLjQiTiAxMznCsDQ2JzAxLjciRQ!5e0!3m2!1sen!2sjp!4v1620000000000!5m2!1sen!2sjp" width="100%" height="450" style="border:0;" allowfullscreen="" loading="lazy" class="w-full h-96"></iframe>
|
| 286 |
+
</div>
|
| 287 |
+
<div class="p-6">
|
| 288 |
+
<h3 class="text-xl font-bold text-gray-800 mb-2">Japanese Motors Showroom</h3>
|
| 289 |
+
<p class="text-gray-600 mb-4">123 Automotive Way, Chuo-ku, Tokyo, Japan 104-0061</p>
|
| 290 |
+
<div class="flex flex-wrap gap-4">
|
| 291 |
+
<a href="https://maps.google.com/?q=123+Automotive+Way,Chuo-ku,Tokyo,Japan" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md font-medium transition duration-300 inline-flex items-center">
|
| 292 |
+
<i data-feather="map" class="w-4 h-4 mr-2"></i> Get Directions
|
| 293 |
+
</a>
|
| 294 |
+
<a href="tel:+254756709823" class="bg-gray-800 hover:bg-gray-900 text-white px-4 py-2 rounded-md font-medium transition duration-300 inline-flex items-center">
|
| 295 |
+
<i data-feather="phone" class="w-4 h-4 mr-2"></i> Call for Directions
|
| 296 |
+
</a>
|
| 297 |
+
</div>
|
| 298 |
+
</div>
|
| 299 |
+
</div>
|
| 300 |
+
</div>
|
| 301 |
+
</section>
|
| 302 |
+
|
| 303 |
+
<!-- Live Chat Widget (Initially Hidden) -->
|
| 304 |
+
<div id="chatWidget" class="fixed bottom-6 right-6 w-80 bg-white rounded-lg shadow-xl z-50 hidden">
|
| 305 |
+
<div class="bg-red-500 text-white p-4 rounded-t-lg flex justify-between items-center">
|
| 306 |
+
<h3 class="font-bold">Chat with Japanese Motors</h3>
|
| 307 |
+
<button onclick="closeChat()" class="text-white hover:text-gray-200">
|
| 308 |
+
<i data-feather="x" class="w-5 h-5"></i>
|
| 309 |
+
</button>
|
| 310 |
+
</div>
|
| 311 |
+
<div class="p-4 h-80 overflow-y-auto">
|
| 312 |
+
<div class="chat-bubble mb-4">
|
| 313 |
+
<p class="text-gray-800">Hello! How can we help you today?</p>
|
| 314 |
+
</div>
|
| 315 |
+
<div class="text-right mb-4 hidden" id="userMessage">
|
| 316 |
+
<div class="bg-red-500 text-white p-3 rounded-lg inline-block">
|
| 317 |
+
<p id="messageText"></p>
|
| 318 |
+
</div>
|
| 319 |
+
</div>
|
| 320 |
+
<div class="chat-bubble mb-4 hidden" id="responseMessage">
|
| 321 |
+
<p class="text-gray-800">Thanks for your message! Our team will respond shortly.</p>
|
| 322 |
+
</div>
|
| 323 |
+
</div>
|
| 324 |
+
<div class="p-4 border-t">
|
| 325 |
+
<div class="flex">
|
| 326 |
+
<input type="text" placeholder="Type your message..." class="flex-1 border border-gray-300 rounded-l-md px-4 py-2 focus:outline-none focus:ring-2 focus:ring-red-500">
|
| 327 |
+
<button class="bg-red-500 text-white px-4 py-2 rounded-r-md hover:bg-red-600 transition duration-300">
|
| 328 |
+
<i data-feather="send" class="w-4 h-4"></i>
|
| 329 |
+
</button>
|
| 330 |
+
</div>
|
| 331 |
+
</div>
|
| 332 |
+
</div>
|
| 333 |
+
|
| 334 |
+
<!-- Floating WhatsApp Button -->
|
| 335 |
+
<div class="floating-chat">
|
| 336 |
+
<a href="https://wa.me/254756709823" class="bg-green-500 text-white p-4 rounded-full shadow-lg hover:bg-green-600 transition duration-300 flex items-center justify-center">
|
| 337 |
+
<i data-feather="message-circle" class="w-6 h-6"></i>
|
| 338 |
+
</a>
|
| 339 |
+
</div>
|
| 340 |
+
|
| 341 |
+
<!-- Footer -->
|
| 342 |
+
<footer class="bg-gray-900 text-white py-12">
|
| 343 |
+
<div class="container mx-auto px-4">
|
| 344 |
+
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
| 345 |
+
<div>
|
| 346 |
+
<h3 class="text-xl font-bold mb-4">Japanese Motors</h3>
|
| 347 |
+
<p class="text-gray-400">Premium Japanese performance vehicles imported directly from Japan.</p>
|
| 348 |
+
</div>
|
| 349 |
+
<div>
|
| 350 |
+
<h3 class="text-lg font-bold mb-4">Quick Links</h3>
|
| 351 |
+
<ul class="space-y-2">
|
| 352 |
+
<li><a href="../index.html" class="text-gray-400 hover:text-red-500">Home</a></li>
|
| 353 |
+
<li><a href="gallery.html" class="text-gray-400 hover:text-red-500">Inventory</a></li>
|
| 354 |
+
<li><a href="services.html" class="text-gray-400 hover:text-red-500">Services</a></li>
|
| 355 |
+
<li><a href="about.html" class="text-gray-400 hover:text-red-500">About Us</a></li>
|
| 356 |
+
<li><a href="contact.html" class="text-gray-400 hover:text-red-500">Contact</a></li>
|
| 357 |
+
</ul>
|
| 358 |
+
</div>
|
| 359 |
+
<div>
|
| 360 |
+
<h3 class="text-lg font-bold mb-4">Contact Info</h3>
|
| 361 |
+
<ul class="space-y-2">
|
| 362 |
+
<li class="flex items-center">
|
| 363 |
+
<i data-feather="map-pin" class="mr-2 w-4 h-4"></i>
|
| 364 |
+
<span class="text-gray-400">123 Automotive Way, Tokyo, Japan</span>
|
| 365 |
+
</li>
|
| 366 |
+
<li class="flex items-center">
|
| 367 |
+
<i data-feather="phone" class="mr-2 w-4 h-4"></i>
|
| 368 |
+
<span class="text-gray-400">+81 3 1234 5678</span>
|
| 369 |
+
</li>
|
| 370 |
+
<li class="flex items-center">
|
| 371 |
+
<i data-feather="mail" class="mr-2 w-4 h-4"></i>
|
| 372 |
+
<span class="text-gray-400">info@japanesemotors.com</span>
|
| 373 |
+
</li>
|
| 374 |
+
</ul>
|
| 375 |
+
</div>
|
| 376 |
+
<div>
|
| 377 |
+
<h3 class="text-lg font-bold mb-4">Follow Us</h3>
|
| 378 |
+
<div class="flex space-x-4">
|
| 379 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="facebook" class="w-6 h-6"></i></a>
|
| 380 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="instagram" class="w-6 h-6"></i></a>
|
| 381 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="twitter" class="w-6 h-6"></i></a>
|
| 382 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="youtube" class="w-6 h-6"></i></a>
|
| 383 |
+
</div>
|
| 384 |
+
</div>
|
| 385 |
+
</div>
|
| 386 |
+
<div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-400">
|
| 387 |
+
<p>© 2023 Japanese Motors. All rights reserved.</p>
|
| 388 |
+
</div>
|
| 389 |
+
</div>
|
| 390 |
+
</footer>
|
| 391 |
+
|
| 392 |
+
<script>
|
| 393 |
+
// Initialize Feather Icons and AOS
|
| 394 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 395 |
+
feather.replace();
|
| 396 |
+
AOS.init();
|
| 397 |
+
|
| 398 |
+
// Form submission
|
| 399 |
+
document.getElementById('contactForm').addEventListener('submit', function(e) {
|
| 400 |
+
e.preventDefault();
|
| 401 |
+
alert('Thank you for your message! We will contact you shortly.');
|
| 402 |
+
this.reset();
|
| 403 |
+
});
|
| 404 |
+
});
|
| 405 |
+
|
| 406 |
+
// Chat functions
|
| 407 |
+
function openChat() {
|
| 408 |
+
document.getElementById('chatWidget').classList.remove('hidden');
|
| 409 |
+
}
|
| 410 |
+
|
| 411 |
+
function closeChat() {
|
| 412 |
+
document.getElementById('chatWidget').classList.add('hidden');
|
| 413 |
+
}
|
| 414 |
+
|
| 415 |
+
// Simulate chat interaction
|
| 416 |
+
document.querySelector('#chatWidget button').addEventListener('click', function() {
|
| 417 |
+
const input = document.querySelector('#chatWidget input');
|
| 418 |
+
if (input.value.trim() !== '') {
|
| 419 |
+
document.getElementById('userMessage').classList.remove('hidden');
|
| 420 |
+
document.getElementById('messageText').textContent = input.value;
|
| 421 |
+
input.value = '';
|
| 422 |
+
|
| 423 |
+
setTimeout(function() {
|
| 424 |
+
document.getElementById('responseMessage').classList.remove('hidden');
|
| 425 |
+
}, 1000);
|
| 426 |
+
}
|
| 427 |
+
});
|
| 428 |
+
</script>
|
| 429 |
+
</body>
|
| 430 |
+
</html>
|
jweb/1a/gallery.html
ADDED
|
@@ -0,0 +1,926 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Inventory - Japanese Motors</title>
|
| 7 |
+
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 8 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
+
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
|
| 10 |
+
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
|
| 11 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 12 |
+
<script src="https://unpkg.com/feather-icons"></script>
|
| 13 |
+
<link rel="stylesheet" href="assets/css/1b.css">
|
| 14 |
+
</head>
|
| 15 |
+
<body class="bg-gray-100 font-sans">
|
| 16 |
+
<!-- Navigation -->
|
| 17 |
+
<nav class="bg-white shadow-lg fixed w-full z-10">
|
| 18 |
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
| 19 |
+
<div class="flex justify-between h-16">
|
| 20 |
+
<div class="flex items-center">
|
| 21 |
+
<a href="gallery.html" class="flex-shrink-0 flex items-center">
|
| 22 |
+
<i data-feather="zap" class="h-8 w-8 text-red-500"></i>
|
| 23 |
+
<span class="ml-2 text-xl font-bold text-gray-900">JAPANESE MOTORS</span>
|
| 24 |
+
</a>
|
| 25 |
+
</div>
|
| 26 |
+
<div class="hidden md:flex items-center space-x-8">
|
| 27 |
+
<a href="../index.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Home</a>
|
| 28 |
+
<a href="gallery.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Inventory</a>
|
| 29 |
+
<a href="services.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Services</a>
|
| 30 |
+
<a href="about.html" class="nav-link text-red-500 px-3 py-2 rounded-md text-sm font-medium">About</a>
|
| 31 |
+
<a href="contact.html" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">Contact</a>
|
| 32 |
+
</div>
|
| 33 |
+
<div class="md:hidden flex items-center">
|
| 34 |
+
<button class="text-gray-500 hover:text-gray-900 focus:outline-none">
|
| 35 |
+
<i data-feather="menu"></i>
|
| 36 |
+
</button>
|
| 37 |
+
</div>
|
| 38 |
+
</div>
|
| 39 |
+
</div>
|
| 40 |
+
</nav>
|
| 41 |
+
|
| 42 |
+
<!-- Hero Section -->
|
| 43 |
+
<div class="relative pt-32 pb-20 bg-gray-900">
|
| 44 |
+
<div class="absolute inset-0 bg-black opacity-50"></div>
|
| 45 |
+
<div class="absolute inset-0 bg-center bg-cover" style="background-image: url('https://images.unsplash.com/photo-1492144534655-ae79c964c9d7?ixlib=rb-4.0.3&auto=format&fit=crop&w=1600&q=80');"></div>
|
| 46 |
+
<div class="container mx-auto px-4 relative">
|
| 47 |
+
<div class="text-center">
|
| 48 |
+
<h1 class="text-4xl font-bold text-white mb-4" data-aos="fade-up">Our Premium Inventory</h1>
|
| 49 |
+
<p class="text-xl text-gray-300 max-w-2xl mx-auto" data-aos="fade-up" data-aos-delay="100">Explore our exclusive collection of Japanese performance vehicles</p>
|
| 50 |
+
</div>
|
| 51 |
+
</div>
|
| 52 |
+
</div>
|
| 53 |
+
|
| 54 |
+
<!-- Motor Type Selection -->
|
| 55 |
+
<section class="py-8 bg-white">
|
| 56 |
+
<div class="container mx-auto px-4">
|
| 57 |
+
<h2 class="text-xl font-bold text-gray-800 mb-6 text-center">Select Motor Type</h2>
|
| 58 |
+
<div class="flex flex-wrap justify-center gap-4">
|
| 59 |
+
<button class="motor-type-btn active px-6 py-3 rounded-full border border-gray-300 hover:bg-red-500 hover:text-white transition duration-300" data-type="all">
|
| 60 |
+
All Types
|
| 61 |
+
</button>
|
| 62 |
+
<button class="motor-type-btn px-6 py-3 rounded-full border border-gray-300 hover:bg-red-500 hover:text-white transition duration-300" data-type="sports">
|
| 63 |
+
Sports Cars
|
| 64 |
+
</button>
|
| 65 |
+
<button class="motor-type-btn px-6 py-3 rounded-full border border-gray-300 hover:bg-red-500 hover:text-white transition duration-300" data-type="sedan">
|
| 66 |
+
Sedans
|
| 67 |
+
</button>
|
| 68 |
+
<button class="motor-type-btn px-6 py-3 rounded-full border border-gray-300 hover:bg-red-500 hover:text-white transition duration-300" data-type="suv">
|
| 69 |
+
SUVs
|
| 70 |
+
</button>
|
| 71 |
+
<button class="motor-type-btn px-6 py-3 rounded-full border border-gray-300 hover:bg-red-500 hover:text-white transition duration-300" data-type="jdm">
|
| 72 |
+
JDM Classics
|
| 73 |
+
</button>
|
| 74 |
+
</div>
|
| 75 |
+
</div>
|
| 76 |
+
</section>
|
| 77 |
+
|
| 78 |
+
<!-- Inventory Filters -->
|
| 79 |
+
<section class="py-12 bg-white">
|
| 80 |
+
<div class="container mx-auto px-4">
|
| 81 |
+
<div class="bg-gray-100 p-6 rounded-lg">
|
| 82 |
+
<h2 class="text-xl font-bold text-gray-800 mb-6">Find Your Perfect Vehicle</h2>
|
| 83 |
+
<form class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
| 84 |
+
<div>
|
| 85 |
+
<label for="make" class="block text-sm font-medium text-gray-700 mb-1">Make</label>
|
| 86 |
+
<select id="make" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500">
|
| 87 |
+
<option value="">All Makes</option>
|
| 88 |
+
<option value="toyota">Toyota</option>
|
| 89 |
+
<option value="nissan">Nissan</option>
|
| 90 |
+
<option value="honda">Honda</option>
|
| 91 |
+
<option value="mazda">Mazda</option>
|
| 92 |
+
<option value="subaru">Subaru</option>
|
| 93 |
+
<option value="mitsubishi">Mitsubishi</option>
|
| 94 |
+
<option value="lexus">Lexus</option>
|
| 95 |
+
<option value="acura">Acura</option>
|
| 96 |
+
</select>
|
| 97 |
+
</div>
|
| 98 |
+
<div>
|
| 99 |
+
<label for="model" class="block text-sm font-medium text-gray-700 mb-1">Model</label>
|
| 100 |
+
<select id="model" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500">
|
| 101 |
+
<option value="">All Models</option>
|
| 102 |
+
</select>
|
| 103 |
+
</div>
|
| 104 |
+
<div>
|
| 105 |
+
<label for="price" class="block text-sm font-medium text-gray-700 mb-1">Price Range</label>
|
| 106 |
+
<select id="price" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500">
|
| 107 |
+
<option value="">All Prices</option>
|
| 108 |
+
<option value="0-50000">Under $50,000</option>
|
| 109 |
+
<option value="50000-100000">$50,000 - $100,000</option>
|
| 110 |
+
<option value="100000-150000">$100,000 - $150,000</option>
|
| 111 |
+
<option value="150000+">Over $150,000</option>
|
| 112 |
+
</select>
|
| 113 |
+
</div>
|
| 114 |
+
<div>
|
| 115 |
+
<label for="year" class="block text-sm font-medium text-gray-700 mb-1">Year</label>
|
| 116 |
+
<select id="year" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500">
|
| 117 |
+
<option value="">All Years</option>
|
| 118 |
+
<option value="2023">2023</option>
|
| 119 |
+
<option value="2022">2022</option>
|
| 120 |
+
<option value="2021">2021</option>
|
| 121 |
+
<option value="2020">2020</option>
|
| 122 |
+
<option value="2019">2019</option>
|
| 123 |
+
<option value="2018">2018</option>
|
| 124 |
+
<option value="2017">2017</option>
|
| 125 |
+
</select>
|
| 126 |
+
</div>
|
| 127 |
+
<div class="md:col-span-4 flex justify-end space-x-3">
|
| 128 |
+
<button type="reset" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-100">Reset</button>
|
| 129 |
+
<button type="submit" class="px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600">Search</button>
|
| 130 |
+
</div>
|
| 131 |
+
</form>
|
| 132 |
+
</div>
|
| 133 |
+
</div>
|
| 134 |
+
</section>
|
| 135 |
+
|
| 136 |
+
<!-- Inventory Grid -->
|
| 137 |
+
<section class="py-12 bg-gray-100">
|
| 138 |
+
<div class="container mx-auto px-4">
|
| 139 |
+
<div class="flex justify-between items-center mb-8">
|
| 140 |
+
<h2 class="text-2xl font-bold text-gray-800">Available Vehicles</h2>
|
| 141 |
+
<div class="flex items-center">
|
| 142 |
+
<span class="text-sm text-gray-600 mr-2">Sort by:</span>
|
| 143 |
+
<select id="sortBy" class="px-3 py-1 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-red-500 text-sm">
|
| 144 |
+
<option value="newest">Newest First</option>
|
| 145 |
+
<option value="price-low">Price: Low to High</option>
|
| 146 |
+
<option value="price-high">Price: High to Low</option>
|
| 147 |
+
<option value="mileage">Mileage: Low to High</option>
|
| 148 |
+
</select>
|
| 149 |
+
</div>
|
| 150 |
+
</div>
|
| 151 |
+
|
| 152 |
+
<div id="inventoryGrid" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
| 153 |
+
<!-- Cars will be dynamically loaded here -->
|
| 154 |
+
</div>
|
| 155 |
+
|
| 156 |
+
<!-- Pagination -->
|
| 157 |
+
<div class="mt-12 flex justify-center">
|
| 158 |
+
<nav id="pagination" class="flex items-center space-x-2">
|
| 159 |
+
<!-- Pagination will be dynamically generated -->
|
| 160 |
+
</nav>
|
| 161 |
+
</div>
|
| 162 |
+
</div>
|
| 163 |
+
</section>
|
| 164 |
+
|
| 165 |
+
<!-- VR Showroom -->
|
| 166 |
+
<section class="py-16 bg-white">
|
| 167 |
+
<div class="container mx-auto px-4">
|
| 168 |
+
<div class="text-center mb-12">
|
| 169 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-4">Virtual Showroom</h2>
|
| 170 |
+
<div class="w-20 h-1 bg-red-500 mx-auto"></div>
|
| 171 |
+
<p class="mt-4 text-gray-600 max-w-2xl mx-auto">Experience our vehicles in immersive 360° virtual reality</p>
|
| 172 |
+
</div>
|
| 173 |
+
|
| 174 |
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
| 175 |
+
<div class="vr-container rounded-lg overflow-hidden shadow-lg">
|
| 176 |
+
<iframe class="vr-iframe" src="https://www.youtube.com/embed/dQw4w9WgXcQ" title="Virtual Showroom" allowfullscreen></iframe>
|
| 177 |
+
</div>
|
| 178 |
+
<div>
|
| 179 |
+
<h3 class="text-xl font-bold text-gray-800 mb-4">Explore From Anywhere</h3>
|
| 180 |
+
<p class="text-gray-600 mb-6">Our virtual showroom allows you to examine every detail of our vehicles as if you were standing right next to them. Rotate, zoom, and explore interiors and exteriors with our cutting-edge VR technology.</p>
|
| 181 |
+
<ul class="space-y-3 mb-6">
|
| 182 |
+
<li class="flex items-start">
|
| 183 |
+
<i data-feather="check-circle" class="text-green-500 mr-2 mt-1"></i>
|
| 184 |
+
<span class="text-gray-700">360° exterior and interior views</span>
|
| 185 |
+
</li>
|
| 186 |
+
<li class="flex items-start">
|
| 187 |
+
<i data-feather="check-circle" class="text-green-500 mr-2 mt-1"></i>
|
| 188 |
+
<span class="text-gray-700">Interactive features and specifications</span>
|
| 189 |
+
</li>
|
| 190 |
+
<li class="flex items-start">
|
| 191 |
+
<i data-feather="check-circle" class="text-green-500 mr-2 mt-1"></i>
|
| 192 |
+
<span class="text-gray-700">Available on desktop and mobile</span>
|
| 193 |
+
</li>
|
| 194 |
+
<li class="flex items-start">
|
| 195 |
+
<i data-feather="check-circle" class="text-green-500 mr-2 mt-1"></i>
|
| 196 |
+
<span class="text-gray-700">VR headset compatible for full immersion</span>
|
| 197 |
+
</li>
|
| 198 |
+
</ul>
|
| 199 |
+
<a href="../vr-showroom/index.php" class="inline-block bg-red-500 hover:bg-red-600 text-white px-6 py-3 rounded-md font-medium transition duration-300">
|
| 200 |
+
<i data-feather="vr-chart" class="w-5 h-5 inline mr-2"></i> Enter VR Showroom
|
| 201 |
+
</a>
|
| 202 |
+
</div>
|
| 203 |
+
</div>
|
| 204 |
+
</div>
|
| 205 |
+
</section>
|
| 206 |
+
|
| 207 |
+
<!-- Call to Action -->
|
| 208 |
+
<section class="py-16 bg-red-500 text-white">
|
| 209 |
+
<div class="container mx-auto px-4 text-center">
|
| 210 |
+
<h2 class="text-3xl font-bold mb-6">Can't Find What You're Looking For?</h2>
|
| 211 |
+
<p class="text-xl mb-8 max-w-2xl mx-auto">Contact our sales team for assistance with special requests or custom orders.</p>
|
| 212 |
+
<div class="flex flex-col sm:flex-row justify-center gap-4">
|
| 213 |
+
<a href="tel:+254794330243" class="bg-white text-red-500 px-8 py-3 rounded-md font-bold transition duration-300 hover:bg-gray-100">
|
| 214 |
+
<i data-feather="phone" class="w-5 h-5 inline mr-2"></i> Call Now
|
| 215 |
+
</a>
|
| 216 |
+
<a href="https://wa.me/254794330243?text=Hello%20Japanese%20Motors,%20I'm%20interested%20in%20your%20vehicles" class="border-2 border-white text-white px-8 py-3 rounded-md font-bold transition duration-300 hover:bg-white hover:text-red-500" target="_blank">
|
| 217 |
+
<i data-feather="message-circle" class="w-5 h-5 inline mr-2"></i> WhatsApp
|
| 218 |
+
</a>
|
| 219 |
+
</div>
|
| 220 |
+
</div>
|
| 221 |
+
</section>
|
| 222 |
+
|
| 223 |
+
<!-- Newsletter -->
|
| 224 |
+
<section class="py-16 bg-gray-800 text-white">
|
| 225 |
+
<div class="container mx-auto px-4">
|
| 226 |
+
<div class="max-w-3xl mx-auto text-center">
|
| 227 |
+
<h2 class="text-3xl font-bold mb-6">Get Notified About New Arrivals</h2>
|
| 228 |
+
<p class="mb-8 text-gray-300">Be the first to know when we add new vehicles to our inventory. Sign up for our exclusive newsletter.</p>
|
| 229 |
+
<form class="flex flex-col sm:flex-row gap-4">
|
| 230 |
+
<input type="email" placeholder="Your email address" class="flex-grow px-4 py-3 rounded-md text-gray-800 focus:outline-none focus:ring-2 focus:ring-red-500">
|
| 231 |
+
<button type="submit" class="bg-red-500 hover:bg-red-600 text-white px-6 py-3 rounded-md font-medium transition duration-300">Subscribe</button>
|
| 232 |
+
</form>
|
| 233 |
+
</div>
|
| 234 |
+
</div>
|
| 235 |
+
</section>
|
| 236 |
+
|
| 237 |
+
<!-- Vehicle Detail Modal -->
|
| 238 |
+
<div id="vehicleModal" class="modal">
|
| 239 |
+
<div class="modal-content">
|
| 240 |
+
<span class="close-modal text-white">×</span>
|
| 241 |
+
<div id="modalContent" class="p-6">
|
| 242 |
+
<!-- Content will be loaded here by JavaScript -->
|
| 243 |
+
</div>
|
| 244 |
+
</div>
|
| 245 |
+
</div>
|
| 246 |
+
|
| 247 |
+
<!-- Footer -->
|
| 248 |
+
<footer class="bg-gray-900 text-white py-12">
|
| 249 |
+
<div class="container mx-auto px-4">
|
| 250 |
+
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
| 251 |
+
<div>
|
| 252 |
+
<h3 class="text-xl font-bold mb-4">Japanese Motors</h3>
|
| 253 |
+
<p class="text-gray-400">Premium Japanese performance vehicles imported directly from Japan.</p>
|
| 254 |
+
</div>
|
| 255 |
+
<div>
|
| 256 |
+
<h3 class="text-lg font-bold mb-4">Quick Links</h3>
|
| 257 |
+
<ul class="space-y-2">
|
| 258 |
+
<li><a href="../index.html" class="text-gray-400 hover:text-red-500">Home</a></li>
|
| 259 |
+
<li><a href="gallery.html" class="text-gray-400 hover:text-red-500">Inventory</a></li>
|
| 260 |
+
<li><a href="services.html" class="text-gray-400 hover:text-red-500">Services</a></li>
|
| 261 |
+
<li><a href="about.html" class="text-gray-400 hover:text-red-500">About Us</a></li>
|
| 262 |
+
<li><a href="contact.html" class="text-gray-400 hover:text-red-500">Contact</a></li>
|
| 263 |
+
</ul>
|
| 264 |
+
</div>
|
| 265 |
+
<div>
|
| 266 |
+
<h3 class="text-lg font-bold mb-4">Contact Info</h3>
|
| 267 |
+
<ul class="space-y-2">
|
| 268 |
+
<li class="flex items-center">
|
| 269 |
+
<i data-feather="map-pin" class="mr-2 w-4 h-4"></i>
|
| 270 |
+
<span class="text-gray-400">123 Automotive Way, Tokyo, Japan</span>
|
| 271 |
+
</li>
|
| 272 |
+
<li class="flex items-center">
|
| 273 |
+
<i data-feather="phone" class="mr-2 w-4 h-4"></i>
|
| 274 |
+
<span class="text-gray-400">+254 794 330 243</span>
|
| 275 |
+
</li>
|
| 276 |
+
<li class="flex items-center">
|
| 277 |
+
<i data-feather="mail" class="mr-2 w-4 h-4"></i>
|
| 278 |
+
<span class="text-gray-400">info@japanesemotors.com</span>
|
| 279 |
+
</li>
|
| 280 |
+
</ul>
|
| 281 |
+
</div>
|
| 282 |
+
<div>
|
| 283 |
+
<h3 class="text-lg font-bold mb-4">Follow Us</h3>
|
| 284 |
+
<div class="flex space-x-4">
|
| 285 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="facebook" class="w-6 h-6"></i></a>
|
| 286 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="instagram" class="w-6 h-6"></i></a>
|
| 287 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="twitter" class="w-6 h-6"></i></a>
|
| 288 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="youtube" class="w-6 h-6"></i></a>
|
| 289 |
+
</div>
|
| 290 |
+
</div>
|
| 291 |
+
</div>
|
| 292 |
+
<div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-400">
|
| 293 |
+
<p>© 2023 Japanese Motors. All rights reserved.</p>
|
| 294 |
+
</div>
|
| 295 |
+
</div>
|
| 296 |
+
</footer>
|
| 297 |
+
|
| 298 |
+
<script>
|
| 299 |
+
// Initialize Feather Icons and AOS
|
| 300 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 301 |
+
feather.replace();
|
| 302 |
+
AOS.init();
|
| 303 |
+
|
| 304 |
+
// Vehicle data with more cars
|
| 305 |
+
const vehicleData = {
|
| 306 |
+
1: {
|
| 307 |
+
title: "Toyota Supra",
|
| 308 |
+
price: "$52,000",
|
| 309 |
+
discount: "$3,000 OFF",
|
| 310 |
+
deposit: "$5,200 (10%)",
|
| 311 |
+
type: "sports",
|
| 312 |
+
year: "2023",
|
| 313 |
+
location: "Osaka",
|
| 314 |
+
engine: "382HP Turbocharged I6",
|
| 315 |
+
images: [
|
| 316 |
+
"https://images.unsplash.com/photo-1617814076367-b759c7d7e738?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80",
|
| 317 |
+
"https://images.unsplash.com/photo-1626668893636-424a8d2c7e0d?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80",
|
| 318 |
+
"https://images.unsplash.com/photo-1620746616760-b52632e1c4af?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80"
|
| 319 |
+
],
|
| 320 |
+
description: "The Toyota Supra is a legendary sports car that combines breathtaking performance with head-turning style. This 2023 model features a 3.0-liter turbocharged inline-6 engine producing 382 horsepower, delivering exhilarating acceleration and precise handling.",
|
| 321 |
+
features: ["3.0L Turbocharged Inline-6 Engine", "382 Horsepower", "8-Speed Automatic Transmission", "Adaptive Variable Suspension", "19-inch Alloy Wheels", "Leather Sports Seats", "8.8-inch Touchscreen Display", "Apple CarPlay & Android Auto"],
|
| 322 |
+
specifications: {
|
| 323 |
+
"Engine": "3.0L Turbocharged I6",
|
| 324 |
+
"Horsepower": "382 HP",
|
| 325 |
+
"Torque": "368 lb-ft",
|
| 326 |
+
"Transmission": "8-Speed Automatic",
|
| 327 |
+
"0-60 mph": "3.9 seconds",
|
| 328 |
+
"Top Speed": "155 mph (electronically limited)",
|
| 329 |
+
"Fuel Economy": "24 MPG combined"
|
| 330 |
+
}
|
| 331 |
+
},
|
| 332 |
+
2: {
|
| 333 |
+
title: "Nissan GT-R Nismo",
|
| 334 |
+
price: "$135,000",
|
| 335 |
+
discount: "Limited Stock",
|
| 336 |
+
deposit: "$13,500 (10%)",
|
| 337 |
+
type: "sports",
|
| 338 |
+
year: "2023",
|
| 339 |
+
location: "Tokyo",
|
| 340 |
+
engine: "600HP Twin-Turbo V6",
|
| 341 |
+
images: [
|
| 342 |
+
"https://i.pinimg.com/1200x/83/b9/94/83b99420acbce687f2b13921da41c80e.jpg",
|
| 343 |
+
"https://i.pinimg.com/1200x/0c/09/e3/0c09e31d9d586670f49009efa58512e2.jpg",
|
| 344 |
+
"https://i.pinimg.com/736x/c6/5d/0d/c65d0dc9beffbfe51c33f9d09fa39961.jpg"
|
| 345 |
+
],
|
| 346 |
+
description: "The Nissan GT-R Nismo represents the pinnacle of Nissan's engineering excellence. With a hand-built 3.8-liter twin-turbo V6 producing 600 horsepower, this track-focused supercar delivers unparalleled performance and precision.",
|
| 347 |
+
features: ["3.8L Twin-Turbo V6 Engine", "600 Horsepower", "6-Speed Dual-Clutch Transmission", "ATTESA E-TS All-Wheel Drive", "Carbon Fiber Rear Spoiler", "Recaro Racing Seats", "Nismo-tuned Suspension", "Carbon Ceramic Brakes"],
|
| 348 |
+
specifications: {
|
| 349 |
+
"Engine": "3.8L Twin-Turbo V6",
|
| 350 |
+
"Horsepower": "600 HP",
|
| 351 |
+
"Torque": "481 lb-ft",
|
| 352 |
+
"Transmission": "6-Speed Dual-Clutch",
|
| 353 |
+
"0-60 mph": "2.5 seconds",
|
| 354 |
+
"Top Speed": "205 mph",
|
| 355 |
+
"Fuel Economy": "19 MPG combined"
|
| 356 |
+
}
|
| 357 |
+
},
|
| 358 |
+
3: {
|
| 359 |
+
title: "Honda NSX Type S",
|
| 360 |
+
price: "$175,000",
|
| 361 |
+
discount: "Arriving Soon",
|
| 362 |
+
deposit: "$17,500 (10%)",
|
| 363 |
+
type: "sports",
|
| 364 |
+
year: "2023",
|
| 365 |
+
location: "Yokohama",
|
| 366 |
+
engine: "600HP Hybrid V6",
|
| 367 |
+
images: [
|
| 368 |
+
"https://images.unsplash.com/photo-1549399542-7e82138aae82?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80",
|
| 369 |
+
"https://images.unsplash.com/photo-1549399542-7e82138aae83?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80",
|
| 370 |
+
"https://images.unsplash.com/photo-1549399542-7e82138aae84?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80"
|
| 371 |
+
],
|
| 372 |
+
description: "The Honda NSX Type S is a limited-production hybrid supercar that combines cutting-edge technology with exceptional performance. With its twin-turbo V6 and three electric motors, it delivers 600 horsepower with instant response and incredible efficiency.",
|
| 373 |
+
features: ["3.5L Twin-Turbo V6 Hybrid", "600 Total Horsepower", "9-Speed Dual-Clutch Transmission", "Sport Hybrid SH-AWD", "Carbon Fiber Roof", "Semi-Aniline Leather Seats", "Custom Drive Mode", "Lightweight Forged Wheels"],
|
| 374 |
+
specifications: {
|
| 375 |
+
"Engine": "3.5L Twin-Turbo V6 + 3 Electric Motors",
|
| 376 |
+
"Total Power": "600 HP",
|
| 377 |
+
"Torque": "492 lb-ft",
|
| 378 |
+
"Transmission": "9-Speed Dual-Clutch",
|
| 379 |
+
"0-60 mph": "2.7 seconds",
|
| 380 |
+
"Top Speed": "191 mph",
|
| 381 |
+
"Fuel Economy": "21 MPG combined"
|
| 382 |
+
}
|
| 383 |
+
},
|
| 384 |
+
4: {
|
| 385 |
+
title: "Mazda RX-7 FD",
|
| 386 |
+
price: "$65,000",
|
| 387 |
+
discount: "Collector's Item",
|
| 388 |
+
deposit: "$6,500 (10%)",
|
| 389 |
+
type: "jdm",
|
| 390 |
+
year: "1995",
|
| 391 |
+
location: "Hiroshima",
|
| 392 |
+
engine: "276HP Twin-Rotor",
|
| 393 |
+
images: [
|
| 394 |
+
"https://i.pinimg.com/1200x/bc/4a/ef/bc4aefd8503bb0df01e990485634c7a3.jpg",
|
| 395 |
+
"https://i.pinimg.com/1200x/89/b1/93/89b193af5e69a308d02c4b797483504e.jpg",
|
| 396 |
+
"https://i.pinimg.com/736x/bf/c4/37/bfc4375ab7595b8f89a5ed8df38b5a7a.jpg"
|
| 397 |
+
],
|
| 398 |
+
description: "The Mazda RX-7 FD is a legendary Japanese sports car renowned for its unique rotary engine and exceptional handling. This 1995 model has been meticulously maintained and represents one of the finest examples of this iconic vehicle.",
|
| 399 |
+
features: ["1.3L Twin-Rotor Rotary Engine", "276 Horsepower", "5-Speed Manual Transmission", "Sequential Twin-Turbo System", "Lightweight Body Construction", "Pop-Up Headlights", "Leather Recaro Seats", "Bose Sound System"],
|
| 400 |
+
specifications: {
|
| 401 |
+
"Engine": "1.3L Twin-Rotor Rotary",
|
| 402 |
+
"Horsepower": "276 HP",
|
| 403 |
+
"Torque": "231 lb-ft",
|
| 404 |
+
"Transmission": "5-Speed Manual",
|
| 405 |
+
"0-60 mph": "4.9 seconds",
|
| 406 |
+
"Top Speed": "156 mph",
|
| 407 |
+
"Fuel Economy": "18 MPG combined"
|
| 408 |
+
}
|
| 409 |
+
},
|
| 410 |
+
5: {
|
| 411 |
+
title: "Subaru WRX STI S209",
|
| 412 |
+
price: "$48,500",
|
| 413 |
+
discount: "$2,500 OFF",
|
| 414 |
+
deposit: "$4,850 (10%)",
|
| 415 |
+
type: "sedan",
|
| 416 |
+
year: "2020",
|
| 417 |
+
location: "Gunma",
|
| 418 |
+
engine: "341HP Turbocharged H4",
|
| 419 |
+
images: [
|
| 420 |
+
"https://i.pinimg.com/1200x/ac/08/98/ac08981ca5b2e9a8d849cf183b77f418.jpg",
|
| 421 |
+
"https://i.pinimg.com/1200x/13/84/ce/1384ce690731a69ef3385544744e617c.jpg",
|
| 422 |
+
"https://i.pinimg.com/736x/ce/cd/54/cecd54fe7c82eaff661a2cc4d38cc0bf.jpg"
|
| 423 |
+
],
|
| 424 |
+
description: "The Subaru WRX STI S209 is a limited-edition high-performance sedan that represents the pinnacle of Subaru's motorsport technology. With its enhanced 2.5-liter turbocharged boxer engine and race-bred suspension, it delivers exceptional performance in all conditions.",
|
| 425 |
+
features: ["2.5L Turbocharged Boxer Engine", "341 Horsepower", "6-Speed Manual Transmission", "Symmetrical All-Wheel Drive", "Brembo Brakes", "Recaro Sport Seats", "Wider Bodywork", "Enhanced Aerodynamics"],
|
| 426 |
+
specifications: {
|
| 427 |
+
"Engine": "2.5L Turbocharged H4",
|
| 428 |
+
"Horsepower": "341 HP",
|
| 429 |
+
"Torque": "330 lb-ft",
|
| 430 |
+
"Transmission": "6-Speed Manual",
|
| 431 |
+
"0-60 mph": "4.5 seconds",
|
| 432 |
+
"Top Speed": "155 mph (electronically limited)",
|
| 433 |
+
"Fuel Economy": "19 MPG combined"
|
| 434 |
+
}
|
| 435 |
+
},
|
| 436 |
+
6: {
|
| 437 |
+
title: "Toyota GR Yaris",
|
| 438 |
+
price: "$38,000",
|
| 439 |
+
discount: "Almost Gone",
|
| 440 |
+
deposit: "$3,800 (10%)",
|
| 441 |
+
type: "sports",
|
| 442 |
+
year: "2023",
|
| 443 |
+
location: "Nagoya",
|
| 444 |
+
engine: "268HP Turbocharged I3",
|
| 445 |
+
images: [
|
| 446 |
+
"https://images.unsplash.com/photo-1617814076367-b759c7d7e738?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80",
|
| 447 |
+
"https://i.pinimg.com/736x/3d/99/8d/3d998d4c8f4cff0461bab252c574a8b7.jpg",
|
| 448 |
+
"https://i.pinimg.com/1200x/68/49/a4/6849a43c2034f2f5f495fc40310e9448.jpg"
|
| 449 |
+
],
|
| 450 |
+
description: "The Toyota GR Yaris is a rally-bred hot hatch that brings World Rally Championship technology to the road. With its turbocharged three-cylinder engine and GR-FOUR all-wheel-drive system, it delivers exceptional performance and agility.",
|
| 451 |
+
features: ["1.6L Turbocharged I3 Engine", "268 Horsepower", "6-Speed Manual Transmission", "GR-FOUR All-Wheel Drive", "Lightweight Body Construction", "Sports Seats", "Dual-Zone Climate Control", "Toyota Safety Sense"],
|
| 452 |
+
specifications: {
|
| 453 |
+
"Engine": "1.6L Turbocharged I3",
|
| 454 |
+
"Horsepower": "268 HP",
|
| 455 |
+
"Torque": "273 lb-ft",
|
| 456 |
+
"Transmission": "6-Speed Manual",
|
| 457 |
+
"0-60 mph": "5.2 seconds",
|
| 458 |
+
"Top Speed": "143 mph",
|
| 459 |
+
"Fuel Economy": "28 MPG combined"
|
| 460 |
+
}
|
| 461 |
+
},
|
| 462 |
+
7: {
|
| 463 |
+
title: "Lexus LC 500",
|
| 464 |
+
price: "$95,000",
|
| 465 |
+
discount: "Premium Edition",
|
| 466 |
+
deposit: "$9,500 (10%)",
|
| 467 |
+
type: "sports",
|
| 468 |
+
year: "2023",
|
| 469 |
+
location: "Kyoto",
|
| 470 |
+
engine: "471HP V8",
|
| 471 |
+
images: [
|
| 472 |
+
"https://images.unsplash.com/photo-1580273916554-8b7e9ee5f50d?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80",
|
| 473 |
+
"https://images.unsplash.com/photo-1580273916554-8b7e9ee5f50e?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80",
|
| 474 |
+
"https://images.unsplash.com/photo-1580273916554-8b7e9ee5f50f?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80"
|
| 475 |
+
],
|
| 476 |
+
description: "The Lexus LC 500 is a luxury grand tourer that combines stunning design with exhilarating performance. Its naturally aspirated 5.0-liter V8 engine delivers a thrilling driving experience with a symphony of exhaust notes.",
|
| 477 |
+
features: ["5.0L V8 Engine", "471 Horsepower", "10-Speed Automatic Transmission", "Rear-Wheel Drive", "Carbon Fiber Roof", "Semi-Aniline Leather Interior", "Mark Levinson Sound System", "Adaptive Variable Suspension"],
|
| 478 |
+
specifications: {
|
| 479 |
+
"Engine": "5.0L V8",
|
| 480 |
+
"Horsepower": "471 HP",
|
| 481 |
+
"Torque": "398 lb-ft",
|
| 482 |
+
"Transmission": "10-Speed Automatic",
|
| 483 |
+
"0-60 mph": "4.4 seconds",
|
| 484 |
+
"Top Speed": "168 mph",
|
| 485 |
+
"Fuel Economy": "19 MPG combined"
|
| 486 |
+
}
|
| 487 |
+
},
|
| 488 |
+
8: {
|
| 489 |
+
title: "Nissan 370Z Nismo",
|
| 490 |
+
price: "$42,000",
|
| 491 |
+
discount: "Special Offer",
|
| 492 |
+
deposit: "$4,200 (10%)",
|
| 493 |
+
type: "sports",
|
| 494 |
+
year: "2022",
|
| 495 |
+
location: "Yokohama",
|
| 496 |
+
engine: "350HP V6",
|
| 497 |
+
images: [
|
| 498 |
+
"https://images.unsplash.com/photo-1601268859287-9cec8a74e9f8?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80",
|
| 499 |
+
"https://images.unsplash.com/photo-1601268859287-9cec8a74e9f9?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80",
|
| 500 |
+
"https://images.unsplash.com/photo-1601268859287-9cec8a74e9fa?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80"
|
| 501 |
+
],
|
| 502 |
+
description: "The Nissan 370Z Nismo is a pure sports car that delivers thrilling performance with its 3.7-liter V6 engine and sharp handling. The Nismo edition adds aggressive styling and enhanced performance features.",
|
| 503 |
+
features: ["3.7L V6 Engine", "350 Horsepower", "6-Speed Manual Transmission", "Rear-Wheel Drive", "Nismo Body Kit", "Recaro Sport Seats", "Brembo Brakes", "Viscous Limited-Slip Differential"],
|
| 504 |
+
specifications: {
|
| 505 |
+
"Engine": "3.7L V6",
|
| 506 |
+
"Horsepower": "350 HP",
|
| 507 |
+
"Torque": "276 lb-ft",
|
| 508 |
+
"Transmission": "6-Speed Manual",
|
| 509 |
+
"0-60 mph": "4.5 seconds",
|
| 510 |
+
"Top Speed": "155 mph",
|
| 511 |
+
"Fuel Economy": "22 MPG combined"
|
| 512 |
+
}
|
| 513 |
+
},
|
| 514 |
+
9: {
|
| 515 |
+
title: "Toyota Land Cruiser",
|
| 516 |
+
price: "$85,000",
|
| 517 |
+
discount: "Adventure Ready",
|
| 518 |
+
deposit: "$8,500 (10%)",
|
| 519 |
+
type: "suv",
|
| 520 |
+
year: "2023",
|
| 521 |
+
location: "Osaka",
|
| 522 |
+
engine: "409HP Twin-Turbo V6",
|
| 523 |
+
images: [
|
| 524 |
+
"https://images.unsplash.com/photo-1580274437636-1c384e567539?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80",
|
| 525 |
+
"https://images.unsplash.com/photo-1580274437636-1c384e56753a?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80",
|
| 526 |
+
"https://images.unsplash.com/photo-1580274437636-1c384e56753b?ixlib=rb-4.0.3&auto=format&fit=crop&w=1080&q=80"
|
| 527 |
+
],
|
| 528 |
+
description: "The Toyota Land Cruiser is the ultimate luxury SUV built for both on-road comfort and off-road capability. With its powerful twin-turbo V6 engine and advanced four-wheel drive system, it can conquer any terrain.",
|
| 529 |
+
features: ["3.5L Twin-Turbo V6 Hybrid", "409 Horsepower", "10-Speed Automatic", "Full-Time 4WD", "Multi-Terrain Select", "Crawl Control", "Premium Leather Interior", "12.3-inch Touchscreen"],
|
| 530 |
+
specifications: {
|
| 531 |
+
"Engine": "3.5L Twin-Turbo V6 Hybrid",
|
| 532 |
+
"Horsepower": "409 HP",
|
| 533 |
+
"Torque": "479 lb-ft",
|
| 534 |
+
"Transmission": "10-Speed Automatic",
|
| 535 |
+
"0-60 mph": "5.7 seconds",
|
| 536 |
+
"Towing Capacity": "8,100 lbs",
|
| 537 |
+
"Fuel Economy": "22 MPG combined"
|
| 538 |
+
}
|
| 539 |
+
}
|
| 540 |
+
};
|
| 541 |
+
|
| 542 |
+
// Pagination variables
|
| 543 |
+
const itemsPerPage = 6;
|
| 544 |
+
let currentPage = 1;
|
| 545 |
+
let filteredCars = Object.keys(vehicleData);
|
| 546 |
+
let currentType = 'all';
|
| 547 |
+
let currentSort = 'newest';
|
| 548 |
+
|
| 549 |
+
// Function to render cars based on current page and filters
|
| 550 |
+
function renderCars() {
|
| 551 |
+
const inventoryGrid = document.getElementById('inventoryGrid');
|
| 552 |
+
inventoryGrid.innerHTML = '';
|
| 553 |
+
|
| 554 |
+
// Calculate start and end index for current page
|
| 555 |
+
const startIndex = (currentPage - 1) * itemsPerPage;
|
| 556 |
+
const endIndex = Math.min(startIndex + itemsPerPage, filteredCars.length);
|
| 557 |
+
|
| 558 |
+
// Get cars for current page
|
| 559 |
+
const currentCars = filteredCars.slice(startIndex, endIndex);
|
| 560 |
+
|
| 561 |
+
// Render each car
|
| 562 |
+
currentCars.forEach(carId => {
|
| 563 |
+
const car = vehicleData[carId];
|
| 564 |
+
const carCard = document.createElement('div');
|
| 565 |
+
carCard.className = 'car-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300';
|
| 566 |
+
carCard.setAttribute('data-type', car.type);
|
| 567 |
+
carCard.setAttribute('data-aos', 'fade-up');
|
| 568 |
+
|
| 569 |
+
let badgeHtml = '';
|
| 570 |
+
if (car.discount.includes('NEW')) {
|
| 571 |
+
badgeHtml = `<div class="absolute top-4 right-4 bg-red-500 text-white px-3 py-1 rounded-full text-xs font-bold">NEW</div>`;
|
| 572 |
+
} else if (car.discount.includes('LIMITED')) {
|
| 573 |
+
badgeHtml = `<div class="absolute top-4 right-4 bg-red-500 text-white px-3 py-1 rounded-full text-xs font-bold">LIMITED</div>`;
|
| 574 |
+
}
|
| 575 |
+
|
| 576 |
+
let statusHtml = '';
|
| 577 |
+
if (car.discount.includes('OFF')) {
|
| 578 |
+
statusHtml = `<div class="text-sm bg-green-100 text-green-800 px-2 py-1 rounded">
|
| 579 |
+
<i data-feather="tag" class="w-3 h-3 inline mr-1"></i> ${car.discount}
|
| 580 |
+
</div>`;
|
| 581 |
+
} else if (car.discount.includes('Limited')) {
|
| 582 |
+
statusHtml = `<div class="text-sm bg-yellow-100 text-yellow-800 px-2 py-1 rounded">
|
| 583 |
+
<i data-feather="clock" class="w-3 h-3 inline mr-1"></i> ${car.discount}
|
| 584 |
+
</div>`;
|
| 585 |
+
} else if (car.discount.includes('Arriving')) {
|
| 586 |
+
statusHtml = `<div class="text-sm bg-blue-100 text-blue-800 px-2 py-1 rounded">
|
| 587 |
+
<i data-feather="truck" class="w-3 h-3 inline mr-1"></i> ${car.discount}
|
| 588 |
+
</div>`;
|
| 589 |
+
} else if (car.discount.includes('Collector')) {
|
| 590 |
+
statusHtml = `<div class="text-sm bg-purple-100 text-purple-800 px-2 py-1 rounded">
|
| 591 |
+
<i data-feather="star" class="w-3 h-3 inline mr-1"></i> ${car.discount}
|
| 592 |
+
</div>`;
|
| 593 |
+
} else if (car.discount.includes('Almost')) {
|
| 594 |
+
statusHtml = `<div class="text-sm bg-red-100 text-red-800 px-2 py-1 rounded">
|
| 595 |
+
<i data-feather="alert-circle" class="w-3 h-3 inline mr-1"></i> ${car.discount}
|
| 596 |
+
</div>`;
|
| 597 |
+
} else {
|
| 598 |
+
statusHtml = `<div class="text-sm bg-gray-100 text-gray-800 px-2 py-1 rounded">
|
| 599 |
+
${car.discount}
|
| 600 |
+
</div>`;
|
| 601 |
+
}
|
| 602 |
+
|
| 603 |
+
carCard.innerHTML = `
|
| 604 |
+
<div class="relative overflow-hidden h-64">
|
| 605 |
+
<img class="w-full h-full object-cover car-image" src="${car.images[0]}" alt="${car.title}" data-car-id="${carId}">
|
| 606 |
+
${badgeHtml}
|
| 607 |
+
<div class="absolute bottom-4 left-4">
|
| 608 |
+
<button class="bg-black bg-opacity-70 text-white px-3 py-1 rounded-full text-xs flex items-center hover:bg-opacity-90">
|
| 609 |
+
<i data-feather="maximize-2" class="w-3 h-3 mr-1"></i> 360° View
|
| 610 |
+
</button>
|
| 611 |
+
</div>
|
| 612 |
+
</div>
|
| 613 |
+
<div class="p-6">
|
| 614 |
+
<h3 class="text-xl font-bold text-gray-800 mb-2">${car.title}</h3>
|
| 615 |
+
<div class="flex items-center text-gray-600 mb-4">
|
| 616 |
+
<i data-feather="clock" class="mr-2"></i>
|
| 617 |
+
<span>${car.year} Model</span>
|
| 618 |
+
<i data-feather="map-pin" class="ml-4 mr-2"></i>
|
| 619 |
+
<span>${car.location}</span>
|
| 620 |
+
</div>
|
| 621 |
+
<div class="flex items-center text-gray-600 mb-4">
|
| 622 |
+
<i data-feather="zap" class="mr-2"></i>
|
| 623 |
+
<span>${car.engine}</span>
|
| 624 |
+
</div>
|
| 625 |
+
<div class="flex justify-between items-center mb-4">
|
| 626 |
+
<div class="flex items-center">
|
| 627 |
+
<i data-feather="dollar-sign" class="text-red-500 mr-1"></i>
|
| 628 |
+
<span class="text-2xl font-bold text-gray-900">${car.price}</span>
|
| 629 |
+
</div>
|
| 630 |
+
${statusHtml}
|
| 631 |
+
</div>
|
| 632 |
+
<div class="flex justify-between">
|
| 633 |
+
<button class="view-details-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300 flex-1 mr-2 text-center" data-car-id="${carId}">Details</button>
|
| 634 |
+
<button class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-md text-sm font-medium transition duration-300 flex-1 ml-2">
|
| 635 |
+
<i data-feather="heart" class="w-4 h-4 inline"></i>
|
| 636 |
+
</button>
|
| 637 |
+
</div>
|
| 638 |
+
</div>
|
| 639 |
+
`;
|
| 640 |
+
|
| 641 |
+
inventoryGrid.appendChild(carCard);
|
| 642 |
+
});
|
| 643 |
+
|
| 644 |
+
// Reinitialize feather icons
|
| 645 |
+
feather.replace();
|
| 646 |
+
|
| 647 |
+
// Add event listeners to new elements
|
| 648 |
+
addCarEventListeners();
|
| 649 |
+
|
| 650 |
+
// Update pagination
|
| 651 |
+
updatePagination();
|
| 652 |
+
}
|
| 653 |
+
|
| 654 |
+
// Function to update pagination
|
| 655 |
+
function updatePagination() {
|
| 656 |
+
const pagination = document.getElementById('pagination');
|
| 657 |
+
const totalPages = Math.ceil(filteredCars.length / itemsPerPage);
|
| 658 |
+
|
| 659 |
+
let paginationHtml = '';
|
| 660 |
+
|
| 661 |
+
// Previous button
|
| 662 |
+
if (currentPage > 1) {
|
| 663 |
+
paginationHtml += `<button class="pagination-btn px-3 py-1 rounded border border-gray-300 text-gray-700 hover:bg-gray-100" data-page="${currentPage - 1}">
|
| 664 |
+
<i data-feather="chevron-left" class="w-4 h-4"></i>
|
| 665 |
+
</button>`;
|
| 666 |
+
} else {
|
| 667 |
+
paginationHtml += `<button class="px-3 py-1 rounded border border-gray-300 text-gray-500 hover:bg-gray-100 disabled" disabled>
|
| 668 |
+
<i data-feather="chevron-left" class="w-4 h-4"></i>
|
| 669 |
+
</button>`;
|
| 670 |
+
}
|
| 671 |
+
|
| 672 |
+
// Page numbers
|
| 673 |
+
const maxVisiblePages = 5;
|
| 674 |
+
let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
|
| 675 |
+
let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);
|
| 676 |
+
|
| 677 |
+
if (endPage - startPage + 1 < maxVisiblePages) {
|
| 678 |
+
startPage = Math.max(1, endPage - maxVisiblePages + 1);
|
| 679 |
+
}
|
| 680 |
+
|
| 681 |
+
for (let i = startPage; i <= endPage; i++) {
|
| 682 |
+
if (i === currentPage) {
|
| 683 |
+
paginationHtml += `<button class="pagination-btn active px-3 py-1 rounded bg-red-500 text-white" data-page="${i}">${i}</button>`;
|
| 684 |
+
} else {
|
| 685 |
+
paginationHtml += `<button class="pagination-btn px-3 py-1 rounded border border-gray-300 text-gray-700 hover:bg-gray-100" data-page="${i}">${i}</button>`;
|
| 686 |
+
}
|
| 687 |
+
}
|
| 688 |
+
|
| 689 |
+
// Next button
|
| 690 |
+
if (currentPage < totalPages) {
|
| 691 |
+
paginationHtml += `<button class="pagination-btn px-3 py-1 rounded border border-gray-300 text-gray-700 hover:bg-gray-100" data-page="${currentPage + 1}">
|
| 692 |
+
<i data-feather="chevron-right" class="w-4 h-4"></i>
|
| 693 |
+
</button>`;
|
| 694 |
+
} else {
|
| 695 |
+
paginationHtml += `<button class="px-3 py-1 rounded border border-gray-300 text-gray-500 hover:bg-gray-100 disabled" disabled>
|
| 696 |
+
<i data-feather="chevron-right" class="w-4 h-4"></i>
|
| 697 |
+
</button>`;
|
| 698 |
+
}
|
| 699 |
+
|
| 700 |
+
pagination.innerHTML = paginationHtml;
|
| 701 |
+
|
| 702 |
+
// Add event listeners to pagination buttons
|
| 703 |
+
document.querySelectorAll('.pagination-btn').forEach(button => {
|
| 704 |
+
button.addEventListener('click', function() {
|
| 705 |
+
currentPage = parseInt(this.getAttribute('data-page'));
|
| 706 |
+
renderCars();
|
| 707 |
+
window.scrollTo({ top: document.getElementById('inventoryGrid').offsetTop - 100, behavior: 'smooth' });
|
| 708 |
+
});
|
| 709 |
+
});
|
| 710 |
+
}
|
| 711 |
+
|
| 712 |
+
// Function to add event listeners to car elements
|
| 713 |
+
function addCarEventListeners() {
|
| 714 |
+
// Add event listeners to view details buttons
|
| 715 |
+
document.querySelectorAll('.view-details-btn').forEach(button => {
|
| 716 |
+
button.addEventListener('click', function() {
|
| 717 |
+
const carId = this.getAttribute('data-car-id');
|
| 718 |
+
openModal(carId);
|
| 719 |
+
});
|
| 720 |
+
});
|
| 721 |
+
|
| 722 |
+
// Add event listeners to car images
|
| 723 |
+
document.querySelectorAll('.car-image').forEach(image => {
|
| 724 |
+
image.addEventListener('click', function() {
|
| 725 |
+
const carId = this.getAttribute('data-car-id');
|
| 726 |
+
openModal(carId);
|
| 727 |
+
});
|
| 728 |
+
});
|
| 729 |
+
}
|
| 730 |
+
|
| 731 |
+
// Motor type filtering
|
| 732 |
+
const motorTypeButtons = document.querySelectorAll('.motor-type-btn');
|
| 733 |
+
|
| 734 |
+
motorTypeButtons.forEach(button => {
|
| 735 |
+
button.addEventListener('click', function() {
|
| 736 |
+
// Remove active class from all buttons
|
| 737 |
+
motorTypeButtons.forEach(btn => btn.classList.remove('active', 'bg-red-500', 'text-white'));
|
| 738 |
+
|
| 739 |
+
// Add active class to clicked button
|
| 740 |
+
this.classList.add('active', 'bg-red-500', 'text-white');
|
| 741 |
+
|
| 742 |
+
currentType = this.getAttribute('data-type');
|
| 743 |
+
currentPage = 1;
|
| 744 |
+
|
| 745 |
+
// Filter cars
|
| 746 |
+
if (currentType === 'all') {
|
| 747 |
+
filteredCars = Object.keys(vehicleData);
|
| 748 |
+
} else {
|
| 749 |
+
filteredCars = Object.keys(vehicleData).filter(id => vehicleData[id].type === currentType);
|
| 750 |
+
}
|
| 751 |
+
|
| 752 |
+
// Apply sorting
|
| 753 |
+
applySorting();
|
| 754 |
+
|
| 755 |
+
// Render cars
|
| 756 |
+
renderCars();
|
| 757 |
+
});
|
| 758 |
+
});
|
| 759 |
+
|
| 760 |
+
// Sort functionality
|
| 761 |
+
const sortSelect = document.getElementById('sortBy');
|
| 762 |
+
sortSelect.addEventListener('change', function() {
|
| 763 |
+
currentSort = this.value;
|
| 764 |
+
applySorting();
|
| 765 |
+
renderCars();
|
| 766 |
+
});
|
| 767 |
+
|
| 768 |
+
// Function to apply sorting
|
| 769 |
+
function applySorting() {
|
| 770 |
+
switch(currentSort) {
|
| 771 |
+
case 'price-low':
|
| 772 |
+
filteredCars.sort((a, b) => {
|
| 773 |
+
const priceA = parseFloat(vehicleData[a].price.replace(/[^0-9.]/g, ''));
|
| 774 |
+
const priceB = parseFloat(vehicleData[b].price.replace(/[^0-9.]/g, ''));
|
| 775 |
+
return priceA - priceB;
|
| 776 |
+
});
|
| 777 |
+
break;
|
| 778 |
+
case 'price-high':
|
| 779 |
+
filteredCars.sort((a, b) => {
|
| 780 |
+
const priceA = parseFloat(vehicleData[a].price.replace(/[^0-9.]/g, ''));
|
| 781 |
+
const priceB = parseFloat(vehicleData[b].price.replace(/[^0-9.]/g, ''));
|
| 782 |
+
return priceB - priceA;
|
| 783 |
+
});
|
| 784 |
+
break;
|
| 785 |
+
case 'newest':
|
| 786 |
+
default:
|
| 787 |
+
// Default sorting (by year descending)
|
| 788 |
+
filteredCars.sort((a, b) => {
|
| 789 |
+
const yearA = parseInt(vehicleData[a].year);
|
| 790 |
+
const yearB = parseInt(vehicleData[b].year);
|
| 791 |
+
return yearB - yearA;
|
| 792 |
+
});
|
| 793 |
+
break;
|
| 794 |
+
}
|
| 795 |
+
}
|
| 796 |
+
|
| 797 |
+
// Modal functionality
|
| 798 |
+
const modal = document.getElementById('vehicleModal');
|
| 799 |
+
const modalContent = document.getElementById('modalContent');
|
| 800 |
+
const closeModal = document.querySelector('.close-modal');
|
| 801 |
+
|
| 802 |
+
// Function to open modal with car details
|
| 803 |
+
function openModal(carId) {
|
| 804 |
+
const car = vehicleData[carId];
|
| 805 |
+
if (!car) return;
|
| 806 |
+
|
| 807 |
+
let featuresHtml = '';
|
| 808 |
+
car.features.forEach(feature => {
|
| 809 |
+
featuresHtml += `<li class="flex items-start">
|
| 810 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 811 |
+
<span>${feature}</span>
|
| 812 |
+
</li>`;
|
| 813 |
+
});
|
| 814 |
+
|
| 815 |
+
let specificationsHtml = '';
|
| 816 |
+
for (const [key, value] of Object.entries(car.specifications)) {
|
| 817 |
+
specificationsHtml += `<tr>
|
| 818 |
+
<td class="py-2 px-4 border-b border-gray-200 font-medium">${key}</td>
|
| 819 |
+
<td class="py-2 px-4 border-b border-gray-200">${value}</td>
|
| 820 |
+
</tr>`;
|
| 821 |
+
}
|
| 822 |
+
|
| 823 |
+
let imagesHtml = '';
|
| 824 |
+
car.images.forEach((img, index) => {
|
| 825 |
+
imagesHtml += `<div class="car-thumbnail ${index === 0 ? 'border-2 border-red-500' : 'border border-gray-300'}" data-index="${index}">
|
| 826 |
+
<img src="${img}" alt="${car.title}" class="h-16 w-full object-cover">
|
| 827 |
+
</div>`;
|
| 828 |
+
});
|
| 829 |
+
|
| 830 |
+
modalContent.innerHTML = `
|
| 831 |
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
| 832 |
+
<div>
|
| 833 |
+
<div class="mb-4">
|
| 834 |
+
<img id="mainCarImage" src="${car.images[0]}" alt="${car.title}" class="w-full h-80 object-cover rounded-lg">
|
| 835 |
+
</div>
|
| 836 |
+
<div class="grid grid-cols-3 gap-2">
|
| 837 |
+
${imagesHtml}
|
| 838 |
+
</div>
|
| 839 |
+
</div>
|
| 840 |
+
<div>
|
| 841 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-2">${car.title}</h2>
|
| 842 |
+
<div class="flex items-center mb-4">
|
| 843 |
+
<span class="text-2xl font-bold text-red-500">${car.price}</span>
|
| 844 |
+
<span class="ml-4 bg-green-100 text-green-800 px-2 py-1 rounded text-sm">${car.discount}</span>
|
| 845 |
+
</div>
|
| 846 |
+
<p class="text-gray-600 mb-6">${car.description}</p>
|
| 847 |
+
|
| 848 |
+
<div class="mb-6">
|
| 849 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Key Features</h3>
|
| 850 |
+
<ul class="space-y-2">
|
| 851 |
+
${featuresHtml}
|
| 852 |
+
</ul>
|
| 853 |
+
</div>
|
| 854 |
+
|
| 855 |
+
<div class="mb-6">
|
| 856 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Specifications</h3>
|
| 857 |
+
<table class="w-full">
|
| 858 |
+
<tbody>
|
| 859 |
+
${specificationsHtml}
|
| 860 |
+
</tbody>
|
| 861 |
+
</table>
|
| 862 |
+
</div>
|
| 863 |
+
|
| 864 |
+
<div class="bg-gray-100 p-4 rounded-lg mb-6">
|
| 865 |
+
<h3 class="text-lg font-bold text-gray-800 mb-2">Financial Details</h3>
|
| 866 |
+
<p class="text-gray-600">Minimum Deposit: <span class="font-bold">${car.deposit}</span></p>
|
| 867 |
+
<p class="text-gray-600">Financing options available with approved credit</p>
|
| 868 |
+
</div>
|
| 869 |
+
|
| 870 |
+
<div class="flex space-x-4">
|
| 871 |
+
<button class="bg-red-500 hover:bg-red-600 text-white px-6 py-3 rounded-md font-medium transition duration-300 flex-1">
|
| 872 |
+
<i data-feather="dollar-sign" class="w-5 h-5 inline mr-2"></i> Apply for Financing
|
| 873 |
+
</button>
|
| 874 |
+
<a href="tel:+254794330243" class="bg-gray-800 hover:bg-gray-900 text-white px-6 py-3 rounded-md font-medium transition duration-300 flex-1 text-center">
|
| 875 |
+
<i data-feather="phone" class="w-5 h-5 inline mr-2"></i> Contact Sales
|
| 876 |
+
</a>
|
| 877 |
+
</div>
|
| 878 |
+
</div>
|
| 879 |
+
</div>
|
| 880 |
+
`;
|
| 881 |
+
|
| 882 |
+
// Re-initialize feather icons in modal
|
| 883 |
+
feather.replace();
|
| 884 |
+
|
| 885 |
+
// Add event listeners to thumbnail images
|
| 886 |
+
const thumbnails = document.querySelectorAll('.car-thumbnail');
|
| 887 |
+
const mainImage = document.getElementById('mainCarImage');
|
| 888 |
+
|
| 889 |
+
thumbnails.forEach(thumb => {
|
| 890 |
+
thumb.addEventListener('click', function() {
|
| 891 |
+
const index = this.getAttribute('data-index');
|
| 892 |
+
mainImage.src = car.images[index];
|
| 893 |
+
|
| 894 |
+
// Update active thumbnail
|
| 895 |
+
thumbnails.forEach(t => t.classList.remove('border-2', 'border-red-500'));
|
| 896 |
+
thumbnails.forEach(t => t.classList.add('border', 'border-gray-300'));
|
| 897 |
+
this.classList.remove('border', 'border-gray-300');
|
| 898 |
+
this.classList.add('border-2', 'border-red-500');
|
| 899 |
+
});
|
| 900 |
+
});
|
| 901 |
+
|
| 902 |
+
modal.style.display = 'block';
|
| 903 |
+
document.body.style.overflow = 'hidden';
|
| 904 |
+
}
|
| 905 |
+
|
| 906 |
+
// Close modal when clicking on X
|
| 907 |
+
closeModal.addEventListener('click', function() {
|
| 908 |
+
modal.style.display = 'none';
|
| 909 |
+
document.body.style.overflow = 'auto';
|
| 910 |
+
});
|
| 911 |
+
|
| 912 |
+
// Close modal when clicking outside of content
|
| 913 |
+
window.addEventListener('click', function(event) {
|
| 914 |
+
if (event.target === modal) {
|
| 915 |
+
modal.style.display = 'none';
|
| 916 |
+
document.body.style.overflow = 'auto';
|
| 917 |
+
}
|
| 918 |
+
});
|
| 919 |
+
|
| 920 |
+
// Initial render
|
| 921 |
+
applySorting();
|
| 922 |
+
renderCars();
|
| 923 |
+
});
|
| 924 |
+
</script>
|
| 925 |
+
</body>
|
| 926 |
+
</html>
|
jweb/1a/services.html
ADDED
|
@@ -0,0 +1,855 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Services - Japanese Motors</title>
|
| 7 |
+
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 8 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
+
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
|
| 10 |
+
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
|
| 11 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 12 |
+
<script src="https://unpkg.com/feather-icons"></script>
|
| 13 |
+
<link rel="stylesheet" href="assets/css/1e.css">
|
| 14 |
+
</head>
|
| 15 |
+
<body class="bg-gray-100 font-sans">
|
| 16 |
+
<!-- Navigation -->
|
| 17 |
+
<nav class="bg-white shadow-lg fixed w-full z-10">
|
| 18 |
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
| 19 |
+
<div class="flex justify-between h-16">
|
| 20 |
+
<div class="flex items-center">
|
| 21 |
+
<a href="services.html" class="flex-shrink-0 flex items-center">
|
| 22 |
+
<i data-feather="zap" class="h-8 w-8 text-red-500"></i>
|
| 23 |
+
<span class="ml-2 text-xl font-bold text-gray-900">JAPANESE MOTORS</span>
|
| 24 |
+
</a>
|
| 25 |
+
</div>
|
| 26 |
+
<div class="hidden md:flex items-center space-x-8">
|
| 27 |
+
<a href="../index.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Home</a>
|
| 28 |
+
<a href="gallery.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Inventory</a>
|
| 29 |
+
<a href="services.html" class="nav-link text-gray-700 hover:text-red-500 px-3 py-2 rounded-md text-sm font-medium">Services</a>
|
| 30 |
+
<a href="about.html" class="nav-link text-red-500 px-3 py-2 rounded-md text-sm font-medium">About</a>
|
| 31 |
+
<a href="contact.html" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">Contact</a>
|
| 32 |
+
</div>
|
| 33 |
+
<div class="md:hidden flex items-center">
|
| 34 |
+
<button class="text-gray-500 hover:text-gray-900 focus:outline-none">
|
| 35 |
+
<i data-feather="menu"></i>
|
| 36 |
+
</button>
|
| 37 |
+
</div>
|
| 38 |
+
</div>
|
| 39 |
+
</div>
|
| 40 |
+
</nav>
|
| 41 |
+
|
| 42 |
+
<!-- Hero Section -->
|
| 43 |
+
<div class="relative pt-32 pb-20 bg-gray-900">
|
| 44 |
+
<div class="absolute inset-0 bg-black opacity-50"></div>
|
| 45 |
+
<div class="absolute inset-0 bg-center bg-cover" style="background-image: url('https://images.unsplash.com/photo-1492144534655-ae79c964c9d7?ixlib=rb-4.0.3&auto=format&fit=crop&w=1600&q=80');"></div>
|
| 46 |
+
<div class="container mx-auto px-4 relative">
|
| 47 |
+
<div class="text-center">
|
| 48 |
+
<h1 class="text-4xl font-bold text-white mb-4" data-aos="fade-up">Premium Services</h1>
|
| 49 |
+
<p class="text-xl text-gray-300 max-w-2xl mx-auto" data-aos="fade-up" data-aos-delay="100">Expert care for your Japanese performance vehicle</p>
|
| 50 |
+
</div>
|
| 51 |
+
</div>
|
| 52 |
+
</div>
|
| 53 |
+
|
| 54 |
+
<!-- Services Tabs -->
|
| 55 |
+
<section class="py-12 bg-white">
|
| 56 |
+
<div class="container mx-auto px-4">
|
| 57 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-2 text-center">Our Services</h2>
|
| 58 |
+
<p class="text-gray-600 text-center mb-10 max-w-3xl mx-auto">From routine maintenance to performance upgrades, our certified technicians provide exceptional service for your Japanese vehicle.</p>
|
| 59 |
+
|
| 60 |
+
<div class="flex flex-wrap justify-center gap-4 mb-12">
|
| 61 |
+
<button class="service-tab active px-6 py-3 rounded-full border border-gray-300 hover:bg-red-500 hover:text-white transition duration-300" data-service="maintenance">
|
| 62 |
+
<i data-feather="settings" class="w-5 h-5 inline mr-2"></i> Maintenance
|
| 63 |
+
</button>
|
| 64 |
+
<button class="service-tab px-6 py-3 rounded-full border border-gray-300 hover:bg-red-500 hover:text-white transition duration-300" data-service="repairs">
|
| 65 |
+
<i data-feather="tool" class="w-5 h-5 inline mr-2"></i> Repairs
|
| 66 |
+
</button>
|
| 67 |
+
<button class="service-tab px-6 py-3 rounded-full border border-gray-300 hover:bg-red-500 hover:text-white transition duration-300" data-service="performance">
|
| 68 |
+
<i data-feather="zap" class="w-5 h-5 inline mr-2"></i> Performance
|
| 69 |
+
</button>
|
| 70 |
+
<button class="service-tab px-6 py-3 rounded-full border border-gray-300 hover:bg-red-500 hover:text-white transition duration-300" data-service="detailing">
|
| 71 |
+
<i data-feather="star" class="w-5 h-5 inline mr-2"></i> Detailing
|
| 72 |
+
</button>
|
| 73 |
+
</div>
|
| 74 |
+
|
| 75 |
+
<!-- Maintenance Services -->
|
| 76 |
+
<div id="maintenance" class="service-content active">
|
| 77 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
| 78 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6" data-aos="fade-up">
|
| 79 |
+
<div class="text-red-500 mb-4">
|
| 80 |
+
<i data-feather="refresh-cw" class="w-12 h-12"></i>
|
| 81 |
+
</div>
|
| 82 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Oil Change Service</h3>
|
| 83 |
+
<p class="text-gray-600 mb-4">Complete oil and filter change using premium synthetic oils specifically formulated for Japanese performance engines.</p>
|
| 84 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 85 |
+
<li class="flex items-start">
|
| 86 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 87 |
+
<span>Full synthetic oil change</span>
|
| 88 |
+
</li>
|
| 89 |
+
<li class="flex items-start">
|
| 90 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 91 |
+
<span>OEM oil filter replacement</span>
|
| 92 |
+
</li>
|
| 93 |
+
<li class="flex items-start">
|
| 94 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 95 |
+
<span>Multi-point inspection</span>
|
| 96 |
+
</li>
|
| 97 |
+
</ul>
|
| 98 |
+
<div class="flex justify-between items-center">
|
| 99 |
+
<span class="text-2xl font-bold text-red-500">From $89</span>
|
| 100 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 101 |
+
Book Now
|
| 102 |
+
</button>
|
| 103 |
+
</div>
|
| 104 |
+
</div>
|
| 105 |
+
|
| 106 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6" data-aos="fade-up" data-aos-delay="100">
|
| 107 |
+
<div class="text-red-500 mb-4">
|
| 108 |
+
<i data-feather="clipboard" class="w-12 h-12"></i>
|
| 109 |
+
</div>
|
| 110 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Scheduled Maintenance</h3>
|
| 111 |
+
<p class="text-gray-600 mb-4">Factory-recommended service intervals to keep your vehicle performing at its best and maintain warranty coverage.</p>
|
| 112 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 113 |
+
<li class="flex items-start">
|
| 114 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 115 |
+
<span>30,000/60,000/90,000 mile services</span>
|
| 116 |
+
</li>
|
| 117 |
+
<li class="flex items-start">
|
| 118 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 119 |
+
<span>Fluid changes and inspections</span>
|
| 120 |
+
</li>
|
| 121 |
+
<li class="flex items-start">
|
| 122 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 123 |
+
<span>Comprehensive vehicle health report</span>
|
| 124 |
+
</li>
|
| 125 |
+
</ul>
|
| 126 |
+
<div class="flex justify-between items-center">
|
| 127 |
+
<span class="text-2xl font-bold text-red-500">From $249</span>
|
| 128 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 129 |
+
Book Now
|
| 130 |
+
</button>
|
| 131 |
+
</div>
|
| 132 |
+
</div>
|
| 133 |
+
|
| 134 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6" data-aos="fade-up" data-aos-delay="200">
|
| 135 |
+
<div class="text-red-500 mb-4">
|
| 136 |
+
<i data-feather="rotate-cw" class="w-12 h-12"></i>
|
| 137 |
+
</div>
|
| 138 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Brake Service</h3>
|
| 139 |
+
<p class="text-gray-600 mb-4">Complete brake inspection and service to ensure your safety and optimal stopping performance.</p>
|
| 140 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 141 |
+
<li class="flex items-start">
|
| 142 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 143 |
+
<span>Brake pad replacement</span>
|
| 144 |
+
</li>
|
| 145 |
+
<li class="flex items-start">
|
| 146 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 147 |
+
<span>Rotor resurfacing or replacement</span>
|
| 148 |
+
</li>
|
| 149 |
+
<li class="flex items-start">
|
| 150 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 151 |
+
<span>Brake fluid flush</span>
|
| 152 |
+
</li>
|
| 153 |
+
</ul>
|
| 154 |
+
<div class="flex justify-between items-center">
|
| 155 |
+
<span class="text-2xl font-bold text-red-500">From $199</span>
|
| 156 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 157 |
+
Book Now
|
| 158 |
+
</button>
|
| 159 |
+
</div>
|
| 160 |
+
</div>
|
| 161 |
+
</div>
|
| 162 |
+
</div>
|
| 163 |
+
|
| 164 |
+
<!-- Repair Services -->
|
| 165 |
+
<div id="repairs" class="service-content">
|
| 166 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
| 167 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6">
|
| 168 |
+
<div class="text-red-500 mb-4">
|
| 169 |
+
<i data-feather="alert-circle" class="w-12 h-12"></i>
|
| 170 |
+
</div>
|
| 171 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Engine Repair</h3>
|
| 172 |
+
<p class="text-gray-600 mb-4">Expert diagnosis and repair of engine issues, from minor tune-ups to major overhauls.</p>
|
| 173 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 174 |
+
<li class="flex items-start">
|
| 175 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 176 |
+
<span>Diagnostic testing</span>
|
| 177 |
+
</li>
|
| 178 |
+
<li class="flex items-start">
|
| 179 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 180 |
+
<span>Timing belt replacement</span>
|
| 181 |
+
</li>
|
| 182 |
+
<li class="flex items-start">
|
| 183 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 184 |
+
<span>Engine rebuilds</span>
|
| 185 |
+
</li>
|
| 186 |
+
</ul>
|
| 187 |
+
<div class="flex justify-between items-center">
|
| 188 |
+
<span class="text-2xl font-bold text-red-500">From $299</span>
|
| 189 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 190 |
+
Book Now
|
| 191 |
+
</button>
|
| 192 |
+
</div>
|
| 193 |
+
</div>
|
| 194 |
+
|
| 195 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6">
|
| 196 |
+
<div class="text-red-500 mb-4">
|
| 197 |
+
<i data-feather="cpu" class="w-12 h-12"></i>
|
| 198 |
+
</div>
|
| 199 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Transmission Service</h3>
|
| 200 |
+
<p class="text-gray-600 mb-4">Specialized service for manual, automatic, and CVT transmissions found in Japanese performance vehicles.</p>
|
| 201 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 202 |
+
<li class="flex items-start">
|
| 203 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 204 |
+
<span>Transmission fluid change</span>
|
| 205 |
+
</li>
|
| 206 |
+
<li class="flex items start">
|
| 207 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 208 |
+
<span>Clutch replacement</span>
|
| 209 |
+
</li>
|
| 210 |
+
<li class="flex items-start">
|
| 211 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 212 |
+
<span>Transmission rebuild</span>
|
| 213 |
+
</li>
|
| 214 |
+
</ul>
|
| 215 |
+
<div class="flex justify-between items-center">
|
| 216 |
+
<span class="text-2xl font-bold text-red-500">From $349</span>
|
| 217 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 218 |
+
Book Now
|
| 219 |
+
</button>
|
| 220 |
+
</div>
|
| 221 |
+
</div>
|
| 222 |
+
|
| 223 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6">
|
| 224 |
+
<div class="text-red-500 mb-4">
|
| 225 |
+
<i data-feather="battery" class="w-12 h-12"></i>
|
| 226 |
+
</div>
|
| 227 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Electrical Systems</h3>
|
| 228 |
+
<p class="text-gray-600 mb-4">Diagnosis and repair of complex electrical systems in modern Japanese vehicles.</p>
|
| 229 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 230 |
+
<li class="flex items-start">
|
| 231 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 232 |
+
<span>Battery replacement</span>
|
| 233 |
+
</li>
|
| 234 |
+
<li class="flex items-start">
|
| 235 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 236 |
+
<span>Alternator and starter service</span>
|
| 237 |
+
</li>
|
| 238 |
+
<li class="flex items-start">
|
| 239 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 240 |
+
<span>Wiring diagnostics</span>
|
| 241 |
+
</li>
|
| 242 |
+
</ul>
|
| 243 |
+
<div class="flex justify-between items-center">
|
| 244 |
+
<span class="text-2xl font-bold text-red-500">From $159</span>
|
| 245 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 246 |
+
Book Now
|
| 247 |
+
</button>
|
| 248 |
+
</div>
|
| 249 |
+
</div>
|
| 250 |
+
</div>
|
| 251 |
+
</div>
|
| 252 |
+
|
| 253 |
+
<!-- Performance Services -->
|
| 254 |
+
<div id="performance" class="service-content">
|
| 255 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
| 256 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6">
|
| 257 |
+
<div class="text-red-500 mb-4">
|
| 258 |
+
<i data-feather="bar-chart-2" class="w-12 h-12"></i>
|
| 259 |
+
</div>
|
| 260 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">ECU Tuning</h3>
|
| 261 |
+
<p class="text-gray-600 mb-4">Custom engine tuning to unlock hidden performance while maintaining reliability.</p>
|
| 262 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 263 |
+
<li class="flex items-start">
|
| 264 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 265 |
+
<span>Dyno tuning sessions</span>
|
| 266 |
+
</li>
|
| 267 |
+
<li class="flex items-start">
|
| 268 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 269 |
+
<span>Custom ECU mapping</span>
|
| 270 |
+
</li>
|
| 271 |
+
<li class="flex items-start">
|
| 272 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 273 |
+
<span>Performance optimization</span>
|
| 274 |
+
</li>
|
| 275 |
+
</ul>
|
| 276 |
+
<div class="flex justify-between items-center">
|
| 277 |
+
<span class="text-2xl font-bold text-red-500">From $499</span>
|
| 278 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 279 |
+
Book Now
|
| 280 |
+
</button>
|
| 281 |
+
</div>
|
| 282 |
+
</div>
|
| 283 |
+
|
| 284 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6">
|
| 285 |
+
<div class="text-red-500 mb-4">
|
| 286 |
+
<i data-feather="wind" class="w-12 h-12"></i>
|
| 287 |
+
</div>
|
| 288 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Turbocharger Services</h3>
|
| 289 |
+
<p class="text-gray-600 mb-4">Installation, maintenance, and upgrade services for turbocharged vehicles.</p>
|
| 290 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 291 |
+
<li class="flex items-start">
|
| 292 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 293 |
+
<span>Turbo installation</span>
|
| 294 |
+
</li>
|
| 295 |
+
<li class="flex items-start">
|
| 296 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 297 |
+
<span>Turbo rebuilds</span>
|
| 298 |
+
</li>
|
| 299 |
+
<li class="flex items-start">
|
| 300 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 301 |
+
<span>Intercooler upgrades</span>
|
| 302 |
+
</li>
|
| 303 |
+
</ul>
|
| 304 |
+
<div class="flex justify-between items-center">
|
| 305 |
+
<span class="text-2xl font-bold text-red-500">From $799</span>
|
| 306 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 307 |
+
Book Now
|
| 308 |
+
</button>
|
| 309 |
+
</div>
|
| 310 |
+
</div>
|
| 311 |
+
|
| 312 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6">
|
| 313 |
+
<div class="text-red-500 mb-4">
|
| 314 |
+
<i data-feather="sliders" class="w-12 h-12"></i>
|
| 315 |
+
</div>
|
| 316 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Suspension Upgrades</h3>
|
| 317 |
+
<p class="text-gray-600 mb-4">Performance suspension systems to improve handling and driving dynamics.</p>
|
| 318 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 319 |
+
<li class="flex items-start">
|
| 320 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 321 |
+
<span>Coilover installation</span>
|
| 322 |
+
</li>
|
| 323 |
+
<li class="flex items-start">
|
| 324 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 325 |
+
<span>Alignment and corner balancing</span>
|
| 326 |
+
</li>
|
| 327 |
+
<li class="flex items-start">
|
| 328 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 329 |
+
<span>Handling packages</span>
|
| 330 |
+
</li>
|
| 331 |
+
</ul>
|
| 332 |
+
<div class="flex justify-between items-center">
|
| 333 |
+
<span class="text-2xl font-bold text-red-500">From $599</span>
|
| 334 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 335 |
+
Book Now
|
| 336 |
+
</button>
|
| 337 |
+
</div>
|
| 338 |
+
</div>
|
| 339 |
+
</div>
|
| 340 |
+
</div>
|
| 341 |
+
|
| 342 |
+
<!-- Detailing Services -->
|
| 343 |
+
<div id="detailing" class="service-content">
|
| 344 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
| 345 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6">
|
| 346 |
+
<div class="text-red-500 mb-4">
|
| 347 |
+
<i data-feather="droplet" class="w-12 h-12"></i>
|
| 348 |
+
</div>
|
| 349 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Premium Detailing</h3>
|
| 350 |
+
<p class="text-gray-600 mb-4">Showroom-quality detailing to restore and protect your vehicle's appearance.</p>
|
| 351 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 352 |
+
<li class="flex items-start">
|
| 353 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 354 |
+
<span>Paint correction</span>
|
| 355 |
+
</li>
|
| 356 |
+
<li class="flex items-start">
|
| 357 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 358 |
+
<span>Ceramic coating</span>
|
| 359 |
+
</li>
|
| 360 |
+
<li class="flex items-start">
|
| 361 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 362 |
+
<span>Interior deep cleaning</span>
|
| 363 |
+
</li>
|
| 364 |
+
</ul>
|
| 365 |
+
<div class="flex justify-between items-center">
|
| 366 |
+
<span class="text-2xl font-bold text-red-500">From $299</span>
|
| 367 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 368 |
+
Book Now
|
| 369 |
+
</button>
|
| 370 |
+
</div>
|
| 371 |
+
</div>
|
| 372 |
+
|
| 373 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6">
|
| 374 |
+
<div class="text-red-500 mb-4">
|
| 375 |
+
<i data-feather="shield" class="w-12 h-12"></i>
|
| 376 |
+
</div>
|
| 377 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Paint Protection</h3>
|
| 378 |
+
<p class="text-gray-600 mb-4">Advanced protection solutions to keep your vehicle looking new for years to come.</p>
|
| 379 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 380 |
+
<li class="flex items-start">
|
| 381 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 382 |
+
<span>Paint protection film</span>
|
| 383 |
+
</li>
|
| 384 |
+
<li class="flex items-start">
|
| 385 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 386 |
+
<span>Ceramic coating pro</span>
|
| 387 |
+
</li>
|
| 388 |
+
<li class="flex items-start">
|
| 389 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 390 |
+
<span>Window tinting</span>
|
| 391 |
+
</li>
|
| 392 |
+
</ul>
|
| 393 |
+
<div class="flex justify-between items-center">
|
| 394 |
+
<span class="text-2xl font-bold text-red-500">From $999</span>
|
| 395 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 396 |
+
Book Now
|
| 397 |
+
</button>
|
| 398 |
+
</div>
|
| 399 |
+
</div>
|
| 400 |
+
|
| 401 |
+
<div class="service-card bg-white rounded-lg overflow-hidden shadow-md transition duration-300 p-6">
|
| 402 |
+
<div class="text-red-500 mb-4">
|
| 403 |
+
<i data-feather="umbrella" class="w-12 h-12"></i>
|
| 404 |
+
</div>
|
| 405 |
+
<h3 class="text-xl font-bold text-gray-800 mb-3">Interior Renewal</h3>
|
| 406 |
+
<p class="text-gray-600 mb-4">Complete interior restoration and protection services.</p>
|
| 407 |
+
<ul class="text-gray-700 mb-6 space-y-2">
|
| 408 |
+
<li class="flex items-start">
|
| 409 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 410 |
+
<span>Leather conditioning</span>
|
| 411 |
+
</li>
|
| 412 |
+
<li class="flex items-start">
|
| 413 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 414 |
+
<span>Fabric protection</span>
|
| 415 |
+
</li>
|
| 416 |
+
<li class="flex items-start">
|
| 417 |
+
<i data-feather="check" class="text-green-500 mr-2 mt-1"></i>
|
| 418 |
+
<span>Odor elimination</span>
|
| 419 |
+
</li>
|
| 420 |
+
</ul>
|
| 421 |
+
<div class="flex justify-between items-center">
|
| 422 |
+
<span class="text-2xl font-bold text-red-500">From $199</span>
|
| 423 |
+
<button class="book-now-btn bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-300">
|
| 424 |
+
Book Now
|
| 425 |
+
</button>
|
| 426 |
+
</div>
|
| 427 |
+
</div>
|
| 428 |
+
</div>
|
| 429 |
+
</div>
|
| 430 |
+
</div>
|
| 431 |
+
</section>
|
| 432 |
+
|
| 433 |
+
<!-- Booking Modal -->
|
| 434 |
+
<div id="bookingModal" class="modal-overlay">
|
| 435 |
+
<div class="modal-container">
|
| 436 |
+
<div class="p-6">
|
| 437 |
+
<div class="flex justify-between items-center pb-4 border-b">
|
| 438 |
+
<h3 class="text-2xl font-bold text-gray-800">Book Service</h3>
|
| 439 |
+
<button id="closeModal" class="text-gray-500 hover:text-gray-700">
|
| 440 |
+
<i data-feather="x" class="w-6 h-6"></i>
|
| 441 |
+
</button>
|
| 442 |
+
</div>
|
| 443 |
+
|
| 444 |
+
<form id="bookingForm" class="mt-4 space-y-4">
|
| 445 |
+
<input type="hidden" id="serviceTypeInput" name="service_type">
|
| 446 |
+
<input type="hidden" id="serviceNameInput" name="service_name">
|
| 447 |
+
|
| 448 |
+
<div>
|
| 449 |
+
<label for="customer_name" class="block text-sm font-medium text-gray-700">Full Name *</label>
|
| 450 |
+
<input type="text" id="customer_name" name="customer_name" required
|
| 451 |
+
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-red-500 focus:border-red-500">
|
| 452 |
+
</div>
|
| 453 |
+
|
| 454 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
| 455 |
+
<div>
|
| 456 |
+
<label for="email" class="block text-sm font-medium text-gray-700">Email *</label>
|
| 457 |
+
<input type="email" id="email" name="email" required
|
| 458 |
+
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-red-500 focus:border-red-500">
|
| 459 |
+
</div>
|
| 460 |
+
|
| 461 |
+
<div>
|
| 462 |
+
<label for="phone" class="block text-sm font-medium text-gray-700">Phone *</label>
|
| 463 |
+
<input type="tel" id="phone" name="phone" required
|
| 464 |
+
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-red-500 focus:border-red-500">
|
| 465 |
+
</div>
|
| 466 |
+
</div>
|
| 467 |
+
|
| 468 |
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
| 469 |
+
<div>
|
| 470 |
+
<label for="vehicle_make" class="block text-sm font-medium text-gray-700">Vehicle Make *</label>
|
| 471 |
+
<select id="vehicle_make" name="vehicle_make" required
|
| 472 |
+
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-red-500 focus:border-red-500">
|
| 473 |
+
<option value="">Select Make</option>
|
| 474 |
+
<option value="Toyota">Toyota</option>
|
| 475 |
+
<option value="Honda">Honda</option>
|
| 476 |
+
<option value="Nissan">Nissan</option>
|
| 477 |
+
<option value="Mazda">Mazda</option>
|
| 478 |
+
<option value="Subaru">Subaru</option>
|
| 479 |
+
<option value="Mitsubishi">Mitsubishi</option>
|
| 480 |
+
<option value="Lexus">Lexus</option>
|
| 481 |
+
<option value="Acura">Acura</option>
|
| 482 |
+
<option value="Infiniti">Infiniti</option>
|
| 483 |
+
<option value="Other">Other</option>
|
| 484 |
+
</select>
|
| 485 |
+
</div>
|
| 486 |
+
|
| 487 |
+
<div>
|
| 488 |
+
<label for="vehicle_model" class="block text-sm font-medium text-gray-700">Model *</label>
|
| 489 |
+
<input type="text" id="vehicle_model" name="vehicle_model" required
|
| 490 |
+
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-red-500 focus:border-red-500">
|
| 491 |
+
</div>
|
| 492 |
+
|
| 493 |
+
<div>
|
| 494 |
+
<label for="vehicle_year" class="block text-sm font-medium text-gray-700">Year</label>
|
| 495 |
+
<input type="number" id="vehicle_year" name="vehicle_year" min="1990" max="2030"
|
| 496 |
+
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-red-500 focus:border-red-500">
|
| 497 |
+
</div>
|
| 498 |
+
</div>
|
| 499 |
+
|
| 500 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
| 501 |
+
<div>
|
| 502 |
+
<label for="preferred_date" class="block text-sm font-medium text-gray-700">Preferred Date</label>
|
| 503 |
+
<input type="date" id="preferred_date" name="preferred_date" min="<?php echo date('Y-m-d'); ?>"
|
| 504 |
+
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-red-500 focus:border-red-500">
|
| 505 |
+
</div>
|
| 506 |
+
|
| 507 |
+
<div>
|
| 508 |
+
<label for="preferred_time" class="block text-sm font-medium text-gray-700">Preferred Time</label>
|
| 509 |
+
<select id="preferred_time" name="preferred_time"
|
| 510 |
+
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-red-500 focus:border-red-500">
|
| 511 |
+
<option value="">Any Time</option>
|
| 512 |
+
<option value="08:00:00">8:00 AM</option>
|
| 513 |
+
<option value="09:00:00">9:00 AM</option>
|
| 514 |
+
<option value="10:00:00">10:00 AM</option>
|
| 515 |
+
<option value="11:00:00">11:00 AM</option>
|
| 516 |
+
<option value="13:00:00">1:00 PM</option>
|
| 517 |
+
<option value="14:00:00">2:00 PM</option>
|
| 518 |
+
<option value="15:00:00">3:00 PM</option>
|
| 519 |
+
<option value="16:00:00">4:00 PM</option>
|
| 520 |
+
</select>
|
| 521 |
+
</div>
|
| 522 |
+
</div>
|
| 523 |
+
|
| 524 |
+
<div>
|
| 525 |
+
<label for="message" class="block text-sm font-medium text-gray-700">Additional Notes</label>
|
| 526 |
+
<textarea id="message" name="message" rows="3"
|
| 527 |
+
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-red-500 focus:border-red-500"></textarea>
|
| 528 |
+
</div>
|
| 529 |
+
|
| 530 |
+
<div class="pt-4 border-t">
|
| 531 |
+
<button type="submit" class="w-full bg-red-500 hover:bg-red-600 text-white font-bold py-3 px-4 rounded-md transition duration-300">
|
| 532 |
+
Confirm Booking
|
| 533 |
+
</button>
|
| 534 |
+
</div>
|
| 535 |
+
</form>
|
| 536 |
+
</div>
|
| 537 |
+
</div>
|
| 538 |
+
</div>
|
| 539 |
+
|
| 540 |
+
<!-- Notification Toast -->
|
| 541 |
+
<div id="notification" class="notification">
|
| 542 |
+
<span id="notificationIcon" class="mr-3"></span>
|
| 543 |
+
<p id="notificationMessage" class="text-white"></p>
|
| 544 |
+
</div>
|
| 545 |
+
|
| 546 |
+
<!-- Why Choose Us -->
|
| 547 |
+
<section class="py-16 bg-gray-100">
|
| 548 |
+
<div class="container mx-auto px-4">
|
| 549 |
+
<div class="text-center mb-12">
|
| 550 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-4">Why Choose Japanese Motors</h2>
|
| 551 |
+
<div class="w-20 h-1 bg-red-500 mx-auto"></div>
|
| 552 |
+
</div>
|
| 553 |
+
|
| 554 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
|
| 555 |
+
<div class="text-center" data-aos="fade-up">
|
| 556 |
+
<div class="bg-red-100 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4">
|
| 557 |
+
<i data-feather="award" class="w-10 h-10 text-red-500"></i>
|
| 558 |
+
</div>
|
| 559 |
+
<h3 class="text-xl font-bold text-gray-800 mb-2">Certified Technicians</h3>
|
| 560 |
+
<p class="text-gray-600">Our technicians are factory-trained and certified to work on Japanese performance vehicles.</p>
|
| 561 |
+
</div>
|
| 562 |
+
|
| 563 |
+
<div class="text-center" data-aos="fade-up" data-aos-delay="100">
|
| 564 |
+
<div class="bg-red-100 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4">
|
| 565 |
+
<i data-feather="tool" class="w-10 h-10 text-red-500"></i>
|
| 566 |
+
</div>
|
| 567 |
+
<h3 class="text-xl font-bold text-gray-800 mb-2">Genuine Parts</h3>
|
| 568 |
+
<p class="text-gray-600">We use only genuine OEM parts or premium aftermarket equivalents for all repairs.</p>
|
| 569 |
+
</div>
|
| 570 |
+
|
| 571 |
+
<div class="text-center" data-aos="fade-up" data-aos-delay="200">
|
| 572 |
+
<div class="bg-red-100 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4">
|
| 573 |
+
<i data-feather="clock" class="w-10 h-10 text-red-500"></i>
|
| 574 |
+
</div>
|
| 575 |
+
<h3 class="text-xl font-bold text-gray-800 mb-2">Quick Turnaround</h3>
|
| 576 |
+
<p class="text-gray-600">Most services completed same-day with our efficient workflow and ample resources.</p>
|
| 577 |
+
</div>
|
| 578 |
+
|
| 579 |
+
<div class="text-center" data-aos="fade-up" data-aos-delay="300">
|
| 580 |
+
<div class="bg-red-100 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4">
|
| 581 |
+
<i data-feather="dollar-sign" class="w-10 h-10 text-red-500"></i>
|
| 582 |
+
</div>
|
| 583 |
+
<h3 class="text-xl font-bold text-gray-800 mb-2">Fair Pricing</h3>
|
| 584 |
+
<p class="text-gray-600">Competitive pricing with no hidden fees and upfront estimates for all work.</p>
|
| 585 |
+
</div>
|
| 586 |
+
</div>
|
| 587 |
+
</div>
|
| 588 |
+
</section>
|
| 589 |
+
|
| 590 |
+
<!-- FAQ Section -->
|
| 591 |
+
<section class="py-16 bg-white">
|
| 592 |
+
<div class="container mx-auto px-4">
|
| 593 |
+
<div class="text-center mb-12">
|
| 594 |
+
<h2 class="text-3xl font-bold text-gray-800 mb-4">Frequently Asked Questions</h2>
|
| 595 |
+
<div class="w-20 h-1 bg-red-500 mx-auto"></div>
|
| 596 |
+
</div>
|
| 597 |
+
|
| 598 |
+
<div class="max-w-3xl mx-auto">
|
| 599 |
+
<div class="accordion-item border-b border-gray-200 py-4">
|
| 600 |
+
<button class="accordion-button w-full flex justify-between items-center text-left font-medium text-gray-800 hover:text-red-500">
|
| 601 |
+
<span>How often should I service my Japanese performance vehicle?</span>
|
| 602 |
+
<i data-feather="chevron-down" class="w-5 h-5 text-red-500 transition-transform"></i>
|
| 603 |
+
</button>
|
| 604 |
+
<div class="accordion-content mt-2">
|
| 605 |
+
<p class="text-gray-600">We recommend following the manufacturer's scheduled maintenance intervals, typically every 5,000-7,500 miles for oil changes and every 30,000 miles for major services. Performance vehicles driven hard may require more frequent servicing.</p>
|
| 606 |
+
</div>
|
| 607 |
+
</div>
|
| 608 |
+
|
| 609 |
+
<div class="accordion-item border-b border-gray-200 py-4">
|
| 610 |
+
<button class="accordion-button w-full flex justify-between items-center text-left font-medium text-gray-800 hover:text-red-500">
|
| 611 |
+
<span>Do you offer warranty on your services?</span>
|
| 612 |
+
<i data-feather="chevron-down" class="w-5 h-5 text-red-500 transition-transform"></i>
|
| 613 |
+
</button>
|
| 614 |
+
<div class="accordion-content mt-2">
|
| 615 |
+
<p class="text-gray-600">Yes, all our services come with a warranty. Parts and labor are typically covered for 12 months/12,000 miles. Specific warranty terms may vary by service type - details are provided with every estimate.</p>
|
| 616 |
+
</div>
|
| 617 |
+
</div>
|
| 618 |
+
|
| 619 |
+
<div class="accordion-item border-b border-gray-200 py-4">
|
| 620 |
+
<button class="accordion-button w-full flex justify-between items-center text-left font-medium text-gray-800 hover:text-red-500">
|
| 621 |
+
<span>Can I bring my own parts?</span>
|
| 622 |
+
<i data-feather="chevron-down" class="w-5 h-5 text-red-500 transition-transform"></i>
|
| 623 |
+
</button>
|
| 624 |
+
<div class="accordion-content mt-2">
|
| 625 |
+
<p class="text-gray-600">While we prefer to source parts ourselves to ensure quality and compatibility, we can install customer-provided parts. However, the warranty would only cover labor, not the parts themselves.</p>
|
| 626 |
+
</div>
|
| 627 |
+
</div>
|
| 628 |
+
|
| 629 |
+
<div class="accordion-item border-b border-gray-200 py-4">
|
| 630 |
+
<button class="accordion-button w-full flex justify-between items-center text-left font-medium text-gray-800 hover:text-red-500">
|
| 631 |
+
<span>How long do typical services take?</span>
|
| 632 |
+
<i data-feather="chevron-down" class="w-5 h-5 text-red-500 transition-transform"></i>
|
| 633 |
+
</button>
|
| 634 |
+
<div class="accordion-content mt-2">
|
| 635 |
+
<p class="text-gray-600">Most maintenance services can be completed within 2-3 hours. Larger repairs may take a day or more depending on complexity. We offer loaner vehicles and shuttle service for extended repairs.</p>
|
| 636 |
+
</div>
|
| 637 |
+
</div>
|
| 638 |
+
|
| 639 |
+
<div class="accordion-item border-b border-gray-200 py-4">
|
| 640 |
+
<button class="accordion-button w-full flex justify-between items-center text-left font-medium text-gray-800 hover:text-red-500">
|
| 641 |
+
<span>Do you work on all Japanese brands?</span>
|
| 642 |
+
<i data-feather="chevron-down" class="w-5 h-5 text-red-500 transition-transform"></i>
|
| 643 |
+
</button>
|
| 644 |
+
<div class="accordion-content mt-2">
|
| 645 |
+
<p class="text-gray-600">Yes, we specialize in all Japanese performance brands including Toyota, Nissan, Honda, Mazda, Subaru, Mitsubishi, Lexus, Acura, and Infiniti. Our technicians have specific expertise with performance models from these manufacturers.</p>
|
| 646 |
+
</div>
|
| 647 |
+
</div>
|
| 648 |
+
</div>
|
| 649 |
+
</div>
|
| 650 |
+
</section>
|
| 651 |
+
|
| 652 |
+
<!-- Call to Action -->
|
| 653 |
+
<section class="py-16 bg-red-500 text-white">
|
| 654 |
+
<div class="container mx-auto px-4 text-center">
|
| 655 |
+
<h2 class="text-3xl font-bold mb-6">Ready to Service Your Vehicle?</h2>
|
| 656 |
+
<p class="text-xl mb-8 max-w-2xl mx-auto">Schedule your appointment today and experience the Japanese Motors difference.</p>
|
| 657 |
+
<div class="flex flex-col sm:flex-row justify-center gap-4">
|
| 658 |
+
<a href="contact.html" class="bg-white text-red-500 px-8 py-3 rounded-md font-bold transition duration-300 hover:bg-gray-100">
|
| 659 |
+
Schedule Appointment
|
| 660 |
+
</a>
|
| 661 |
+
<a href="tel:+254794330243" class="border-2 border-white text-white px-8 py-3 rounded-md font-bold transition duration-300 hover:bg-white hover:text-red-500">
|
| 662 |
+
<i data-feather="phone" class="w-5 h-5 inline mr-2"></i> Call Now
|
| 663 |
+
</a>
|
| 664 |
+
</div>
|
| 665 |
+
</div>
|
| 666 |
+
</section>
|
| 667 |
+
|
| 668 |
+
<!-- Footer -->
|
| 669 |
+
<footer class="bg-gray-900 text-white py-12">
|
| 670 |
+
<div class="container mx-auto px-4">
|
| 671 |
+
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
| 672 |
+
<div>
|
| 673 |
+
<h3 class="text-xl font-bold mb-4">Japanese Motors</h3>
|
| 674 |
+
<p class="text-gray-400">Premium Japanese performance vehicles imported directly from Japan.</p>
|
| 675 |
+
</div>
|
| 676 |
+
<div>
|
| 677 |
+
<h3 class="text-lg font-bold mb-4">Quick Links</h3>
|
| 678 |
+
<ul class="space-y-2">
|
| 679 |
+
<li><a href="../index.html" class="text-gray-400 hover:text-red-500">Home</a></li>
|
| 680 |
+
<li><a href="gallery.html" class="text-gray-400 hover:text-red-500">Inventory</a></li>
|
| 681 |
+
<li><a href="services.html" class="text-gray-400 hover:text-red-500">Services</a></li>
|
| 682 |
+
<li><a href="about.html" class="text-gray-400 hover:text-red-500">About Us</a></li>
|
| 683 |
+
<li><a href="contact.html" class="text-gray-400 hover:text-red-500">Contact</a></li>
|
| 684 |
+
</ul>
|
| 685 |
+
</div>
|
| 686 |
+
<div>
|
| 687 |
+
<h3 class="text-lg font-bold mb-4">Contact Info</h3>
|
| 688 |
+
<ul class="space-y-2">
|
| 689 |
+
<li class="flex items-center">
|
| 690 |
+
<i data-feather="map-pin" class="mr-2 w-4 h-4"></i>
|
| 691 |
+
<span class="text-gray-400">123 Automotive Way, Tokyo, Japan</span>
|
| 692 |
+
</li>
|
| 693 |
+
<li class="flex items-center">
|
| 694 |
+
<i data-feather="phone" class="mr-2 w-4 h-4"></i>
|
| 695 |
+
<span class="text-gray-400">+254 794 330 243</span>
|
| 696 |
+
</li>
|
| 697 |
+
<li class="flex items-center">
|
| 698 |
+
<i data-feather="mail" class="mr-2 w-4 h-4"></i>
|
| 699 |
+
<span class="text-gray-400">info@japanesemotors.com</span>
|
| 700 |
+
</li>
|
| 701 |
+
</ul>
|
| 702 |
+
</div>
|
| 703 |
+
<div>
|
| 704 |
+
<h3 class="text-lg font-bold mb-4">Follow Us</h3>
|
| 705 |
+
<div class="flex space-x-4">
|
| 706 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="facebook" class="w-6 h-6"></i></a>
|
| 707 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="instagram" class="w-6 h-6"></i></a>
|
| 708 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="twitter" class="w-6 h-6"></i></a>
|
| 709 |
+
<a href="#" class="text-gray-400 hover:text-red-500"><i data-feather="youtube" class="w-6 h-6"></i></a>
|
| 710 |
+
</div>
|
| 711 |
+
</div>
|
| 712 |
+
</div>
|
| 713 |
+
<div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-400">
|
| 714 |
+
<p>© 2023 Japanese Motors. All rights reserved.</p>
|
| 715 |
+
</div>
|
| 716 |
+
</div>
|
| 717 |
+
</footer>
|
| 718 |
+
|
| 719 |
+
<script>
|
| 720 |
+
// Initialize Feather Icons and AOS
|
| 721 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 722 |
+
feather.replace();
|
| 723 |
+
AOS.init();
|
| 724 |
+
|
| 725 |
+
// Service tabs functionality
|
| 726 |
+
const serviceTabs = document.querySelectorAll('.service-tab');
|
| 727 |
+
const serviceContents = document.querySelectorAll('.service-content');
|
| 728 |
+
|
| 729 |
+
serviceTabs.forEach(tab => {
|
| 730 |
+
tab.addEventListener('click', function() {
|
| 731 |
+
// Remove active class from all tabs
|
| 732 |
+
serviceTabs.forEach(t => t.classList.remove('active', 'bg-red-500', 'text-white'));
|
| 733 |
+
|
| 734 |
+
// Add active class to clicked tab
|
| 735 |
+
this.classList.add('active', 'bg-red-500', 'text-white');
|
| 736 |
+
|
| 737 |
+
// Hide all service contents
|
| 738 |
+
serviceContents.forEach(content => content.classList.remove('active'));
|
| 739 |
+
|
| 740 |
+
// Show the selected service content
|
| 741 |
+
const serviceType = this.getAttribute('data-service');
|
| 742 |
+
document.getElementById(serviceType).classList.add('active');
|
| 743 |
+
});
|
| 744 |
+
});
|
| 745 |
+
|
| 746 |
+
// Booking modal functionality
|
| 747 |
+
const bookingModal = document.getElementById('bookingModal');
|
| 748 |
+
const bookingForm = document.getElementById('bookingForm');
|
| 749 |
+
const closeModalBtn = document.getElementById('closeModal');
|
| 750 |
+
const notification = document.getElementById('notification');
|
| 751 |
+
|
| 752 |
+
// Store service info when Book Now is clicked
|
| 753 |
+
document.querySelectorAll('.book-now-btn').forEach(button => {
|
| 754 |
+
button.addEventListener('click', function() {
|
| 755 |
+
const card = this.closest('.service-card');
|
| 756 |
+
const serviceName = card.querySelector('h3').textContent;
|
| 757 |
+
const serviceContent = card.closest('.service-content');
|
| 758 |
+
const serviceType = serviceContent ? serviceContent.id : 'maintenance';
|
| 759 |
+
|
| 760 |
+
document.getElementById('serviceTypeInput').value = serviceType;
|
| 761 |
+
document.getElementById('serviceNameInput').value = serviceName;
|
| 762 |
+
|
| 763 |
+
bookingModal.classList.add('active');
|
| 764 |
+
document.body.style.overflow = 'hidden';
|
| 765 |
+
});
|
| 766 |
+
});
|
| 767 |
+
|
| 768 |
+
// Close modal
|
| 769 |
+
closeModalBtn.addEventListener('click', function() {
|
| 770 |
+
bookingModal.classList.remove('active');
|
| 771 |
+
document.body.style.overflow = 'auto';
|
| 772 |
+
});
|
| 773 |
+
|
| 774 |
+
// Close modal when clicking outside
|
| 775 |
+
bookingModal.addEventListener('click', function(e) {
|
| 776 |
+
if (e.target === bookingModal) {
|
| 777 |
+
bookingModal.classList.remove('active');
|
| 778 |
+
document.body.style.overflow = 'auto';
|
| 779 |
+
}
|
| 780 |
+
});
|
| 781 |
+
|
| 782 |
+
// Handle form submission
|
| 783 |
+
bookingForm.addEventListener('submit', function(e) {
|
| 784 |
+
e.preventDefault();
|
| 785 |
+
|
| 786 |
+
const formData = new FormData(this);
|
| 787 |
+
|
| 788 |
+
fetch('assets/api/booking_handler.php', {
|
| 789 |
+
method: 'POST',
|
| 790 |
+
body: formData
|
| 791 |
+
})
|
| 792 |
+
.then(response => response.json())
|
| 793 |
+
.then(data => {
|
| 794 |
+
if (data.status === 'success') {
|
| 795 |
+
showNotification(data.message, 'success');
|
| 796 |
+
bookingForm.reset();
|
| 797 |
+
setTimeout(() => {
|
| 798 |
+
bookingModal.classList.remove('active');
|
| 799 |
+
document.body.style.overflow = 'auto';
|
| 800 |
+
}, 2000);
|
| 801 |
+
} else {
|
| 802 |
+
showNotification(data.message, 'error');
|
| 803 |
+
}
|
| 804 |
+
})
|
| 805 |
+
.catch(error => {
|
| 806 |
+
showNotification('An error occurred. Please try again.', 'error');
|
| 807 |
+
console.error('Error:', error);
|
| 808 |
+
});
|
| 809 |
+
});
|
| 810 |
+
|
| 811 |
+
// Show notification function
|
| 812 |
+
function showNotification(message, type) {
|
| 813 |
+
const icon = document.getElementById('notificationIcon');
|
| 814 |
+
const messageEl = document.getElementById('notificationMessage');
|
| 815 |
+
|
| 816 |
+
messageEl.textContent = message;
|
| 817 |
+
|
| 818 |
+
if (type === 'success') {
|
| 819 |
+
notification.className = 'notification success';
|
| 820 |
+
icon.innerHTML = '<i data-feather="check-circle" class="w-6 h-6 text-white"></i>';
|
| 821 |
+
} else {
|
| 822 |
+
notification.className = 'notification error';
|
| 823 |
+
icon.innerHTML = '<i data-feather="alert-circle" class="w-6 h-6 text-white"></i>';
|
| 824 |
+
}
|
| 825 |
+
|
| 826 |
+
notification.style.display = 'flex';
|
| 827 |
+
feather.replace();
|
| 828 |
+
|
| 829 |
+
setTimeout(() => {
|
| 830 |
+
notification.style.display = 'none';
|
| 831 |
+
}, 5000);
|
| 832 |
+
}
|
| 833 |
+
|
| 834 |
+
// FAQ accordion functionality
|
| 835 |
+
const accordionItems = document.querySelectorAll('.accordion-item');
|
| 836 |
+
|
| 837 |
+
accordionItems.forEach(item => {
|
| 838 |
+
const button = item.querySelector('.accordion-button');
|
| 839 |
+
|
| 840 |
+
button.addEventListener('click', function() {
|
| 841 |
+
// Toggle active class on clicked item
|
| 842 |
+
item.classList.toggle('active');
|
| 843 |
+
|
| 844 |
+
// Close other accordion items
|
| 845 |
+
accordionItems.forEach(otherItem => {
|
| 846 |
+
if (otherItem !== item) {
|
| 847 |
+
otherItem.classList.remove('active');
|
| 848 |
+
}
|
| 849 |
+
});
|
| 850 |
+
});
|
| 851 |
+
});
|
| 852 |
+
});
|
| 853 |
+
</script>
|
| 854 |
+
</body>
|
| 855 |
+
</html>
|
jweb/ac1/assets/css/st.css
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
* {
|
| 2 |
+
margin: 0;
|
| 3 |
+
padding: 0;
|
| 4 |
+
box-sizing: border-box;
|
| 5 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
body {
|
| 9 |
+
background: linear-gradient(135deg, #d62828, #f77f00, #fcbf49);
|
| 10 |
+
display: flex;
|
| 11 |
+
justify-content: center;
|
| 12 |
+
align-items: center;
|
| 13 |
+
min-height: 100vh;
|
| 14 |
+
padding: 20px;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
.container {
|
| 18 |
+
width: 100%;
|
| 19 |
+
max-width: 480px;
|
| 20 |
+
background-color: linear-gradient(135deg, #f75c5c, #945e25, #c79b42);
|
| 21 |
+
border-radius: 16px;
|
| 22 |
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
| 23 |
+
overflow: hidden;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
.header {
|
| 27 |
+
background: linear-gradient(135deg, #d62828, #f77f00, #fcbf49);
|
| 28 |
+
color: white;
|
| 29 |
+
padding: 30px;
|
| 30 |
+
text-align: center;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
.logo {
|
| 34 |
+
text-align: center;
|
| 35 |
+
margin-bottom: 30px;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
.logo h1 {
|
| 39 |
+
font-size: 28px;
|
| 40 |
+
font-weight: 700;
|
| 41 |
+
color: #152536;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
.subtitle {
|
| 45 |
+
font-size: 16px;
|
| 46 |
+
opacity: 0.9;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
.form-container {
|
| 50 |
+
padding: 30px;
|
| 51 |
+
background: linear-gradient(135deg, #d62828, #f77f00, #fcbf49);
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
.form-group {
|
| 55 |
+
margin-bottom: 20px;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
label {
|
| 59 |
+
display: block;
|
| 60 |
+
font-size: 14px;
|
| 61 |
+
color: #f8f9fa;
|
| 62 |
+
margin-bottom: 8px;
|
| 63 |
+
font-weight: 500;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
input, select {
|
| 67 |
+
width: 100%;
|
| 68 |
+
padding: 14px 16px;
|
| 69 |
+
border: 1px solid #e1e3e6;
|
| 70 |
+
border-radius: 8px;
|
| 71 |
+
background: linear-gradient(135deg, #f7ae60, #f3b944);
|
| 72 |
+
font-size: 15px;
|
| 73 |
+
color: #f4f5f7;
|
| 74 |
+
transition: all 0.3s;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
input:focus, select:focus {
|
| 78 |
+
outline: none;
|
| 79 |
+
border-color: #4f46e5;
|
| 80 |
+
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2);
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
.input-icon {
|
| 84 |
+
position: relative;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
.input-icon i {
|
| 88 |
+
position: absolute;
|
| 89 |
+
left: 15px;
|
| 90 |
+
top: 50%;
|
| 91 |
+
transform: translateY(-50%);
|
| 92 |
+
color: #eeeff0;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
.input-icon input {
|
| 96 |
+
padding-left: 45px;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
.password-row {
|
| 100 |
+
display: flex;
|
| 101 |
+
gap: 15px;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
.password-row .form-group {
|
| 105 |
+
flex: 1;
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
.create-account-btn {
|
| 109 |
+
width: 100%;
|
| 110 |
+
background: linear-gradient(135deg, #f77f00, #fcbf49);
|
| 111 |
+
color: black;
|
| 112 |
+
border: none;
|
| 113 |
+
border-radius: 8px;
|
| 114 |
+
padding: 16px;
|
| 115 |
+
font-size: 16px;
|
| 116 |
+
font-weight: 600;
|
| 117 |
+
margin-top: 15px;
|
| 118 |
+
cursor: pointer;
|
| 119 |
+
transition: all 0.3s;
|
| 120 |
+
box-shadow: 0 4px 6px rgba(79, 70, 229, 0.2);
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
.create-account-btn:hover {
|
| 124 |
+
transform: translateY(-2px);
|
| 125 |
+
box-shadow: 0 6px 12px rgba(79, 70, 229, 0.25);
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
.create-account-btn:active {
|
| 129 |
+
transform: translateY(0);
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
.signin-link {
|
| 133 |
+
text-align: center;
|
| 134 |
+
margin-top: 25px;
|
| 135 |
+
font-size: 15px;
|
| 136 |
+
color: #f3f4f5;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
.signin-link a {
|
| 140 |
+
color: #4f46e5;
|
| 141 |
+
text-decoration: none;
|
| 142 |
+
font-weight: 600;
|
| 143 |
+
transition: all 0.2s;
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
.signin-link a:hover {
|
| 147 |
+
text-decoration: underline;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
.footer {
|
| 151 |
+
position: fixed;
|
| 152 |
+
font-size: 13px;
|
| 153 |
+
color: #f6f8fa;
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
.country-flag {
|
| 157 |
+
position: absolute;
|
| 158 |
+
right: 15px;
|
| 159 |
+
top: 50%;
|
| 160 |
+
transform: translateY(-50%);
|
| 161 |
+
color: #94a3b8;
|
| 162 |
+
pointer-events: none;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
.password-toggle {
|
| 166 |
+
position: absolute;
|
| 167 |
+
right: 15px;
|
| 168 |
+
top: 50%;
|
| 169 |
+
transform: translateY(-50%);
|
| 170 |
+
color: #94a3b8;
|
| 171 |
+
cursor: pointer;
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
@media (max-width: 520px) {
|
| 175 |
+
.password-row {
|
| 176 |
+
flex-direction: column;
|
| 177 |
+
gap: 20px;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
.container {
|
| 181 |
+
border-radius: 12px;
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
.header {
|
| 185 |
+
padding: 25px;
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
.form-container {
|
| 189 |
+
padding: 25px;
|
| 190 |
+
}
|
| 191 |
+
}
|
jweb/ac1/assets/css/sty.css
ADDED
|
@@ -0,0 +1,759 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:root {
|
| 2 |
+
--sidebar-bg: #1e293b;
|
| 3 |
+
--main-bg: #4b5563;
|
| 4 |
+
--text-white: #ffffff;
|
| 5 |
+
--text-gray: #d1d5db;
|
| 6 |
+
--banner-gradient-start: #a855f7;
|
| 7 |
+
--banner-gradient-end: #ec4899;
|
| 8 |
+
--green-check: #22c55e;
|
| 9 |
+
--gray-check: #9ca3af;
|
| 10 |
+
--yellow-button: #eab308;
|
| 11 |
+
--purple-user: #a855f7;
|
| 12 |
+
--premium-bg: #eab308;
|
| 13 |
+
--link-blue: #60a5fa;
|
| 14 |
+
--award-yellow: #fde047;
|
| 15 |
+
--transition-speed: 0.3s;
|
| 16 |
+
--card-bg: rgba(255, 255, 255, 0.05);
|
| 17 |
+
--primary: #4361ee;
|
| 18 |
+
--secondary: #3a0ca3;
|
| 19 |
+
--gray: #adb5bd;
|
| 20 |
+
--warning: #ffd166;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
* {
|
| 24 |
+
margin: 0;
|
| 25 |
+
padding: 0;
|
| 26 |
+
box-sizing: border-box;
|
| 27 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
body {
|
| 31 |
+
background-color: var(--main-bg);
|
| 32 |
+
color: var(--text-white);
|
| 33 |
+
display: flex;
|
| 34 |
+
min-height: 100vh;
|
| 35 |
+
overflow-x: hidden;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
.sidebar {
|
| 39 |
+
width: 220px;
|
| 40 |
+
background-color: var(--sidebar-bg);
|
| 41 |
+
padding: 20px 15px;
|
| 42 |
+
position: fixed;
|
| 43 |
+
height: 100vh;
|
| 44 |
+
overflow-y: auto;
|
| 45 |
+
z-index: 1000;
|
| 46 |
+
display: flex;
|
| 47 |
+
flex-direction: column;
|
| 48 |
+
transition: transform var(--transition-speed);
|
| 49 |
+
box-shadow: 2px 0 10px rgba(0, 0, 0, 0.2);
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
.sidebar.collapsed {
|
| 53 |
+
transform: translateX(-100%);
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
.sidebar .logo {
|
| 57 |
+
display: flex;
|
| 58 |
+
align-items: center;
|
| 59 |
+
margin-bottom: 30px;
|
| 60 |
+
padding-bottom: 10px;
|
| 61 |
+
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
.sidebar .logo img {
|
| 65 |
+
width: 40px;
|
| 66 |
+
height: 40px;
|
| 67 |
+
border-radius: 50%;
|
| 68 |
+
margin-right: 10px;
|
| 69 |
+
transition: transform 0.3s ease;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
.sidebar .logo img:hover {
|
| 73 |
+
transform: scale(1.1);
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
.sidebar .logo-text {
|
| 77 |
+
font-size: 18px;
|
| 78 |
+
font-weight: bold;
|
| 79 |
+
color: var(--yellow-button);
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
.sidebar .logo-subtext {
|
| 83 |
+
font-size: 12px;
|
| 84 |
+
color: var(--text-gray);
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
.sidebar ul {
|
| 88 |
+
list-style: none;
|
| 89 |
+
flex: 1;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
.sidebar ul li {
|
| 93 |
+
margin-bottom: 10px;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
.sidebar ul li a {
|
| 97 |
+
display: flex;
|
| 98 |
+
align-items: center;
|
| 99 |
+
color: var(--text-gray);
|
| 100 |
+
text-decoration: none;
|
| 101 |
+
padding: 8px 10px;
|
| 102 |
+
border-radius: 6px;
|
| 103 |
+
transition: background var(--transition-speed), transform var(--transition-speed);
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
.sidebar ul li a:hover {
|
| 107 |
+
background-color: rgba(255, 255, 255, 0.1);
|
| 108 |
+
color: var(--text-white);
|
| 109 |
+
transform: translateX(5px);
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
.sidebar ul li a i {
|
| 113 |
+
margin-right: 10px;
|
| 114 |
+
width: 20px;
|
| 115 |
+
text-align: center;
|
| 116 |
+
transition: color var(--transition-speed);
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.sidebar ul li a:hover i {
|
| 120 |
+
color: var(--yellow-button);
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
.sidebar .user-info {
|
| 124 |
+
display: flex;
|
| 125 |
+
align-items: center;
|
| 126 |
+
padding: 10px;
|
| 127 |
+
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
| 128 |
+
margin-top: auto;
|
| 129 |
+
background: rgba(255, 255, 255, 0.03);
|
| 130 |
+
border-radius: 8px;
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
.sidebar .user-avatar {
|
| 134 |
+
background-color: var(--purple-user);
|
| 135 |
+
color: var(--text-white);
|
| 136 |
+
width: 30px;
|
| 137 |
+
height: 30px;
|
| 138 |
+
border-radius: 50%;
|
| 139 |
+
display: flex;
|
| 140 |
+
align-items: center;
|
| 141 |
+
justify-content: center;
|
| 142 |
+
font-weight: bold;
|
| 143 |
+
margin-right: 10px;
|
| 144 |
+
box-shadow: 0 0 5px rgba(168, 85, 247, 0.5);
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
.sidebar .user-text {
|
| 148 |
+
font-size: 14px;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
.sidebar .user-status {
|
| 152 |
+
font-size: 12px;
|
| 153 |
+
color: var(--text-gray);
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
.main-content {
|
| 157 |
+
flex: 1;
|
| 158 |
+
margin-left: 220px;
|
| 159 |
+
padding: 20px;
|
| 160 |
+
transition: margin-left var(--transition-speed);
|
| 161 |
+
background: rgba(75, 85, 99, 0.9);
|
| 162 |
+
backdrop-filter: blur(5px);
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
.main-content.expanded {
|
| 166 |
+
margin-left: 0;
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
.topbar {
|
| 170 |
+
display: flex;
|
| 171 |
+
align-items: center;
|
| 172 |
+
justify-content: space-between;
|
| 173 |
+
margin-bottom: 40px;
|
| 174 |
+
padding: 10px 20px;
|
| 175 |
+
background: rgba(30, 41, 59, 0.8);
|
| 176 |
+
border-radius: 10px;
|
| 177 |
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
.topbar .logo {
|
| 181 |
+
display: flex;
|
| 182 |
+
align-items: center;
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
.topbar .logo img {
|
| 186 |
+
width: 30px;
|
| 187 |
+
height: 30px;
|
| 188 |
+
margin-right: 10px;
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
.topbar .logo-text {
|
| 192 |
+
font-size: 18px;
|
| 193 |
+
font-weight: bold;
|
| 194 |
+
color: var(--yellow-button);
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
.topbar nav {
|
| 198 |
+
display: flex;
|
| 199 |
+
gap: 20px;
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
.topbar nav a {
|
| 203 |
+
color: var(--link-blue);
|
| 204 |
+
text-decoration: none;
|
| 205 |
+
font-weight: 500;
|
| 206 |
+
transition: color var(--transition-speed);
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
.topbar nav a:hover {
|
| 210 |
+
color: var(--primary);
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
.topbar .right {
|
| 214 |
+
display: flex;
|
| 215 |
+
align-items: center;
|
| 216 |
+
gap: 15px;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
.topbar .toggle-btn {
|
| 220 |
+
background: linear-gradient(90deg, var(--primary), var(--secondary));
|
| 221 |
+
color: var(--text-white);
|
| 222 |
+
border: none;
|
| 223 |
+
border-radius: 50%;
|
| 224 |
+
width: 40px;
|
| 225 |
+
height: 40px;
|
| 226 |
+
font-size: 18px;
|
| 227 |
+
cursor: pointer;
|
| 228 |
+
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
| 229 |
+
transition: transform var(--transition-speed), background var(--transition-speed);
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
.topbar .toggle-btn:hover {
|
| 233 |
+
transform: scale(1.1);
|
| 234 |
+
background: linear-gradient(90deg, #2a4494, #270a66);
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
.topbar .notification {
|
| 238 |
+
position: relative;
|
| 239 |
+
}
|
| 240 |
+
|
| 241 |
+
.topbar .notification i {
|
| 242 |
+
color: var(--text-gray);
|
| 243 |
+
font-size: 18px;
|
| 244 |
+
transition: color var(--transition-speed);
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
.topbar .notification i:hover {
|
| 248 |
+
color: var(--warning);
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
.topbar .notification .dot {
|
| 252 |
+
position: absolute;
|
| 253 |
+
top: -2px;
|
| 254 |
+
right: -2px;
|
| 255 |
+
width: 8px;
|
| 256 |
+
height: 8px;
|
| 257 |
+
background-color: #ef4444;
|
| 258 |
+
border-radius: 50%;
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
.topbar .user {
|
| 262 |
+
display: flex;
|
| 263 |
+
align-items: center;
|
| 264 |
+
gap: 5px;
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
.topbar .user-avatar {
|
| 268 |
+
background-color: var(--premium-bg);
|
| 269 |
+
color: #000;
|
| 270 |
+
width: 25px;
|
| 271 |
+
height: 25px;
|
| 272 |
+
border-radius: 50%;
|
| 273 |
+
display: flex;
|
| 274 |
+
align-items: center;
|
| 275 |
+
justify-content: center;
|
| 276 |
+
font-weight: bold;
|
| 277 |
+
font-size: 12px;
|
| 278 |
+
box-shadow: 0 0 5px rgba(234, 179, 8, 0.5);
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
.topbar .user-name {
|
| 282 |
+
font-weight: 500;
|
| 283 |
+
color: var(--text-white);
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
.topbar .premium {
|
| 287 |
+
background-color: var(--premium-bg);
|
| 288 |
+
color: #000;
|
| 289 |
+
padding: 2px 6px;
|
| 290 |
+
border-radius: 4px;
|
| 291 |
+
font-size: 12px;
|
| 292 |
+
font-weight: bold;
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
.topbar .logout i {
|
| 296 |
+
color: var(--text-gray);
|
| 297 |
+
font-size: 18px;
|
| 298 |
+
transition: color var(--transition-speed);
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
.topbar .logout i:hover {
|
| 302 |
+
color: #ef4444;
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
.banner {
|
| 306 |
+
max-width: 400px;
|
| 307 |
+
margin: 0 auto 40px;
|
| 308 |
+
background: linear-gradient(135deg, var(--banner-gradient-start), var(--banner-gradient-end));
|
| 309 |
+
border-radius: 16px;
|
| 310 |
+
padding: 20px;
|
| 311 |
+
text-align: center;
|
| 312 |
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
|
| 313 |
+
animation: pulse 2s infinite;
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
@keyframes pulse {
|
| 317 |
+
0% { transform: scale(1); }
|
| 318 |
+
50% { transform: scale(1.05); }
|
| 319 |
+
100% { transform: scale(1); }
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
.banner .title {
|
| 323 |
+
font-size: 16px;
|
| 324 |
+
margin-bottom: 15px;
|
| 325 |
+
color: var(--text-white);
|
| 326 |
+
font-weight: bold;
|
| 327 |
+
}
|
| 328 |
+
|
| 329 |
+
.banner p {
|
| 330 |
+
font-size: 14px;
|
| 331 |
+
line-height: 1.4;
|
| 332 |
+
margin-bottom: 15px;
|
| 333 |
+
color: var(--award-yellow);
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
.banner .footer {
|
| 337 |
+
font-size: 12px;
|
| 338 |
+
color: rgba(255, 255, 255, 0.8);
|
| 339 |
+
font-style: italic;
|
| 340 |
+
}
|
| 341 |
+
|
| 342 |
+
.packages-section {
|
| 343 |
+
text-align: center;
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
.packages-section h1 {
|
| 347 |
+
font-size: 24px;
|
| 348 |
+
margin-bottom: 10px;
|
| 349 |
+
color: var(--yellow-button);
|
| 350 |
+
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
.packages-section .subtitle {
|
| 354 |
+
font-size: 14px;
|
| 355 |
+
color: var(--text-gray);
|
| 356 |
+
margin-bottom: 30px;
|
| 357 |
+
}
|
| 358 |
+
|
| 359 |
+
.packages {
|
| 360 |
+
display: flex;
|
| 361 |
+
justify-content: center;
|
| 362 |
+
gap: 20px;
|
| 363 |
+
}
|
| 364 |
+
|
| 365 |
+
.package-card {
|
| 366 |
+
background-color: #6b7280;
|
| 367 |
+
border-radius: 12px;
|
| 368 |
+
padding: 20px;
|
| 369 |
+
width: 200px;
|
| 370 |
+
text-align: left;
|
| 371 |
+
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
| 372 |
+
transition: transform var(--transition-speed), box-shadow var(--transition-speed);
|
| 373 |
+
}
|
| 374 |
+
|
| 375 |
+
.package-card:hover {
|
| 376 |
+
transform: translateY(-5px);
|
| 377 |
+
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
|
| 378 |
+
}
|
| 379 |
+
|
| 380 |
+
.package-header {
|
| 381 |
+
display: flex;
|
| 382 |
+
align-items: center;
|
| 383 |
+
margin-bottom: 15px;
|
| 384 |
+
}
|
| 385 |
+
|
| 386 |
+
.package-header i {
|
| 387 |
+
color: var(--text-gray);
|
| 388 |
+
margin-right: 10px;
|
| 389 |
+
font-size: 18px;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
.package-header .name {
|
| 393 |
+
font-size: 18px;
|
| 394 |
+
font-weight: bold;
|
| 395 |
+
color: var(--yellow-button);
|
| 396 |
+
}
|
| 397 |
+
|
| 398 |
+
.package-features {
|
| 399 |
+
list-style: none;
|
| 400 |
+
margin-bottom: 20px;
|
| 401 |
+
}
|
| 402 |
+
|
| 403 |
+
.package-features li {
|
| 404 |
+
display: flex;
|
| 405 |
+
align-items: center;
|
| 406 |
+
margin-bottom: 8px;
|
| 407 |
+
color: var(--text-gray);
|
| 408 |
+
font-size: 14px;
|
| 409 |
+
transition: color var(--transition-speed);
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
.package-features li:hover {
|
| 413 |
+
color: var(--text-white);
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
.package-features li i {
|
| 417 |
+
margin-right: 10px;
|
| 418 |
+
}
|
| 419 |
+
|
| 420 |
+
.package-features .checked i {
|
| 421 |
+
color: var(--green-check);
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
.package-features .unchecked i {
|
| 425 |
+
color: var(--gray-check);
|
| 426 |
+
}
|
| 427 |
+
|
| 428 |
+
.package-award {
|
| 429 |
+
font-size: 16px;
|
| 430 |
+
font-weight: bold;
|
| 431 |
+
color: var(--award-yellow);
|
| 432 |
+
margin-bottom: 10px;
|
| 433 |
+
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
| 434 |
+
}
|
| 435 |
+
|
| 436 |
+
.package-button {
|
| 437 |
+
background-color: var(--yellow-button);
|
| 438 |
+
color: #000;
|
| 439 |
+
padding: 8px 16px;
|
| 440 |
+
border: none;
|
| 441 |
+
border-radius: 6px;
|
| 442 |
+
font-weight: bold;
|
| 443 |
+
cursor: pointer;
|
| 444 |
+
width: 100%;
|
| 445 |
+
transition: background var(--transition-speed), transform var(--transition-speed);
|
| 446 |
+
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
| 447 |
+
}
|
| 448 |
+
|
| 449 |
+
.package-button:hover {
|
| 450 |
+
background-color: #d97706;
|
| 451 |
+
transform: scale(1.05);
|
| 452 |
+
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
|
| 453 |
+
}
|
| 454 |
+
|
| 455 |
+
.welcome {
|
| 456 |
+
display: flex;
|
| 457 |
+
align-items: center;
|
| 458 |
+
margin-bottom: 20px;
|
| 459 |
+
padding: 15px;
|
| 460 |
+
background: rgba(255, 255, 255, 0.05);
|
| 461 |
+
border-radius: 10px;
|
| 462 |
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
| 463 |
+
}
|
| 464 |
+
|
| 465 |
+
.user-avatar {
|
| 466 |
+
width: 50px;
|
| 467 |
+
height: 50px;
|
| 468 |
+
border-radius: 50%;
|
| 469 |
+
background-color: var(--primary);
|
| 470 |
+
display: flex;
|
| 471 |
+
align-items: center;
|
| 472 |
+
justify-content: center;
|
| 473 |
+
color: var(--text-white);
|
| 474 |
+
font-size: 20px;
|
| 475 |
+
margin-right: 15px;
|
| 476 |
+
box-shadow: 0 0 10px rgba(67, 97, 238, 0.5);
|
| 477 |
+
}
|
| 478 |
+
|
| 479 |
+
.welcome-text h2 {
|
| 480 |
+
font-size: 18px;
|
| 481 |
+
margin-bottom: 5px;
|
| 482 |
+
color: var(--text-white);
|
| 483 |
+
}
|
| 484 |
+
|
| 485 |
+
.welcome-text p {
|
| 486 |
+
color: var(--gray);
|
| 487 |
+
font-size: 14px;
|
| 488 |
+
}
|
| 489 |
+
|
| 490 |
+
.balance-cards {
|
| 491 |
+
display: grid;
|
| 492 |
+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
| 493 |
+
gap: 20px;
|
| 494 |
+
margin-bottom: 30px;
|
| 495 |
+
}
|
| 496 |
+
|
| 497 |
+
.card {
|
| 498 |
+
background-color: #6b7280;
|
| 499 |
+
border-radius: 12px;
|
| 500 |
+
padding: 20px;
|
| 501 |
+
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
| 502 |
+
transition: transform var(--transition-speed);
|
| 503 |
+
}
|
| 504 |
+
|
| 505 |
+
.card:hover {
|
| 506 |
+
transform: translateY(-5px);
|
| 507 |
+
}
|
| 508 |
+
|
| 509 |
+
.card-title {
|
| 510 |
+
font-size: 16px;
|
| 511 |
+
color: var(--gray);
|
| 512 |
+
margin-bottom: 15px;
|
| 513 |
+
}
|
| 514 |
+
|
| 515 |
+
.meta-balance {
|
| 516 |
+
display: flex;
|
| 517 |
+
justify-content: space-between;
|
| 518 |
+
align-items: center;
|
| 519 |
+
}
|
| 520 |
+
|
| 521 |
+
.balance-amount {
|
| 522 |
+
font-size: 28px;
|
| 523 |
+
font-weight: 700;
|
| 524 |
+
color: var(--primary);
|
| 525 |
+
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
| 526 |
+
}
|
| 527 |
+
|
| 528 |
+
.balance-actions {
|
| 529 |
+
display: flex;
|
| 530 |
+
gap: 10px;
|
| 531 |
+
}
|
| 532 |
+
|
| 533 |
+
.btn {
|
| 534 |
+
padding: 8px 15px;
|
| 535 |
+
border-radius: 5px;
|
| 536 |
+
border: none;
|
| 537 |
+
font-weight: 600;
|
| 538 |
+
cursor: pointer;
|
| 539 |
+
transition: all var(--transition-speed);
|
| 540 |
+
}
|
| 541 |
+
|
| 542 |
+
.btn-primary {
|
| 543 |
+
background-color: var(--primary);
|
| 544 |
+
color: var(--text-white);
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
.btn-primary:hover {
|
| 548 |
+
background-color: var(--secondary);
|
| 549 |
+
transform: scale(1.05);
|
| 550 |
+
}
|
| 551 |
+
|
| 552 |
+
.btn-outline {
|
| 553 |
+
background-color: transparent;
|
| 554 |
+
border: 1px solid var(--primary);
|
| 555 |
+
color: var(--primary);
|
| 556 |
+
}
|
| 557 |
+
|
| 558 |
+
.btn-outline:hover {
|
| 559 |
+
background-color: var(--primary);
|
| 560 |
+
color: var(--text-white);
|
| 561 |
+
transform: scale(1.05);
|
| 562 |
+
}
|
| 563 |
+
|
| 564 |
+
.stats {
|
| 565 |
+
display: grid;
|
| 566 |
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
| 567 |
+
gap: 20px;
|
| 568 |
+
margin-bottom: 30px;
|
| 569 |
+
}
|
| 570 |
+
|
| 571 |
+
.stat-card {
|
| 572 |
+
background-color: #6b7280;
|
| 573 |
+
border-radius: 12px;
|
| 574 |
+
padding: 20px;
|
| 575 |
+
text-align: center;
|
| 576 |
+
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
| 577 |
+
transition: transform var(--transition-speed);
|
| 578 |
+
}
|
| 579 |
+
|
| 580 |
+
.stat-card:hover {
|
| 581 |
+
transform: translateY(-5px);
|
| 582 |
+
}
|
| 583 |
+
|
| 584 |
+
.stat-value {
|
| 585 |
+
font-size: 24px;
|
| 586 |
+
font-weight: 700;
|
| 587 |
+
margin: 10px 0;
|
| 588 |
+
color: var(--primary);
|
| 589 |
+
}
|
| 590 |
+
|
| 591 |
+
.stat-label {
|
| 592 |
+
color: var(--gray);
|
| 593 |
+
font-size: 14px;
|
| 594 |
+
}
|
| 595 |
+
|
| 596 |
+
.dashboard-cards {
|
| 597 |
+
display: grid;
|
| 598 |
+
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
| 599 |
+
gap: 20px;
|
| 600 |
+
margin-bottom: 30px;
|
| 601 |
+
}
|
| 602 |
+
|
| 603 |
+
.dashboard-card {
|
| 604 |
+
background-color: #6b7280;
|
| 605 |
+
border-radius: 12px;
|
| 606 |
+
padding: 20px;
|
| 607 |
+
color: var(--text-white);
|
| 608 |
+
text-align: center;
|
| 609 |
+
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
| 610 |
+
transition: transform var(--transition-speed);
|
| 611 |
+
}
|
| 612 |
+
|
| 613 |
+
.dashboard-card:hover {
|
| 614 |
+
transform: translateY(-5px);
|
| 615 |
+
}
|
| 616 |
+
|
| 617 |
+
.dashboard-card h2 {
|
| 618 |
+
margin: 10px 0;
|
| 619 |
+
font-size: 22px;
|
| 620 |
+
color: var(--primary);
|
| 621 |
+
}
|
| 622 |
+
|
| 623 |
+
.dashboard-card p {
|
| 624 |
+
font-size: 14px;
|
| 625 |
+
color: var(--gray);
|
| 626 |
+
}
|
| 627 |
+
|
| 628 |
+
.dashboard-btn {
|
| 629 |
+
background: var(--yellow-button);
|
| 630 |
+
color: #000;
|
| 631 |
+
padding: 8px 18px;
|
| 632 |
+
border: none;
|
| 633 |
+
border-radius: 6px;
|
| 634 |
+
cursor: pointer;
|
| 635 |
+
font-weight: bold;
|
| 636 |
+
margin-top: 10px;
|
| 637 |
+
transition: background var(--transition-speed), transform var(--transition-speed);
|
| 638 |
+
}
|
| 639 |
+
|
| 640 |
+
.dashboard-btn:hover {
|
| 641 |
+
background: #d97706;
|
| 642 |
+
transform: scale(1.05);
|
| 643 |
+
}
|
| 644 |
+
|
| 645 |
+
.modal {
|
| 646 |
+
display: none;
|
| 647 |
+
position: fixed;
|
| 648 |
+
top: 0;
|
| 649 |
+
left: 0;
|
| 650 |
+
width: 100%;
|
| 651 |
+
height: 100%;
|
| 652 |
+
background-color: rgba(0, 0, 0, 0.5);
|
| 653 |
+
z-index: 2000;
|
| 654 |
+
justify-content: center;
|
| 655 |
+
align-items: center;
|
| 656 |
+
}
|
| 657 |
+
|
| 658 |
+
.modal-content {
|
| 659 |
+
background-color: var(--sidebar-bg);
|
| 660 |
+
padding: 30px;
|
| 661 |
+
border-radius: 10px;
|
| 662 |
+
width: 90%;
|
| 663 |
+
max-width: 500px;
|
| 664 |
+
color: var(--text-white);
|
| 665 |
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
| 666 |
+
animation: fadeIn 0.3s ease;
|
| 667 |
+
}
|
| 668 |
+
|
| 669 |
+
@keyframes fadeIn {
|
| 670 |
+
from { opacity: 0; transform: scale(0.9); }
|
| 671 |
+
to { opacity: 1; transform: scale(1); }
|
| 672 |
+
}
|
| 673 |
+
|
| 674 |
+
.modal-header {
|
| 675 |
+
display: flex;
|
| 676 |
+
justify-content: space-between;
|
| 677 |
+
align-items: center;
|
| 678 |
+
margin-bottom: 20px;
|
| 679 |
+
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
| 680 |
+
padding-bottom: 10px;
|
| 681 |
+
}
|
| 682 |
+
|
| 683 |
+
.close {
|
| 684 |
+
font-size: 24px;
|
| 685 |
+
cursor: pointer;
|
| 686 |
+
color: var(--gray);
|
| 687 |
+
transition: color var(--transition-speed);
|
| 688 |
+
}
|
| 689 |
+
|
| 690 |
+
.close:hover {
|
| 691 |
+
color: #ef4444;
|
| 692 |
+
}
|
| 693 |
+
|
| 694 |
+
.form-group {
|
| 695 |
+
margin-bottom: 20px;
|
| 696 |
+
}
|
| 697 |
+
|
| 698 |
+
.form-group label {
|
| 699 |
+
display: block;
|
| 700 |
+
margin-bottom: 5px;
|
| 701 |
+
font-weight: 600;
|
| 702 |
+
color: var(--text-white);
|
| 703 |
+
}
|
| 704 |
+
|
| 705 |
+
.form-group input, .form-group select {
|
| 706 |
+
width: 100%;
|
| 707 |
+
padding: 10px;
|
| 708 |
+
border: 1px solid var(--gray);
|
| 709 |
+
border-radius: 5px;
|
| 710 |
+
background: rgba(255, 255, 255, 0.1);
|
| 711 |
+
color: var(--text-white);
|
| 712 |
+
transition: border-color var(--transition-speed);
|
| 713 |
+
}
|
| 714 |
+
|
| 715 |
+
.form-group input:focus, .form-group select:focus {
|
| 716 |
+
border-color: var(--primary);
|
| 717 |
+
outline: none;
|
| 718 |
+
}
|
| 719 |
+
|
| 720 |
+
@media (max-width: 768px) {
|
| 721 |
+
.sidebar {
|
| 722 |
+
transform: translateX(-100%);
|
| 723 |
+
}
|
| 724 |
+
|
| 725 |
+
.sidebar.active {
|
| 726 |
+
transform: translateX(0);
|
| 727 |
+
}
|
| 728 |
+
|
| 729 |
+
.main-content {
|
| 730 |
+
margin-left: 0;
|
| 731 |
+
}
|
| 732 |
+
|
| 733 |
+
.main-content.expanded {
|
| 734 |
+
margin-left: 0;
|
| 735 |
+
}
|
| 736 |
+
|
| 737 |
+
.packages {
|
| 738 |
+
flex-direction: column;
|
| 739 |
+
align-items: center;
|
| 740 |
+
}
|
| 741 |
+
|
| 742 |
+
.balance-cards, .stats, .dashboard-cards {
|
| 743 |
+
grid-template-columns: 1fr;
|
| 744 |
+
}
|
| 745 |
+
|
| 746 |
+
.balance-actions {
|
| 747 |
+
flex-direction: column;
|
| 748 |
+
}
|
| 749 |
+
|
| 750 |
+
.topbar {
|
| 751 |
+
flex-direction: column;
|
| 752 |
+
gap: 15px;
|
| 753 |
+
}
|
| 754 |
+
|
| 755 |
+
.topbar nav {
|
| 756 |
+
flex-direction: column;
|
| 757 |
+
gap: 10px;
|
| 758 |
+
}
|
| 759 |
+
}
|
jweb/ac1/assets/css/style.css
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Background */
|
| 2 |
+
body {
|
| 3 |
+
margin: 0;
|
| 4 |
+
font-family: Arial, sans-serif;
|
| 5 |
+
background: linear-gradient(135deg, #c0392b, #e67e22);
|
| 6 |
+
height: 100vh;
|
| 7 |
+
display: flex;
|
| 8 |
+
justify-content: center;
|
| 9 |
+
align-items: center;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
/* Form Container */
|
| 13 |
+
.container {
|
| 14 |
+
display: flex;
|
| 15 |
+
justify-content: center;
|
| 16 |
+
align-items: center;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
.form-box {
|
| 20 |
+
background: rgba(255, 255, 255, 0.1);
|
| 21 |
+
backdrop-filter: blur(8px);
|
| 22 |
+
padding: 30px;
|
| 23 |
+
border-radius: 12px;
|
| 24 |
+
width: 350px;
|
| 25 |
+
box-shadow: 0 8px 25px rgba(0,0,0,0.2);
|
| 26 |
+
text-align: center;
|
| 27 |
+
color: white;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
/* Branding */
|
| 31 |
+
.brand {
|
| 32 |
+
font-size: 26px;
|
| 33 |
+
font-weight: bold;
|
| 34 |
+
margin-bottom: 5px;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
.subtitle {
|
| 38 |
+
font-size: 14px;
|
| 39 |
+
margin-bottom: 20px;
|
| 40 |
+
color: #eee;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
/* Input Fields */
|
| 44 |
+
.input-group {
|
| 45 |
+
text-align: left;
|
| 46 |
+
margin-bottom: 15px;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
.input-group label {
|
| 50 |
+
font-size: 14px;
|
| 51 |
+
display: block;
|
| 52 |
+
margin-bottom: 5px;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
.input-group input {
|
| 56 |
+
width: 100%;
|
| 57 |
+
padding: 10px;
|
| 58 |
+
border: none;
|
| 59 |
+
border-radius: 6px;
|
| 60 |
+
outline: none;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
/* Button */
|
| 64 |
+
.btn {
|
| 65 |
+
background: #8BC34A;
|
| 66 |
+
color: #fff;
|
| 67 |
+
border: none;
|
| 68 |
+
padding: 12px;
|
| 69 |
+
width: 100%;
|
| 70 |
+
border-radius: 6px;
|
| 71 |
+
cursor: pointer;
|
| 72 |
+
font-size: 16px;
|
| 73 |
+
transition: 0.3s;
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
.btn:hover {
|
| 77 |
+
background: #7CB342;
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
/* Login Text */
|
| 81 |
+
.login-text {
|
| 82 |
+
margin-top: 15px;
|
| 83 |
+
font-size: 14px;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
.login-text a {
|
| 87 |
+
color: #fff;
|
| 88 |
+
text-decoration: underline;
|
| 89 |
+
}
|
jweb/ac1/assets/css/styles.css
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
* {
|
| 2 |
+
margin: 0;
|
| 3 |
+
padding: 0;
|
| 4 |
+
box-sizing: border-box;
|
| 5 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
body {
|
| 9 |
+
background: linear-gradient(135deg, #6e8efb, #a777e3);
|
| 10 |
+
min-height: 100vh;
|
| 11 |
+
display: flex;
|
| 12 |
+
justify-content: center;
|
| 13 |
+
align-items: center;
|
| 14 |
+
padding: 20px;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
.container {
|
| 18 |
+
background: rgba(255, 255, 255, 0.95);
|
| 19 |
+
border-radius: 15px;
|
| 20 |
+
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);
|
| 21 |
+
width: 100%;
|
| 22 |
+
max-width: 550px;
|
| 23 |
+
overflow: hidden;
|
| 24 |
+
position: relative;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
.form-container {
|
| 28 |
+
padding: 30px;
|
| 29 |
+
transition: transform 0.6s ease-in-out;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
h2 {
|
| 33 |
+
text-align: center;
|
| 34 |
+
color: #333;
|
| 35 |
+
margin-bottom: 25px;
|
| 36 |
+
font-size: 28px;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
.form-group {
|
| 40 |
+
margin-bottom: 20px;
|
| 41 |
+
position: relative;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
.form-group {
|
| 45 |
+
margin-bottom: 15px;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
.input-container {
|
| 49 |
+
position: relative;
|
| 50 |
+
display: flex;
|
| 51 |
+
align-items: center;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
.input-container i {
|
| 55 |
+
position: absolute;
|
| 56 |
+
left: 12px;
|
| 57 |
+
color: #ccc;
|
| 58 |
+
font-size: 14px;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
.input-container input,
|
| 62 |
+
.input-container select {
|
| 63 |
+
width: 100%;
|
| 64 |
+
padding: 10px 12px 10px 35px; /* left padding for icon */
|
| 65 |
+
border: 1px solid #ddd;
|
| 66 |
+
border-radius: 6px;
|
| 67 |
+
outline: none;
|
| 68 |
+
background: rgba(255, 255, 255, 0.1);
|
| 69 |
+
color: #fff;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
.password-container .toggle-password {
|
| 73 |
+
position: absolute;
|
| 74 |
+
right: 12px;
|
| 75 |
+
cursor: pointer;
|
| 76 |
+
color: #ccc;
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
label {
|
| 80 |
+
display: block;
|
| 81 |
+
margin-bottom: 8px;
|
| 82 |
+
font-weight: 600;
|
| 83 |
+
color: #444;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
input, select {
|
| 87 |
+
width: 100%;
|
| 88 |
+
padding: 14px;
|
| 89 |
+
border: 2px solid #ddd;
|
| 90 |
+
border-radius: 8px;
|
| 91 |
+
font-size: 16px;
|
| 92 |
+
transition: border 0.3s;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
input:focus, select:focus {
|
| 96 |
+
border-color: #6e8efb;
|
| 97 |
+
outline: none;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
.password-row {
|
| 101 |
+
display: flex;
|
| 102 |
+
gap: 15px;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
.password-column {
|
| 106 |
+
flex: 1;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
.password-container {
|
| 110 |
+
position: relative;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
.toggle-password {
|
| 114 |
+
position: absolute;
|
| 115 |
+
right: 15px;
|
| 116 |
+
top: 50%;
|
| 117 |
+
transform: translateY(-50%);
|
| 118 |
+
cursor: pointer;
|
| 119 |
+
color: #777;
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
.error-message {
|
| 123 |
+
color: #e74c3c;
|
| 124 |
+
font-size: 14px;
|
| 125 |
+
margin-top: 5px;
|
| 126 |
+
min-height: 20px;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
.btn {
|
| 130 |
+
width: 100%;
|
| 131 |
+
padding: 14px;
|
| 132 |
+
background: linear-gradient(135deg, #6e8efb, #a777e3);
|
| 133 |
+
border: none;
|
| 134 |
+
border-radius: 8px;
|
| 135 |
+
color: white;
|
| 136 |
+
font-size: 18px;
|
| 137 |
+
font-weight: 600;
|
| 138 |
+
cursor: pointer;
|
| 139 |
+
transition: all 0.3s;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
.btn:hover {
|
| 143 |
+
background: linear-gradient(135deg, #5d7ce0, #9666d3);
|
| 144 |
+
transform: translateY(-2px);
|
| 145 |
+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
.switch-form {
|
| 149 |
+
text-align: center;
|
| 150 |
+
margin-top: 20px;
|
| 151 |
+
color: #555;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
.switch-form a {
|
| 155 |
+
color: #6e8efb;
|
| 156 |
+
text-decoration: none;
|
| 157 |
+
font-weight: 600;
|
| 158 |
+
cursor: pointer;
|
| 159 |
+
transition: color 0.3s;
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
.switch-form a:hover {
|
| 163 |
+
color: #a777e3;
|
| 164 |
+
text-decoration: underline;
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
.success-message {
|
| 168 |
+
background: linear-gradient(135deg, #6e8efb, #a777e3);
|
| 169 |
+
color: white;
|
| 170 |
+
padding: 20px;
|
| 171 |
+
text-align: center;
|
| 172 |
+
border-radius: 10px;
|
| 173 |
+
margin-bottom: 20px;
|
| 174 |
+
display: none;
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
.success-message i {
|
| 178 |
+
font-size: 48px;
|
| 179 |
+
margin-bottom: 10px;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
@media (max-width: 576px) {
|
| 183 |
+
.container {
|
| 184 |
+
border-radius: 10px;
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
.form-container {
|
| 188 |
+
padding: 20px;
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
.password-row {
|
| 192 |
+
flex-direction: column;
|
| 193 |
+
gap: 0;
|
| 194 |
+
}
|
| 195 |
+
}
|
jweb/ac1/assets/database/db.sql
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
CREATE TABLE `users` (
|
| 2 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 3 |
+
`user_type` enum('marketer','agent','admin') DEFAULT 'marketer',
|
| 4 |
+
`referred_by` int DEFAULT NULL,
|
| 5 |
+
`username` varchar(50) NOT NULL,
|
| 6 |
+
`email` varchar(100) NOT NULL,
|
| 7 |
+
`country` varchar(2) NOT NULL,
|
| 8 |
+
`phone_number` varchar(20) NOT NULL,
|
| 9 |
+
`tier` enum('Basic','Premium') DEFAULT 'Basic',
|
| 10 |
+
`current_package_id` int DEFAULT NULL,
|
| 11 |
+
`package_start_date` datetime DEFAULT NULL,
|
| 12 |
+
`package_end_date` datetime DEFAULT NULL,
|
| 13 |
+
`package` enum('None','NOVA','SUPERIOR','GOLD') DEFAULT 'None',
|
| 14 |
+
`balance` decimal(10,2) DEFAULT '0.00',
|
| 15 |
+
`verification_token` varchar(100) DEFAULT NULL,
|
| 16 |
+
`reset_token` varchar(100) DEFAULT NULL,
|
| 17 |
+
`reset_token_expiry` datetime DEFAULT NULL,
|
| 18 |
+
`total_invested` decimal(15,2) DEFAULT '0.00',
|
| 19 |
+
`total_earnings` decimal(15,2) DEFAULT '0.00',
|
| 20 |
+
`total_deposits` decimal(10,2) DEFAULT '0.00',
|
| 21 |
+
`total_withdrawals` decimal(10,2) DEFAULT '0.00',
|
| 22 |
+
`rewards` decimal(10,2) DEFAULT '0.00',
|
| 23 |
+
`meta_earnings` decimal(10,2) DEFAULT '0.00',
|
| 24 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 25 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 26 |
+
`last_login` timestamp NULL DEFAULT NULL,
|
| 27 |
+
`pin_hash` varchar(255) DEFAULT '',
|
| 28 |
+
`password_hash` varchar(255) NOT NULL,
|
| 29 |
+
`currency` varchar(3) DEFAULT 'KES',
|
| 30 |
+
`exchange_rate` decimal(10,4) DEFAULT '1.0000',
|
| 31 |
+
`referral_code` varchar(20) DEFAULT NULL,
|
| 32 |
+
`is_active` tinyint(1) DEFAULT '1',
|
| 33 |
+
`login_attempts` int DEFAULT '0',
|
| 34 |
+
`last_login_attempt` timestamp NULL DEFAULT NULL,
|
| 35 |
+
`account_status` enum('active','suspended','pending') DEFAULT 'active',
|
| 36 |
+
PRIMARY KEY (`id`),
|
| 37 |
+
UNIQUE KEY `username` (`username`),
|
| 38 |
+
UNIQUE KEY `email` (`email`),
|
| 39 |
+
UNIQUE KEY `referral_code` (`referral_code`),
|
| 40 |
+
KEY `idx_users_email` (`email`),
|
| 41 |
+
KEY `idx_users_username` (`username`),
|
| 42 |
+
KEY `idx_account_status` (`account_status`)
|
| 43 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
CREATE TABLE `user_sessions` (
|
| 47 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 48 |
+
`user_id` int NOT NULL,
|
| 49 |
+
`session_id` varchar(128) NOT NULL,
|
| 50 |
+
`ip_address` varchar(45) DEFAULT NULL,
|
| 51 |
+
`user_agent` text,
|
| 52 |
+
`login_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 53 |
+
`last_activity` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 54 |
+
`expires_at` datetime NOT NULL,
|
| 55 |
+
`is_active` tinyint(1) DEFAULT '1',
|
| 56 |
+
PRIMARY KEY (`id`),
|
| 57 |
+
UNIQUE KEY `session_id` (`session_id`),
|
| 58 |
+
KEY `user_id` (`user_id`),
|
| 59 |
+
KEY `idx_expires_at` (`expires_at`),
|
| 60 |
+
KEY `idx_is_active` (`is_active`),
|
| 61 |
+
CONSTRAINT `user_sessions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 62 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
CREATE TABLE `user_activity_log` (
|
| 66 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 67 |
+
`user_id` int NOT NULL,
|
| 68 |
+
`activity_type` varchar(50) NOT NULL,
|
| 69 |
+
`description` text,
|
| 70 |
+
`ip_address` varchar(45) DEFAULT NULL,
|
| 71 |
+
`user_agent` text,
|
| 72 |
+
`metadata` json DEFAULT NULL,
|
| 73 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 74 |
+
PRIMARY KEY (`id`),
|
| 75 |
+
KEY `user_id` (`user_id`),
|
| 76 |
+
KEY `idx_activity_type` (`activity_type`),
|
| 77 |
+
KEY `idx_created_at` (`created_at`),
|
| 78 |
+
CONSTRAINT `user_activity_log_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 79 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
INSERT INTO `users` (
|
| 83 |
+
`username`, `email`, `country`, `phone_number`, `password_hash`, `referral_code`, `tier`, `package`
|
| 84 |
+
) VALUES
|
| 85 |
+
('admin', 'admin@jmotors.com', 'KE', '+254700000000', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'ADMIN001', 'Premium', 'GOLD'),
|
| 86 |
+
('testuser', 'test@jmotors.com', 'KE', '+254711111111', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'TEST002', 'Basic', 'NOVA');
|
jweb/ac1/assets/database/jm.sql
ADDED
|
@@ -0,0 +1,930 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
CREATE TABLE `access_tokens` (
|
| 2 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 3 |
+
`user_id` INT NOT NULL,
|
| 4 |
+
`name` VARCHAR(100) NOT NULL,
|
| 5 |
+
`token` VARCHAR(255) NOT NULL UNIQUE,
|
| 6 |
+
`permissions` JSON NOT NULL,
|
| 7 |
+
`ip_restrictions` TEXT DEFAULT NULL,
|
| 8 |
+
`expires_at` DATETIME DEFAULT NULL,
|
| 9 |
+
`status` ENUM('active','revoked') DEFAULT 'active',
|
| 10 |
+
`last_used` TIMESTAMP NULL DEFAULT NULL,
|
| 11 |
+
`usage_count` INT DEFAULT 0,
|
| 12 |
+
`metadata` JSON DEFAULT NULL,
|
| 13 |
+
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 14 |
+
PRIMARY KEY (`id`),
|
| 15 |
+
KEY `idx_user_id` (`user_id`),
|
| 16 |
+
KEY `idx_expires_at` (`expires_at`),
|
| 17 |
+
CONSTRAINT `fk_access_tokens_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 18 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 19 |
+
|
| 20 |
+
CREATE TABLE `admin_payments` (
|
| 21 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 22 |
+
`user_id` INT NOT NULL,
|
| 23 |
+
`amount` DECIMAL(10,2) NOT NULL,
|
| 24 |
+
`mpesa_code` VARCHAR(20) UNIQUE NOT NULL,
|
| 25 |
+
`phone_number` VARCHAR(20) NOT NULL,
|
| 26 |
+
`status` ENUM('pending','verified','rejected') DEFAULT 'pending',
|
| 27 |
+
`verified_by` INT DEFAULT NULL,
|
| 28 |
+
`verified_at` TIMESTAMP NULL DEFAULT NULL,
|
| 29 |
+
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 30 |
+
PRIMARY KEY (`id`),
|
| 31 |
+
KEY `idx_user_id` (`user_id`),
|
| 32 |
+
CONSTRAINT `fk_admin_payments_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 33 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 34 |
+
|
| 35 |
+
CREATE TABLE `advertisement_payments` (
|
| 36 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 37 |
+
`advertisement_id` INT NOT NULL,
|
| 38 |
+
`user_id` INT NOT NULL,
|
| 39 |
+
`amount` DECIMAL(10,2) NOT NULL,
|
| 40 |
+
`payment_method` ENUM('mpesa','bank_transfer','wallet','card') DEFAULT 'mpesa',
|
| 41 |
+
`transaction_code` VARCHAR(100) UNIQUE,
|
| 42 |
+
`status` ENUM('pending','completed','failed','refunded') DEFAULT 'pending',
|
| 43 |
+
`payment_date` TIMESTAMP NULL DEFAULT NULL,
|
| 44 |
+
`confirmed_by` INT DEFAULT NULL,
|
| 45 |
+
`confirmed_at` TIMESTAMP NULL DEFAULT NULL,
|
| 46 |
+
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 47 |
+
PRIMARY KEY (`id`),
|
| 48 |
+
KEY `idx_advertisement_id` (`advertisement_id`),
|
| 49 |
+
KEY `idx_user_id` (`user_id`),
|
| 50 |
+
KEY `idx_confirmed_by` (`confirmed_by`),
|
| 51 |
+
CONSTRAINT `fk_adv_payments_advertisement` FOREIGN KEY (`advertisement_id`) REFERENCES `advertisements` (`id`) ON DELETE CASCADE,
|
| 52 |
+
CONSTRAINT `fk_adv_payments_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 53 |
+
CONSTRAINT `fk_adv_payments_confirmer` FOREIGN KEY (`confirmed_by`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
| 54 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 55 |
+
|
| 56 |
+
CREATE TABLE `advertisements` (
|
| 57 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 58 |
+
`user_id` INT NOT NULL,
|
| 59 |
+
`agent_id` INT DEFAULT NULL,
|
| 60 |
+
`title` VARCHAR(255) NOT NULL,
|
| 61 |
+
`description` TEXT,
|
| 62 |
+
`image_url` VARCHAR(500) DEFAULT NULL,
|
| 63 |
+
`video_url` VARCHAR(500) DEFAULT NULL,
|
| 64 |
+
`target_platform` ENUM('facebook','instagram','whatsapp','twitter','all') DEFAULT 'all',
|
| 65 |
+
`budget` DECIMAL(10,2) NOT NULL,
|
| 66 |
+
`duration_days` INT DEFAULT 7,
|
| 67 |
+
`status` ENUM('pending','approved','rejected','active','completed','paused') DEFAULT 'pending',
|
| 68 |
+
`admin_notes` TEXT,
|
| 69 |
+
`approved_by` INT DEFAULT NULL,
|
| 70 |
+
`approved_at` TIMESTAMP NULL DEFAULT NULL,
|
| 71 |
+
`start_date` DATE DEFAULT NULL,
|
| 72 |
+
`end_date` DATE DEFAULT NULL,
|
| 73 |
+
`impressions` INT DEFAULT 0,
|
| 74 |
+
`clicks` INT DEFAULT 0,
|
| 75 |
+
`conversions` INT DEFAULT 0,
|
| 76 |
+
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 77 |
+
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 78 |
+
PRIMARY KEY (`id`),
|
| 79 |
+
KEY `idx_user_id` (`user_id`),
|
| 80 |
+
KEY `idx_agent_id` (`agent_id`),
|
| 81 |
+
KEY `idx_approved_by` (`approved_by`),
|
| 82 |
+
CONSTRAINT `fk_ads_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 83 |
+
CONSTRAINT `fk_ads_agent` FOREIGN KEY (`agent_id`) REFERENCES `users` (`id`) ON DELETE SET NULL,
|
| 84 |
+
CONSTRAINT `fk_ads_approver` FOREIGN KEY (`approved_by`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
| 85 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 86 |
+
|
| 87 |
+
CREATE TABLE `agent_applications` (
|
| 88 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 89 |
+
`user_id` INT NOT NULL,
|
| 90 |
+
`sponsor_id` INT NOT NULL,
|
| 91 |
+
`full_name` VARCHAR(255) NOT NULL,
|
| 92 |
+
`phone` VARCHAR(20) NOT NULL,
|
| 93 |
+
`email` VARCHAR(255) DEFAULT NULL,
|
| 94 |
+
`location` VARCHAR(255) NOT NULL,
|
| 95 |
+
`id_front` VARCHAR(500) DEFAULT NULL,
|
| 96 |
+
`id_back` VARCHAR(500) DEFAULT NULL,
|
| 97 |
+
`status` ENUM('pending','approved','rejected','documents_needed') DEFAULT 'pending',
|
| 98 |
+
`applied_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 99 |
+
`reviewed_by` INT DEFAULT NULL,
|
| 100 |
+
`reviewed_at` TIMESTAMP NULL DEFAULT NULL,
|
| 101 |
+
`review_notes` TEXT,
|
| 102 |
+
`commission_rate` DECIMAL(5,2) DEFAULT 10.00,
|
| 103 |
+
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 104 |
+
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 105 |
+
PRIMARY KEY (`id`),
|
| 106 |
+
KEY `idx_user_id` (`user_id`),
|
| 107 |
+
KEY `idx_sponsor_id` (`sponsor_id`),
|
| 108 |
+
KEY `idx_reviewed_by` (`reviewed_by`),
|
| 109 |
+
CONSTRAINT `fk_agent_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 110 |
+
CONSTRAINT `fk_agent_sponsor` FOREIGN KEY (`sponsor_id`) REFERENCES `users` (`id`) ON DELETE SET NULL,
|
| 111 |
+
CONSTRAINT `fk_agent_reviewer` FOREIGN KEY (`reviewed_by`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
| 112 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 113 |
+
|
| 114 |
+
CREATE TABLE `agent_claims` (
|
| 115 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 116 |
+
`user_id` INT NOT NULL,
|
| 117 |
+
`claim_type` ENUM('commission','bonus','referral','override','other') NOT NULL,
|
| 118 |
+
`amount` DECIMAL(15,2) NOT NULL,
|
| 119 |
+
`description` TEXT,
|
| 120 |
+
`claim_period` VARCHAR(50) DEFAULT NULL,
|
| 121 |
+
`status` ENUM('pending','approved','rejected','processing') DEFAULT 'pending',
|
| 122 |
+
`approved_by` INT DEFAULT NULL,
|
| 123 |
+
`approved_amount` DECIMAL(15,2) DEFAULT NULL,
|
| 124 |
+
`approval_notes` TEXT,
|
| 125 |
+
`approved_at` DATETIME DEFAULT NULL,
|
| 126 |
+
`supporting_docs` JSON DEFAULT NULL,
|
| 127 |
+
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 128 |
+
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 129 |
+
PRIMARY KEY (`id`),
|
| 130 |
+
KEY `idx_approved_by` (`approved_by`),
|
| 131 |
+
KEY `idx_user_id` (`user_id`),
|
| 132 |
+
KEY `idx_status` (`status`),
|
| 133 |
+
KEY `idx_created_at` (`created_at`),
|
| 134 |
+
CONSTRAINT `fk_claim_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 135 |
+
CONSTRAINT `fk_claim_approved_by` FOREIGN KEY (`approved_by`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
| 136 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 137 |
+
|
| 138 |
+
CREATE TABLE `agent_hierarchy` (
|
| 139 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 140 |
+
`upline_id` INT NOT NULL,
|
| 141 |
+
`downline_id` INT NOT NULL,
|
| 142 |
+
`level` INT NOT NULL,
|
| 143 |
+
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 144 |
+
PRIMARY KEY (`id`),
|
| 145 |
+
KEY `idx_upline_id` (`upline_id`),
|
| 146 |
+
KEY `idx_downline_id` (`downline_id`),
|
| 147 |
+
CONSTRAINT `fk_hierarchy_upline` FOREIGN KEY (`upline_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 148 |
+
CONSTRAINT `fk_hierarchy_downline` FOREIGN KEY (`downline_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 149 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 150 |
+
|
| 151 |
+
CREATE TABLE `agents` (
|
| 152 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 153 |
+
`user_id` INT NOT NULL,
|
| 154 |
+
`full_name` VARCHAR(100) NOT NULL,
|
| 155 |
+
`phone` VARCHAR(20) NOT NULL,
|
| 156 |
+
`location` VARCHAR(100) NOT NULL,
|
| 157 |
+
`id_front` VARCHAR(255) DEFAULT NULL,
|
| 158 |
+
`id_back` VARCHAR(255) DEFAULT NULL,
|
| 159 |
+
`status` ENUM('pending','approved','rejected','documents_needed') DEFAULT 'pending',
|
| 160 |
+
`applied_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 161 |
+
`reviewed_at` TIMESTAMP DEFAULT NULL,
|
| 162 |
+
`reviewed_by` INT DEFAULT NULL,
|
| 163 |
+
`notes` TEXT,
|
| 164 |
+
PRIMARY KEY (`id`),
|
| 165 |
+
KEY `idx_user_id` (`user_id`),
|
| 166 |
+
KEY `idx_reviewed_by` (`reviewed_by`),
|
| 167 |
+
CONSTRAINT `fk_agents_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 168 |
+
CONSTRAINT `fk_agents_reviewed_by` FOREIGN KEY (`reviewed_by`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
| 169 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 170 |
+
|
| 171 |
+
CREATE TABLE `audit_logs` (
|
| 172 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 173 |
+
`user_id` INT DEFAULT NULL,
|
| 174 |
+
`action` VARCHAR(100) NOT NULL,
|
| 175 |
+
`description` TEXT,
|
| 176 |
+
`ip_address` VARCHAR(45) DEFAULT NULL,
|
| 177 |
+
`user_agent` TEXT,
|
| 178 |
+
`metadata` JSON DEFAULT NULL,
|
| 179 |
+
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 180 |
+
PRIMARY KEY (`id`),
|
| 181 |
+
KEY `idx_user_id` (`user_id`),
|
| 182 |
+
CONSTRAINT `fk_audit_logs_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
| 183 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 184 |
+
|
| 185 |
+
CREATE TABLE `balance_history` (
|
| 186 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 187 |
+
`user_id` INT NOT NULL,
|
| 188 |
+
`transaction_id` INT DEFAULT NULL,
|
| 189 |
+
`amount` DECIMAL(10,2) NOT NULL,
|
| 190 |
+
`balance_before` DECIMAL(10,2) NOT NULL,
|
| 191 |
+
`balance_after` DECIMAL(10,2) NOT NULL,
|
| 192 |
+
`type` ENUM('transfer_sent','transfer_received','deposit','withdrawal') DEFAULT NULL,
|
| 193 |
+
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 194 |
+
PRIMARY KEY (`id`),
|
| 195 |
+
KEY `idx_user_id` (`user_id`),
|
| 196 |
+
KEY `idx_transaction_id` (`transaction_id`),
|
| 197 |
+
CONSTRAINT `fk_balance_history_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 198 |
+
CONSTRAINT `fk_balance_history_transaction` FOREIGN KEY (`transaction_id`) REFERENCES `transactions` (`id`) ON DELETE SET NULL
|
| 199 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 200 |
+
|
| 201 |
+
CREATE TABLE `commissions` (
|
| 202 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 203 |
+
`upline_id` INT NOT NULL,
|
| 204 |
+
`downline_id` INT NOT NULL,
|
| 205 |
+
`advertisement_id` INT NOT NULL,
|
| 206 |
+
`amount` DECIMAL(10,2) NOT NULL,
|
| 207 |
+
`commission_rate` DECIMAL(5,2) NOT NULL,
|
| 208 |
+
`commission_amount` DECIMAL(10,2) NOT NULL,
|
| 209 |
+
`percentage` DECIMAL(5,2) NOT NULL,
|
| 210 |
+
`description` VARCHAR(255) DEFAULT NULL,
|
| 211 |
+
`status` ENUM('pending','paid','cancelled') DEFAULT 'pending',
|
| 212 |
+
`paid_at` TIMESTAMP NULL DEFAULT NULL,
|
| 213 |
+
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 214 |
+
PRIMARY KEY (`id`),
|
| 215 |
+
KEY `idx_upline_id` (`upline_id`),
|
| 216 |
+
KEY `idx_downline_id` (`downline_id`),
|
| 217 |
+
KEY `idx_advertisement_id` (`advertisement_id`),
|
| 218 |
+
CONSTRAINT `fk_commissions_upline` FOREIGN KEY (`upline_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 219 |
+
CONSTRAINT `fk_commissions_downline` FOREIGN KEY (`downline_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 220 |
+
CONSTRAINT `fk_commissions_advertisement` FOREIGN KEY (`advertisement_id`) REFERENCES `advertisements` (`id`) ON DELETE SET NULL
|
| 221 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 222 |
+
|
| 223 |
+
CREATE TABLE `currency_rates` (
|
| 224 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 225 |
+
`base_currency` VARCHAR(3) NOT NULL DEFAULT 'KES',
|
| 226 |
+
`target_currency` VARCHAR(3) NOT NULL,
|
| 227 |
+
`exchange_rate` DECIMAL(10,4) NOT NULL DEFAULT 1.0000,
|
| 228 |
+
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 229 |
+
PRIMARY KEY (`id`),
|
| 230 |
+
UNIQUE KEY `idx_currency_pair` (`base_currency`, `target_currency`)
|
| 231 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 232 |
+
|
| 233 |
+
CREATE TABLE `daily_earnings` (
|
| 234 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 235 |
+
`investment_id` INT NOT NULL,
|
| 236 |
+
`user_id` INT NOT NULL,
|
| 237 |
+
`amount` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 238 |
+
`earning_date` DATE NOT NULL,
|
| 239 |
+
`status` ENUM('pending','paid','reinvested') NOT NULL DEFAULT 'pending',
|
| 240 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 241 |
+
PRIMARY KEY (`id`),
|
| 242 |
+
KEY `idx_investment_id` (`investment_id`),
|
| 243 |
+
KEY `idx_user_id` (`user_id`),
|
| 244 |
+
CONSTRAINT `daily_earnings_ibfk_1` FOREIGN KEY (`investment_id`) REFERENCES `user_investments` (`id`) ON DELETE CASCADE,
|
| 245 |
+
CONSTRAINT `daily_earnings_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 246 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 247 |
+
|
| 248 |
+
CREATE TABLE `daily_token_stats` (
|
| 249 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 250 |
+
`user_id` INT NOT NULL,
|
| 251 |
+
`date` DATE NOT NULL,
|
| 252 |
+
`tokens_generated` INT NOT NULL DEFAULT 0,
|
| 253 |
+
`tokens_revoked` INT NOT NULL DEFAULT 0,
|
| 254 |
+
`api_calls` INT NOT NULL DEFAULT 0,
|
| 255 |
+
`total_processing_time_ms` INT NOT NULL DEFAULT 0,
|
| 256 |
+
`unique_endpoints` INT NOT NULL DEFAULT 0,
|
| 257 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 258 |
+
PRIMARY KEY (`id`),
|
| 259 |
+
UNIQUE KEY `unique_user_date` (`user_id`,`date`),
|
| 260 |
+
KEY `idx_date` (`date`),
|
| 261 |
+
CONSTRAINT `daily_token_stats_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 262 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 263 |
+
|
| 264 |
+
CREATE TABLE `eligibility_criteria` (
|
| 265 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 266 |
+
`min_deposit_amount` DECIMAL(15,2) NOT NULL DEFAULT 20000.00,
|
| 267 |
+
`min_account_age_months` INT NOT NULL DEFAULT 6,
|
| 268 |
+
`min_successful_uploads` INT NOT NULL DEFAULT 10,
|
| 269 |
+
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
| 270 |
+
`cooling_period_days` INT NOT NULL DEFAULT 30,
|
| 271 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 272 |
+
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 273 |
+
PRIMARY KEY (`id`)
|
| 274 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 275 |
+
|
| 276 |
+
CREATE TABLE `faqs` (
|
| 277 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 278 |
+
`question` TEXT NOT NULL,
|
| 279 |
+
`answer` TEXT NOT NULL,
|
| 280 |
+
`category` VARCHAR(50) DEFAULT NULL,
|
| 281 |
+
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
| 282 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 283 |
+
PRIMARY KEY (`id`)
|
| 284 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 285 |
+
|
| 286 |
+
CREATE TABLE `ledger` (
|
| 287 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 288 |
+
`user_id` INT NOT NULL,
|
| 289 |
+
`change_amount` DECIMAL(15,2) NOT NULL,
|
| 290 |
+
`balance_after` DECIMAL(15,2) NOT NULL,
|
| 291 |
+
`type` ENUM('deposit','withdrawal','transfer','reward','fee') NOT NULL,
|
| 292 |
+
`reference` VARCHAR(100) NOT NULL,
|
| 293 |
+
`description` TEXT DEFAULT NULL,
|
| 294 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 295 |
+
PRIMARY KEY (`id`),
|
| 296 |
+
KEY `user_id` (`user_id`),
|
| 297 |
+
CONSTRAINT `ledger_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 298 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 299 |
+
|
| 300 |
+
CREATE TABLE `loan_applications` (
|
| 301 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 302 |
+
`user_id` INT NOT NULL,
|
| 303 |
+
`amount` DECIMAL(15,2) NOT NULL,
|
| 304 |
+
`duration_days` INT NOT NULL,
|
| 305 |
+
`purpose` VARCHAR(255) NOT NULL,
|
| 306 |
+
`disbursement_method` ENUM('mpesa','bank','paypal') NOT NULL,
|
| 307 |
+
`mpesa_phone` VARCHAR(15) DEFAULT NULL,
|
| 308 |
+
`bank_name` VARCHAR(100) DEFAULT NULL,
|
| 309 |
+
`account_number` VARCHAR(50) DEFAULT NULL,
|
| 310 |
+
`account_name` VARCHAR(100) DEFAULT NULL,
|
| 311 |
+
`paypal_email` VARCHAR(100) DEFAULT NULL,
|
| 312 |
+
`notification_number` VARCHAR(15) NOT NULL,
|
| 313 |
+
`status` ENUM('pending','approved','rejected','disbursed','completed') NOT NULL DEFAULT 'pending',
|
| 314 |
+
`application_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 315 |
+
`approval_date` TIMESTAMP NULL DEFAULT NULL,
|
| 316 |
+
`due_date` DATE DEFAULT NULL,
|
| 317 |
+
`processing_fee` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 318 |
+
`interest_rate` DECIMAL(5,2) NOT NULL DEFAULT 5.00,
|
| 319 |
+
`total_repayment` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 320 |
+
PRIMARY KEY (`id`),
|
| 321 |
+
KEY `user_id` (`user_id`),
|
| 322 |
+
CONSTRAINT `loan_applications_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 323 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 324 |
+
|
| 325 |
+
CREATE TABLE `loan_repayments` (
|
| 326 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 327 |
+
`loan_id` INT NOT NULL,
|
| 328 |
+
`due_date` DATE NOT NULL,
|
| 329 |
+
`amount_due` DECIMAL(15,2) NOT NULL,
|
| 330 |
+
`amount_paid` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 331 |
+
`status` ENUM('pending','partial','paid','overdue') NOT NULL DEFAULT 'pending',
|
| 332 |
+
`payment_date` TIMESTAMP NULL DEFAULT NULL,
|
| 333 |
+
PRIMARY KEY (`id`),
|
| 334 |
+
KEY `loan_id` (`loan_id`),
|
| 335 |
+
CONSTRAINT `loan_repayments_ibfk_1` FOREIGN KEY (`loan_id`) REFERENCES `loan_applications` (`id`) ON DELETE CASCADE
|
| 336 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 337 |
+
|
| 338 |
+
CREATE TABLE `loans` (
|
| 339 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 340 |
+
`user_id` INT NOT NULL,
|
| 341 |
+
`amount` DECIMAL(15,2) NOT NULL,
|
| 342 |
+
`interest_rate` DECIMAL(5,2) NOT NULL DEFAULT 5.00,
|
| 343 |
+
`duration_days` INT NOT NULL,
|
| 344 |
+
`purpose` TEXT DEFAULT NULL,
|
| 345 |
+
`status` ENUM('pending','approved','rejected','active','paid') NOT NULL DEFAULT 'pending',
|
| 346 |
+
`approved_by` INT DEFAULT NULL,
|
| 347 |
+
`approved_at` DATETIME DEFAULT NULL,
|
| 348 |
+
`due_date` DATE DEFAULT NULL,
|
| 349 |
+
`amount_paid` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 350 |
+
`created_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
| 351 |
+
`updated_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 352 |
+
PRIMARY KEY (`id`),
|
| 353 |
+
KEY `user_id` (`user_id`),
|
| 354 |
+
KEY `approved_by` (`approved_by`),
|
| 355 |
+
CONSTRAINT `loans_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 356 |
+
CONSTRAINT `loans_ibfk_2` FOREIGN KEY (`approved_by`) REFERENCES `users` (`id`)
|
| 357 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 358 |
+
|
| 359 |
+
CREATE TABLE `main_account` (
|
| 360 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 361 |
+
`account_name` VARCHAR(100) NOT NULL DEFAULT 'JMotors Main Account',
|
| 362 |
+
`paybill_number` VARCHAR(20) DEFAULT NULL,
|
| 363 |
+
`account_number` VARCHAR(50) DEFAULT NULL,
|
| 364 |
+
`account_type` ENUM('paybill','bank','mpesa') NOT NULL DEFAULT 'paybill',
|
| 365 |
+
`total_balance` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 366 |
+
`total_deposits` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 367 |
+
`total_withdrawals` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 368 |
+
`currency` VARCHAR(3) NOT NULL DEFAULT 'KES',
|
| 369 |
+
`mpesa_phone` VARCHAR(20) DEFAULT NULL,
|
| 370 |
+
`created_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
| 371 |
+
`updated_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 372 |
+
PRIMARY KEY (`id`)
|
| 373 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 374 |
+
|
| 375 |
+
CREATE TABLE `meta_uploads` (
|
| 376 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 377 |
+
`user_id` INT NOT NULL,
|
| 378 |
+
`file_name` VARCHAR(255) NOT NULL,
|
| 379 |
+
`file_type` VARCHAR(50) NOT NULL,
|
| 380 |
+
`file_size` BIGINT NOT NULL,
|
| 381 |
+
`file_path` VARCHAR(500) NOT NULL,
|
| 382 |
+
`upload_date` DATE NOT NULL,
|
| 383 |
+
`status` ENUM('pending','approved','rejected') NOT NULL DEFAULT 'pending',
|
| 384 |
+
`reward_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 385 |
+
`reviewed_by` INT DEFAULT NULL,
|
| 386 |
+
`reviewed_at` TIMESTAMP NULL DEFAULT NULL,
|
| 387 |
+
`created_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
| 388 |
+
PRIMARY KEY (`id`),
|
| 389 |
+
KEY `user_id` (`user_id`),
|
| 390 |
+
KEY `reviewed_by` (`reviewed_by`)
|
| 391 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 392 |
+
|
| 393 |
+
CREATE TABLE `packages` (
|
| 394 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 395 |
+
`name` VARCHAR(50) NOT NULL,
|
| 396 |
+
`min_investment` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 397 |
+
`max_investment` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 398 |
+
`daily_return` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
|
| 399 |
+
`price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 400 |
+
`award` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 401 |
+
`return_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 402 |
+
`duration_days` INT NOT NULL DEFAULT 0,
|
| 403 |
+
`referral_bonus` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
|
| 404 |
+
`daily_return_percent` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
|
| 405 |
+
`features` TEXT,
|
| 406 |
+
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
| 407 |
+
`created_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
| 408 |
+
`updated_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 409 |
+
PRIMARY KEY (`id`)
|
| 410 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 411 |
+
|
| 412 |
+
CREATE TABLE `pin_setup` (
|
| 413 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 414 |
+
`user_id` INT NOT NULL,
|
| 415 |
+
`pin_hash` VARCHAR(255) NOT NULL DEFAULT '',
|
| 416 |
+
`setup_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 417 |
+
PRIMARY KEY (`id`),
|
| 418 |
+
KEY `user_id` (`user_id`),
|
| 419 |
+
CONSTRAINT `pin_setup_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 420 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 421 |
+
|
| 422 |
+
CREATE TABLE `products` (
|
| 423 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 424 |
+
`name` VARCHAR(100) NOT NULL DEFAULT '',
|
| 425 |
+
`value` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 426 |
+
`package_requirement` VARCHAR(50) NOT NULL DEFAULT 'all',
|
| 427 |
+
`image_url` VARCHAR(500) DEFAULT NULL,
|
| 428 |
+
`stock` INT NOT NULL DEFAULT 0,
|
| 429 |
+
`description` TEXT DEFAULT NULL,
|
| 430 |
+
`price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 431 |
+
`image_code` VARCHAR(10) NOT NULL DEFAULT '',
|
| 432 |
+
`cashback_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 433 |
+
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
| 434 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 435 |
+
PRIMARY KEY (`id`)
|
| 436 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 437 |
+
|
| 438 |
+
CREATE TABLE `recharge_transactions` (
|
| 439 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 440 |
+
`user_id` INT NOT NULL,
|
| 441 |
+
`main_account_id` INT NOT NULL,
|
| 442 |
+
`amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 443 |
+
`virtual_balance_before` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 444 |
+
`virtual_balance_after` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 445 |
+
`main_balance_before` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 446 |
+
`main_balance_after` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 447 |
+
`currency` VARCHAR(3) NOT NULL DEFAULT 'KES',
|
| 448 |
+
`payment_method` VARCHAR(50) NOT NULL DEFAULT '',
|
| 449 |
+
`phone_number` VARCHAR(20) NOT NULL DEFAULT '',
|
| 450 |
+
`mpesa_receipt` VARCHAR(100) DEFAULT NULL,
|
| 451 |
+
`transaction_id` VARCHAR(100) DEFAULT NULL,
|
| 452 |
+
`paybill_number` VARCHAR(20) NOT NULL DEFAULT '542542',
|
| 453 |
+
`account_number` VARCHAR(50) NOT NULL DEFAULT '00106664176150',
|
| 454 |
+
`status` ENUM('pending','completed','failed','verified') NOT NULL DEFAULT 'pending',
|
| 455 |
+
`bonus_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 456 |
+
`verified_by` INT DEFAULT NULL,
|
| 457 |
+
`verified_at` TIMESTAMP NULL DEFAULT NULL,
|
| 458 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 459 |
+
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 460 |
+
PRIMARY KEY (`id`),
|
| 461 |
+
KEY `user_id` (`user_id`),
|
| 462 |
+
KEY `fk_recharge_main` (`main_account_id`),
|
| 463 |
+
CONSTRAINT `fk_recharge_main` FOREIGN KEY (`main_account_id`) REFERENCES `main_account` (`id`),
|
| 464 |
+
CONSTRAINT `recharge_transactions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
|
| 465 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 466 |
+
|
| 467 |
+
CREATE TABLE `referrals` (
|
| 468 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 469 |
+
`referrer_id` INT NOT NULL,
|
| 470 |
+
`referred_id` INT NOT NULL,
|
| 471 |
+
`status` ENUM('pending','completed','cancelled') NOT NULL DEFAULT 'pending',
|
| 472 |
+
`commission_earned` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 473 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 474 |
+
PRIMARY KEY (`id`),
|
| 475 |
+
KEY `referrer_id` (`referrer_id`),
|
| 476 |
+
KEY `referred_id` (`referred_id`),
|
| 477 |
+
CONSTRAINT `referrals_ibfk_1` FOREIGN KEY (`referrer_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 478 |
+
CONSTRAINT `referrals_ibfk_2` FOREIGN KEY (`referred_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 479 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 480 |
+
|
| 481 |
+
CREATE TABLE `reward_settings` (
|
| 482 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 483 |
+
`setting_key` VARCHAR(50) NOT NULL,
|
| 484 |
+
`setting_value` VARCHAR(255) NOT NULL,
|
| 485 |
+
`description` TEXT DEFAULT NULL,
|
| 486 |
+
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 487 |
+
PRIMARY KEY (`id`),
|
| 488 |
+
UNIQUE KEY `setting_key` (`setting_key`)
|
| 489 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 490 |
+
|
| 491 |
+
CREATE TABLE `reward_transactions` (
|
| 492 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 493 |
+
`user_id` INT NOT NULL,
|
| 494 |
+
`type` ENUM('upload','bonus','withdrawal') NOT NULL,
|
| 495 |
+
`amount` DECIMAL(10,2) NOT NULL,
|
| 496 |
+
`description` VARCHAR(255) DEFAULT NULL,
|
| 497 |
+
`reference_id` INT DEFAULT NULL,
|
| 498 |
+
`status` ENUM('pending','completed','failed') NOT NULL DEFAULT 'completed',
|
| 499 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 500 |
+
PRIMARY KEY (`id`),
|
| 501 |
+
KEY `user_id` (`user_id`),
|
| 502 |
+
CONSTRAINT `reward_transactions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 503 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 504 |
+
|
| 505 |
+
CREATE TABLE `sessions` (
|
| 506 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 507 |
+
`user_id` INT NOT NULL,
|
| 508 |
+
`session_token` VARCHAR(255) NOT NULL,
|
| 509 |
+
`ip_address` VARCHAR(45) DEFAULT NULL,
|
| 510 |
+
`user_agent` TEXT,
|
| 511 |
+
`expires_at` DATETIME NOT NULL,
|
| 512 |
+
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
| 513 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 514 |
+
PRIMARY KEY (`id`),
|
| 515 |
+
UNIQUE KEY `session_token` (`session_token`),
|
| 516 |
+
KEY `user_id` (`user_id`),
|
| 517 |
+
CONSTRAINT `sessions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 518 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 519 |
+
|
| 520 |
+
CREATE TABLE `support_agents` (
|
| 521 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 522 |
+
`name` VARCHAR(100) NOT NULL,
|
| 523 |
+
`email` VARCHAR(255) NOT NULL,
|
| 524 |
+
`phone` VARCHAR(20) DEFAULT NULL,
|
| 525 |
+
`department` VARCHAR(50) DEFAULT NULL,
|
| 526 |
+
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
| 527 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 528 |
+
PRIMARY KEY (`id`),
|
| 529 |
+
UNIQUE KEY `email` (`email`)
|
| 530 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 531 |
+
|
| 532 |
+
CREATE TABLE `support_tickets` (
|
| 533 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 534 |
+
`user_id` int DEFAULT NULL,
|
| 535 |
+
`ticket_number` varchar(20) NOT NULL,
|
| 536 |
+
`issue_type` enum('technical','account','payment','product','other') NOT NULL,
|
| 537 |
+
`subject` varchar(200) NOT NULL,
|
| 538 |
+
`description` text NOT NULL,
|
| 539 |
+
`status` enum('open','in_progress','resolved','closed') DEFAULT 'open',
|
| 540 |
+
`priority` enum('low','medium','high','urgent') DEFAULT 'medium',
|
| 541 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 542 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 543 |
+
PRIMARY KEY (`id`),
|
| 544 |
+
UNIQUE KEY `ticket_number` (`ticket_number`),
|
| 545 |
+
KEY `user_id` (`user_id`),
|
| 546 |
+
CONSTRAINT `support_tickets_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 547 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 548 |
+
|
| 549 |
+
CREATE TABLE `support_users` (
|
| 550 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 551 |
+
`username` VARCHAR(100) NOT NULL,
|
| 552 |
+
`email` VARCHAR(255) NOT NULL,
|
| 553 |
+
`tier` VARCHAR(50) NOT NULL DEFAULT 'standard',
|
| 554 |
+
`package` VARCHAR(50) NOT NULL DEFAULT 'basic',
|
| 555 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 556 |
+
PRIMARY KEY (`id`),
|
| 557 |
+
UNIQUE KEY `email` (`email`)
|
| 558 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 559 |
+
|
| 560 |
+
CREATE TABLE `system_config` (
|
| 561 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 562 |
+
`config_key` VARCHAR(100) NOT NULL,
|
| 563 |
+
`config_value` TEXT NOT NULL,
|
| 564 |
+
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 565 |
+
PRIMARY KEY (`id`),
|
| 566 |
+
UNIQUE KEY `config_key` (`config_key`)
|
| 567 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 568 |
+
|
| 569 |
+
CREATE TABLE `team_relationships` (
|
| 570 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 571 |
+
`sponsor_id` INT NOT NULL,
|
| 572 |
+
`agent_id` INT NOT NULL,
|
| 573 |
+
`level` INT NOT NULL,
|
| 574 |
+
`status` ENUM('active','inactive') NOT NULL DEFAULT 'active',
|
| 575 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 576 |
+
PRIMARY KEY (`id`),
|
| 577 |
+
UNIQUE KEY `unique_relationship` (`sponsor_id`,`agent_id`),
|
| 578 |
+
KEY `agent_id` (`agent_id`),
|
| 579 |
+
CONSTRAINT `team_relationships_ibfk_1` FOREIGN KEY (`sponsor_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 580 |
+
CONSTRAINT `team_relationships_ibfk_2` FOREIGN KEY (`agent_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 581 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 582 |
+
|
| 583 |
+
CREATE TABLE `ticket_assignments` (
|
| 584 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 585 |
+
`ticket_id` INT NOT NULL,
|
| 586 |
+
`agent_id` INT NOT NULL,
|
| 587 |
+
`assigned_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 588 |
+
PRIMARY KEY (`id`),
|
| 589 |
+
KEY `ticket_id` (`ticket_id`),
|
| 590 |
+
KEY `agent_id` (`agent_id`),
|
| 591 |
+
CONSTRAINT `ticket_assignments_ibfk_1` FOREIGN KEY (`ticket_id`) REFERENCES `support_tickets` (`id`) ON DELETE CASCADE,
|
| 592 |
+
CONSTRAINT `ticket_assignments_ibfk_2` FOREIGN KEY (`agent_id`) REFERENCES `support_agents` (`id`) ON DELETE CASCADE
|
| 593 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 594 |
+
|
| 595 |
+
CREATE TABLE `ticket_responses` (
|
| 596 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 597 |
+
`ticket_id` INT NOT NULL,
|
| 598 |
+
`responder_type` ENUM('user','support_agent') NOT NULL,
|
| 599 |
+
`message` TEXT NOT NULL,
|
| 600 |
+
`attachments` TEXT,
|
| 601 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 602 |
+
PRIMARY KEY (`id`),
|
| 603 |
+
KEY `ticket_id` (`ticket_id`),
|
| 604 |
+
CONSTRAINT `ticket_responses_ibfk_1` FOREIGN KEY (`ticket_id`) REFERENCES `support_tickets` (`id`) ON DELETE CASCADE
|
| 605 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 606 |
+
|
| 607 |
+
CREATE TABLE `token_usage_logs` (
|
| 608 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 609 |
+
`token_id` INT NOT NULL,
|
| 610 |
+
`user_id` INT NOT NULL,
|
| 611 |
+
`endpoint` VARCHAR(100) NOT NULL,
|
| 612 |
+
`ip_address` VARCHAR(45),
|
| 613 |
+
`user_agent` TEXT,
|
| 614 |
+
`request_method` VARCHAR(10),
|
| 615 |
+
`response_code` INT,
|
| 616 |
+
`processing_time_ms` INT,
|
| 617 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 618 |
+
PRIMARY KEY (`id`),
|
| 619 |
+
KEY `user_id` (`user_id`),
|
| 620 |
+
KEY `idx_created_at` (`created_at`),
|
| 621 |
+
KEY `idx_token_id` (`token_id`),
|
| 622 |
+
CONSTRAINT `token_usage_logs_ibfk_1` FOREIGN KEY (`token_id`) REFERENCES `access_tokens` (`id`) ON DELETE CASCADE,
|
| 623 |
+
CONSTRAINT `token_usage_logs_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 624 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 625 |
+
|
| 626 |
+
CREATE TABLE `transactions` (
|
| 627 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 628 |
+
`sender_id` INT NOT NULL,
|
| 629 |
+
`user_id` INT NOT NULL,
|
| 630 |
+
`recipient_id` INT NOT NULL,
|
| 631 |
+
`type` ENUM('deposit','withdrawal','product_purchase','cashback') NOT NULL,
|
| 632 |
+
`amount` DECIMAL(10,2) NOT NULL,
|
| 633 |
+
`balance_after` DECIMAL(10,2) NOT NULL,
|
| 634 |
+
`description` TEXT,
|
| 635 |
+
`message` TEXT,
|
| 636 |
+
`transaction_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 637 |
+
`reference` VARCHAR(100),
|
| 638 |
+
`status` ENUM('pending','completed','failed') DEFAULT 'pending',
|
| 639 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 640 |
+
`completed_at` TIMESTAMP,
|
| 641 |
+
PRIMARY KEY (`id`),
|
| 642 |
+
KEY `fk_sender` (`sender_id`),
|
| 643 |
+
KEY `fk_recipient` (`recipient_id`),
|
| 644 |
+
KEY `fk_transactions_user` (`user_id`),
|
| 645 |
+
CONSTRAINT `fk_sender` FOREIGN KEY (`sender_id`) REFERENCES `users` (`id`),
|
| 646 |
+
CONSTRAINT `fk_recipient` FOREIGN KEY (`recipient_id`) REFERENCES `users` (`id`),
|
| 647 |
+
CONSTRAINT `fk_transactions_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 648 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 649 |
+
|
| 650 |
+
CREATE TABLE `transaction_verifications` (
|
| 651 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 652 |
+
`transaction_id` INT,
|
| 653 |
+
`user_id` INT,
|
| 654 |
+
`amount` DECIMAL(10,2),
|
| 655 |
+
`paybill_number` VARCHAR(20),
|
| 656 |
+
`account_number` VARCHAR(50),
|
| 657 |
+
`mpesa_receipt` VARCHAR(100),
|
| 658 |
+
`screenshot_path` VARCHAR(255),
|
| 659 |
+
`status` ENUM('pending','approved','rejected') DEFAULT 'pending',
|
| 660 |
+
`reviewed_by` INT,
|
| 661 |
+
`reviewed_at` TIMESTAMP,
|
| 662 |
+
`notes` TEXT,
|
| 663 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 664 |
+
PRIMARY KEY (`id`),
|
| 665 |
+
KEY `fk_transaction` (`transaction_id`),
|
| 666 |
+
KEY `fk_user` (`user_id`),
|
| 667 |
+
CONSTRAINT `fk_transaction` FOREIGN KEY (`transaction_id`) REFERENCES `recharge_transactions` (`id`) ON DELETE SET NULL,
|
| 668 |
+
CONSTRAINT `fk_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
| 669 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 670 |
+
|
| 671 |
+
CREATE TABLE `upload_rewards` (
|
| 672 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 673 |
+
`user_id` INT NOT NULL,
|
| 674 |
+
`upload_date` DATE NOT NULL,
|
| 675 |
+
`total_uploads` INT DEFAULT 0,
|
| 676 |
+
`completed_uploads` INT DEFAULT 0,
|
| 677 |
+
`total_reward` DECIMAL(10,2) DEFAULT 0.00,
|
| 678 |
+
`status` ENUM('pending','processed') DEFAULT 'pending',
|
| 679 |
+
`processed_at` TIMESTAMP,
|
| 680 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 681 |
+
PRIMARY KEY (`id`),
|
| 682 |
+
UNIQUE KEY `unique_user_date` (`user_id`,`upload_date`),
|
| 683 |
+
CONSTRAINT `fk_upload_rewards_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 684 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 685 |
+
|
| 686 |
+
CREATE TABLE `user_accounts` (
|
| 687 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 688 |
+
`user_id` INT,
|
| 689 |
+
`virtual_account_number` VARCHAR(50) UNIQUE,
|
| 690 |
+
`current_balance` DECIMAL(15,2) DEFAULT 0.00,
|
| 691 |
+
`total_invested` DECIMAL(15,2) DEFAULT 0.00,
|
| 692 |
+
`total_earnings` DECIMAL(15,2) DEFAULT 0.00,
|
| 693 |
+
`total_withdrawn` DECIMAL(15,2) DEFAULT 0.00,
|
| 694 |
+
`currency` VARCHAR(3) DEFAULT 'KES',
|
| 695 |
+
`status` ENUM('active','suspended','closed') DEFAULT 'active',
|
| 696 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 697 |
+
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 698 |
+
PRIMARY KEY (`id`),
|
| 699 |
+
KEY `idx_user_id` (`user_id`),
|
| 700 |
+
CONSTRAINT `fk_user_accounts_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 701 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 702 |
+
|
| 703 |
+
CREATE TABLE `user_activity` (
|
| 704 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 705 |
+
`user_id` INT,
|
| 706 |
+
`activity_type` VARCHAR(50),
|
| 707 |
+
`description` TEXT,
|
| 708 |
+
`ip_address` VARCHAR(45),
|
| 709 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 710 |
+
PRIMARY KEY (`id`),
|
| 711 |
+
KEY `idx_user_id` (`user_id`),
|
| 712 |
+
CONSTRAINT `fk_user_activity_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 713 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 714 |
+
|
| 715 |
+
CREATE TABLE `user_channel_subscriptions` (
|
| 716 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 717 |
+
`user_id` INT,
|
| 718 |
+
`channel_id` INT,
|
| 719 |
+
`subscribed_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 720 |
+
PRIMARY KEY (`id`),
|
| 721 |
+
UNIQUE KEY `uniq_user_channel` (`user_id`,`channel_id`),
|
| 722 |
+
KEY `idx_channel_id` (`channel_id`),
|
| 723 |
+
CONSTRAINT `fk_user_channel_subscriptions_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 724 |
+
CONSTRAINT `fk_user_channel_subscriptions_channel` FOREIGN KEY (`channel_id`) REFERENCES `whatsapp_channels` (`id`) ON DELETE CASCADE
|
| 725 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 726 |
+
|
| 727 |
+
CREATE TABLE `user_investments` (
|
| 728 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 729 |
+
`user_id` INT NOT NULL,
|
| 730 |
+
`package_id` INT NOT NULL,
|
| 731 |
+
`amount` DECIMAL(15,2) NOT NULL,
|
| 732 |
+
`start_date` DATETIME NOT NULL,
|
| 733 |
+
`end_date` DATETIME NOT NULL,
|
| 734 |
+
`status` ENUM('active','completed','cancelled') NOT NULL DEFAULT 'active',
|
| 735 |
+
`total_earnings` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 736 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 737 |
+
PRIMARY KEY (`id`),
|
| 738 |
+
KEY `idx_user_id` (`user_id`),
|
| 739 |
+
KEY `idx_package_id` (`package_id`),
|
| 740 |
+
CONSTRAINT `fk_user_investments_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 741 |
+
CONSTRAINT `fk_user_investments_package` FOREIGN KEY (`package_id`) REFERENCES `packages` (`id`) ON DELETE CASCADE
|
| 742 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 743 |
+
|
| 744 |
+
CREATE TABLE `user_packages` (
|
| 745 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 746 |
+
`user_id` INT NOT NULL,
|
| 747 |
+
`package_id` INT NOT NULL,
|
| 748 |
+
`purchase_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 749 |
+
`start_date` DATETIME NULL DEFAULT NULL,
|
| 750 |
+
`end_date` DATETIME NULL DEFAULT NULL,
|
| 751 |
+
`amount_paid` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 752 |
+
`status` ENUM('active','completed','cancelled') NOT NULL DEFAULT 'active',
|
| 753 |
+
`investment_amount` DECIMAL(10,2) NOT NULL,
|
| 754 |
+
`expected_return` DECIMAL(10,2) NOT NULL,
|
| 755 |
+
PRIMARY KEY (`id`),
|
| 756 |
+
KEY `idx_user_id` (`user_id`),
|
| 757 |
+
KEY `idx_package_id` (`package_id`),
|
| 758 |
+
CONSTRAINT `fk_user_packages_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 759 |
+
CONSTRAINT `fk_user_packages_package` FOREIGN KEY (`package_id`) REFERENCES `packages` (`id`) ON DELETE CASCADE
|
| 760 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 761 |
+
|
| 762 |
+
CREATE TABLE `user_products` (
|
| 763 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 764 |
+
`user_id` INT NOT NULL,
|
| 765 |
+
`product_id` INT NOT NULL,
|
| 766 |
+
`investment_id` INT NOT NULL,
|
| 767 |
+
`assigned_date` DATE NOT NULL,
|
| 768 |
+
`purchase_price` DECIMAL(10,2) NOT NULL,
|
| 769 |
+
`cashback_received` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
| 770 |
+
`purchase_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 771 |
+
`status` ENUM('active','completed','cancelled') NOT NULL DEFAULT 'active',
|
| 772 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 773 |
+
PRIMARY KEY (`id`),
|
| 774 |
+
KEY `idx_user_id` (`user_id`),
|
| 775 |
+
KEY `idx_product_id` (`product_id`),
|
| 776 |
+
CONSTRAINT `fk_user_products_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 777 |
+
CONSTRAINT `fk_user_products_product` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE CASCADE
|
| 778 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 779 |
+
|
| 780 |
+
CREATE TABLE `user_profiles` (
|
| 781 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 782 |
+
`user_id` INT NOT NULL,
|
| 783 |
+
`first_name` VARCHAR(50),
|
| 784 |
+
`last_name` VARCHAR(50),
|
| 785 |
+
`date_of_birth` DATE,
|
| 786 |
+
`gender` ENUM('Male','Female','Other'),
|
| 787 |
+
`profile_picture` VARCHAR(255),
|
| 788 |
+
`address` TEXT,
|
| 789 |
+
`city` VARCHAR(50),
|
| 790 |
+
`state` VARCHAR(50),
|
| 791 |
+
`zip_code` VARCHAR(20),
|
| 792 |
+
`bio` TEXT,
|
| 793 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 794 |
+
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 795 |
+
PRIMARY KEY (`id`),
|
| 796 |
+
KEY `idx_user_id` (`user_id`),
|
| 797 |
+
CONSTRAINT `fk_user_profiles_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 798 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 799 |
+
|
| 800 |
+
CREATE TABLE `users` (
|
| 801 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 802 |
+
`user_type` ENUM('marketer','agent','admin') NOT NULL DEFAULT 'marketer',
|
| 803 |
+
`referred_by` INT,
|
| 804 |
+
`username` VARCHAR(50) NOT NULL,
|
| 805 |
+
`email` VARCHAR(100) NOT NULL,
|
| 806 |
+
`country` CHAR(2) NOT NULL,
|
| 807 |
+
`phone_number` VARCHAR(20) NOT NULL,
|
| 808 |
+
`tier` ENUM('Basic','Premium') NOT NULL DEFAULT 'Basic',
|
| 809 |
+
`current_package_id` INT,
|
| 810 |
+
`package_start_date` DATETIME,
|
| 811 |
+
`package_end_date` DATETIME,
|
| 812 |
+
`package` ENUM('None','NOVA','SUPERIOR','GOLD') NOT NULL DEFAULT 'None',
|
| 813 |
+
`balance` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 814 |
+
`verification_token` VARCHAR(100),
|
| 815 |
+
`reset_token` VARCHAR(100),
|
| 816 |
+
`reset_token_expiry` DATETIME,
|
| 817 |
+
`total_invested` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 818 |
+
`total_earnings` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 819 |
+
`total_deposits` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 820 |
+
`total_withdrawals` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 821 |
+
`rewards` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 822 |
+
`meta_earnings` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 823 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 824 |
+
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 825 |
+
`last_login` TIMESTAMP,
|
| 826 |
+
`pin_hash` VARCHAR(255) NOT NULL,
|
| 827 |
+
`password_hash` VARCHAR(255) NOT NULL,
|
| 828 |
+
`currency` CHAR(3) NOT NULL DEFAULT 'KES',
|
| 829 |
+
`exchange_rate` DECIMAL(10,4) NOT NULL DEFAULT 1.0000,
|
| 830 |
+
`referral_code` VARCHAR(20),
|
| 831 |
+
PRIMARY KEY (`id`),
|
| 832 |
+
UNIQUE KEY `uk_users_username` (`username`),
|
| 833 |
+
UNIQUE KEY `uk_users_email` (`email`),
|
| 834 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 835 |
+
|
| 836 |
+
CREATE TABLE `user_security` (
|
| 837 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 838 |
+
`user_id` INT NOT NULL,
|
| 839 |
+
`two_factor_enabled` TINYINT(1) NOT NULL DEFAULT 0,
|
| 840 |
+
`two_factor_secret` VARCHAR(32),
|
| 841 |
+
`password_reset_token` VARCHAR(100),
|
| 842 |
+
`reset_token_expires` TIMESTAMP,
|
| 843 |
+
`login_attempts` INT NOT NULL DEFAULT 0,
|
| 844 |
+
`last_login_attempt` TIMESTAMP,
|
| 845 |
+
PRIMARY KEY (`id`),
|
| 846 |
+
UNIQUE KEY `uk_user_security_user_id` (`user_id`),
|
| 847 |
+
CONSTRAINT `fk_user_security_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 848 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 849 |
+
|
| 850 |
+
CREATE TABLE `user_settings` (
|
| 851 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 852 |
+
`user_id` INT NOT NULL,
|
| 853 |
+
`dark_mode` TINYINT(1) NOT NULL DEFAULT 1,
|
| 854 |
+
`language` VARCHAR(10) NOT NULL DEFAULT 'en',
|
| 855 |
+
`currency` VARCHAR(3) NOT NULL DEFAULT 'KES',
|
| 856 |
+
`auto_logout` TINYINT(1) NOT NULL DEFAULT 1,
|
| 857 |
+
`email_notifications` TINYINT(1) NOT NULL DEFAULT 1,
|
| 858 |
+
`push_notifications` TINYINT(1) NOT NULL DEFAULT 1,
|
| 859 |
+
PRIMARY KEY (`id`),
|
| 860 |
+
UNIQUE KEY `uk_user_settings_user_id` (`user_id`),
|
| 861 |
+
CONSTRAINT `fk_user_settings_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 862 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 863 |
+
|
| 864 |
+
CREATE TABLE `whatsapp_channels` (
|
| 865 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 866 |
+
`channel_name` VARCHAR(100) NOT NULL,
|
| 867 |
+
`channel_type` ENUM('group','channel','tips','elite') NOT NULL,
|
| 868 |
+
`whatsapp_link` VARCHAR(500) NOT NULL,
|
| 869 |
+
`description` TEXT DEFAULT NULL,
|
| 870 |
+
`icon_class` VARCHAR(50) DEFAULT NULL,
|
| 871 |
+
`color_class` VARCHAR(50) DEFAULT NULL,
|
| 872 |
+
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
| 873 |
+
`member_count` INT NOT NULL DEFAULT 0,
|
| 874 |
+
`max_capacity` INT NOT NULL DEFAULT 1000,
|
| 875 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 876 |
+
PRIMARY KEY (`id`)
|
| 877 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 878 |
+
|
| 879 |
+
CREATE TABLE `withdrawal_destinations` (
|
| 880 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 881 |
+
`user_id` INT NOT NULL,
|
| 882 |
+
`type` ENUM('mpesa','bank','airtel','tkash') NOT NULL,
|
| 883 |
+
`details` VARCHAR(255) NOT NULL,
|
| 884 |
+
`is_default` TINYINT(1) NOT NULL DEFAULT 0,
|
| 885 |
+
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
| 886 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 887 |
+
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 888 |
+
PRIMARY KEY (`id`),
|
| 889 |
+
KEY `user_id` (`user_id`),
|
| 890 |
+
CONSTRAINT `withdrawal_destinations_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 891 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 892 |
+
|
| 893 |
+
CREATE TABLE `withdrawals` (
|
| 894 |
+
`id` INT NOT NULL AUTO_INCREMENT,
|
| 895 |
+
`user_id` INT NOT NULL,
|
| 896 |
+
`destination_id` INT NOT NULL,
|
| 897 |
+
`amount` DECIMAL(15,2) NOT NULL,
|
| 898 |
+
`fee` DECIMAL(15,2) NOT NULL DEFAULT 0.00,
|
| 899 |
+
`net_amount` DECIMAL(15,2) NOT NULL,
|
| 900 |
+
`status` ENUM('pending','processing','completed','failed','cancelled') NOT NULL DEFAULT 'pending',
|
| 901 |
+
`idempotency_key` VARCHAR(255) NOT NULL,
|
| 902 |
+
`reference` VARCHAR(100) NOT NULL,
|
| 903 |
+
`failure_reason` TEXT,
|
| 904 |
+
`processed_at` TIMESTAMP NULL DEFAULT NULL,
|
| 905 |
+
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 906 |
+
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 907 |
+
PRIMARY KEY (`id`),
|
| 908 |
+
UNIQUE KEY `idempotency_key` (`idempotency_key`),
|
| 909 |
+
KEY `user_id` (`user_id`),
|
| 910 |
+
KEY `destination_id` (`destination_id`),
|
| 911 |
+
CONSTRAINT `withdrawals_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 912 |
+
CONSTRAINT `withdrawals_ibfk_2` FOREIGN KEY (`destination_id`) REFERENCES `withdrawal_destinations` (`id`) ON DELETE CASCADE
|
| 913 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 914 |
+
|
| 915 |
+
CREATE VIEW `user_teams` AS
|
| 916 |
+
SELECT
|
| 917 |
+
u.id AS user_id,
|
| 918 |
+
u.username,
|
| 919 |
+
u.referral_code,
|
| 920 |
+
COUNT(r.referred_id) AS team_size,
|
| 921 |
+
COALESCE(SUM(ref.commission_earned), 0) AS total_earnings
|
| 922 |
+
FROM
|
| 923 |
+
users u
|
| 924 |
+
LEFT JOIN
|
| 925 |
+
referrals r ON u.id = r.referrer_id
|
| 926 |
+
LEFT JOIN
|
| 927 |
+
referrals ref ON u.id = ref.referrer_id AND ref.status = 'completed'
|
| 928 |
+
GROUP BY
|
| 929 |
+
u.id, u.username, u.referral_code;
|
| 930 |
+
|
jweb/ac1/assets/database/mdb.sql
ADDED
|
@@ -0,0 +1,936 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
CREATE TABLE `access_tokens` (
|
| 2 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 3 |
+
`user_id` int NOT NULL,
|
| 4 |
+
`name` varchar(100) NOT NULL,
|
| 5 |
+
`token` varchar(255) NOT NULL,
|
| 6 |
+
`permissions` json NOT NULL,
|
| 7 |
+
`ip_restrictions` text,
|
| 8 |
+
`expires_at` datetime DEFAULT NULL,
|
| 9 |
+
`status` enum('active','revoked') DEFAULT 'active',
|
| 10 |
+
`is_revoked` tinyint(1) DEFAULT '0',
|
| 11 |
+
`last_used` timestamp NULL DEFAULT NULL,
|
| 12 |
+
`usage_count` int DEFAULT '0',
|
| 13 |
+
`metadata` json DEFAULT NULL,
|
| 14 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 15 |
+
PRIMARY KEY (`id`),
|
| 16 |
+
KEY `idx_token_value` (`token`),
|
| 17 |
+
KEY `idx_user_id` (`user_id`),
|
| 18 |
+
KEY `idx_expires_at` (`expires_at`),
|
| 19 |
+
CONSTRAINT `access_tokens_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 20 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 21 |
+
|
| 22 |
+
CREATE TABLE `admin_payments` (
|
| 23 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 24 |
+
`user_id` int DEFAULT NULL,
|
| 25 |
+
`amount` decimal(10,2) DEFAULT NULL,
|
| 26 |
+
`mpesa_code` varchar(20) DEFAULT NULL,
|
| 27 |
+
`phone_number` varchar(20) DEFAULT NULL,
|
| 28 |
+
`status` enum('pending','verified','rejected') DEFAULT 'pending',
|
| 29 |
+
`verified_by` int DEFAULT NULL,
|
| 30 |
+
`verified_at` timestamp NULL DEFAULT NULL,
|
| 31 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 32 |
+
PRIMARY KEY (`id`),
|
| 33 |
+
KEY `user_id` (`user_id`),
|
| 34 |
+
CONSTRAINT `admin_payments_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
|
| 35 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 36 |
+
|
| 37 |
+
CREATE TABLE `advertisement_payments` (
|
| 38 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 39 |
+
`advertisement_id` int NOT NULL,
|
| 40 |
+
`user_id` int NOT NULL,
|
| 41 |
+
`amount` decimal(10,2) NOT NULL,
|
| 42 |
+
`payment_method` enum('mpesa','bank_transfer','wallet','card') DEFAULT 'mpesa',
|
| 43 |
+
`transaction_code` varchar(100) DEFAULT NULL,
|
| 44 |
+
`status` enum('pending','completed','failed','refunded') DEFAULT 'pending',
|
| 45 |
+
`payment_date` timestamp NULL DEFAULT NULL,
|
| 46 |
+
`confirmed_by` int DEFAULT NULL,
|
| 47 |
+
`confirmed_at` timestamp NULL DEFAULT NULL,
|
| 48 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 49 |
+
PRIMARY KEY (`id`),
|
| 50 |
+
KEY `advertisement_id` (`advertisement_id`),
|
| 51 |
+
KEY `user_id` (`user_id`),
|
| 52 |
+
KEY `confirmed_by` (`confirmed_by`),
|
| 53 |
+
CONSTRAINT `advertisement_payments_ibfk_1` FOREIGN KEY (`advertisement_id`) REFERENCES `advertisements` (`id`),
|
| 54 |
+
CONSTRAINT `advertisement_payments_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
|
| 55 |
+
CONSTRAINT `advertisement_payments_ibfk_3` FOREIGN KEY (`confirmed_by`) REFERENCES `users` (`id`)
|
| 56 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 57 |
+
|
| 58 |
+
CREATE TABLE `advertisements` (
|
| 59 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 60 |
+
`user_id` int NOT NULL,
|
| 61 |
+
`agent_id` int DEFAULT NULL,
|
| 62 |
+
`title` varchar(255) NOT NULL,
|
| 63 |
+
`description` text,
|
| 64 |
+
`image_url` varchar(500) DEFAULT NULL,
|
| 65 |
+
`video_url` varchar(500) DEFAULT NULL,
|
| 66 |
+
`target_platform` enum('facebook','instagram','whatsapp','twitter','all') DEFAULT 'all',
|
| 67 |
+
`budget` decimal(10,2) NOT NULL,
|
| 68 |
+
`duration_days` int DEFAULT '7',
|
| 69 |
+
`status` enum('pending','approved','rejected','active','completed','paused') DEFAULT 'pending',
|
| 70 |
+
`admin_notes` text,
|
| 71 |
+
`approved_by` int DEFAULT NULL,
|
| 72 |
+
`approved_at` timestamp NULL DEFAULT NULL,
|
| 73 |
+
`start_date` date DEFAULT NULL,
|
| 74 |
+
`end_date` date DEFAULT NULL,
|
| 75 |
+
`impressions` int DEFAULT '0',
|
| 76 |
+
`clicks` int DEFAULT '0',
|
| 77 |
+
`conversions` int DEFAULT '0',
|
| 78 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 79 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 80 |
+
PRIMARY KEY (`id`),
|
| 81 |
+
KEY `user_id` (`user_id`),
|
| 82 |
+
KEY `agent_id` (`agent_id`),
|
| 83 |
+
KEY `approved_by` (`approved_by`),
|
| 84 |
+
CONSTRAINT `advertisements_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
|
| 85 |
+
CONSTRAINT `advertisements_ibfk_2` FOREIGN KEY (`agent_id`) REFERENCES `users` (`id`),
|
| 86 |
+
CONSTRAINT `advertisements_ibfk_3` FOREIGN KEY (`approved_by`) REFERENCES `users` (`id`)
|
| 87 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 88 |
+
|
| 89 |
+
CREATE TABLE `agent_applications` (
|
| 90 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 91 |
+
`user_id` int NOT NULL,
|
| 92 |
+
`sponsor_id` int NOT NULL,
|
| 93 |
+
`full_name` varchar(255) NOT NULL,
|
| 94 |
+
`phone` varchar(20) NOT NULL,
|
| 95 |
+
`email` varchar(255) DEFAULT NULL,
|
| 96 |
+
`location` varchar(255) NOT NULL,
|
| 97 |
+
`id_front` varchar(500) DEFAULT NULL,
|
| 98 |
+
`id_back` varchar(500) DEFAULT NULL,
|
| 99 |
+
`status` enum('pending','approved','rejected','documents_needed') DEFAULT 'pending',
|
| 100 |
+
`applied_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 101 |
+
`reviewed_by` int DEFAULT NULL,
|
| 102 |
+
`reviewed_at` timestamp NULL DEFAULT NULL,
|
| 103 |
+
`review_notes` text,
|
| 104 |
+
`commission_rate` decimal(5,2) DEFAULT '10.00',
|
| 105 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 106 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 107 |
+
PRIMARY KEY (`id`),
|
| 108 |
+
KEY `user_id` (`user_id`),
|
| 109 |
+
KEY `sponsor_id` (`sponsor_id`),
|
| 110 |
+
KEY `reviewed_by` (`reviewed_by`),
|
| 111 |
+
CONSTRAINT `agent_applications_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
|
| 112 |
+
CONSTRAINT `agent_applications_ibfk_2` FOREIGN KEY (`sponsor_id`) REFERENCES `users` (`id`),
|
| 113 |
+
CONSTRAINT `agent_applications_ibfk_3` FOREIGN KEY (`reviewed_by`) REFERENCES `users` (`id`)
|
| 114 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 115 |
+
|
| 116 |
+
CREATE TABLE `agent_claims` (
|
| 117 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 118 |
+
`user_id` int NOT NULL,
|
| 119 |
+
`claim_type` enum('commission','bonus','referral','override','other') NOT NULL,
|
| 120 |
+
`amount` decimal(15,2) NOT NULL,
|
| 121 |
+
`description` text,
|
| 122 |
+
`claim_period` varchar(50) DEFAULT NULL,
|
| 123 |
+
`status` enum('pending','approved','rejected','processing') DEFAULT 'pending',
|
| 124 |
+
`approved_by` int DEFAULT NULL,
|
| 125 |
+
`approved_amount` decimal(15,2) DEFAULT NULL,
|
| 126 |
+
`approval_notes` text,
|
| 127 |
+
`approved_at` datetime DEFAULT NULL,
|
| 128 |
+
`supporting_docs` json DEFAULT NULL,
|
| 129 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 130 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 131 |
+
PRIMARY KEY (`id`),
|
| 132 |
+
KEY `approved_by` (`approved_by`),
|
| 133 |
+
KEY `idx_user_id` (`user_id`),
|
| 134 |
+
KEY `idx_status` (`status`),
|
| 135 |
+
KEY `idx_created_at` (`created_at`),
|
| 136 |
+
CONSTRAINT `agent_claims_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 137 |
+
CONSTRAINT `agent_claims_ibfk_2` FOREIGN KEY (`approved_by`) REFERENCES `users` (`id`)
|
| 138 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 139 |
+
|
| 140 |
+
CREATE TABLE `agent_hierarchy` (
|
| 141 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 142 |
+
`upline_id` int NOT NULL,
|
| 143 |
+
`downline_id` int NOT NULL,
|
| 144 |
+
`level` int NOT NULL,
|
| 145 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 146 |
+
PRIMARY KEY (`id`),
|
| 147 |
+
KEY `upline_id` (`upline_id`),
|
| 148 |
+
KEY `downline_id` (`downline_id`),
|
| 149 |
+
CONSTRAINT `agent_hierarchy_ibfk_1` FOREIGN KEY (`upline_id`) REFERENCES `users` (`id`),
|
| 150 |
+
CONSTRAINT `agent_hierarchy_ibfk_2` FOREIGN KEY (`downline_id`) REFERENCES `users` (`id`)
|
| 151 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 152 |
+
|
| 153 |
+
CREATE TABLE `agents` (
|
| 154 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 155 |
+
`user_id` int NOT NULL,
|
| 156 |
+
`full_name` varchar(100) NOT NULL,
|
| 157 |
+
`phone` varchar(20) NOT NULL,
|
| 158 |
+
`location` varchar(100) NOT NULL,
|
| 159 |
+
`id_front` varchar(255) DEFAULT NULL,
|
| 160 |
+
`id_back` varchar(255) DEFAULT NULL,
|
| 161 |
+
`status` enum('pending','approved','rejected','documents_needed') DEFAULT 'pending',
|
| 162 |
+
`applied_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 163 |
+
`reviewed_at` timestamp NULL DEFAULT NULL,
|
| 164 |
+
`reviewed_by` int DEFAULT NULL,
|
| 165 |
+
`notes` text,
|
| 166 |
+
PRIMARY KEY (`id`),
|
| 167 |
+
KEY `user_id` (`user_id`),
|
| 168 |
+
KEY `reviewed_by` (`reviewed_by`),
|
| 169 |
+
CONSTRAINT `agents_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
|
| 170 |
+
CONSTRAINT `agents_ibfk_2` FOREIGN KEY (`reviewed_by`) REFERENCES `users` (`id`)
|
| 171 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 172 |
+
|
| 173 |
+
CREATE TABLE `audit_logs` (
|
| 174 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 175 |
+
`user_id` int DEFAULT NULL,
|
| 176 |
+
`action` varchar(100) NOT NULL,
|
| 177 |
+
`description` text,
|
| 178 |
+
`ip_address` varchar(45) DEFAULT NULL,
|
| 179 |
+
`user_agent` text,
|
| 180 |
+
`metadata` json DEFAULT NULL,
|
| 181 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 182 |
+
PRIMARY KEY (`id`)
|
| 183 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 184 |
+
|
| 185 |
+
CREATE TABLE `balance_history` (
|
| 186 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 187 |
+
`user_id` int NOT NULL,
|
| 188 |
+
`transaction_id` int DEFAULT NULL,
|
| 189 |
+
`amount` decimal(10,2) NOT NULL,
|
| 190 |
+
`balance_before` decimal(10,2) NOT NULL,
|
| 191 |
+
`balance_after` decimal(10,2) NOT NULL,
|
| 192 |
+
`type` enum('transfer_sent','transfer_received','deposit','withdrawal') DEFAULT NULL,
|
| 193 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 194 |
+
PRIMARY KEY (`id`),
|
| 195 |
+
KEY `user_id` (`user_id`),
|
| 196 |
+
KEY `transaction_id` (`transaction_id`),
|
| 197 |
+
CONSTRAINT `balance_history_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
|
| 198 |
+
CONSTRAINT `balance_history_ibfk_2` FOREIGN KEY (`transaction_id`) REFERENCES `transactions` (`id`)
|
| 199 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 200 |
+
|
| 201 |
+
CREATE TABLE `commissions` (
|
| 202 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 203 |
+
`upline_id` int NOT NULL,
|
| 204 |
+
`downline_id` int NOT NULL,
|
| 205 |
+
`advertisement_id` int NOT NULL,
|
| 206 |
+
`amount` decimal(10,2) NOT NULL,
|
| 207 |
+
`commission_rate` decimal(5,2) NOT NULL,
|
| 208 |
+
`commission_amount` decimal(10,2) NOT NULL,
|
| 209 |
+
`percentage` decimal(5,2) NOT NULL,
|
| 210 |
+
`description` varchar(255) DEFAULT NULL,
|
| 211 |
+
`status` enum('pending','paid','cancelled') DEFAULT 'pending',
|
| 212 |
+
`paid_at` timestamp NULL DEFAULT NULL,
|
| 213 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 214 |
+
PRIMARY KEY (`id`),
|
| 215 |
+
KEY `upline_id` (`upline_id`),
|
| 216 |
+
KEY `downline_id` (`downline_id`),
|
| 217 |
+
KEY `fk_commission_advertisement` (`advertisement_id`),
|
| 218 |
+
CONSTRAINT `commissions_ibfk_1` FOREIGN KEY (`upline_id`) REFERENCES `users` (`id`),
|
| 219 |
+
CONSTRAINT `commissions_ibfk_2` FOREIGN KEY (`downline_id`) REFERENCES `users` (`id`),
|
| 220 |
+
CONSTRAINT `fk_commission_advertisement` FOREIGN KEY (`advertisement_id`) REFERENCES `advertisements` (`id`)
|
| 221 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 222 |
+
|
| 223 |
+
CREATE TABLE `currency_rates` (
|
| 224 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 225 |
+
`base_currency` varchar(3) DEFAULT 'KES',
|
| 226 |
+
`target_currency` varchar(3) DEFAULT NULL,
|
| 227 |
+
`exchange_rate` decimal(10,4) DEFAULT NULL,
|
| 228 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 229 |
+
PRIMARY KEY (`id`)
|
| 230 |
+
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 231 |
+
|
| 232 |
+
CREATE TABLE `daily_earnings` (
|
| 233 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 234 |
+
`investment_id` int NOT NULL,
|
| 235 |
+
`user_id` int NOT NULL,
|
| 236 |
+
`amount` decimal(15,2) NOT NULL,
|
| 237 |
+
`earning_date` date NOT NULL,
|
| 238 |
+
`status` enum('pending','paid','reinvested') DEFAULT 'pending',
|
| 239 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 240 |
+
PRIMARY KEY (`id`),
|
| 241 |
+
KEY `investment_id` (`investment_id`),
|
| 242 |
+
KEY `user_id` (`user_id`),
|
| 243 |
+
CONSTRAINT `daily_earnings_ibfk_1` FOREIGN KEY (`investment_id`) REFERENCES `user_investments` (`id`),
|
| 244 |
+
CONSTRAINT `daily_earnings_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
|
| 245 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 246 |
+
|
| 247 |
+
CREATE TABLE `daily_token_stats` (
|
| 248 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 249 |
+
`user_id` int NOT NULL,
|
| 250 |
+
`date` date NOT NULL,
|
| 251 |
+
`tokens_generated` int DEFAULT '0',
|
| 252 |
+
`tokens_revoked` int DEFAULT '0',
|
| 253 |
+
`api_calls` int DEFAULT '0',
|
| 254 |
+
`total_processing_time_ms` int DEFAULT '0',
|
| 255 |
+
`unique_endpoints` int DEFAULT '0',
|
| 256 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 257 |
+
PRIMARY KEY (`id`),
|
| 258 |
+
UNIQUE KEY `unique_user_date` (`user_id`,`date`),
|
| 259 |
+
KEY `idx_date` (`date`),
|
| 260 |
+
CONSTRAINT `daily_token_stats_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 261 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 262 |
+
|
| 263 |
+
CREATE TABLE `eligibility_criteria` (
|
| 264 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 265 |
+
`min_deposit_amount` decimal(15,2) DEFAULT '20000.00',
|
| 266 |
+
`min_account_age_months` int DEFAULT '6',
|
| 267 |
+
`min_successful_uploads` int DEFAULT '10',
|
| 268 |
+
`is_active` tinyint(1) DEFAULT '1',
|
| 269 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 270 |
+
`cooling_period_days` int DEFAULT '30',
|
| 271 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 272 |
+
PRIMARY KEY (`id`)
|
| 273 |
+
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 274 |
+
|
| 275 |
+
CREATE TABLE `faqs` (
|
| 276 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 277 |
+
`question` text NOT NULL,
|
| 278 |
+
`answer` text NOT NULL,
|
| 279 |
+
`category` varchar(50) DEFAULT NULL,
|
| 280 |
+
`is_active` tinyint(1) DEFAULT '1',
|
| 281 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 282 |
+
PRIMARY KEY (`id`)
|
| 283 |
+
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 284 |
+
|
| 285 |
+
CREATE TABLE `ledger` (
|
| 286 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 287 |
+
`user_id` int NOT NULL,
|
| 288 |
+
`change_amount` decimal(15,2) NOT NULL,
|
| 289 |
+
`balance_after` decimal(15,2) NOT NULL,
|
| 290 |
+
`type` enum('deposit','withdrawal','transfer','reward','fee') NOT NULL,
|
| 291 |
+
`reference` varchar(100) NOT NULL,
|
| 292 |
+
`description` text,
|
| 293 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 294 |
+
PRIMARY KEY (`id`),
|
| 295 |
+
KEY `user_id` (`user_id`),
|
| 296 |
+
CONSTRAINT `ledger_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 297 |
+
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 298 |
+
|
| 299 |
+
CREATE TABLE `loan_applications` (
|
| 300 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 301 |
+
`user_id` int NOT NULL,
|
| 302 |
+
`amount` decimal(15,2) NOT NULL,
|
| 303 |
+
`duration_days` int NOT NULL,
|
| 304 |
+
`purpose` varchar(255) NOT NULL,
|
| 305 |
+
`disbursement_method` enum('mpesa','bank','paypal') NOT NULL,
|
| 306 |
+
`mpesa_phone` varchar(15) DEFAULT NULL,
|
| 307 |
+
`bank_name` varchar(100) DEFAULT NULL,
|
| 308 |
+
`account_number` varchar(50) DEFAULT NULL,
|
| 309 |
+
`account_name` varchar(100) DEFAULT NULL,
|
| 310 |
+
`paypal_email` varchar(100) DEFAULT NULL,
|
| 311 |
+
`notification_number` varchar(15) NOT NULL,
|
| 312 |
+
`status` enum('pending','approved','rejected','disbursed','completed') DEFAULT 'pending',
|
| 313 |
+
`application_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 314 |
+
`approval_date` timestamp NULL DEFAULT NULL,
|
| 315 |
+
`due_date` date DEFAULT NULL,
|
| 316 |
+
`processing_fee` decimal(15,2) DEFAULT '0.00',
|
| 317 |
+
`interest_rate` decimal(5,2) DEFAULT '5.00',
|
| 318 |
+
`total_repayment` decimal(15,2) DEFAULT '0.00',
|
| 319 |
+
PRIMARY KEY (`id`),
|
| 320 |
+
KEY `user_id` (`user_id`),
|
| 321 |
+
CONSTRAINT `loan_applications_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 322 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 323 |
+
|
| 324 |
+
CREATE TABLE `loan_repayments` (
|
| 325 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 326 |
+
`loan_id` int NOT NULL,
|
| 327 |
+
`due_date` date NOT NULL,
|
| 328 |
+
`amount_due` decimal(15,2) NOT NULL,
|
| 329 |
+
`amount_paid` decimal(15,2) DEFAULT '0.00',
|
| 330 |
+
`status` enum('pending','partial','paid','overdue') DEFAULT 'pending',
|
| 331 |
+
`payment_date` timestamp NULL DEFAULT NULL,
|
| 332 |
+
PRIMARY KEY (`id`),
|
| 333 |
+
KEY `loan_id` (`loan_id`),
|
| 334 |
+
CONSTRAINT `loan_repayments_ibfk_1` FOREIGN KEY (`loan_id`) REFERENCES `loan_applications` (`id`) ON DELETE CASCADE
|
| 335 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 336 |
+
|
| 337 |
+
CREATE TABLE `loans` (
|
| 338 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 339 |
+
`user_id` int NOT NULL,
|
| 340 |
+
`amount` decimal(15,2) NOT NULL,
|
| 341 |
+
`interest_rate` decimal(5,2) NOT NULL,
|
| 342 |
+
`duration_days` int NOT NULL,
|
| 343 |
+
`purpose` text,
|
| 344 |
+
`status` enum('pending','approved','rejected','active','paid') DEFAULT 'pending',
|
| 345 |
+
`approved_by` int DEFAULT NULL,
|
| 346 |
+
`approved_at` datetime DEFAULT NULL,
|
| 347 |
+
`due_date` date DEFAULT NULL,
|
| 348 |
+
`amount_paid` decimal(15,2) DEFAULT '0.00',
|
| 349 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 350 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 351 |
+
PRIMARY KEY (`id`),
|
| 352 |
+
KEY `user_id` (`user_id`),
|
| 353 |
+
KEY `approved_by` (`approved_by`),
|
| 354 |
+
CONSTRAINT `loans_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 355 |
+
CONSTRAINT `loans_ibfk_2` FOREIGN KEY (`approved_by`) REFERENCES `users` (`id`)
|
| 356 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 357 |
+
|
| 358 |
+
CREATE TABLE `main_account` (
|
| 359 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 360 |
+
`account_name` varchar(100) DEFAULT 'JMotors Main Account',
|
| 361 |
+
`paybill_number` varchar(20) DEFAULT '542542',
|
| 362 |
+
`account_number` varchar(50) DEFAULT '00106664176150',
|
| 363 |
+
`account_type` enum('paybill','bank','mpesa') DEFAULT 'paybill',
|
| 364 |
+
`total_balance` decimal(15,2) DEFAULT '0.00',
|
| 365 |
+
`total_deposits` decimal(15,2) DEFAULT '0.00',
|
| 366 |
+
`total_withdrawals` decimal(15,2) DEFAULT '0.00',
|
| 367 |
+
`currency` varchar(3) DEFAULT 'KES',
|
| 368 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 369 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 370 |
+
`mpesa_phone` varchar(20) DEFAULT '0756709823',
|
| 371 |
+
PRIMARY KEY (`id`)
|
| 372 |
+
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 373 |
+
|
| 374 |
+
CREATE TABLE `meta_uploads` (
|
| 375 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 376 |
+
`user_id` int NOT NULL,
|
| 377 |
+
`file_name` varchar(255) NOT NULL,
|
| 378 |
+
`file_type` varchar(50) NOT NULL,
|
| 379 |
+
`file_size` bigint NOT NULL,
|
| 380 |
+
`file_path` varchar(500) NOT NULL,
|
| 381 |
+
`upload_date` date NOT NULL,
|
| 382 |
+
`status` enum('pending','approved','rejected') DEFAULT 'pending',
|
| 383 |
+
`reward_amount` decimal(10,2) DEFAULT '0.00',
|
| 384 |
+
`reviewed_by` int DEFAULT NULL,
|
| 385 |
+
`reviewed_at` timestamp NULL DEFAULT NULL,
|
| 386 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 387 |
+
PRIMARY KEY (`id`),
|
| 388 |
+
KEY `user_id` (`user_id`),
|
| 389 |
+
KEY `reviewed_by` (`reviewed_by`),
|
| 390 |
+
CONSTRAINT `meta_uploads_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
|
| 391 |
+
CONSTRAINT `meta_uploads_ibfk_2` FOREIGN KEY (`reviewed_by`) REFERENCES `users` (`id`)
|
| 392 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 393 |
+
|
| 394 |
+
CREATE TABLE `packages` (
|
| 395 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 396 |
+
`name` varchar(50) NOT NULL,
|
| 397 |
+
`min_investment` decimal(15,2) NOT NULL,
|
| 398 |
+
`max_investment` decimal(15,2) NOT NULL,
|
| 399 |
+
`daily_return` decimal(5,2) NOT NULL,
|
| 400 |
+
`price` decimal(10,2) NOT NULL,
|
| 401 |
+
`award` decimal(10,2) NOT NULL,
|
| 402 |
+
`return_amount` decimal(10,2) NOT NULL,
|
| 403 |
+
`duration_days` int NOT NULL,
|
| 404 |
+
`referral_bonus` decimal(5,2) NOT NULL,
|
| 405 |
+
`daily_return_percent` decimal(5,2) NOT NULL,
|
| 406 |
+
`features` text,
|
| 407 |
+
`is_active` tinyint(1) DEFAULT '1',
|
| 408 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 409 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 410 |
+
PRIMARY KEY (`id`)
|
| 411 |
+
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 412 |
+
|
| 413 |
+
CREATE TABLE `pin_setup` (
|
| 414 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 415 |
+
`user_id` int NOT NULL,
|
| 416 |
+
`pin_hash` varchar(255) NOT NULL,
|
| 417 |
+
`setup_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 418 |
+
PRIMARY KEY (`id`),
|
| 419 |
+
KEY `user_id` (`user_id`),
|
| 420 |
+
CONSTRAINT `pin_setup_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 421 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 422 |
+
|
| 423 |
+
CREATE TABLE `products` (
|
| 424 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 425 |
+
`name` varchar(100) NOT NULL,
|
| 426 |
+
`value` decimal(15,2) NOT NULL,
|
| 427 |
+
`package_requirement` varchar(50) DEFAULT 'all',
|
| 428 |
+
`image_url` varchar(500) DEFAULT NULL,
|
| 429 |
+
`stock` int DEFAULT '0',
|
| 430 |
+
`description` text,
|
| 431 |
+
`price` decimal(10,2) NOT NULL,
|
| 432 |
+
`image_code` varchar(10) NOT NULL,
|
| 433 |
+
`cashback_amount` decimal(10,2) DEFAULT '0.00',
|
| 434 |
+
`is_active` tinyint(1) DEFAULT '1',
|
| 435 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 436 |
+
PRIMARY KEY (`id`)
|
| 437 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 438 |
+
|
| 439 |
+
CREATE TABLE `recharge_transactions` (
|
| 440 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 441 |
+
`user_id` int DEFAULT NULL,
|
| 442 |
+
`main_account_id` int DEFAULT NULL,
|
| 443 |
+
`amount` decimal(10,2) DEFAULT NULL,
|
| 444 |
+
`virtual_balance_before` decimal(10,2) DEFAULT NULL,
|
| 445 |
+
`virtual_balance_after` decimal(10,2) DEFAULT NULL,
|
| 446 |
+
`main_balance_before` decimal(10,2) DEFAULT NULL,
|
| 447 |
+
`main_balance_after` decimal(10,2) DEFAULT NULL,
|
| 448 |
+
`currency` varchar(3) DEFAULT 'KES',
|
| 449 |
+
`payment_method` varchar(50) DEFAULT NULL,
|
| 450 |
+
`phone_number` varchar(20) DEFAULT NULL,
|
| 451 |
+
`mpesa_receipt` varchar(100) DEFAULT NULL,
|
| 452 |
+
`transaction_id` varchar(100) DEFAULT NULL,
|
| 453 |
+
`paybill_number` varchar(20) DEFAULT '542542',
|
| 454 |
+
`account_number` varchar(50) DEFAULT '00106664176150',
|
| 455 |
+
`status` enum('pending','completed','failed','verified') DEFAULT 'pending',
|
| 456 |
+
`bonus_amount` decimal(10,2) DEFAULT '0.00',
|
| 457 |
+
`verified_by` int DEFAULT NULL,
|
| 458 |
+
`verified_at` timestamp NULL DEFAULT NULL,
|
| 459 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 460 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 461 |
+
PRIMARY KEY (`id`),
|
| 462 |
+
KEY `user_id` (`user_id`),
|
| 463 |
+
KEY `fk_recharge_main` (`main_account_id`),
|
| 464 |
+
CONSTRAINT `fk_recharge_main` FOREIGN KEY (`main_account_id`) REFERENCES `main_account` (`id`),
|
| 465 |
+
CONSTRAINT `recharge_transactions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
|
| 466 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 467 |
+
|
| 468 |
+
CREATE TABLE `referrals` (
|
| 469 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 470 |
+
`referrer_id` int NOT NULL,
|
| 471 |
+
`referred_id` int NOT NULL,
|
| 472 |
+
`status` enum('pending','completed','cancelled') DEFAULT 'pending',
|
| 473 |
+
`commission_earned` decimal(10,2) DEFAULT '0.00',
|
| 474 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 475 |
+
PRIMARY KEY (`id`),
|
| 476 |
+
KEY `referrer_id` (`referrer_id`),
|
| 477 |
+
KEY `referred_id` (`referred_id`),
|
| 478 |
+
CONSTRAINT `referrals_ibfk_1` FOREIGN KEY (`referrer_id`) REFERENCES `users` (`id`),
|
| 479 |
+
CONSTRAINT `referrals_ibfk_2` FOREIGN KEY (`referred_id`) REFERENCES `users` (`id`)
|
| 480 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 481 |
+
|
| 482 |
+
CREATE TABLE `reward_settings` (
|
| 483 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 484 |
+
`setting_key` varchar(50) NOT NULL,
|
| 485 |
+
`setting_value` varchar(255) NOT NULL,
|
| 486 |
+
`description` text,
|
| 487 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 488 |
+
PRIMARY KEY (`id`),
|
| 489 |
+
UNIQUE KEY `setting_key` (`setting_key`)
|
| 490 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 491 |
+
|
| 492 |
+
CREATE TABLE `reward_transactions` (
|
| 493 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 494 |
+
`user_id` int NOT NULL,
|
| 495 |
+
`type` enum('upload','bonus','withdrawal') NOT NULL,
|
| 496 |
+
`amount` decimal(10,2) NOT NULL,
|
| 497 |
+
`description` varchar(255) DEFAULT NULL,
|
| 498 |
+
`reference_id` int DEFAULT NULL,
|
| 499 |
+
`status` enum('pending','completed','failed') DEFAULT 'completed',
|
| 500 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 501 |
+
PRIMARY KEY (`id`),
|
| 502 |
+
KEY `user_id` (`user_id`),
|
| 503 |
+
CONSTRAINT `reward_transactions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
|
| 504 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 505 |
+
|
| 506 |
+
CREATE TABLE `sessions` (
|
| 507 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 508 |
+
`user_id` int NOT NULL,
|
| 509 |
+
`session_token` varchar(255) NOT NULL,
|
| 510 |
+
`ip_address` varchar(45) DEFAULT NULL,
|
| 511 |
+
`user_agent` text,
|
| 512 |
+
`expires_at` datetime NOT NULL,
|
| 513 |
+
`is_active` tinyint(1) DEFAULT '1',
|
| 514 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 515 |
+
PRIMARY KEY (`id`),
|
| 516 |
+
UNIQUE KEY `session_token` (`session_token`),
|
| 517 |
+
KEY `user_id` (`user_id`),
|
| 518 |
+
CONSTRAINT `sessions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 519 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 520 |
+
|
| 521 |
+
CREATE TABLE `support_agents` (
|
| 522 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 523 |
+
`name` varchar(100) NOT NULL,
|
| 524 |
+
`email` varchar(255) NOT NULL,
|
| 525 |
+
`phone` varchar(20) DEFAULT NULL,
|
| 526 |
+
`department` varchar(50) DEFAULT NULL,
|
| 527 |
+
`is_active` tinyint(1) DEFAULT '1',
|
| 528 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 529 |
+
PRIMARY KEY (`id`),
|
| 530 |
+
UNIQUE KEY `email` (`email`)
|
| 531 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 532 |
+
|
| 533 |
+
CREATE TABLE `support_tickets` (
|
| 534 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 535 |
+
`user_id` int DEFAULT NULL,
|
| 536 |
+
`ticket_number` varchar(20) NOT NULL,
|
| 537 |
+
`issue_type` enum('technical','account','payment','product','other') NOT NULL,
|
| 538 |
+
`subject` varchar(200) NOT NULL,
|
| 539 |
+
`description` text NOT NULL,
|
| 540 |
+
`status` enum('open','in_progress','resolved','closed') DEFAULT 'open',
|
| 541 |
+
`priority` enum('low','medium','high','urgent') DEFAULT 'medium',
|
| 542 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 543 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 544 |
+
PRIMARY KEY (`id`),
|
| 545 |
+
UNIQUE KEY `ticket_number` (`ticket_number`),
|
| 546 |
+
KEY `user_id` (`user_id`),
|
| 547 |
+
CONSTRAINT `support_tickets_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 548 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 549 |
+
|
| 550 |
+
CREATE TABLE `support_users` (
|
| 551 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 552 |
+
`username` varchar(100) NOT NULL,
|
| 553 |
+
`email` varchar(255) NOT NULL,
|
| 554 |
+
`tier` varchar(50) DEFAULT NULL,
|
| 555 |
+
`package` varchar(50) DEFAULT NULL,
|
| 556 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 557 |
+
PRIMARY KEY (`id`)
|
| 558 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 559 |
+
|
| 560 |
+
CREATE TABLE `system_config` (
|
| 561 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 562 |
+
`config_key` varchar(100) NOT NULL,
|
| 563 |
+
`config_value` text NOT NULL,
|
| 564 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 565 |
+
PRIMARY KEY (`id`),
|
| 566 |
+
UNIQUE KEY `config_key` (`config_key`)
|
| 567 |
+
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 568 |
+
|
| 569 |
+
CREATE TABLE `team_relationships` (
|
| 570 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 571 |
+
`sponsor_id` int NOT NULL,
|
| 572 |
+
`agent_id` int NOT NULL,
|
| 573 |
+
`level` int NOT NULL,
|
| 574 |
+
`status` enum('active','inactive') DEFAULT 'active',
|
| 575 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 576 |
+
PRIMARY KEY (`id`),
|
| 577 |
+
UNIQUE KEY `unique_relationship` (`sponsor_id`,`agent_id`),
|
| 578 |
+
KEY `agent_id` (`agent_id`),
|
| 579 |
+
CONSTRAINT `team_relationships_ibfk_1` FOREIGN KEY (`sponsor_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 580 |
+
CONSTRAINT `team_relationships_ibfk_2` FOREIGN KEY (`agent_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 581 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 582 |
+
|
| 583 |
+
CREATE TABLE `ticket_assignments` (
|
| 584 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 585 |
+
`ticket_id` int NOT NULL,
|
| 586 |
+
`agent_id` int NOT NULL,
|
| 587 |
+
`assigned_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 588 |
+
PRIMARY KEY (`id`),
|
| 589 |
+
KEY `ticket_id` (`ticket_id`),
|
| 590 |
+
KEY `agent_id` (`agent_id`),
|
| 591 |
+
CONSTRAINT `ticket_assignments_ibfk_1` FOREIGN KEY (`ticket_id`) REFERENCES `support_tickets` (`id`) ON DELETE CASCADE,
|
| 592 |
+
CONSTRAINT `ticket_assignments_ibfk_2` FOREIGN KEY (`agent_id`) REFERENCES `support_agents` (`id`) ON DELETE CASCADE
|
| 593 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 594 |
+
|
| 595 |
+
CREATE TABLE `ticket_responses` (
|
| 596 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 597 |
+
`ticket_id` int NOT NULL,
|
| 598 |
+
`responder_type` enum('user','support_agent') NOT NULL,
|
| 599 |
+
`message` text NOT NULL,
|
| 600 |
+
`attachments` text,
|
| 601 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 602 |
+
PRIMARY KEY (`id`),
|
| 603 |
+
KEY `ticket_id` (`ticket_id`),
|
| 604 |
+
CONSTRAINT `ticket_responses_ibfk_1` FOREIGN KEY (`ticket_id`) REFERENCES `support_tickets` (`id`) ON DELETE CASCADE
|
| 605 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 606 |
+
|
| 607 |
+
CREATE TABLE `token_usage_logs` (
|
| 608 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 609 |
+
`token_id` int NOT NULL,
|
| 610 |
+
`user_id` int NOT NULL,
|
| 611 |
+
`endpoint` varchar(100) NOT NULL,
|
| 612 |
+
`ip_address` varchar(45) DEFAULT NULL,
|
| 613 |
+
`user_agent` text,
|
| 614 |
+
`request_method` varchar(10) DEFAULT NULL,
|
| 615 |
+
`response_code` int DEFAULT NULL,
|
| 616 |
+
`processing_time_ms` int DEFAULT NULL,
|
| 617 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 618 |
+
PRIMARY KEY (`id`),
|
| 619 |
+
KEY `user_id` (`user_id`),
|
| 620 |
+
KEY `idx_created_at` (`created_at`),
|
| 621 |
+
KEY `idx_token_id` (`token_id`),
|
| 622 |
+
CONSTRAINT `token_usage_logs_ibfk_1` FOREIGN KEY (`token_id`) REFERENCES `access_tokens` (`id`) ON DELETE CASCADE,
|
| 623 |
+
CONSTRAINT `token_usage_logs_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 624 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 625 |
+
|
| 626 |
+
CREATE TABLE `transactions` (
|
| 627 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 628 |
+
`sender_id` int NOT NULL,
|
| 629 |
+
`user_id` int NOT NULL,
|
| 630 |
+
`type` enum('deposit','withdrawal','product_purchase','cashback') NOT NULL,
|
| 631 |
+
`description` text,
|
| 632 |
+
`balance_after` decimal(10,2) NOT NULL,
|
| 633 |
+
`recipient_id` int NOT NULL,
|
| 634 |
+
`amount` decimal(10,2) NOT NULL,
|
| 635 |
+
`message` text,
|
| 636 |
+
`transaction_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 637 |
+
`reference` varchar(100) DEFAULT NULL,
|
| 638 |
+
`status` enum('pending','completed','failed') DEFAULT 'pending',
|
| 639 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 640 |
+
`completed_at` timestamp NULL DEFAULT NULL,
|
| 641 |
+
PRIMARY KEY (`id`),
|
| 642 |
+
KEY `fk_sender` (`sender_id`),
|
| 643 |
+
KEY `fk_recipient` (`recipient_id`),
|
| 644 |
+
KEY `fk_transactions_user` (`user_id`),
|
| 645 |
+
CONSTRAINT `fk_recipient` FOREIGN KEY (`recipient_id`) REFERENCES `users` (`id`),
|
| 646 |
+
CONSTRAINT `fk_sender` FOREIGN KEY (`sender_id`) REFERENCES `users` (`id`),
|
| 647 |
+
CONSTRAINT `fk_transactions_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 648 |
+
CONSTRAINT `transactions_ibfk_1` FOREIGN KEY (`sender_id`) REFERENCES `users` (`id`),
|
| 649 |
+
CONSTRAINT `transactions_ibfk_2` FOREIGN KEY (`recipient_id`) REFERENCES `users` (`id`)
|
| 650 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 651 |
+
|
| 652 |
+
CREATE TABLE `transaction_verifications` (
|
| 653 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 654 |
+
`transaction_id` int DEFAULT NULL,
|
| 655 |
+
`user_id` int DEFAULT NULL,
|
| 656 |
+
`amount` decimal(10,2) DEFAULT NULL,
|
| 657 |
+
`paybill_number` varchar(20) DEFAULT NULL,
|
| 658 |
+
`account_number` varchar(50) DEFAULT NULL,
|
| 659 |
+
`mpesa_receipt` varchar(100) DEFAULT NULL,
|
| 660 |
+
`screenshot_path` varchar(255) DEFAULT NULL,
|
| 661 |
+
`status` enum('pending','approved','rejected') DEFAULT 'pending',
|
| 662 |
+
`reviewed_by` int DEFAULT NULL,
|
| 663 |
+
`reviewed_at` timestamp NULL DEFAULT NULL,
|
| 664 |
+
`notes` text,
|
| 665 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 666 |
+
PRIMARY KEY (`id`),
|
| 667 |
+
KEY `transaction_id` (`transaction_id`),
|
| 668 |
+
KEY `user_id` (`user_id`),
|
| 669 |
+
CONSTRAINT `transaction_verifications_ibfk_1` FOREIGN KEY (`transaction_id`) REFERENCES `recharge_transactions` (`id`),
|
| 670 |
+
CONSTRAINT `transaction_verifications_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
|
| 671 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 672 |
+
|
| 673 |
+
CREATE TABLE `upload_rewards` (
|
| 674 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 675 |
+
`user_id` int NOT NULL,
|
| 676 |
+
`upload_date` date NOT NULL,
|
| 677 |
+
`total_uploads` int DEFAULT '0',
|
| 678 |
+
`completed_uploads` int DEFAULT '0',
|
| 679 |
+
`total_reward` decimal(10,2) DEFAULT '0.00',
|
| 680 |
+
`status` enum('pending','processed') DEFAULT 'pending',
|
| 681 |
+
`processed_at` timestamp NULL DEFAULT NULL,
|
| 682 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 683 |
+
PRIMARY KEY (`id`),
|
| 684 |
+
UNIQUE KEY `unique_user_date` (`user_id`,`upload_date`),
|
| 685 |
+
CONSTRAINT `upload_rewards_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
|
| 686 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 687 |
+
|
| 688 |
+
CREATE TABLE `user_accounts` (
|
| 689 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 690 |
+
`user_id` int DEFAULT NULL,
|
| 691 |
+
`virtual_account_number` varchar(50) DEFAULT NULL,
|
| 692 |
+
`current_balance` decimal(15,2) DEFAULT '0.00',
|
| 693 |
+
`total_invested` decimal(15,2) DEFAULT '0.00',
|
| 694 |
+
`total_earnings` decimal(15,2) DEFAULT '0.00',
|
| 695 |
+
`total_withdrawn` decimal(15,2) DEFAULT '0.00',
|
| 696 |
+
`currency` varchar(3) DEFAULT 'KES',
|
| 697 |
+
`status` enum('active','suspended','closed') DEFAULT 'active',
|
| 698 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 699 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 700 |
+
PRIMARY KEY (`id`),
|
| 701 |
+
UNIQUE KEY `virtual_account_number` (`virtual_account_number`),
|
| 702 |
+
KEY `user_id` (`user_id`),
|
| 703 |
+
CONSTRAINT `user_accounts_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
|
| 704 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 705 |
+
|
| 706 |
+
CREATE TABLE `user_activity` (
|
| 707 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 708 |
+
`user_id` int DEFAULT NULL,
|
| 709 |
+
`activity_type` varchar(50) DEFAULT NULL,
|
| 710 |
+
`description` text,
|
| 711 |
+
`ip_address` varchar(45) DEFAULT NULL,
|
| 712 |
+
`timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 713 |
+
PRIMARY KEY (`id`),
|
| 714 |
+
KEY `user_id` (`user_id`),
|
| 715 |
+
CONSTRAINT `user_activity_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 716 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 717 |
+
|
| 718 |
+
CREATE TABLE `user_channel_subscriptions` (
|
| 719 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 720 |
+
`user_id` int DEFAULT NULL,
|
| 721 |
+
`channel_id` int DEFAULT NULL,
|
| 722 |
+
`subscribed_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 723 |
+
PRIMARY KEY (`id`),
|
| 724 |
+
UNIQUE KEY `unique_subscription` (`user_id`,`channel_id`),
|
| 725 |
+
KEY `channel_id` (`channel_id`),
|
| 726 |
+
CONSTRAINT `user_channel_subscriptions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 727 |
+
CONSTRAINT `user_channel_subscriptions_ibfk_2` FOREIGN KEY (`channel_id`) REFERENCES `whatsapp_channels` (`id`) ON DELETE CASCADE
|
| 728 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 729 |
+
|
| 730 |
+
CREATE TABLE `user_investments` (
|
| 731 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 732 |
+
`user_id` int NOT NULL,
|
| 733 |
+
`package_id` int NOT NULL,
|
| 734 |
+
`amount` decimal(15,2) NOT NULL,
|
| 735 |
+
`start_date` datetime NOT NULL,
|
| 736 |
+
`end_date` datetime NOT NULL,
|
| 737 |
+
`status` enum('active','completed','cancelled') DEFAULT 'active',
|
| 738 |
+
`total_earnings` decimal(15,2) DEFAULT '0.00',
|
| 739 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 740 |
+
PRIMARY KEY (`id`),
|
| 741 |
+
KEY `user_id` (`user_id`),
|
| 742 |
+
KEY `package_id` (`package_id`),
|
| 743 |
+
CONSTRAINT `user_investments_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
|
| 744 |
+
CONSTRAINT `user_investments_ibfk_2` FOREIGN KEY (`package_id`) REFERENCES `packages` (`id`)
|
| 745 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 746 |
+
|
| 747 |
+
CREATE TABLE `user_packages` (
|
| 748 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 749 |
+
`user_id` int NOT NULL,
|
| 750 |
+
`package_id` int NOT NULL,
|
| 751 |
+
`purchase_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 752 |
+
`start_date` datetime DEFAULT NULL,
|
| 753 |
+
`end_date` datetime DEFAULT NULL,
|
| 754 |
+
`amount_paid` decimal(10,2) DEFAULT NULL,
|
| 755 |
+
`status` enum('active','completed','cancelled') DEFAULT 'active',
|
| 756 |
+
`investment_amount` decimal(10,2) NOT NULL,
|
| 757 |
+
`expected_return` decimal(10,2) NOT NULL,
|
| 758 |
+
PRIMARY KEY (`id`),
|
| 759 |
+
KEY `user_id` (`user_id`),
|
| 760 |
+
KEY `package_id` (`package_id`),
|
| 761 |
+
CONSTRAINT `user_packages_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 762 |
+
CONSTRAINT `user_packages_ibfk_2` FOREIGN KEY (`package_id`) REFERENCES `packages` (`id`)
|
| 763 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 764 |
+
|
| 765 |
+
CREATE TABLE `user_products` (
|
| 766 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 767 |
+
`user_id` int NOT NULL,
|
| 768 |
+
`product_id` int NOT NULL,
|
| 769 |
+
`assigned_date` date NOT NULL,
|
| 770 |
+
`investment_id` int NOT NULL,
|
| 771 |
+
`purchase_price` decimal(10,2) NOT NULL,
|
| 772 |
+
`cashback_received` decimal(10,2) DEFAULT '0.00',
|
| 773 |
+
`purchase_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 774 |
+
`status` enum('active','completed','cancelled') DEFAULT 'active',
|
| 775 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 776 |
+
PRIMARY KEY (`id`),
|
| 777 |
+
KEY `user_id` (`user_id`),
|
| 778 |
+
KEY `product_id` (`product_id`),
|
| 779 |
+
CONSTRAINT `user_products_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 780 |
+
CONSTRAINT `user_products_ibfk_2` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE CASCADE
|
| 781 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 782 |
+
|
| 783 |
+
CREATE TABLE `user_profiles` (
|
| 784 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 785 |
+
`user_id` int NOT NULL,
|
| 786 |
+
`first_name` varchar(50) DEFAULT NULL,
|
| 787 |
+
`last_name` varchar(50) DEFAULT NULL,
|
| 788 |
+
`date_of_birth` date DEFAULT NULL,
|
| 789 |
+
`gender` enum('Male','Female','Other') DEFAULT NULL,
|
| 790 |
+
`profile_picture` varchar(255) DEFAULT NULL,
|
| 791 |
+
`address` text,
|
| 792 |
+
`city` varchar(50) DEFAULT NULL,
|
| 793 |
+
`state` varchar(50) DEFAULT NULL,
|
| 794 |
+
`zip_code` varchar(20) DEFAULT NULL,
|
| 795 |
+
`bio` text,
|
| 796 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 797 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 798 |
+
PRIMARY KEY (`id`),
|
| 799 |
+
KEY `user_id` (`user_id`),
|
| 800 |
+
CONSTRAINT `user_profiles_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 801 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 802 |
+
|
| 803 |
+
CREATE TABLE `users` (
|
| 804 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 805 |
+
`user_type` enum('marketer','agent','admin') DEFAULT 'marketer',
|
| 806 |
+
`referred_by` int DEFAULT NULL,
|
| 807 |
+
`username` varchar(50) NOT NULL,
|
| 808 |
+
`email` varchar(100) NOT NULL,
|
| 809 |
+
`country` varchar(2) NOT NULL,
|
| 810 |
+
`phone_number` varchar(20) NOT NULL,
|
| 811 |
+
`tier` enum('Basic','Premium') DEFAULT 'Basic',
|
| 812 |
+
`current_package_id` int DEFAULT NULL,
|
| 813 |
+
`package_start_date` datetime DEFAULT NULL,
|
| 814 |
+
`package_end_date` datetime DEFAULT NULL,
|
| 815 |
+
`package` enum('None','NOVA','SUPERIOR','GOLD') DEFAULT 'None',
|
| 816 |
+
`balance` decimal(10,2) DEFAULT '0.00',
|
| 817 |
+
`verification_token` varchar(100) DEFAULT NULL,
|
| 818 |
+
`reset_token` varchar(100) DEFAULT NULL,
|
| 819 |
+
`reset_token_expiry` datetime DEFAULT NULL,
|
| 820 |
+
`total_invested` decimal(15,2) DEFAULT '0.00',
|
| 821 |
+
`total_earnings` decimal(15,2) DEFAULT '0.00',
|
| 822 |
+
`total_deposits` decimal(10,2) DEFAULT '0.00',
|
| 823 |
+
`total_withdrawals` decimal(10,2) DEFAULT '0.00',
|
| 824 |
+
`rewards` decimal(10,2) DEFAULT '0.00',
|
| 825 |
+
`meta_earnings` decimal(10,2) DEFAULT '0.00',
|
| 826 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 827 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 828 |
+
`last_login` timestamp NULL DEFAULT NULL,
|
| 829 |
+
`pin_hash` varchar(255) NOT NULL,
|
| 830 |
+
`password_hash` varchar(255) NOT NULL,
|
| 831 |
+
`currency` varchar(3) DEFAULT 'KES',
|
| 832 |
+
`exchange_rate` decimal(10,4) DEFAULT '1.0000',
|
| 833 |
+
`referral_code` varchar(20) DEFAULT NULL,
|
| 834 |
+
PRIMARY KEY (`id`),
|
| 835 |
+
UNIQUE KEY `username` (`username`),
|
| 836 |
+
UNIQUE KEY `email` (`email`),
|
| 837 |
+
UNIQUE KEY `referral_code` (`referral_code`),
|
| 838 |
+
KEY `idx_users_email` (`email`),
|
| 839 |
+
KEY `idx_users_username` (`username`)
|
| 840 |
+
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 841 |
+
|
| 842 |
+
CREATE TABLE `user_security` (
|
| 843 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 844 |
+
`user_id` int DEFAULT NULL,
|
| 845 |
+
`two_factor_enabled` tinyint(1) DEFAULT '0',
|
| 846 |
+
`two_factor_secret` varchar(32) DEFAULT NULL,
|
| 847 |
+
`password_reset_token` varchar(100) DEFAULT NULL,
|
| 848 |
+
`reset_token_expires` timestamp NULL DEFAULT NULL,
|
| 849 |
+
`login_attempts` int DEFAULT '0',
|
| 850 |
+
`last_login_attempt` timestamp NULL DEFAULT NULL,
|
| 851 |
+
PRIMARY KEY (`id`),
|
| 852 |
+
UNIQUE KEY `user_id` (`user_id`),
|
| 853 |
+
CONSTRAINT `user_security_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 854 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 855 |
+
|
| 856 |
+
CREATE TABLE `user_settings` (
|
| 857 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 858 |
+
`user_id` int DEFAULT NULL,
|
| 859 |
+
`dark_mode` tinyint(1) DEFAULT '1',
|
| 860 |
+
`language` varchar(10) DEFAULT 'en',
|
| 861 |
+
`currency` varchar(3) DEFAULT 'KES',
|
| 862 |
+
`auto_logout` tinyint(1) DEFAULT '1',
|
| 863 |
+
`email_notifications` tinyint(1) DEFAULT '1',
|
| 864 |
+
`push_notifications` tinyint(1) DEFAULT '1',
|
| 865 |
+
PRIMARY KEY (`id`),
|
| 866 |
+
UNIQUE KEY `user_id` (`user_id`),
|
| 867 |
+
CONSTRAINT `user_settings_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 868 |
+
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 869 |
+
|
| 870 |
+
CREATE TABLE `whatsapp_channels` (
|
| 871 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 872 |
+
`channel_name` varchar(100) NOT NULL,
|
| 873 |
+
`channel_type` enum('group','channel','tips','elite') NOT NULL,
|
| 874 |
+
`whatsapp_link` varchar(500) NOT NULL,
|
| 875 |
+
`description` text,
|
| 876 |
+
`icon_class` varchar(50) DEFAULT NULL,
|
| 877 |
+
`color_class` varchar(50) DEFAULT NULL,
|
| 878 |
+
`is_active` tinyint(1) DEFAULT '1',
|
| 879 |
+
`member_count` int DEFAULT '0',
|
| 880 |
+
`max_capacity` int DEFAULT '1000',
|
| 881 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 882 |
+
PRIMARY KEY (`id`)
|
| 883 |
+
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 884 |
+
|
| 885 |
+
CREATE TABLE `withdrawal_destinations` (
|
| 886 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 887 |
+
`user_id` int NOT NULL,
|
| 888 |
+
`type` enum('mpesa','bank','airtel','tkash') NOT NULL,
|
| 889 |
+
`details` varchar(255) NOT NULL,
|
| 890 |
+
`is_default` tinyint(1) DEFAULT '0',
|
| 891 |
+
`is_active` tinyint(1) DEFAULT '1',
|
| 892 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 893 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 894 |
+
PRIMARY KEY (`id`),
|
| 895 |
+
KEY `user_id` (`user_id`),
|
| 896 |
+
CONSTRAINT `withdrawal_destinations_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
| 897 |
+
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 898 |
+
|
| 899 |
+
CREATE TABLE `withdrawals` (
|
| 900 |
+
`id` int NOT NULL AUTO_INCREMENT,
|
| 901 |
+
`user_id` int NOT NULL,
|
| 902 |
+
`destination_id` int NOT NULL,
|
| 903 |
+
`amount` decimal(15,2) NOT NULL,
|
| 904 |
+
`fee` decimal(15,2) NOT NULL DEFAULT '0.00',
|
| 905 |
+
`net_amount` decimal(15,2) NOT NULL,
|
| 906 |
+
`status` enum('pending','processing','completed','failed','cancelled') DEFAULT 'pending',
|
| 907 |
+
`idempotency_key` varchar(255) NOT NULL,
|
| 908 |
+
`reference` varchar(100) NOT NULL,
|
| 909 |
+
`failure_reason` text,
|
| 910 |
+
`processed_at` timestamp NULL DEFAULT NULL,
|
| 911 |
+
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
| 912 |
+
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
| 913 |
+
PRIMARY KEY (`id`),
|
| 914 |
+
UNIQUE KEY `idempotency_key` (`idempotency_key`),
|
| 915 |
+
KEY `user_id` (`user_id`),
|
| 916 |
+
KEY `destination_id` (`destination_id`),
|
| 917 |
+
CONSTRAINT `withdrawals_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
|
| 918 |
+
CONSTRAINT `withdrawals_ibfk_2` FOREIGN KEY (`destination_id`) REFERENCES `withdrawal_destinations` (`id`) ON DELETE CASCADE
|
| 919 |
+
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
| 920 |
+
|
| 921 |
+
CREATE ALGORITHM=UNDEFINED
|
| 922 |
+
DEFINER=`root`@`localhost`
|
| 923 |
+
SQL SECURITY DEFINER
|
| 924 |
+
VIEW `user_teams` AS
|
| 925 |
+
SELECT
|
| 926 |
+
`u`.`id` AS `user_id`,
|
| 927 |
+
`u`.`username` AS `username`,
|
| 928 |
+
`u`.`referral_code` AS `referral_code`,
|
| 929 |
+
COUNT(`r`.`referred_id`) AS `team_size`,
|
| 930 |
+
COALESCE(SUM(`ref`.`commission_earned`),0) AS `total_earnings`
|
| 931 |
+
FROM
|
| 932 |
+
((`users` `u`
|
| 933 |
+
LEFT JOIN `referrals` `r` ON (`u`.`id` = `r`.`referrer_id`))
|
| 934 |
+
LEFT JOIN `referrals` `ref` ON (`u`.`id` = `ref`.`referrer_id` AND `ref`.`status` = 'completed')))
|
| 935 |
+
GROUP BY
|
| 936 |
+
`u`.`id`, `u`.`username`, `u`.`referral_code`;
|
jweb/ac1/assets/images
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
<!-- This file is intentionally left blank. -->
|
jweb/ac1/assets/js/script.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
document.getElementById("signupForm").addEventListener("submit", function(e) {
|
| 2 |
+
e.preventDefault();
|
| 3 |
+
|
| 4 |
+
const password = document.getElementById("password").value;
|
| 5 |
+
const confirmPassword = document.getElementById("confirmPassword").value;
|
| 6 |
+
|
| 7 |
+
if (password !== confirmPassword) {
|
| 8 |
+
alert("Passwords do not match!");
|
| 9 |
+
return;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
alert("Account created successfully for Japanese Motors!");
|
| 13 |
+
// Here you can add backend API integration (AJAX/Fetch)
|
| 14 |
+
});
|
jweb/ac1/assets/js/scripts.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// filepath: /jmotors/jmotors/src/assets/js/scripts.js
|
| 2 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 3 |
+
// Function to handle logout
|
| 4 |
+
function handleLogout() {
|
| 5 |
+
fetch('logout.php', {
|
| 6 |
+
method: 'POST'
|
| 7 |
+
})
|
| 8 |
+
.then(response => response.json())
|
| 9 |
+
.then(data => {
|
| 10 |
+
if (data.success) {
|
| 11 |
+
window.location.href = 'pages/home.php';
|
| 12 |
+
} else {
|
| 13 |
+
alert(data.message);
|
| 14 |
+
}
|
| 15 |
+
})
|
| 16 |
+
.catch(error => console.error('Error:', error));
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
// Event listener for logout button
|
| 20 |
+
const logoutButton = document.getElementById('logout-button');
|
| 21 |
+
if (logoutButton) {
|
| 22 |
+
logoutButton.addEventListener('click', function(e) {
|
| 23 |
+
e.preventDefault();
|
| 24 |
+
handleLogout();
|
| 25 |
+
});
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
// Additional JavaScript functionality can be added here
|
| 29 |
+
});
|
jweb/ac1/check_session.php
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// check_session.php - Validate user sessions
|
| 3 |
+
session_start();
|
| 4 |
+
|
| 5 |
+
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
|
| 6 |
+
header('HTTP/1.1 401 Unauthorized');
|
| 7 |
+
echo json_encode(array("logged_in" => false));
|
| 8 |
+
exit;
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
// Return user data if logged in
|
| 12 |
+
echo json_encode(array(
|
| 13 |
+
"logged_in" => true,
|
| 14 |
+
"user_id" => $_SESSION['user_id'],
|
| 15 |
+
"username" => $_SESSION['username'],
|
| 16 |
+
"email" => $_SESSION['email'],
|
| 17 |
+
"tier" => $_SESSION['tier'],
|
| 18 |
+
"package" => $_SESSION['package'],
|
| 19 |
+
"balance" => $_SESSION['balance'],
|
| 20 |
+
"total_deposits" => $_SESSION['total_deposits'],
|
| 21 |
+
"total_withdrawals" => $_SESSION['total_withdrawals'],
|
| 22 |
+
"rewards" => $_SESSION['rewards']
|
| 23 |
+
));
|
| 24 |
+
?>
|
jweb/ac1/config.php
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Database configuration
|
| 3 |
+
$host = '127.0.0.1';
|
| 4 |
+
$dbname = 'jmdb';
|
| 5 |
+
$username = 'root';
|
| 6 |
+
$password = 'YourStrongPassword123';
|
| 7 |
+
|
| 8 |
+
try {
|
| 9 |
+
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
|
| 10 |
+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
| 11 |
+
} catch (PDOException $e) {
|
| 12 |
+
die("Database connection failed: " . $e->getMessage());
|
| 13 |
+
}
|
| 14 |
+
?>
|
jweb/ac1/db.php
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// db.php - Enhanced database connection with session support
|
| 3 |
+
|
| 4 |
+
class Database {
|
| 5 |
+
private $host = "127.0.0.1";
|
| 6 |
+
private $db_name = "jmdb";
|
| 7 |
+
private $username = "root";
|
| 8 |
+
private $password = "YourStrongPassword123"; // Set your MySQL password here
|
| 9 |
+
public $conn;
|
| 10 |
+
|
| 11 |
+
public function getConnection() {
|
| 12 |
+
$this->conn = null;
|
| 13 |
+
|
| 14 |
+
try {
|
| 15 |
+
$this->conn = new PDO(
|
| 16 |
+
"mysql:host=" . $this->host . ";dbname=" . $this->db_name . ";charset=utf8mb4",
|
| 17 |
+
$this->username,
|
| 18 |
+
$this->password
|
| 19 |
+
);
|
| 20 |
+
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
| 21 |
+
$this->conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
| 22 |
+
} catch(PDOException $exception) {
|
| 23 |
+
error_log("Database connection error: " . $exception->getMessage());
|
| 24 |
+
throw new Exception("Database connection failed: " . $exception->getMessage());
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
return $this->conn;
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
class SessionManager {
|
| 32 |
+
private $db;
|
| 33 |
+
|
| 34 |
+
public function __construct($database) {
|
| 35 |
+
$this->db = $database->getConnection();
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
// Create new session
|
| 39 |
+
public function createSession($user_id, $ip_address = null, $user_agent = null) {
|
| 40 |
+
$session_id = bin2hex(random_bytes(64));
|
| 41 |
+
$expires_at = date('Y-m-d H:i:s', strtotime('+24 hours'));
|
| 42 |
+
|
| 43 |
+
$query = "INSERT INTO user_sessions
|
| 44 |
+
SET user_id = :user_id, session_id = :session_id, ip_address = :ip_address,
|
| 45 |
+
user_agent = :user_agent, expires_at = :expires_at";
|
| 46 |
+
|
| 47 |
+
$stmt = $this->db->prepare($query);
|
| 48 |
+
$stmt->bindParam(":user_id", $user_id);
|
| 49 |
+
$stmt->bindParam(":session_id", $session_id);
|
| 50 |
+
$stmt->bindParam(":ip_address", $ip_address);
|
| 51 |
+
$stmt->bindParam(":user_agent", $user_agent);
|
| 52 |
+
$stmt->bindParam(":expires_at", $expires_at);
|
| 53 |
+
|
| 54 |
+
if ($stmt->execute()) {
|
| 55 |
+
return $session_id;
|
| 56 |
+
}
|
| 57 |
+
return false;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
// Validate session
|
| 61 |
+
public function validateSession($session_id) {
|
| 62 |
+
$query = "SELECT us.*, u.*
|
| 63 |
+
FROM user_sessions us
|
| 64 |
+
JOIN users u ON us.user_id = u.id
|
| 65 |
+
WHERE us.session_id = :session_id
|
| 66 |
+
AND us.is_active = 1
|
| 67 |
+
AND us.expires_at > NOW()";
|
| 68 |
+
|
| 69 |
+
$stmt = $this->db->prepare($query);
|
| 70 |
+
$stmt->bindParam(":session_id", $session_id);
|
| 71 |
+
$stmt->execute();
|
| 72 |
+
|
| 73 |
+
return $stmt->fetch(PDO::FETCH_ASSOC);
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
// Log activity
|
| 77 |
+
public function logActivity($user_id, $activity_type, $description = null, $ip_address = null, $user_agent = null) {
|
| 78 |
+
$query = "INSERT INTO user_activity_log
|
| 79 |
+
SET user_id = :user_id, activity_type = :activity_type, description = :description,
|
| 80 |
+
ip_address = :ip_address, user_agent = :user_agent";
|
| 81 |
+
|
| 82 |
+
$stmt = $this->db->prepare($query);
|
| 83 |
+
$stmt->bindParam(":user_id", $user_id);
|
| 84 |
+
$stmt->bindParam(":activity_type", $activity_type);
|
| 85 |
+
$stmt->bindParam(":description", $description);
|
| 86 |
+
$stmt->bindParam(":ip_address", $ip_address);
|
| 87 |
+
$stmt->bindParam(":user_agent", $user_agent);
|
| 88 |
+
|
| 89 |
+
return $stmt->execute();
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
// Update last login
|
| 93 |
+
public function updateLastLogin($user_id) {
|
| 94 |
+
$query = "UPDATE users SET last_login = NOW() WHERE id = :user_id";
|
| 95 |
+
$stmt = $this->db->prepare($query);
|
| 96 |
+
$stmt->bindParam(":user_id", $user_id);
|
| 97 |
+
return $stmt->execute();
|
| 98 |
+
}
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
// Initialize database and session manager
|
| 102 |
+
try {
|
| 103 |
+
$database = new Database();
|
| 104 |
+
$db = $database->getConnection();
|
| 105 |
+
$sessionManager = new SessionManager($database);
|
| 106 |
+
} catch(Exception $e) {
|
| 107 |
+
error_log("Initialization error: " . $e->getMessage());
|
| 108 |
+
$db = null;
|
| 109 |
+
$sessionManager = null;
|
| 110 |
+
}
|
| 111 |
+
?>
|
jweb/ac1/home.html
ADDED
|
@@ -0,0 +1,692 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Start session and check if user is logged in
|
| 3 |
+
session_start();
|
| 4 |
+
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
|
| 5 |
+
header('Location: ../../index.php');
|
| 6 |
+
exit;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
// Get user data from session
|
| 10 |
+
$username = $_SESSION['username'];
|
| 11 |
+
$email = $_SESSION['email'];
|
| 12 |
+
$tier = $_SESSION['tier'];
|
| 13 |
+
$package = $_SESSION['package'];
|
| 14 |
+
$balance = $_SESSION['balance'];
|
| 15 |
+
$total_deposits = $_SESSION['total_deposits'];
|
| 16 |
+
$total_withdrawals = $_SESSION['total_withdrawals'];
|
| 17 |
+
$rewards = $_SESSION['rewards'];
|
| 18 |
+
$earnings = $total_deposits - $total_withdrawals;
|
| 19 |
+
?>
|
| 20 |
+
<!DOCTYPE html>
|
| 21 |
+
<html lang="en">
|
| 22 |
+
<head>
|
| 23 |
+
<meta charset="UTF-8">
|
| 24 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 25 |
+
<title>Japanese Motors — Customer Care</title>
|
| 26 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 27 |
+
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700;800&display=swap" rel="stylesheet">
|
| 28 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 29 |
+
<style>
|
| 30 |
+
:root {
|
| 31 |
+
--bg: #7b848d;
|
| 32 |
+
--card: #7a2f3b;
|
| 33 |
+
--card-2: #6f2630;
|
| 34 |
+
--accent: #efdf2d;
|
| 35 |
+
--muted: rgba(255,255,255,0.6);
|
| 36 |
+
--glass: rgba(255,255,255,0.04);
|
| 37 |
+
--promo-gradient: linear-gradient(180deg,#a13df0 0%, #ff2a79 50%, #d70b1a 100%);
|
| 38 |
+
font-family: 'Poppins', system-ui, Arial;
|
| 39 |
+
--banner-gradient-start: #a855f7;
|
| 40 |
+
--banner-gradient-end: #ec4899;
|
| 41 |
+
--spacing-unit: 1rem;
|
| 42 |
+
--accent-primary: #7c3aed;
|
| 43 |
+
--accent-secondary: #a855f7;
|
| 44 |
+
--shadow-hover: 0 6px 18px rgba(0, 0, 0, 0.1);
|
| 45 |
+
--premium-gold: #d97706;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
body {
|
| 49 |
+
background: var(--bg);
|
| 50 |
+
font-family: 'Poppins', sans-serif;
|
| 51 |
+
transition: all 0.3s ease;
|
| 52 |
+
min-height: 100vh;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
.sidebar {
|
| 56 |
+
width: 250px;
|
| 57 |
+
height: 100vh;
|
| 58 |
+
background: #0d1321;
|
| 59 |
+
color: #fff;
|
| 60 |
+
position: fixed;
|
| 61 |
+
top: 0;
|
| 62 |
+
left: -250px;
|
| 63 |
+
transition: all 0.3s ease;
|
| 64 |
+
z-index: 1000;
|
| 65 |
+
overflow-y: auto;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
.sidebar.active {
|
| 69 |
+
left: 0;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
#content {
|
| 73 |
+
margin-left: 0;
|
| 74 |
+
transition: all 0.3s ease;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.sidebar.active ~ #content {
|
| 78 |
+
margin-left: 250px;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
header {
|
| 82 |
+
background: #222;
|
| 83 |
+
color: white;
|
| 84 |
+
padding: 15px 20px;
|
| 85 |
+
display: flex;
|
| 86 |
+
justify-content: space-between;
|
| 87 |
+
align-items: center;
|
| 88 |
+
position: relative;
|
| 89 |
+
z-index: 900;
|
| 90 |
+
transition: all 0.3s ease;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
.sidebar.active ~ #content header {
|
| 94 |
+
margin-left: 250px;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
.menu-toggle {
|
| 98 |
+
background: transparent;
|
| 99 |
+
border: none;
|
| 100 |
+
color: white;
|
| 101 |
+
font-size: 1.5rem;
|
| 102 |
+
cursor: pointer;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
.logo-section {
|
| 106 |
+
padding: 15px;
|
| 107 |
+
border-bottom: 1px solid #1c2230;
|
| 108 |
+
display: flex;
|
| 109 |
+
align-items: center;
|
| 110 |
+
gap: 10px;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
.brand {
|
| 114 |
+
font-size: 1.2rem;
|
| 115 |
+
font-weight: 700;
|
| 116 |
+
color: #ff9800;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.subtitle {
|
| 120 |
+
font-size: 0.75rem;
|
| 121 |
+
color: #aaa;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
.menu {
|
| 125 |
+
list-style: none;
|
| 126 |
+
padding: 0;
|
| 127 |
+
margin: 0;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
.menu li a {
|
| 131 |
+
display: flex;
|
| 132 |
+
align-items: center;
|
| 133 |
+
padding: 12px 20px;
|
| 134 |
+
color: white;
|
| 135 |
+
text-decoration: none;
|
| 136 |
+
transition: background 0.3s;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
.menu li a:hover {
|
| 140 |
+
background: #1c2230;
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
.menu li a i {
|
| 144 |
+
margin-right: 12px;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
.user-footer {
|
| 148 |
+
padding: 15px;
|
| 149 |
+
background: #222;
|
| 150 |
+
display: flex;
|
| 151 |
+
align-items: center;
|
| 152 |
+
gap: 10px;
|
| 153 |
+
position: sticky;
|
| 154 |
+
bottom: 0;
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
.avatar {
|
| 158 |
+
width: 35px;
|
| 159 |
+
height: 35px;
|
| 160 |
+
background: #444;
|
| 161 |
+
border-radius: 50%;
|
| 162 |
+
display: flex;
|
| 163 |
+
align-items: center;
|
| 164 |
+
justify-content: center;
|
| 165 |
+
font-weight: bold;
|
| 166 |
+
color: white;
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
.banner {
|
| 170 |
+
max-width: 450px;
|
| 171 |
+
margin: 0 auto calc(var(--spacing-unit) * 2);
|
| 172 |
+
background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
|
| 173 |
+
border-radius: 12px;
|
| 174 |
+
padding: calc(var(--spacing-unit) * 1.5);
|
| 175 |
+
text-align: center;
|
| 176 |
+
box-shadow: var(--shadow-hover);
|
| 177 |
+
animation: fadeIn 0.5s ease;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
@keyframes fadeIn {
|
| 181 |
+
from { opacity: 0; transform: translateY(20px); }
|
| 182 |
+
to { opacity: 1; transform: translateY(0); }
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
@keyframes blink {
|
| 186 |
+
0% { opacity: 1; }
|
| 187 |
+
50% { opacity: 0.3; }
|
| 188 |
+
100% { opacity: 1; }
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
.banner .title {
|
| 192 |
+
font-size: 1.25rem;
|
| 193 |
+
margin-bottom: calc(var(--spacing-unit) * 1);
|
| 194 |
+
color: #ffffff;
|
| 195 |
+
font-weight: 700;
|
| 196 |
+
animation: blink 1.5s infinite;
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
.banner p {
|
| 200 |
+
font-size: 0.95rem;
|
| 201 |
+
line-height: 1.6;
|
| 202 |
+
margin-bottom: calc(var(--spacing-unit) * 1);
|
| 203 |
+
color: var(--premium-gold);
|
| 204 |
+
animation: blink 1.5s infinite;
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
.banner .footer {
|
| 208 |
+
font-size: 0.75rem;
|
| 209 |
+
color: rgba(255, 255, 255, 0.9);
|
| 210 |
+
font-style: italic;
|
| 211 |
+
animation: blink 1.5s infinite;
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
.card {
|
| 215 |
+
background: var(--card);
|
| 216 |
+
border-radius: 12px;
|
| 217 |
+
padding: 26px;
|
| 218 |
+
color: white;
|
| 219 |
+
box-shadow: 0 6px 0 rgba(0,0,0,0.08) inset;
|
| 220 |
+
flex: 1;
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
.balance {
|
| 224 |
+
background: rgba(255,255,255,0.03);
|
| 225 |
+
padding: 14px;
|
| 226 |
+
border-radius: 10px;
|
| 227 |
+
margin: 18px 0;
|
| 228 |
+
display: flex;
|
| 229 |
+
align-items: center;
|
| 230 |
+
justify-content: space-between;
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
.form-group {
|
| 234 |
+
margin: 12px 0;
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
label {
|
| 238 |
+
display: block;
|
| 239 |
+
margin-bottom: 8px;
|
| 240 |
+
color: rgba(255,255,255,0.85);
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
input, select, textarea {
|
| 244 |
+
width: 100%;
|
| 245 |
+
padding: 14px;
|
| 246 |
+
border-radius: 10px;
|
| 247 |
+
border: 1px solid rgba(255,255,255,0.05);
|
| 248 |
+
background: transparent;
|
| 249 |
+
color: white;
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
.btn {
|
| 253 |
+
display: inline-block;
|
| 254 |
+
padding: 14px 24px;
|
| 255 |
+
border-radius: 10px;
|
| 256 |
+
background: var(--accent);
|
| 257 |
+
color: #111;
|
| 258 |
+
font-weight: 700;
|
| 259 |
+
border: none;
|
| 260 |
+
cursor: pointer;
|
| 261 |
+
width: 100%;
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
.btn-outline {
|
| 265 |
+
background: transparent;
|
| 266 |
+
border: 2px solid var(--accent);
|
| 267 |
+
color: var(--accent);
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
.dashboard-card {
|
| 271 |
+
background: rgba(0,0,0,0.2);
|
| 272 |
+
border-radius: 12px;
|
| 273 |
+
padding: 20px;
|
| 274 |
+
margin-bottom: 20px;
|
| 275 |
+
}
|
| 276 |
+
|
| 277 |
+
.stat-card {
|
| 278 |
+
background: rgba(0,0,0,0.15);
|
| 279 |
+
border-radius: 10px;
|
| 280 |
+
padding: 16px;
|
| 281 |
+
margin-bottom: 16px;
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
.support-ticket {
|
| 285 |
+
background: rgba(0,0,0,0.15);
|
| 286 |
+
border-radius: 10px;
|
| 287 |
+
padding: 16px;
|
| 288 |
+
margin-bottom: 16px;
|
| 289 |
+
border-left: 4px solid var(--accent);
|
| 290 |
+
}
|
| 291 |
+
|
| 292 |
+
.faq-item {
|
| 293 |
+
background: rgba(0,0,0,0.15);
|
| 294 |
+
border-radius: 10px;
|
| 295 |
+
padding: 16px;
|
| 296 |
+
margin-bottom: 16px;
|
| 297 |
+
cursor: pointer;
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
+
.faq-answer {
|
| 301 |
+
display: none;
|
| 302 |
+
padding-top: 12px;
|
| 303 |
+
color: var(--muted);
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
.active-page {
|
| 307 |
+
background: #1c2230;
|
| 308 |
+
border-right: 4px solid var(--accent);
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
.whatsapp-btn {
|
| 312 |
+
background: #25D366;
|
| 313 |
+
color: white;
|
| 314 |
+
display: inline-flex;
|
| 315 |
+
align-items: center;
|
| 316 |
+
justify-content: center;
|
| 317 |
+
gap: 8px;
|
| 318 |
+
padding: 12px 20px;
|
| 319 |
+
border-radius: 10px;
|
| 320 |
+
font-weight: 600;
|
| 321 |
+
text-decoration: none;
|
| 322 |
+
margin-top: 15px;
|
| 323 |
+
}
|
| 324 |
+
|
| 325 |
+
.contact-option {
|
| 326 |
+
background: rgba(0,0,0,0.15);
|
| 327 |
+
border-radius: 10px;
|
| 328 |
+
padding: 16px;
|
| 329 |
+
margin-bottom: 16px;
|
| 330 |
+
transition: transform 0.3s ease;
|
| 331 |
+
}
|
| 332 |
+
|
| 333 |
+
.contact-option:hover {
|
| 334 |
+
transform: translateY(-3px);
|
| 335 |
+
}
|
| 336 |
+
|
| 337 |
+
@media (max-width: 768px) {
|
| 338 |
+
.cards {
|
| 339 |
+
flex-direction: column;
|
| 340 |
+
}
|
| 341 |
+
|
| 342 |
+
.promo {
|
| 343 |
+
width: 92%;
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
.grid-cols-2 {
|
| 347 |
+
grid-template-columns: 1fr;
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
.grid-cols-3 {
|
| 351 |
+
grid-template-columns: 1fr;
|
| 352 |
+
}
|
| 353 |
+
}
|
| 354 |
+
</style>
|
| 355 |
+
</head>
|
| 356 |
+
<body>
|
| 357 |
+
<!-- Sidebar -->
|
| 358 |
+
<aside class="sidebar" id="sidebar">
|
| 359 |
+
<div class="logo-section">
|
| 360 |
+
<i data-feather="zap" class="text-yellow-400"></i>
|
| 361 |
+
<div>
|
| 362 |
+
<h2 class="brand">JMOTORS</h2>
|
| 363 |
+
<p class="subtitle">Marketing Platform</p>
|
| 364 |
+
</div>
|
| 365 |
+
</div>
|
| 366 |
+
|
| 367 |
+
<ul class="menu">
|
| 368 |
+
<li><a href="index.php"><i data-feather="home"></i> Dashboard</a></li>
|
| 369 |
+
<li><a href="meta-uploads.php"><i data-feather="upload"></i> Meta Uploads</a></li>
|
| 370 |
+
<li><a href="transactions.php"><i data-feather="repeat"></i> Transactions</a></li>
|
| 371 |
+
<li><a href="transfer.php"><i data-feather="send"></i> Transfer</a></li>
|
| 372 |
+
<li><a href="daily-product.php"><i data-feather="shopping-bag"></i> Daily Product</a></li>
|
| 373 |
+
<li><a href="withdraw.php"><i data-feather="dollar-sign"></i> Withdraw</a></li>
|
| 374 |
+
<li><a href="packages.php"><i data-feather="package"></i> Packages</a></li>
|
| 375 |
+
<li><a href="loan.php"><i data-feather="credit-card"></i> Loan</a></li>
|
| 376 |
+
<li><a href="recharge.php"><i data-feather="battery-charging"></i> Recharge</a></li>
|
| 377 |
+
<li><a href="agent-approval.php" class="active-page"><i data-feather="user-check"></i> Agent Approval</a></li>
|
| 378 |
+
<li><a href="access-token.php"><i data-feather="key"></i> Access Token</a></li>
|
| 379 |
+
<li><a href="agent-claim.php"><i data-feather="tag"></i> Agent Claim</a></li>
|
| 380 |
+
<li><a href="team.php"><i data-feather="users"></i> Team</a></li>
|
| 381 |
+
</ul>
|
| 382 |
+
|
| 383 |
+
<ul class="menu bottom">
|
| 384 |
+
<li><a href="profile.php"><i data-feather="user"></i> Profile</a></li>
|
| 385 |
+
<li><a href="settings.php"><i data-feather="settings"></i> Settings</a></li>
|
| 386 |
+
<li><a href="whatsapp-channel.php"><i data-feather="message-square"></i> Whatsapp Channel</a></li>
|
| 387 |
+
<li><a href="customer-care.php"><i data-feather="headphones"></i> Customer Care</a></li>
|
| 388 |
+
</ul>
|
| 389 |
+
|
| 390 |
+
<div class="user-footer">
|
| 391 |
+
<div class="avatar"><?php echo substr($username, 0, 2); ?></div>
|
| 392 |
+
<div>
|
| 393 |
+
<h4><?php echo $username; ?></h4>
|
| 394 |
+
<p><?php echo $tier; ?> - Marketer</p>
|
| 395 |
+
</div>
|
| 396 |
+
</div>
|
| 397 |
+
</aside>
|
| 398 |
+
|
| 399 |
+
<!-- Main Content -->
|
| 400 |
+
<div id="content">
|
| 401 |
+
<header class="bg-gray-800 text-white p-4">
|
| 402 |
+
<div class="flex items-center">
|
| 403 |
+
<button class="menu-toggle" id="menu-toggle">
|
| 404 |
+
<i data-feather="menu"></i>
|
| 405 |
+
</button>
|
| 406 |
+
<div class="ml-4 font-bold text-xl">Jmotors</div>
|
| 407 |
+
</div>
|
| 408 |
+
<nav class="flex items-center space-x-6">
|
| 409 |
+
<a href="transfer.php" class="hover:text-yellow-300">Transfer</a>
|
| 410 |
+
<a href="loan.php" class="hover:text-yellow-300">Loans</a>
|
| 411 |
+
<a href="dailyproduct.php" class="hover:text-yellow-300">New Product</a>
|
| 412 |
+
<div class="w-9 h-9 rounded-full bg-gradient-to-r from-yellow-300 to-orange-400 flex items-center justify-center font-bold">MI</div>
|
| 413 |
+
</nav>
|
| 414 |
+
</header>
|
| 415 |
+
|
| 416 |
+
<main class="p-4">
|
| 417 |
+
<div class="banner">
|
| 418 |
+
<div class="title">🛎️ Customer Care Support</div>
|
| 419 |
+
<p>We're here to help you with any issues or questions about your Japanese Motors account</p>
|
| 420 |
+
|
| 421 |
+
<div class="footer">⏰ 24/7 support • Quick response • Expert help</div>
|
| 422 |
+
</div>
|
| 423 |
+
|
| 424 |
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mt-6">
|
| 425 |
+
<div class="dashboard-card md:col-span-2">
|
| 426 |
+
<h3 class="text-lg font-bold mb-4 flex items-center gap-2">
|
| 427 |
+
<i data-feather="help-circle" class="text-blue-400"></i> Submit a Support Request
|
| 428 |
+
</h3>
|
| 429 |
+
|
| 430 |
+
<form id="support-form">
|
| 431 |
+
<div class="form-group">
|
| 432 |
+
<label for="issue-type">Issue Type</label>
|
| 433 |
+
<select id="issue-type" required>
|
| 434 |
+
<option value="">Select issue type</option>
|
| 435 |
+
<option value="technical">Technical Issue</option>
|
| 436 |
+
<option value="account">Account Problem</option>
|
| 437 |
+
<option value="payment">Payment Issue</option>
|
| 438 |
+
<option value="product">Product Related</option>
|
| 439 |
+
<option value="withdrawal">Withdrawal Problem</option>
|
| 440 |
+
<option value="other">Other</option>
|
| 441 |
+
</select>
|
| 442 |
+
</div>
|
| 443 |
+
|
| 444 |
+
<div class="form-group">
|
| 445 |
+
<label for="subject">Subject</label>
|
| 446 |
+
<input type="text" id="subject" placeholder="Brief description of your issue" required>
|
| 447 |
+
</div>
|
| 448 |
+
|
| 449 |
+
<div class="form-group">
|
| 450 |
+
<label for="description">Description</label>
|
| 451 |
+
<textarea id="description" rows="5" placeholder="Please describe your issue in detail..." required></textarea>
|
| 452 |
+
</div>
|
| 453 |
+
|
| 454 |
+
<div class="form-group">
|
| 455 |
+
<label for="priority">Priority Level</label>
|
| 456 |
+
<select id="priority" required>
|
| 457 |
+
<option value="low">Low - General inquiry</option>
|
| 458 |
+
<option value="medium" selected>Medium - Feature request or minor issue</option>
|
| 459 |
+
<option value="high">High - Functionality impaired</option>
|
| 460 |
+
<option value="urgent">Urgent - System down or critical issue</option>
|
| 461 |
+
</select>
|
| 462 |
+
</div>
|
| 463 |
+
|
| 464 |
+
<div class="form-group">
|
| 465 |
+
<label for="attachments">Attachments (Optional)</label>
|
| 466 |
+
<input type="file" id="attachments">
|
| 467 |
+
<p class="text-xs text-gray-400 mt-1">Upload screenshots or documents that might help us understand your issue</p>
|
| 468 |
+
</div>
|
| 469 |
+
|
| 470 |
+
<button type="submit" class="btn">Submit Request</button>
|
| 471 |
+
</form>
|
| 472 |
+
</div>
|
| 473 |
+
|
| 474 |
+
<div class="dashboard-card">
|
| 475 |
+
<h3 class="text-lg font-bold mb-4 flex items-center gap-2">
|
| 476 |
+
<i data-feather="phone" class="text-green-400"></i> Contact Options
|
| 477 |
+
</h3>
|
| 478 |
+
|
| 479 |
+
<div class="contact-option">
|
| 480 |
+
<h4 class="font-bold mb-2 flex items-center gap-2">
|
| 481 |
+
<i data-feather="message-circle" class="text-green-400"></i> Direct WhatsApp Support
|
| 482 |
+
</h4>
|
| 483 |
+
<p class="text-sm mb-3">Chat directly with our support team for instant assistance</p>
|
| 484 |
+
<a href="https://wa.me/254712345678" class="whatsapp-btn" target="_blank">
|
| 485 |
+
<i data-feather="message-circle"></i> Message Support
|
| 486 |
+
</a>
|
| 487 |
+
</div>
|
| 488 |
+
|
| 489 |
+
<div class="contact-option">
|
| 490 |
+
<h4 class="font-bold mb-2 flex items-center gap-2">
|
| 491 |
+
<i data-feather="mail" class="text-blue-400"></i> Email Support
|
| 492 |
+
</h4>
|
| 493 |
+
<p class="text-sm mb-1">Jmotors.com</p>
|
| 494 |
+
<p class="text-sm mb-1">Jmotors.com</p>
|
| 495 |
+
<p class="text-xs text-gray-400">Response within 2 hours</p>
|
| 496 |
+
</div>
|
| 497 |
+
|
| 498 |
+
<div class="contact-option">
|
| 499 |
+
<h4 class="font-bold mb-2 flex items-center gap-2">
|
| 500 |
+
<i data-feather="phone" class="text-purple-400"></i> Phone Support
|
| 501 |
+
</h4>
|
| 502 |
+
<p class="text-sm mb-1">+254 700 123 456</p>
|
| 503 |
+
<p class="text-sm mb-1">+254 711 987 654</p>
|
| 504 |
+
<p class="text-xs text-gray-400">Available 24/7 for urgent issues</p>
|
| 505 |
+
</div>
|
| 506 |
+
|
| 507 |
+
<div class="contact-option">
|
| 508 |
+
<h4 class="font-bold mb-2 flex items-center gap-2">
|
| 509 |
+
<i data-feather="map-pin" class="text-red-400"></i> Office Visit
|
| 510 |
+
</h4>
|
| 511 |
+
<p class="text-sm mb-1">Jmotors Headquarters</p>
|
| 512 |
+
<p class="text-sm mb-1">Nairobi, Kenya</p>
|
| 513 |
+
<p class="text-xs text-gray-400">By appointment only</p>
|
| 514 |
+
</div>
|
| 515 |
+
</div>
|
| 516 |
+
</div>
|
| 517 |
+
|
| 518 |
+
<div class="dashboard-card mt-8">
|
| 519 |
+
<h3 class="text-lg font-bold mb-4 flex items-center gap-2">
|
| 520 |
+
<i data-feather="book-open" class="text-purple-400"></i> Frequently Asked Questions
|
| 521 |
+
</h3>
|
| 522 |
+
|
| 523 |
+
<div class="faq-item">
|
| 524 |
+
<div class="flex justify-between items-center">
|
| 525 |
+
<h4 class="font-bold">How do I reset my password?</h4>
|
| 526 |
+
<i data-feather="chevron-down" class="faq-toggle"></i>
|
| 527 |
+
</div>
|
| 528 |
+
<div class="faq-answer">
|
| 529 |
+
<p>To reset your password, go to the login page and click on "Forgot Password". Enter your registered email address and follow the instructions sent to your email. If you don't receive the email within 5 minutes, check your spam folder or contact support.</p>
|
| 530 |
+
</div>
|
| 531 |
+
</div>
|
| 532 |
+
|
| 533 |
+
<div class="faq-item">
|
| 534 |
+
<div class="flex justify-between items-center">
|
| 535 |
+
<h4 class="font-bold">Why is my withdrawal pending?</h4>
|
| 536 |
+
<i data-feather="chevron-down" class="faq-toggle"></i>
|
| 537 |
+
</div>
|
| 538 |
+
<div class="faq-answer">
|
| 539 |
+
<p>Withdrawals typically process within 24 hours. If it's taking longer, it might be undergoing security verification. Contact support if pending for more than 48 hours. Make sure you've completed the required 5 uploads in the last 7 days to be eligible for withdrawal.</p>
|
| 540 |
+
</div>
|
| 541 |
+
</div>
|
| 542 |
+
|
| 543 |
+
<div class="faq-item">
|
| 544 |
+
<div class="flex justify-between items-center">
|
| 545 |
+
<h4 class="font-bold">How do I join the affiliate program?</h4>
|
| 546 |
+
<i data-feather="chevron-down" class="faq-toggle"></i>
|
| 547 |
+
</div>
|
| 548 |
+
<div class="faq-answer">
|
| 549 |
+
<p>To join our affiliate program, go to your dashboard, click on "Team" and then "Become an Affiliate". Follow the registration process and start inviting members. You need to have been active for at least 30 days and completed 50 successful uploads to qualify.</p>
|
| 550 |
+
</div>
|
| 551 |
+
</div>
|
| 552 |
+
|
| 553 |
+
<div class="faq-item">
|
| 554 |
+
<div class="flex justify-between items-center">
|
| 555 |
+
<h4 class="font-bold">What are the minimum withdrawal requirements?</h4>
|
| 556 |
+
<i data-feather="chevron-down" class="faq-toggle"></i>
|
| 557 |
+
</div>
|
| 558 |
+
<div class="faq-answer">
|
| 559 |
+
<p>The minimum withdrawal amount is KES 500. You must also have completed at least 5 successful uploads in the last 7 days to be eligible for withdrawal. There's a 2% processing fee for withdrawals below KES 2,000.</p>
|
| 560 |
+
</div>
|
| 561 |
+
</div>
|
| 562 |
+
|
| 563 |
+
<div class="faq-item">
|
| 564 |
+
<div class="flex justify-between items-center">
|
| 565 |
+
<h4 class="font-bold">How do I upgrade my account level?</h4>
|
| 566 |
+
<i data-feather="chevron-down" class="faq-toggle"></i>
|
| 567 |
+
</div>
|
| 568 |
+
<div class="faq-answer">
|
| 569 |
+
<p>Account levels are automatically upgraded based on your activity and earnings. To move from Dormant to Active Marketer, you need to complete 10 uploads and earn at least KES 1,000. Higher levels require more activity and team members.</p>
|
| 570 |
+
</div>
|
| 571 |
+
</div>
|
| 572 |
+
|
| 573 |
+
<div class="faq-item">
|
| 574 |
+
<div class="flex justify-between items-center">
|
| 575 |
+
<h4 class="font-bold">What should I do if my uploads are rejected?</h4>
|
| 576 |
+
<i data-feather="chevron-down" class="faq-toggle"></i>
|
| 577 |
+
</div>
|
| 578 |
+
<div class="faq-answer">
|
| 579 |
+
<p>If your uploads are frequently rejected, check the content guidelines in the Meta Uploads section. Make sure your content is original, follows platform rules, and meets the quality standards. If you believe your content was wrongly rejected, contact support with the upload ID.</p>
|
| 580 |
+
</div>
|
| 581 |
+
</div>
|
| 582 |
+
</div>
|
| 583 |
+
|
| 584 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mt-8">
|
| 585 |
+
<div class="dashboard-card">
|
| 586 |
+
<h3 class="text-lg font-bold mb-4 flex items-center gap-2">
|
| 587 |
+
<i data-feather="clock" class="text-yellow-400"></i> Support Hours
|
| 588 |
+
</h3>
|
| 589 |
+
<div class="space-y-3">
|
| 590 |
+
<div class="flex justify-between">
|
| 591 |
+
<span>WhatsApp Support:</span>
|
| 592 |
+
<span class="font-bold">24/7</span>
|
| 593 |
+
</div>
|
| 594 |
+
<div class="flex justify-between">
|
| 595 |
+
<span>Email Support:</span>
|
| 596 |
+
<span class="font-bold">Mon-Sun, 6am-11pm EAT</span>
|
| 597 |
+
</div>
|
| 598 |
+
<div class="flex justify-between">
|
| 599 |
+
<span>Phone Support:</span>
|
| 600 |
+
<span class="font-bold">24/7 for urgent issues</span>
|
| 601 |
+
</div>
|
| 602 |
+
<div class="flex justify-between">
|
| 603 |
+
<span>Average Response Time:</span>
|
| 604 |
+
<span class="font-bold">Under 30 minutes</span>
|
| 605 |
+
</div>
|
| 606 |
+
<div class="flex justify-between">
|
| 607 |
+
<span>Ticket Resolution Time:</span>
|
| 608 |
+
<span class="font-bold">Within 24 hours</span>
|
| 609 |
+
</div>
|
| 610 |
+
</div>
|
| 611 |
+
</div>
|
| 612 |
+
|
| 613 |
+
<div class="dashboard-card">
|
| 614 |
+
<h3 class="text-lg font-bold mb-4 flex items-center gap-2">
|
| 615 |
+
<i data-feather="file-text" class="text-red-400"></i> Support Tickets
|
| 616 |
+
</h3>
|
| 617 |
+
<div class="text-center py-4">
|
| 618 |
+
<i data-feather="inbox" class="mx-auto text-gray-400 text-4xl"></i>
|
| 619 |
+
<p class="mt-2 text-gray-400">No active support tickets</p>
|
| 620 |
+
</div>
|
| 621 |
+
<button class="btn btn-outline mt-2">View Ticket History</button>
|
| 622 |
+
<p class="text-xs text-center text-gray-400 mt-2">You can check the status of previous support requests</p>
|
| 623 |
+
</div>
|
| 624 |
+
</div>
|
| 625 |
+
|
| 626 |
+
<div class="dashboard-card mt-8">
|
| 627 |
+
<h3 class="text-lg font-bold mb-4 flex items-center gap-2">
|
| 628 |
+
<i data-feather="users" class="text-green-400"></i> Community Support
|
| 629 |
+
</h3>
|
| 630 |
+
<p class="mb-4">Join our community of marketers to get help from experienced members and share insights:</p>
|
| 631 |
+
|
| 632 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
| 633 |
+
<div class="stat-card">
|
| 634 |
+
<h4 class="font-bold mb-2">Community Forum</h4>
|
| 635 |
+
<p class="text-sm mb-3">Get answers from other marketers in our community forum</p>
|
| 636 |
+
<a href="#" class="btn btn-outline">Visit Forum</a>
|
| 637 |
+
</div>
|
| 638 |
+
|
| 639 |
+
<div class="stat-card">
|
| 640 |
+
<h4 class="font-bold mb-2">Knowledge Base</h4>
|
| 641 |
+
<p class="text-sm mb-3">Browse our comprehensive knowledge base articles</p>
|
| 642 |
+
<a href="#" class="btn btn-outline">Browse Articles</a>
|
| 643 |
+
</div>
|
| 644 |
+
</div>
|
| 645 |
+
</div>
|
| 646 |
+
</main>
|
| 647 |
+
</div>
|
| 648 |
+
|
| 649 |
+
<script>
|
| 650 |
+
feather.replace();
|
| 651 |
+
|
| 652 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 653 |
+
const toggleBtn = document.getElementById('menu-toggle');
|
| 654 |
+
const sidebar = document.getElementById('sidebar');
|
| 655 |
+
const content = document.getElementById('content');
|
| 656 |
+
|
| 657 |
+
toggleBtn.addEventListener('click', function() {
|
| 658 |
+
sidebar.classList.toggle('active');
|
| 659 |
+
content.classList.toggle('active');
|
| 660 |
+
});
|
| 661 |
+
|
| 662 |
+
// FAQ toggle functionality
|
| 663 |
+
const faqItems = document.querySelectorAll('.faq-item');
|
| 664 |
+
faqItems.forEach(item => {
|
| 665 |
+
item.addEventListener('click', function() {
|
| 666 |
+
const answer = this.querySelector('.faq-answer');
|
| 667 |
+
const icon = this.querySelector('.faq-toggle');
|
| 668 |
+
|
| 669 |
+
if (answer.style.display === 'block') {
|
| 670 |
+
answer.style.display = 'none';
|
| 671 |
+
icon.setAttribute('data-feather', 'chevron-down');
|
| 672 |
+
} else {
|
| 673 |
+
answer.style.display = 'block';
|
| 674 |
+
icon.setAttribute('data-feather', 'chevron-up');
|
| 675 |
+
}
|
| 676 |
+
feather.replace();
|
| 677 |
+
});
|
| 678 |
+
});
|
| 679 |
+
|
| 680 |
+
// Support form submission
|
| 681 |
+
const supportForm = document.getElementById('support-form');
|
| 682 |
+
if (supportForm) {
|
| 683 |
+
supportForm.addEventListener('submit', function(e) {
|
| 684 |
+
e.preventDefault();
|
| 685 |
+
alert('Your support request has been submitted successfully! Our team will contact you shortly.');
|
| 686 |
+
this.reset();
|
| 687 |
+
});
|
| 688 |
+
}
|
| 689 |
+
});
|
| 690 |
+
</script>
|
| 691 |
+
</body>
|
| 692 |
+
</html>
|
jweb/ac1/inde.php
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>MetaView - Create Account</title>
|
| 7 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
| 8 |
+
<link rel="stylesheet" href="assets/css/st.css">
|
| 9 |
+
</head>
|
| 10 |
+
<body>
|
| 11 |
+
<div class="container">
|
| 12 |
+
<div class="login-container">
|
| 13 |
+
<div class="logo">
|
| 14 |
+
<!-- Replace with your logo -->
|
| 15 |
+
<img src="logo.png" alt="Japanese Motors Logo">
|
| 16 |
+
</div>
|
| 17 |
+
<h2>Japanese Motors</h2>
|
| 18 |
+
<p class="subtitle">Access your financial dashboard</p>
|
| 19 |
+
</div>
|
| 20 |
+
<div class="form-container">
|
| 21 |
+
<form>
|
| 22 |
+
<div class="form-group">
|
| 23 |
+
<label for="username">Username</label>
|
| 24 |
+
<div class="input-icon">
|
| 25 |
+
<i class="fas fa-user"></i>
|
| 26 |
+
<input type="text" id="username" value="maha">
|
| 27 |
+
</div>
|
| 28 |
+
</div>
|
| 29 |
+
|
| 30 |
+
<div class="form-group">
|
| 31 |
+
<label for="email">Email</label>
|
| 32 |
+
<div class="input-icon">
|
| 33 |
+
<i class="fas fa-envelope"></i>
|
| 34 |
+
<input type="email" id="email" value="yout@email.com">
|
| 35 |
+
</div>
|
| 36 |
+
</div>
|
| 37 |
+
|
| 38 |
+
<div class="form-group">
|
| 39 |
+
<label for="country">Country</label>
|
| 40 |
+
<div class="input-icon">
|
| 41 |
+
<i class="fas fa-globe"></i>
|
| 42 |
+
<select id="country" required>
|
| 43 |
+
<option value="">Select your country</option>
|
| 44 |
+
</select>
|
| 45 |
+
</div>
|
| 46 |
+
</div>
|
| 47 |
+
|
| 48 |
+
<div class="form-group">
|
| 49 |
+
<label for="phone">Phone Number</label>
|
| 50 |
+
<div class="input-icon">
|
| 51 |
+
<i class="fas fa-phone"></i>
|
| 52 |
+
<input type="tel" id="phone" value="0712515678">
|
| 53 |
+
</div>
|
| 54 |
+
</div>
|
| 55 |
+
|
| 56 |
+
<div class="password-row">
|
| 57 |
+
<div class="form-group">
|
| 58 |
+
<label for="password">Password</label>
|
| 59 |
+
<div class="input-icon">
|
| 60 |
+
<i class="fas fa-lock"></i>
|
| 61 |
+
<input type="password" id="password" value="password123">
|
| 62 |
+
<span class="password-toggle" id="togglePassword">
|
| 63 |
+
<i class="fas fa-eye"></i>
|
| 64 |
+
</span>
|
| 65 |
+
</div>
|
| 66 |
+
</div>
|
| 67 |
+
|
| 68 |
+
<div class="form-group">
|
| 69 |
+
<label for="confirm-password">Confirm Password</label>
|
| 70 |
+
<div class="input-icon">
|
| 71 |
+
<i class="fas fa-lock"></i>
|
| 72 |
+
<input type="password" id="confirm-password" value="password123">
|
| 73 |
+
<span class="password-toggle" id="toggleConfirmPassword">
|
| 74 |
+
<i class="fas fa-eye"></i>
|
| 75 |
+
</span>
|
| 76 |
+
</div>
|
| 77 |
+
</div>
|
| 78 |
+
</div>
|
| 79 |
+
|
| 80 |
+
<button type="submit" class="create-account-btn">Create Account <i class="fas fa-arrow-right"></i></button>
|
| 81 |
+
</form>
|
| 82 |
+
|
| 83 |
+
<p class="signin-link">Already have an account? <a href="#">sign in</a></p>
|
| 84 |
+
</div>
|
| 85 |
+
|
| 86 |
+
</div><br>
|
| 87 |
+
<footer>
|
| 88 |
+
<div class="footer">
|
| 89 |
+
<p>© 2024 Japanese Motors. All rights reserved.</p>
|
| 90 |
+
</div>
|
| 91 |
+
</footer>
|
| 92 |
+
|
| 93 |
+
<script>
|
| 94 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 95 |
+
// Toggle password visibility
|
| 96 |
+
const togglePassword = document.getElementById('togglePassword');
|
| 97 |
+
const toggleConfirmPassword = document.getElementById('toggleConfirmPassword');
|
| 98 |
+
const passwordInput = document.getElementById('password');
|
| 99 |
+
const confirmPasswordInput = document.getElementById('confirm-password');
|
| 100 |
+
|
| 101 |
+
togglePassword.addEventListener('click', function() {
|
| 102 |
+
const type = passwordInput.getAttribute('type') === 'password' ? 'text' : 'password';
|
| 103 |
+
passwordInput.setAttribute('type', type);
|
| 104 |
+
this.querySelector('i').classList.toggle('fa-eye');
|
| 105 |
+
this.querySelector('i').classList.toggle('fa-eye-slash');
|
| 106 |
+
});
|
| 107 |
+
|
| 108 |
+
toggleConfirmPassword.addEventListener('click', function() {
|
| 109 |
+
const type = confirmPasswordInput.getAttribute('type') === 'password' ? 'text' : 'password';
|
| 110 |
+
confirmPasswordInput.setAttribute('type', type);
|
| 111 |
+
this.querySelector('i').classList.toggle('fa-eye');
|
| 112 |
+
this.querySelector('i').classList.toggle('fa-eye-slash');
|
| 113 |
+
});
|
| 114 |
+
|
| 115 |
+
const countries = [
|
| 116 |
+
{ name: "Afghanistan", dial_code: "+93", code: "AF" },
|
| 117 |
+
{ name: "Albania", dial_code: "+355", code: "AL" },
|
| 118 |
+
{ name: "Algeria", dial_code: "+213", code: "DZ" },
|
| 119 |
+
{ name: "Andorra", dial_code: "+376", code: "AD" },
|
| 120 |
+
{ name: "Angola", dial_code: "+244", code: "AO" },
|
| 121 |
+
{ name: "Antigua and Barbuda", dial_code: "+1-268", code: "AG" },
|
| 122 |
+
{ name: "Argentina", dial_code: "+54", code: "AR" },
|
| 123 |
+
{ name: "Armenia", dial_code: "+374", code: "AM" },
|
| 124 |
+
{ name: "Australia", dial_code: "+61", code: "AU" },
|
| 125 |
+
{ name: "Austria", dial_code: "+43", code: "AT" },
|
| 126 |
+
{ name: "Azerbaijan", dial_code: "+994", code: "AZ" },
|
| 127 |
+
{ name: "Bahamas", dial_code: "+1-242", code: "BS" },
|
| 128 |
+
{ name: "Bahrain", dial_code: "+973", code: "BH" },
|
| 129 |
+
{ name: "Bangladesh", dial_code: "+880", code: "BD" },
|
| 130 |
+
{ name: "Barbados", dial_code: "+1-246", code: "BB" },
|
| 131 |
+
{ name: "Belarus", dial_code: "+375", code: "BY" },
|
| 132 |
+
{ name: "Belgium", dial_code: "+32", code: "BE" },
|
| 133 |
+
{ name: "Belize", dial_code: "+501", code: "BZ" },
|
| 134 |
+
{ name: "Benin", dial_code: "+229", code: "BJ" },
|
| 135 |
+
{ name: "Bhutan", dial_code: "+975", code: "BT" },
|
| 136 |
+
{ name: "Bolivia", dial_code: "+591", code: "BO" },
|
| 137 |
+
{ name: "Bosnia and Herzegovina", dial_code: "+387", code: "BA" },
|
| 138 |
+
{ name: "Botswana", dial_code: "+267", code: "BW" },
|
| 139 |
+
{ name: "Brazil", dial_code: "+55", code: "BR" },
|
| 140 |
+
{ name: "Brunei", dial_code: "+673", code: "BN" },
|
| 141 |
+
{ name: "Bulgaria", dial_code: "+359", code: "BG" },
|
| 142 |
+
{ name: "Burkina Faso", dial_code: "+226", code: "BF" },
|
| 143 |
+
{ name: "Burundi", dial_code: "+257", code: "BI" },
|
| 144 |
+
{ name: "Cabo Verde", dial_code: "+238", code: "CV" },
|
| 145 |
+
{ name: "Cambodia", dial_code: "+855", code: "KH" },
|
| 146 |
+
{ name: "Cameroon", dial_code: "+237", code: "CM" },
|
| 147 |
+
{ name: "Canada", dial_code: "+1", code: "CA" },
|
| 148 |
+
{ name: "Central African Republic", dial_code: "+236", code: "CF" },
|
| 149 |
+
{ name: "Chad", dial_code: "+235", code: "TD" },
|
| 150 |
+
{ name: "Chile", dial_code: "+56", code: "CL" },
|
| 151 |
+
{ name: "China", dial_code: "+86", code: "CN" },
|
| 152 |
+
{ name: "Colombia", dial_code: "+57", code: "CO" },
|
| 153 |
+
{ name: "Comoros", dial_code: "+269", code: "KM" },
|
| 154 |
+
{ name: "Congo (Brazzaville)", dial_code: "+242", code: "CG" },
|
| 155 |
+
{ name: "Congo (Kinshasa)", dial_code: "+243", code: "CD" },
|
| 156 |
+
{ name: "Costa Rica", dial_code: "+506", code: "CR" },
|
| 157 |
+
{ name: "Croatia", dial_code: "+385", code: "HR" },
|
| 158 |
+
{ name: "Cuba", dial_code: "+53", code: "CU" },
|
| 159 |
+
{ name: "Cyprus", dial_code: "+357", code: "CY" },
|
| 160 |
+
{ name: "Czechia", dial_code: "+420", code: "CZ" },
|
| 161 |
+
{ name: "Denmark", dial_code: "+45", code: "DK" },
|
| 162 |
+
{ name: "Djibouti", dial_code: "+253", code: "DJ" },
|
| 163 |
+
{ name: "Dominica", dial_code: "+1-767", code: "DM" },
|
| 164 |
+
{ name: "Dominican Republic", dial_code: "+1-809", code: "DO" },
|
| 165 |
+
{ name: "Ecuador", dial_code: "+593", code: "EC" },
|
| 166 |
+
{ name: "Egypt", dial_code: "+20", code: "EG" },
|
| 167 |
+
{ name: "El Salvador", dial_code: "+503", code: "SV" },
|
| 168 |
+
{ name: "Equatorial Guinea", dial_code: "+240", code: "GQ" },
|
| 169 |
+
{ name: "Eritrea", dial_code: "+291", code: "ER" },
|
| 170 |
+
{ name: "Estonia", dial_code: "+372", code: "EE" },
|
| 171 |
+
{ name: "Eswatini", dial_code: "+268", code: "SZ" },
|
| 172 |
+
{ name: "Ethiopia", dial_code: "+251", code: "ET" },
|
| 173 |
+
{ name: "Fiji", dial_code: "+679", code: "FJ" },
|
| 174 |
+
{ name: "Finland", dial_code: "+358", code: "FI" },
|
| 175 |
+
{ name: "France", dial_code: "+33", code: "FR" },
|
| 176 |
+
{ name: "Gabon", dial_code: "+241", code: "GA" },
|
| 177 |
+
{ name: "Gambia", dial_code: "+220", code: "GM" },
|
| 178 |
+
{ name: "Georgia", dial_code: "+995", code: "GE" },
|
| 179 |
+
{ name: "Germany", dial_code: "+49", code: "DE" },
|
| 180 |
+
{ name: "Ghana", dial_code: "+233", code: "GH" },
|
| 181 |
+
{ name: "Greece", dial_code: "+30", code: "GR" },
|
| 182 |
+
{ name: "Grenada", dial_code: "+1-473", code: "GD" },
|
| 183 |
+
{ name: "Guatemala", dial_code: "+502", code: "GT" },
|
| 184 |
+
{ name: "Guinea", dial_code: "+224", code: "GN" },
|
| 185 |
+
{ name: "Guinea-Bissau", dial_code: "+245", code: "GW" },
|
| 186 |
+
{ name: "Guyana", dial_code: "+592", code: "GY" },
|
| 187 |
+
{ name: "Haiti", dial_code: "+509", code: "HT" },
|
| 188 |
+
{ name: "Honduras", dial_code: "+504", code: "HN" },
|
| 189 |
+
{ name: "Hungary", dial_code: "+36", code: "HU" },
|
| 190 |
+
{ name: "Iceland", dial_code: "+354", code: "IS" },
|
| 191 |
+
{ name: "India", dial_code: "+91", code: "IN" },
|
| 192 |
+
{ name: "Indonesia", dial_code: "+62", code: "ID" },
|
| 193 |
+
{ name: "Iran", dial_code: "+98", code: "IR" },
|
| 194 |
+
{ name: "Iraq", dial_code: "+964", code: "IQ" },
|
| 195 |
+
{ name: "Ireland", dial_code: "+353", code: "IE" },
|
| 196 |
+
{ name: "Israel", dial_code: "+972", code: "IL" },
|
| 197 |
+
{ name: "Italy", dial_code: "+39", code: "IT" },
|
| 198 |
+
{ name: "Jamaica", dial_code: "+1-876", code: "JM" },
|
| 199 |
+
{ name: "Japan", dial_code: "+81", code: "JP" },
|
| 200 |
+
{ name: "Jordan", dial_code: "+962", code: "JO" },
|
| 201 |
+
{ name: "Kazakhstan", dial_code: "+7", code: "KZ" },
|
| 202 |
+
{ name: "Kenya", dial_code: "+254", code: "KE" },
|
| 203 |
+
{ name: "Kiribati", dial_code: "+686", code: "KI" },
|
| 204 |
+
{ name: "Kuwait", dial_code: "+965", code: "KW" },
|
| 205 |
+
{ name: "Kyrgyzstan", dial_code: "+996", code: "KG" },
|
| 206 |
+
{ name: "Laos", dial_code: "+856", code: "LA" },
|
| 207 |
+
{ name: "Latvia", dial_code: "+371", code: "LV" },
|
| 208 |
+
{ name: "Lebanon", dial_code: "+961", code: "LB" },
|
| 209 |
+
{ name: "Lesotho", dial_code: "+266", code: "LS" },
|
| 210 |
+
{ name: "Liberia", dial_code: "+231", code: "LR" },
|
| 211 |
+
{ name: "Libya", dial_code: "+218", code: "LY" },
|
| 212 |
+
{ name: "Liechtenstein", dial_code: "+423", code: "LI" },
|
| 213 |
+
{ name: "Lithuania", dial_code: "+370", code: "LT" },
|
| 214 |
+
{ name: "Luxembourg", dial_code: "+352", code: "LU" },
|
| 215 |
+
{ name: "Madagascar", dial_code: "+261", code: "MG" },
|
| 216 |
+
{ name: "Malawi", dial_code: "+265", code: "MW" },
|
| 217 |
+
{ name: "Malaysia", dial_code: "+60", code: "MY" },
|
| 218 |
+
{ name: "Maldives", dial_code: "+960", code: "MV" },
|
| 219 |
+
{ name: "Mali", dial_code: "+223", code: "ML" },
|
| 220 |
+
{ name: "Malta", dial_code: "+356", code: "MT" },
|
| 221 |
+
{ name: "Marshall Islands", dial_code: "+692", code: "MH" },
|
| 222 |
+
{ name: "Mauritania", dial_code: "+222", code: "MR" },
|
| 223 |
+
{ name: "Mauritius", dial_code: "+230", code: "MU" },
|
| 224 |
+
{ name: "Mexico", dial_code: "+52", code: "MX" },
|
| 225 |
+
{ name: "Micronesia", dial_code: "+691", code: "FM" },
|
| 226 |
+
{ name: "Moldova", dial_code: "+373", code: "MD" },
|
| 227 |
+
{ name: "Monaco", dial_code: "+377", code: "MC" },
|
| 228 |
+
{ name: "Mongolia", dial_code: "+976", code: "MN" },
|
| 229 |
+
{ name: "Montenegro", dial_code: "+382", code: "ME" },
|
| 230 |
+
{ name: "Morocco", dial_code: "+212", code: "MA" },
|
| 231 |
+
{ name: "Mozambique", dial_code: "+258", code: "MZ" },
|
| 232 |
+
{ name: "Myanmar", dial_code: "+95", code: "MM" },
|
| 233 |
+
{ name: "Namibia", dial_code: "+264", code: "NA" },
|
| 234 |
+
{ name: "Nauru", dial_code: "+674", code: "NR" },
|
| 235 |
+
{ name: "Nepal", dial_code: "+977", code: "NP" },
|
| 236 |
+
{ name: "Netherlands", dial_code: "+31", code: "NL" },
|
| 237 |
+
{ name: "New Zealand", dial_code: "+64", code: "NZ" },
|
| 238 |
+
{ name: "Nicaragua", dial_code: "+505", code: "NI" },
|
| 239 |
+
{ name: "Niger", dial_code: "+227", code: "NE" },
|
| 240 |
+
{ name: "Nigeria", dial_code: "+234", code: "NG" },
|
| 241 |
+
{ name: "North Korea", dial_code: "+850", code: "KP" },
|
| 242 |
+
{ name: "North Macedonia", dial_code: "+389", code: "MK" },
|
| 243 |
+
{ name: "Norway", dial_code: "+47", code: "NO" },
|
| 244 |
+
{ name: "Oman", dial_code: "+968", code: "OM" },
|
| 245 |
+
{ name: "Pakistan", dial_code: "+92", code: "PK" },
|
| 246 |
+
{ name: "Palau", dial_code: "+680", code: "PW" },
|
| 247 |
+
{ name: "Palestine", dial_code: "+970", code: "PS" },
|
| 248 |
+
{ name: "Panama", dial_code: "+507", code: "PA" },
|
| 249 |
+
{ name: "Papua New Guinea", dial_code: "+675", code: "PG" },
|
| 250 |
+
{ name: "Paraguay", dial_code: "+595", code: "PY" },
|
| 251 |
+
{ name: "Peru", dial_code: "+51", code: "PE" },
|
| 252 |
+
{ name: "Philippines", dial_code: "+63", code: "PH" },
|
| 253 |
+
{ name: "Poland", dial_code: "+48", code: "PL" },
|
| 254 |
+
{ name: "Portugal", dial_code: "+351", code: "PT" },
|
| 255 |
+
{ name: "Qatar", dial_code: "+974", code: "QA" },
|
| 256 |
+
{ name: "Romania", dial_code: "+40", code: "RO" },
|
| 257 |
+
{ name: "Russia", dial_code: "+7", code: "RU" },
|
| 258 |
+
{ name: "Rwanda", dial_code: "+250", code: "RW" },
|
| 259 |
+
{ name: "Saint Kitts and Nevis", dial_code: "+1-869", code: "KN" },
|
| 260 |
+
{ name: "Saint Lucia", dial_code: "+1-758", code: "LC" },
|
| 261 |
+
{ name: "Saint Vincent and the Grenadines", dial_code: "+1-784", code: "VC" },
|
| 262 |
+
{ name: "Samoa", dial_code: "+685", code: "WS" },
|
| 263 |
+
{ name: "San Marino", dial_code: "+378", code: "SM" },
|
| 264 |
+
{ name: "Sao Tome and Principe", dial_code: "+239", code: "ST" },
|
| 265 |
+
{ name: "Saudi Arabia", dial_code: "+966", code: "SA" },
|
| 266 |
+
{ name: "Senegal", dial_code: "+221", code: "SN" },
|
| 267 |
+
{ name: "Serbia", dial_code: "+381", code: "RS" },
|
| 268 |
+
{ name: "Seychelles", dial_code: "+248", code: "SC" },
|
| 269 |
+
{ name: "Sierra Leone", dial_code: "+232", code: "SL" },
|
| 270 |
+
{ name: "Singapore", dial_code: "+65", code: "SG" },
|
| 271 |
+
{ name: "Slovakia", dial_code: "+421", code: "SK" },
|
| 272 |
+
{ name: "Slovenia", dial_code: "+386", code: "SI" },
|
| 273 |
+
{ name: "Solomon Islands", dial_code: "+677", code: "SB" },
|
| 274 |
+
{ name: "Somalia", dial_code: "+252", code: "SO" },
|
| 275 |
+
{ name: "South Africa", dial_code: "+27", code: "ZA" },
|
| 276 |
+
{ name: "South Korea", dial_code: "+82", code: "KR" },
|
| 277 |
+
{ name: "South Sudan", dial_code: "+211", code: "SS" },
|
| 278 |
+
{ name: "Spain", dial_code: "+34", code: "ES" },
|
| 279 |
+
{ name: "Sri Lanka", dial_code: "+94", code: "LK" },
|
| 280 |
+
{ name: "Sudan", dial_code: "+249", code: "SD" },
|
| 281 |
+
{ name: "Suriname", dial_code: "+597", code: "SR" },
|
| 282 |
+
{ name: "Sweden", dial_code: "+46", code: "SE" },
|
| 283 |
+
{ name: "Switzerland", dial_code: "+41", code: "CH" },
|
| 284 |
+
{ name: "Syria", dial_code: "+963", code: "SY" },
|
| 285 |
+
{ name: "Taiwan", dial_code: "+886", code: "TW" },
|
| 286 |
+
{ name: "Tajikistan", dial_code: "+992", code: "TJ" },
|
| 287 |
+
{ name: "Tanzania", dial_code: "+255", code: "TZ" },
|
| 288 |
+
{ name: "Thailand", dial_code: "+66", code: "TH" },
|
| 289 |
+
{ name: "Timor-Leste", dial_code: "+670", code: "TL" },
|
| 290 |
+
{ name: "Togo", dial_code: "+228", code: "TG" },
|
| 291 |
+
{ name: "Tonga", dial_code: "+676", code: "TO" },
|
| 292 |
+
{ name: "Trinidad and Tobago", dial_code: "+1-868", code: "TT" },
|
| 293 |
+
{ name: "Tunisia", dial_code: "+216", code: "TN" },
|
| 294 |
+
{ name: "Turkey", dial_code: "+90", code: "TR" },
|
| 295 |
+
{ name: "Turkmenistan", dial_code: "+993", code: "TM" },
|
| 296 |
+
{ name: "Tuvalu", dial_code: "+688", code: "TV" },
|
| 297 |
+
{ name: "Uganda", dial_code: "+256", code: "UG" },
|
| 298 |
+
{ name: "Ukraine", dial_code: "+380", code: "UA" },
|
| 299 |
+
{ name: "United Arab Emirates", dial_code: "+971", code: "AE" },
|
| 300 |
+
{ name: "United Kingdom", dial_code: "+44", code: "GB" },
|
| 301 |
+
{ name: "United States", dial_code: "+1", code: "US" },
|
| 302 |
+
{ name: "Uruguay", dial_code: "+598", code: "UY" },
|
| 303 |
+
{ name: "Uzbekistan", dial_code: "+998", code: "UZ" },
|
| 304 |
+
{ name: "Vanuatu", dial_code: "+678", code: "VU" },
|
| 305 |
+
{ name: "Vatican City", dial_code: "+379", code: "VA" },
|
| 306 |
+
{ name: "Venezuela", dial_code: "+58", code: "VE" },
|
| 307 |
+
{ name: "Vietnam", dial_code: "+84", code: "VN" },
|
| 308 |
+
{ name: "Yemen", dial_code: "+967", code: "YE" },
|
| 309 |
+
{ name: "Zambia", dial_code: "+260", code: "ZM" },
|
| 310 |
+
{ name: "Zimbabwe", dial_code: "+263", code: "ZW"},
|
| 311 |
+
];
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
const countrySelect = document.getElementById("country");
|
| 315 |
+
|
| 316 |
+
countries.forEach(c => {
|
| 317 |
+
const option = document.createElement("option");
|
| 318 |
+
option.value = c.code;
|
| 319 |
+
option.textContent = `${c.name} (${c.dial_code})`;
|
| 320 |
+
countrySelect.appendChild(option);
|
| 321 |
+
});
|
| 322 |
+
|
| 323 |
+
// Form validation
|
| 324 |
+
const form = document.querySelector('form');
|
| 325 |
+
form.addEventListener('submit', function(e) {
|
| 326 |
+
e.preventDefault();
|
| 327 |
+
|
| 328 |
+
// Simple validation
|
| 329 |
+
if (passwordInput.value !== confirmPasswordInput.value) {
|
| 330 |
+
alert('Passwords do not match!');
|
| 331 |
+
return;
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
+
// If validation passes
|
| 335 |
+
alert('Account created successfully!');
|
| 336 |
+
form.reset();
|
| 337 |
+
});
|
| 338 |
+
});
|
| 339 |
+
</script>
|
| 340 |
+
</body>
|
| 341 |
+
</html>
|
jweb/ac1/index.html
ADDED
|
@@ -0,0 +1,626 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Account Authentication</title>
|
| 7 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
| 8 |
+
|
| 9 |
+
<style>
|
| 10 |
+
* {
|
| 11 |
+
margin: 0;
|
| 12 |
+
padding: 0;
|
| 13 |
+
box-sizing: border-box;
|
| 14 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
body {
|
| 18 |
+
background: linear-gradient(135deg, #6e8efb, #a777e3);
|
| 19 |
+
min-height: 100vh;
|
| 20 |
+
display: flex;
|
| 21 |
+
justify-content: center;
|
| 22 |
+
align-items: center;
|
| 23 |
+
padding: 20px;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
.container {
|
| 27 |
+
background: rgba(255, 255, 255, 0.95);
|
| 28 |
+
border-radius: 15px;
|
| 29 |
+
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);
|
| 30 |
+
width: 100%;
|
| 31 |
+
max-width: 550px;
|
| 32 |
+
overflow: hidden;
|
| 33 |
+
position: relative;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
.form-container {
|
| 37 |
+
padding: 30px;
|
| 38 |
+
transition: transform 0.6s ease-in-out;
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
h2 {
|
| 42 |
+
text-align: center;
|
| 43 |
+
color: #333;
|
| 44 |
+
margin-bottom: 25px;
|
| 45 |
+
font-size: 28px;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
.form-group {
|
| 49 |
+
margin-bottom: 20px;
|
| 50 |
+
position: relative;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
.form-group {
|
| 54 |
+
margin-bottom: 15px;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
.input-container {
|
| 58 |
+
position: relative;
|
| 59 |
+
display: flex;
|
| 60 |
+
align-items: center;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
.input-container i {
|
| 64 |
+
position: absolute;
|
| 65 |
+
left: 12px;
|
| 66 |
+
color: #ccc;
|
| 67 |
+
font-size: 14px;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
.input-container input,
|
| 71 |
+
.input-container select {
|
| 72 |
+
width: 100%;
|
| 73 |
+
padding: 10px 12px 10px 35px; /* left padding for icon */
|
| 74 |
+
border: 1px solid #ddd;
|
| 75 |
+
border-radius: 6px;
|
| 76 |
+
outline: none;
|
| 77 |
+
background: rgba(255, 255, 255, 0.1);
|
| 78 |
+
color: #fff;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
.password-container .toggle-password {
|
| 82 |
+
position: absolute;
|
| 83 |
+
right: 12px;
|
| 84 |
+
cursor: pointer;
|
| 85 |
+
color: #ccc;
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
label {
|
| 89 |
+
display: block;
|
| 90 |
+
margin-bottom: 8px;
|
| 91 |
+
font-weight: 600;
|
| 92 |
+
color: #444;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
input, select {
|
| 96 |
+
width: 100%;
|
| 97 |
+
padding: 14px;
|
| 98 |
+
border: 2px solid #ddd;
|
| 99 |
+
border-radius: 8px;
|
| 100 |
+
font-size: 16px;
|
| 101 |
+
transition: border 0.3s;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
input:focus, select:focus {
|
| 105 |
+
border-color: #6e8efb;
|
| 106 |
+
outline: none;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
.password-row {
|
| 110 |
+
display: flex;
|
| 111 |
+
gap: 15px;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.password-column {
|
| 115 |
+
flex: 1;
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
.password-container {
|
| 119 |
+
position: relative;
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
.toggle-password {
|
| 123 |
+
position: absolute;
|
| 124 |
+
right: 15px;
|
| 125 |
+
top: 50%;
|
| 126 |
+
transform: translateY(-50%);
|
| 127 |
+
cursor: pointer;
|
| 128 |
+
color: #777;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
.error-message {
|
| 132 |
+
color: #e74c3c;
|
| 133 |
+
font-size: 14px;
|
| 134 |
+
margin-top: 5px;
|
| 135 |
+
min-height: 20px;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
.btn {
|
| 139 |
+
width: 100%;
|
| 140 |
+
padding: 14px;
|
| 141 |
+
background: linear-gradient(135deg, #6e8efb, #a777e3);
|
| 142 |
+
border: none;
|
| 143 |
+
border-radius: 8px;
|
| 144 |
+
color: white;
|
| 145 |
+
font-size: 18px;
|
| 146 |
+
font-weight: 600;
|
| 147 |
+
cursor: pointer;
|
| 148 |
+
transition: all 0.3s;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
.btn:hover {
|
| 152 |
+
background: linear-gradient(135deg, #5d7ce0, #9666d3);
|
| 153 |
+
transform: translateY(-2px);
|
| 154 |
+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
.switch-form {
|
| 158 |
+
text-align: center;
|
| 159 |
+
margin-top: 20px;
|
| 160 |
+
color: #555;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
.switch-form a {
|
| 164 |
+
color: #6e8efb;
|
| 165 |
+
text-decoration: none;
|
| 166 |
+
font-weight: 600;
|
| 167 |
+
cursor: pointer;
|
| 168 |
+
transition: color 0.3s;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
.switch-form a:hover {
|
| 172 |
+
color: #a777e3;
|
| 173 |
+
text-decoration: underline;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
.success-message {
|
| 177 |
+
background: linear-gradient(135deg, #6e8efb, #a777e3);
|
| 178 |
+
color: white;
|
| 179 |
+
padding: 20px;
|
| 180 |
+
text-align: center;
|
| 181 |
+
border-radius: 10px;
|
| 182 |
+
margin-bottom: 20px;
|
| 183 |
+
display: none;
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
.success-message i {
|
| 187 |
+
font-size: 48px;
|
| 188 |
+
margin-bottom: 10px;
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
@media (max-width: 576px) {
|
| 192 |
+
.container {
|
| 193 |
+
border-radius: 10px;
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
.form-container {
|
| 197 |
+
padding: 20px;
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
.password-row {
|
| 201 |
+
flex-direction: column;
|
| 202 |
+
gap: 0;
|
| 203 |
+
}
|
| 204 |
+
}
|
| 205 |
+
</style>
|
| 206 |
+
</head>
|
| 207 |
+
<body>
|
| 208 |
+
<div class="container">
|
| 209 |
+
<div class="form-container" id="signup-container">
|
| 210 |
+
<div class="success-message" id="signup-success">
|
| 211 |
+
<i class="fas fa-check-circle"></i>
|
| 212 |
+
<h3>Account Created Successfully!</h3>
|
| 213 |
+
<p>Redirecting to sign in page...</p>
|
| 214 |
+
</div>
|
| 215 |
+
|
| 216 |
+
<h2>Create Your Account</h2>
|
| 217 |
+
<form id="signup-form">
|
| 218 |
+
<div class="form-group">
|
| 219 |
+
<label for="username">Username</label>
|
| 220 |
+
<input type="text" id="username" placeholder="Enter your username" required>
|
| 221 |
+
<div class="error-message" id="username-error"></div>
|
| 222 |
+
</div>
|
| 223 |
+
|
| 224 |
+
<div class="form-group">
|
| 225 |
+
<label for="email">Email Address</label>
|
| 226 |
+
<input type="email" id="email" placeholder="Enter your email" required>
|
| 227 |
+
<div class="error-message" id="email-error"></div>
|
| 228 |
+
</div>
|
| 229 |
+
|
| 230 |
+
<div class="form-group">
|
| 231 |
+
<label for="country">Country</label>
|
| 232 |
+
<select id="country" required>
|
| 233 |
+
<option value="">Select your country</option>
|
| 234 |
+
</select>
|
| 235 |
+
<div class="error-message" id="country-error"></div>
|
| 236 |
+
</div>
|
| 237 |
+
|
| 238 |
+
<div class="form-group">
|
| 239 |
+
<label for="phone">Phone Number</label>
|
| 240 |
+
<input type="tel" id="phone" placeholder="Enter your phone number" required>
|
| 241 |
+
<div class="error-message" id="phone-error"></div>
|
| 242 |
+
</div>
|
| 243 |
+
|
| 244 |
+
<div class="form-group">
|
| 245 |
+
<label>Password</label>
|
| 246 |
+
<div class="password-row">
|
| 247 |
+
<div class="password-column">
|
| 248 |
+
<div class="password-container">
|
| 249 |
+
<input type="password" id="password" placeholder="Create a password" required>
|
| 250 |
+
<span class="toggle-password" id="toggle-password">
|
| 251 |
+
<i class="far fa-eye"></i>
|
| 252 |
+
</span>
|
| 253 |
+
</div>
|
| 254 |
+
<div class="error-message" id="password-error"></div>
|
| 255 |
+
</div>
|
| 256 |
+
<div class="password-column">
|
| 257 |
+
<div class="password-container">
|
| 258 |
+
<input type="password" id="confirm-password" placeholder="Confirm password" required>
|
| 259 |
+
<span class="toggle-password" id="toggle-confirm-password">
|
| 260 |
+
<i class="far fa-eye"></i>
|
| 261 |
+
</span>
|
| 262 |
+
</div>
|
| 263 |
+
<div class="error-message" id="confirm-password-error"></div>
|
| 264 |
+
</div>
|
| 265 |
+
</div>
|
| 266 |
+
</div>
|
| 267 |
+
|
| 268 |
+
<button type="submit" class="btn">Create Account</button>
|
| 269 |
+
|
| 270 |
+
<div class="switch-form">
|
| 271 |
+
Already have an account? <a id="switch-to-signin">Sign In</a>
|
| 272 |
+
</div>
|
| 273 |
+
</form>
|
| 274 |
+
</div>
|
| 275 |
+
|
| 276 |
+
<div class="form-container" id="signin-container" style="display: none; transform: translateX(100%);">
|
| 277 |
+
<h2>Sign In to Your Account</h2>
|
| 278 |
+
<form id="signin-form">
|
| 279 |
+
<div class="form-group">
|
| 280 |
+
<label for="signin-email">Email or Username</label>
|
| 281 |
+
<input type="text" id="signin-email" placeholder="Enter your email or username" required>
|
| 282 |
+
<div class="error-message" id="signin-email-error"></div>
|
| 283 |
+
</div>
|
| 284 |
+
|
| 285 |
+
<div class="form-group">
|
| 286 |
+
<label for="signin-password">Password</label>
|
| 287 |
+
<div class="password-container">
|
| 288 |
+
<input type="password" id="signin-password" placeholder="Enter your password" required>
|
| 289 |
+
<span class="toggle-password" id="toggle-signin-password">
|
| 290 |
+
<i class="far fa-eye"></i>
|
| 291 |
+
</span>
|
| 292 |
+
</div>
|
| 293 |
+
<div class="error-message" id="signin-password-error"></div>
|
| 294 |
+
</div>
|
| 295 |
+
|
| 296 |
+
<button type="submit" class="btn">Sign In</button>
|
| 297 |
+
|
| 298 |
+
<div class="switch-form">
|
| 299 |
+
Don't have an account? <a id="switch-to-signup">Sign Up</a>
|
| 300 |
+
</div>
|
| 301 |
+
</form>
|
| 302 |
+
</div>
|
| 303 |
+
</div>
|
| 304 |
+
|
| 305 |
+
<script>
|
| 306 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 307 |
+
const signupForm = document.getElementById('signup-form');
|
| 308 |
+
const signinForm = document.getElementById('signin-form');
|
| 309 |
+
const successMessage = document.getElementById('signup-success');
|
| 310 |
+
const switchToSignin = document.getElementById('switch-to-signin');
|
| 311 |
+
const switchToSignup = document.getElementById('switch-to-signup');
|
| 312 |
+
const signupContainer = document.getElementById('signup-container');
|
| 313 |
+
const signinContainer = document.getElementById('signin-container');
|
| 314 |
+
|
| 315 |
+
// Password toggle setup
|
| 316 |
+
['password', 'confirm-password', 'signin-password'].forEach(id => {
|
| 317 |
+
const toggle = document.getElementById(`toggle-${id}`);
|
| 318 |
+
const input = document.getElementById(id);
|
| 319 |
+
toggle.addEventListener('click', () => {
|
| 320 |
+
input.type = input.type === 'password' ? 'text' : 'password';
|
| 321 |
+
toggle.innerHTML = input.type === 'password' ? '<i class="far fa-eye"></i>' : '<i class="far fa-eye-slash"></i>';
|
| 322 |
+
});
|
| 323 |
+
});
|
| 324 |
+
|
| 325 |
+
// Switch views
|
| 326 |
+
switchToSignin.addEventListener('click', () => {
|
| 327 |
+
signupContainer.style.transform = 'translateX(-100%)';
|
| 328 |
+
signinContainer.style.display = 'block';
|
| 329 |
+
setTimeout(() => signinContainer.style.transform = 'translateX(0)', 10);
|
| 330 |
+
});
|
| 331 |
+
|
| 332 |
+
switchToSignup.addEventListener('click', () => {
|
| 333 |
+
signinContainer.style.transform = 'translateX(100%)';
|
| 334 |
+
setTimeout(() => {
|
| 335 |
+
signinContainer.style.display = 'none';
|
| 336 |
+
signupContainer.style.transform = 'translateX(0)';
|
| 337 |
+
}, 300);
|
| 338 |
+
});
|
| 339 |
+
|
| 340 |
+
const countries = [
|
| 341 |
+
{ name: "Afghanistan", dial_code: "+93", code: "AF" },
|
| 342 |
+
{ name: "Albania", dial_code: "+355", code: "AL" },
|
| 343 |
+
{ name: "Algeria", dial_code: "+213", code: "DZ" },
|
| 344 |
+
{ name: "Andorra", dial_code: "+376", code: "AD" },
|
| 345 |
+
{ name: "Angola", dial_code: "+244", code: "AO" },
|
| 346 |
+
{ name: "Antigua and Barbuda", dial_code: "+1-268", code: "AG" },
|
| 347 |
+
{ name: "Argentina", dial_code: "+54", code: "AR" },
|
| 348 |
+
{ name: "Armenia", dial_code: "+374", code: "AM" },
|
| 349 |
+
{ name: "Australia", dial_code: "+61", code: "AU" },
|
| 350 |
+
{ name: "Austria", dial_code: "+43", code: "AT" },
|
| 351 |
+
{ name: "Azerbaijan", dial_code: "+994", code: "AZ" },
|
| 352 |
+
{ name: "Bahamas", dial_code: "+1-242", code: "BS" },
|
| 353 |
+
{ name: "Bahrain", dial_code: "+973", code: "BH" },
|
| 354 |
+
{ name: "Bangladesh", dial_code: "+880", code: "BD" },
|
| 355 |
+
{ name: "Barbados", dial_code: "+1-246", code: "BB" },
|
| 356 |
+
{ name: "Belarus", dial_code: "+375", code: "BY" },
|
| 357 |
+
{ name: "Belgium", dial_code: "+32", code: "BE" },
|
| 358 |
+
{ name: "Belize", dial_code: "+501", code: "BZ" },
|
| 359 |
+
{ name: "Benin", dial_code: "+229", code: "BJ" },
|
| 360 |
+
{ name: "Bhutan", dial_code: "+975", code: "BT" },
|
| 361 |
+
{ name: "Bolivia", dial_code: "+591", code: "BO" },
|
| 362 |
+
{ name: "Bosnia and Herzegovina", dial_code: "+387", code: "BA" },
|
| 363 |
+
{ name: "Botswana", dial_code: "+267", code: "BW" },
|
| 364 |
+
{ name: "Brazil", dial_code: "+55", code: "BR" },
|
| 365 |
+
{ name: "Brunei", dial_code: "+673", code: "BN" },
|
| 366 |
+
{ name: "Bulgaria", dial_code: "+359", code: "BG" },
|
| 367 |
+
{ name: "Burkina Faso", dial_code: "+226", code: "BF" },
|
| 368 |
+
{ name: "Burundi", dial_code: "+257", code: "BI" },
|
| 369 |
+
{ name: "Cabo Verde", dial_code: "+238", code: "CV" },
|
| 370 |
+
{ name: "Cambodia", dial_code: "+855", code: "KH" },
|
| 371 |
+
{ name: "Cameroon", dial_code: "+237", code: "CM" },
|
| 372 |
+
{ name: "Canada", dial_code: "+1", code: "CA" },
|
| 373 |
+
{ name: "Central African Republic", dial_code: "+236", code: "CF" },
|
| 374 |
+
{ name: "Chad", dial_code: "+235", code: "TD" },
|
| 375 |
+
{ name: "Chile", dial_code: "+56", code: "CL" },
|
| 376 |
+
{ name: "China", dial_code: "+86", code: "CN" },
|
| 377 |
+
{ name: "Colombia", dial_code: "+57", code: "CO" },
|
| 378 |
+
{ name: "Comoros", dial_code: "+269", code: "KM" },
|
| 379 |
+
{ name: "Congo (Brazzaville)", dial_code: "+242", code: "CG" },
|
| 380 |
+
{ name: "Congo (Kinshasa)", dial_code: "+243", code: "CD" },
|
| 381 |
+
{ name: "Costa Rica", dial_code: "+506", code: "CR" },
|
| 382 |
+
{ name: "Croatia", dial_code: "+385", code: "HR" },
|
| 383 |
+
{ name: "Cuba", dial_code: "+53", code: "CU" },
|
| 384 |
+
{ name: "Cyprus", dial_code: "+357", code: "CY" },
|
| 385 |
+
{ name: "Czechia", dial_code: "+420", code: "CZ" },
|
| 386 |
+
{ name: "Denmark", dial_code: "+45", code: "DK" },
|
| 387 |
+
{ name: "Djibouti", dial_code: "+253", code: "DJ" },
|
| 388 |
+
{ name: "Dominica", dial_code: "+1-767", code: "DM" },
|
| 389 |
+
{ name: "Dominican Republic", dial_code: "+1-809", code: "DO" },
|
| 390 |
+
{ name: "Ecuador", dial_code: "+593", code: "EC" },
|
| 391 |
+
{ name: "Egypt", dial_code: "+20", code: "EG" },
|
| 392 |
+
{ name: "El Salvador", dial_code: "+503", code: "SV" },
|
| 393 |
+
{ name: "Equatorial Guinea", dial_code: "+240", code: "GQ" },
|
| 394 |
+
{ name: "Eritrea", dial_code: "+291", code: "ER" },
|
| 395 |
+
{ name: "Estonia", dial_code: "+372", code: "EE" },
|
| 396 |
+
{ name: "Eswatini", dial_code: "+268", code: "SZ" },
|
| 397 |
+
{ name: "Ethiopia", dial_code: "+251", code: "ET" },
|
| 398 |
+
{ name: "Fiji", dial_code: "+679", code: "FJ" },
|
| 399 |
+
{ name: "Finland", dial_code: "+358", code: "FI" },
|
| 400 |
+
{ name: "France", dial_code: "+33", code: "FR" },
|
| 401 |
+
{ name: "Gabon", dial_code: "+241", code: "GA" },
|
| 402 |
+
{ name: "Gambia", dial_code: "+220", code: "GM" },
|
| 403 |
+
{ name: "Georgia", dial_code: "+995", code: "GE" },
|
| 404 |
+
{ name: "Germany", dial_code: "+49", code: "DE" },
|
| 405 |
+
{ name: "Ghana", dial_code: "+233", code: "GH" },
|
| 406 |
+
{ name: "Greece", dial_code: "+30", code: "GR" },
|
| 407 |
+
{ name: "Grenada", dial_code: "+1-473", code: "GD" },
|
| 408 |
+
{ name: "Guatemala", dial_code: "+502", code: "GT" },
|
| 409 |
+
{ name: "Guinea", dial_code: "+224", code: "GN" },
|
| 410 |
+
{ name: "Guinea-Bissau", dial_code: "+245", code: "GW" },
|
| 411 |
+
{ name: "Guyana", dial_code: "+592", code: "GY" },
|
| 412 |
+
{ name: "Haiti", dial_code: "+509", code: "HT" },
|
| 413 |
+
{ name: "Honduras", dial_code: "+504", code: "HN" },
|
| 414 |
+
{ name: "Hungary", dial_code: "+36", code: "HU" },
|
| 415 |
+
{ name: "Iceland", dial_code: "+354", code: "IS" },
|
| 416 |
+
{ name: "India", dial_code: "+91", code: "IN" },
|
| 417 |
+
{ name: "Indonesia", dial_code: "+62", code: "ID" },
|
| 418 |
+
{ name: "Iran", dial_code: "+98", code: "IR" },
|
| 419 |
+
{ name: "Iraq", dial_code: "+964", code: "IQ" },
|
| 420 |
+
{ name: "Ireland", dial_code: "+353", code: "IE" },
|
| 421 |
+
{ name: "Israel", dial_code: "+972", code: "IL" },
|
| 422 |
+
{ name: "Italy", dial_code: "+39", code: "IT" },
|
| 423 |
+
{ name: "Jamaica", dial_code: "+1-876", code: "JM" },
|
| 424 |
+
{ name: "Japan", dial_code: "+81", code: "JP" },
|
| 425 |
+
{ name: "Jordan", dial_code: "+962", code: "JO" },
|
| 426 |
+
{ name: "Kazakhstan", dial_code: "+7", code: "KZ" },
|
| 427 |
+
{ name: "Kenya", dial_code: "+254", code: "KE" },
|
| 428 |
+
{ name: "Kiribati", dial_code: "+686", code: "KI" },
|
| 429 |
+
{ name: "Kuwait", dial_code: "+965", code: "KW" },
|
| 430 |
+
{ name: "Kyrgyzstan", dial_code: "+996", code: "KG" },
|
| 431 |
+
{ name: "Laos", dial_code: "+856", code: "LA" },
|
| 432 |
+
{ name: "Latvia", dial_code: "+371", code: "LV" },
|
| 433 |
+
{ name: "Lebanon", dial_code: "+961", code: "LB" },
|
| 434 |
+
{ name: "Lesotho", dial_code: "+266", code: "LS" },
|
| 435 |
+
{ name: "Liberia", dial_code: "+231", code: "LR" },
|
| 436 |
+
{ name: "Libya", dial_code: "+218", code: "LY" },
|
| 437 |
+
{ name: "Liechtenstein", dial_code: "+423", code: "LI" },
|
| 438 |
+
{ name: "Lithuania", dial_code: "+370", code: "LT" },
|
| 439 |
+
{ name: "Luxembourg", dial_code: "+352", code: "LU" },
|
| 440 |
+
{ name: "Madagascar", dial_code: "+261", code: "MG" },
|
| 441 |
+
{ name: "Malawi", dial_code: "+265", code: "MW" },
|
| 442 |
+
{ name: "Malaysia", dial_code: "+60", code: "MY" },
|
| 443 |
+
{ name: "Maldives", dial_code: "+960", code: "MV" },
|
| 444 |
+
{ name: "Mali", dial_code: "+223", code: "ML" },
|
| 445 |
+
{ name: "Malta", dial_code: "+356", code: "MT" },
|
| 446 |
+
{ name: "Marshall Islands", dial_code: "+692", code: "MH" },
|
| 447 |
+
{ name: "Mauritania", dial_code: "+222", code: "MR" },
|
| 448 |
+
{ name: "Mauritius", dial_code: "+230", code: "MU" },
|
| 449 |
+
{ name: "Mexico", dial_code: "+52", code: "MX" },
|
| 450 |
+
{ name: "Micronesia", dial_code: "+691", code: "FM" },
|
| 451 |
+
{ name: "Moldova", dial_code: "+373", code: "MD" },
|
| 452 |
+
{ name: "Monaco", dial_code: "+377", code: "MC" },
|
| 453 |
+
{ name: "Mongolia", dial_code: "+976", code: "MN" },
|
| 454 |
+
{ name: "Montenegro", dial_code: "+382", code: "ME" },
|
| 455 |
+
{ name: "Morocco", dial_code: "+212", code: "MA" },
|
| 456 |
+
{ name: "Mozambique", dial_code: "+258", code: "MZ" },
|
| 457 |
+
{ name: "Myanmar", dial_code: "+95", code: "MM" },
|
| 458 |
+
{ name: "Namibia", dial_code: "+264", code: "NA" },
|
| 459 |
+
{ name: "Nauru", dial_code: "+674", code: "NR" },
|
| 460 |
+
{ name: "Nepal", dial_code: "+977", code: "NP" },
|
| 461 |
+
{ name: "Netherlands", dial_code: "+31", code: "NL" },
|
| 462 |
+
{ name: "New Zealand", dial_code: "+64", code: "NZ" },
|
| 463 |
+
{ name: "Nicaragua", dial_code: "+505", code: "NI" },
|
| 464 |
+
{ name: "Niger", dial_code: "+227", code: "NE" },
|
| 465 |
+
{ name: "Nigeria", dial_code: "+234", code: "NG" },
|
| 466 |
+
{ name: "North Korea", dial_code: "+850", code: "KP" },
|
| 467 |
+
{ name: "North Macedonia", dial_code: "+389", code: "MK" },
|
| 468 |
+
{ name: "Norway", dial_code: "+47", code: "NO" },
|
| 469 |
+
{ name: "Oman", dial_code: "+968", code: "OM" },
|
| 470 |
+
{ name: "Pakistan", dial_code: "+92", code: "PK" },
|
| 471 |
+
{ name: "Palau", dial_code: "+680", code: "PW" },
|
| 472 |
+
{ name: "Palestine", dial_code: "+970", code: "PS" },
|
| 473 |
+
{ name: "Panama", dial_code: "+507", code: "PA" },
|
| 474 |
+
{ name: "Papua New Guinea", dial_code: "+675", code: "PG" },
|
| 475 |
+
{ name: "Paraguay", dial_code: "+595", code: "PY" },
|
| 476 |
+
{ name: "Peru", dial_code: "+51", code: "PE" },
|
| 477 |
+
{ name: "Philippines", dial_code: "+63", code: "PH" },
|
| 478 |
+
{ name: "Poland", dial_code: "+48", code: "PL" },
|
| 479 |
+
{ name: "Portugal", dial_code: "+351", code: "PT" },
|
| 480 |
+
{ name: "Qatar", dial_code: "+974", code: "QA" },
|
| 481 |
+
{ name: "Romania", dial_code: "+40", code: "RO" },
|
| 482 |
+
{ name: "Russia", dial_code: "+7", code: "RU" },
|
| 483 |
+
{ name: "Rwanda", dial_code: "+250", code: "RW" },
|
| 484 |
+
{ name: "Saint Kitts and Nevis", dial_code: "+1-869", code: "KN" },
|
| 485 |
+
{ name: "Saint Lucia", dial_code: "+1-758", code: "LC" },
|
| 486 |
+
{ name: "Saint Vincent and the Grenadines", dial_code: "+1-784", code: "VC" },
|
| 487 |
+
{ name: "Samoa", dial_code: "+685", code: "WS" },
|
| 488 |
+
{ name: "San Marino", dial_code: "+378", code: "SM" },
|
| 489 |
+
{ name: "Sao Tome and Principe", dial_code: "+239", code: "ST" },
|
| 490 |
+
{ name: "Saudi Arabia", dial_code: "+966", code: "SA" },
|
| 491 |
+
{ name: "Senegal", dial_code: "+221", code: "SN" },
|
| 492 |
+
{ name: "Serbia", dial_code: "+381", code: "RS" },
|
| 493 |
+
{ name: "Seychelles", dial_code: "+248", code: "SC" },
|
| 494 |
+
{ name: "Sierra Leone", dial_code: "+232", code: "SL" },
|
| 495 |
+
{ name: "Singapore", dial_code: "+65", code: "SG" },
|
| 496 |
+
{ name: "Slovakia", dial_code: "+421", code: "SK" },
|
| 497 |
+
{ name: "Slovenia", dial_code: "+386", code: "SI" },
|
| 498 |
+
{ name: "Solomon Islands", dial_code: "+677", code: "SB" },
|
| 499 |
+
{ name: "Somalia", dial_code: "+252", code: "SO" },
|
| 500 |
+
{ name: "South Africa", dial_code: "+27", code: "ZA" },
|
| 501 |
+
{ name: "South Korea", dial_code: "+82", code: "KR" },
|
| 502 |
+
{ name: "South Sudan", dial_code: "+211", code: "SS" },
|
| 503 |
+
{ name: "Spain", dial_code: "+34", code: "ES" },
|
| 504 |
+
{ name: "Sri Lanka", dial_code: "+94", code: "LK" },
|
| 505 |
+
{ name: "Sudan", dial_code: "+249", code: "SD" },
|
| 506 |
+
{ name: "Suriname", dial_code: "+597", code: "SR" },
|
| 507 |
+
{ name: "Sweden", dial_code: "+46", code: "SE" },
|
| 508 |
+
{ name: "Switzerland", dial_code: "+41", code: "CH" },
|
| 509 |
+
{ name: "Syria", dial_code: "+963", code: "SY" },
|
| 510 |
+
{ name: "Taiwan", dial_code: "+886", code: "TW" },
|
| 511 |
+
{ name: "Tajikistan", dial_code: "+992", code: "TJ" },
|
| 512 |
+
{ name: "Tanzania", dial_code: "+255", code: "TZ" },
|
| 513 |
+
{ name: "Thailand", dial_code: "+66", code: "TH" },
|
| 514 |
+
{ name: "Timor-Leste", dial_code: "+670", code: "TL" },
|
| 515 |
+
{ name: "Togo", dial_code: "+228", code: "TG" },
|
| 516 |
+
{ name: "Tonga", dial_code: "+676", code: "TO" },
|
| 517 |
+
{ name: "Trinidad and Tobago", dial_code: "+1-868", code: "TT" },
|
| 518 |
+
{ name: "Tunisia", dial_code: "+216", code: "TN" },
|
| 519 |
+
{ name: "Turkey", dial_code: "+90", code: "TR" },
|
| 520 |
+
{ name: "Turkmenistan", dial_code: "+993", code: "TM" },
|
| 521 |
+
{ name: "Tuvalu", dial_code: "+688", code: "TV" },
|
| 522 |
+
{ name: "Uganda", dial_code: "+256", code: "UG" },
|
| 523 |
+
{ name: "Ukraine", dial_code: "+380", code: "UA" },
|
| 524 |
+
{ name: "United Arab Emirates", dial_code: "+971", code: "AE" },
|
| 525 |
+
{ name: "United Kingdom", dial_code: "+44", code: "GB" },
|
| 526 |
+
{ name: "United States", dial_code: "+1", code: "US" },
|
| 527 |
+
{ name: "Uruguay", dial_code: "+598", code: "UY" },
|
| 528 |
+
{ name: "Uzbekistan", dial_code: "+998", code: "UZ" },
|
| 529 |
+
{ name: "Vanuatu", dial_code: "+678", code: "VU" },
|
| 530 |
+
{ name: "Vatican City", dial_code: "+379", code: "VA" },
|
| 531 |
+
{ name: "Venezuela", dial_code: "+58", code: "VE" },
|
| 532 |
+
{ name: "Vietnam", dial_code: "+84", code: "VN" },
|
| 533 |
+
{ name: "Yemen", dial_code: "+967", code: "YE" },
|
| 534 |
+
{ name: "Zambia", dial_code: "+260", code: "ZM" },
|
| 535 |
+
{ name: "Zimbabwe", dial_code: "+263", code: "ZW"},
|
| 536 |
+
];
|
| 537 |
+
|
| 538 |
+
|
| 539 |
+
const countrySelect = document.getElementById("country");
|
| 540 |
+
|
| 541 |
+
countries.forEach(c => {
|
| 542 |
+
const option = document.createElement("option");
|
| 543 |
+
option.value = c.code;
|
| 544 |
+
option.textContent = `${c.name} (${c.dial_code})`;
|
| 545 |
+
countrySelect.appendChild(option);
|
| 546 |
+
});
|
| 547 |
+
|
| 548 |
+
switchToSignup.addEventListener('click', function() {
|
| 549 |
+
signinContainer.style.transform = 'translateX(100%)';
|
| 550 |
+
setTimeout(() => {
|
| 551 |
+
signinContainer.style.display = 'none';
|
| 552 |
+
signupContainer.style.transform = 'translateX(0)';
|
| 553 |
+
}, 300);
|
| 554 |
+
});
|
| 555 |
+
|
| 556 |
+
// Signup handler
|
| 557 |
+
signupForm.addEventListener('submit', function(e) {
|
| 558 |
+
e.preventDefault();
|
| 559 |
+
document.querySelectorAll('.error-message').forEach(el => el.textContent = '');
|
| 560 |
+
|
| 561 |
+
// Get form values
|
| 562 |
+
const formData = {
|
| 563 |
+
username: document.getElementById('username').value.trim(),
|
| 564 |
+
email: document.getElementById('email').value.trim(),
|
| 565 |
+
country: document.getElementById('country').value,
|
| 566 |
+
phone: document.getElementById('phone').value.trim(),
|
| 567 |
+
password: document.getElementById('password').value,
|
| 568 |
+
confirm_password: document.getElementById('confirm-password').value
|
| 569 |
+
};
|
| 570 |
+
|
| 571 |
+
fetch('signup.php', {
|
| 572 |
+
method: 'POST',
|
| 573 |
+
headers: {
|
| 574 |
+
'Content-Type': 'application/json',
|
| 575 |
+
},
|
| 576 |
+
body: JSON.stringify(formData)
|
| 577 |
+
})
|
| 578 |
+
.then(res => res.json())
|
| 579 |
+
.then(data => {
|
| 580 |
+
if (data.success) {
|
| 581 |
+
successMessage.style.display = 'block';
|
| 582 |
+
signupForm.style.display = 'none';
|
| 583 |
+
setTimeout(() => {
|
| 584 |
+
successMessage.style.display = 'none';
|
| 585 |
+
signupForm.style.display = 'block';
|
| 586 |
+
switchToSignin.click();
|
| 587 |
+
}, 3000);
|
| 588 |
+
} else {
|
| 589 |
+
alert(data.message);
|
| 590 |
+
}
|
| 591 |
+
})
|
| 592 |
+
.catch(err => console.error('Signup error:', err));
|
| 593 |
+
});
|
| 594 |
+
|
| 595 |
+
// Signin handler
|
| 596 |
+
signinForm.addEventListener('submit', function(e) {
|
| 597 |
+
e.preventDefault();
|
| 598 |
+
document.getElementById('signin-email-error').textContent = '';
|
| 599 |
+
document.getElementById('signin-password-error').textContent = '';
|
| 600 |
+
|
| 601 |
+
const formData = {
|
| 602 |
+
email: document.getElementById('signin-email').value.trim(),
|
| 603 |
+
password: document.getElementById('signin-password').value
|
| 604 |
+
};
|
| 605 |
+
|
| 606 |
+
fetch('login.php', {
|
| 607 |
+
method: 'POST',
|
| 608 |
+
headers: {
|
| 609 |
+
'Content-Type': 'application/json',
|
| 610 |
+
},
|
| 611 |
+
body: JSON.stringify(formData)
|
| 612 |
+
})
|
| 613 |
+
.then(res => res.json())
|
| 614 |
+
.then(data => {
|
| 615 |
+
if (data.success) {
|
| 616 |
+
window.location.href = data.redirect;
|
| 617 |
+
} else {
|
| 618 |
+
alert(data.message);
|
| 619 |
+
}
|
| 620 |
+
})
|
| 621 |
+
.catch(err => console.error('Login error:', err));
|
| 622 |
+
});
|
| 623 |
+
});
|
| 624 |
+
</script>
|
| 625 |
+
</body>
|
| 626 |
+
</html>
|
jweb/ac1/login.php
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// login.php - Enhanced login with session management
|
| 3 |
+
session_start();
|
| 4 |
+
include_once 'db.php';
|
| 5 |
+
|
| 6 |
+
// Check if database connection is available
|
| 7 |
+
if (!$db) {
|
| 8 |
+
http_response_code(503);
|
| 9 |
+
echo json_encode(array("success" => false, "message" => "Service temporarily unavailable."));
|
| 10 |
+
exit;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
// Get posted data
|
| 14 |
+
$input = file_get_contents("php://input");
|
| 15 |
+
$data = json_decode($input);
|
| 16 |
+
|
| 17 |
+
if (json_last_error() !== JSON_ERROR_NONE) {
|
| 18 |
+
http_response_code(400);
|
| 19 |
+
echo json_encode(array("success" => false, "message" => "Invalid JSON data."));
|
| 20 |
+
exit;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
// Check if data is not empty
|
| 24 |
+
if (!empty($data->email) && !empty($data->password)) {
|
| 25 |
+
// Prepare query
|
| 26 |
+
$query = "SELECT id, username, email, password_hash, tier, package, balance,
|
| 27 |
+
total_deposits, total_withdrawals, rewards, account_status, is_active
|
| 28 |
+
FROM users
|
| 29 |
+
WHERE (username = :credential OR email = :credential) AND is_active = 1";
|
| 30 |
+
|
| 31 |
+
$stmt = $db->prepare($query);
|
| 32 |
+
$credential = htmlspecialchars(strip_tags($data->email));
|
| 33 |
+
$stmt->bindParam(":credential", $credential);
|
| 34 |
+
|
| 35 |
+
try {
|
| 36 |
+
$stmt->execute();
|
| 37 |
+
} catch(PDOException $e) {
|
| 38 |
+
error_log("Database error: " . $e->getMessage());
|
| 39 |
+
http_response_code(500);
|
| 40 |
+
echo json_encode(array("success" => false, "message" => "Database error occurred."));
|
| 41 |
+
exit;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
if ($stmt->rowCount() == 1) {
|
| 45 |
+
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
| 46 |
+
|
| 47 |
+
// Check account status
|
| 48 |
+
if ($row['account_status'] !== 'active') {
|
| 49 |
+
http_response_code(403);
|
| 50 |
+
echo json_encode(array("success" => false, "message" => "Account is suspended or pending approval."));
|
| 51 |
+
exit;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
// Verify password
|
| 55 |
+
if (password_verify($data->password, $row['password_hash'])) {
|
| 56 |
+
// Create session
|
| 57 |
+
$ip_address = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
| 58 |
+
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
|
| 59 |
+
$session_id = $sessionManager->createSession($row['id'], $ip_address, $user_agent);
|
| 60 |
+
|
| 61 |
+
if ($session_id) {
|
| 62 |
+
// Log activity
|
| 63 |
+
$sessionManager->logActivity($row['id'], 'login', 'User logged in successfully', $ip_address, $user_agent);
|
| 64 |
+
$sessionManager->updateLastLogin($row['id']);
|
| 65 |
+
|
| 66 |
+
// Set session variables
|
| 67 |
+
$_SESSION['user_id'] = $row['id'];
|
| 68 |
+
$_SESSION['username'] = $row['username'];
|
| 69 |
+
$_SESSION['email'] = $row['email'];
|
| 70 |
+
$_SESSION['tier'] = $row['tier'];
|
| 71 |
+
$_SESSION['package'] = $row['package'];
|
| 72 |
+
$_SESSION['balance'] = $row['balance'];
|
| 73 |
+
$_SESSION['total_deposits'] = $row['total_deposits'];
|
| 74 |
+
$_SESSION['total_withdrawals'] = $row['total_withdrawals'];
|
| 75 |
+
$_SESSION['rewards'] = $row['rewards'];
|
| 76 |
+
$_SESSION['session_id'] = $session_id;
|
| 77 |
+
$_SESSION['logged_in'] = true;
|
| 78 |
+
$_SESSION['login_time'] = time();
|
| 79 |
+
|
| 80 |
+
http_response_code(200);
|
| 81 |
+
echo json_encode(array(
|
| 82 |
+
"success" => true,
|
| 83 |
+
"message" => "Login successful.",
|
| 84 |
+
"redirect" => "src/pages/index.php",
|
| 85 |
+
"user_data" => [
|
| 86 |
+
"user_id" => $row['id'],
|
| 87 |
+
"username" => $row['username'],
|
| 88 |
+
"email" => $row['email'],
|
| 89 |
+
"tier" => $row['tier'],
|
| 90 |
+
"package" => $row['package'],
|
| 91 |
+
"balance" => $row['balance']
|
| 92 |
+
]
|
| 93 |
+
));
|
| 94 |
+
} else {
|
| 95 |
+
http_response_code(500);
|
| 96 |
+
echo json_encode(array("success" => false, "message" => "Session creation failed."));
|
| 97 |
+
}
|
| 98 |
+
} else {
|
| 99 |
+
http_response_code(401);
|
| 100 |
+
echo json_encode(array("success" => false, "message" => "Invalid password."));
|
| 101 |
+
}
|
| 102 |
+
} else {
|
| 103 |
+
http_response_code(404);
|
| 104 |
+
echo json_encode(array("success" => false, "message" => "User not found or account inactive."));
|
| 105 |
+
}
|
| 106 |
+
} else {
|
| 107 |
+
http_response_code(400);
|
| 108 |
+
echo json_encode(array("success" => false, "message" => "Unable to login. Data is incomplete."));
|
| 109 |
+
}
|
| 110 |
+
?>
|
jweb/ac1/login_form.php
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<title>Login</title>
|
| 6 |
+
<link rel="stylesheet" href="style.css">
|
| 7 |
+
<script>
|
| 8 |
+
// Disable right click & inspect
|
| 9 |
+
document.addEventListener("contextmenu", e => e.preventDefault());
|
| 10 |
+
document.onkeydown = function(e) {
|
| 11 |
+
if (e.ctrlKey && (e.key === 'u' || e.key === 'U')) return false;
|
| 12 |
+
if (e.ctrlKey && e.shiftKey && (e.key === 'I' || e.key === 'i')) return false;
|
| 13 |
+
if (e.key === "F12") return false;
|
| 14 |
+
};
|
| 15 |
+
</script>
|
| 16 |
+
</head>
|
| 17 |
+
<body>
|
| 18 |
+
<form action="login.php" method="POST" id="login-form">
|
| 19 |
+
<h2>Login</h2>
|
| 20 |
+
<?php
|
| 21 |
+
session_start();
|
| 22 |
+
if (!empty($_SESSION['error'])) {
|
| 23 |
+
echo "<p class='error'>" . $_SESSION['error'] . "</p>";
|
| 24 |
+
unset($_SESSION['error']);
|
| 25 |
+
}
|
| 26 |
+
?>
|
| 27 |
+
<div class="form-group">
|
| 28 |
+
<label for="username">Username / Email / Phone</label>
|
| 29 |
+
<input type="text" id="username" name="username" required>
|
| 30 |
+
</div>
|
| 31 |
+
<div class="form-group">
|
| 32 |
+
<label for="password">Password</label>
|
| 33 |
+
<input type="password" id="password" name="password" required>
|
| 34 |
+
</div>
|
| 35 |
+
<button type="submit">Login</button>
|
| 36 |
+
</form>
|
| 37 |
+
</body>
|
| 38 |
+
</html>
|
jweb/ac1/logout.php
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// logout.php - Enhanced logout with session cleanup
|
| 3 |
+
session_start();
|
| 4 |
+
include_once 'db.php';
|
| 5 |
+
|
| 6 |
+
// Get user ID before destroying session
|
| 7 |
+
$user_id = $_SESSION['user_id'] ?? null;
|
| 8 |
+
$session_id = $_SESSION['session_id'] ?? null;
|
| 9 |
+
|
| 10 |
+
// Log logout activity
|
| 11 |
+
if ($user_id && $session_id && isset($sessionManager)) {
|
| 12 |
+
try {
|
| 13 |
+
$ip_address = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
| 14 |
+
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
|
| 15 |
+
$sessionManager->logActivity($user_id, 'logout', 'User logged out', $ip_address, $user_agent);
|
| 16 |
+
|
| 17 |
+
// Deactivate session in database
|
| 18 |
+
if ($db) {
|
| 19 |
+
$query = "UPDATE user_sessions SET is_active = 0 WHERE session_id = :session_id";
|
| 20 |
+
$stmt = $db->prepare($query);
|
| 21 |
+
$stmt->bindParam(":session_id", $session_id);
|
| 22 |
+
$stmt->execute();
|
| 23 |
+
}
|
| 24 |
+
} catch(Exception $e) {
|
| 25 |
+
error_log("Logout error: " . $e->getMessage());
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
// Clear all session variables
|
| 30 |
+
$_SESSION = array();
|
| 31 |
+
|
| 32 |
+
// Destroy the session cookie
|
| 33 |
+
if (ini_get("session.use_cookies")) {
|
| 34 |
+
$params = session_get_cookie_params();
|
| 35 |
+
setcookie(session_name(), '', time() - 42000,
|
| 36 |
+
$params["path"], $params["domain"],
|
| 37 |
+
$params["secure"], $params["httponly"]
|
| 38 |
+
);
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
// Destroy the session
|
| 42 |
+
session_destroy();
|
| 43 |
+
|
| 44 |
+
// Return JSON response
|
| 45 |
+
header('Content-Type: application/json');
|
| 46 |
+
echo json_encode(array(
|
| 47 |
+
"success" => true,
|
| 48 |
+
"message" => "Logged out successfully",
|
| 49 |
+
"redirect" => "../index.html"
|
| 50 |
+
));
|
| 51 |
+
exit;
|
| 52 |
+
?>
|
jweb/ac1/setup_database.php
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// setup_database.php
|
| 3 |
+
|
| 4 |
+
// Database configuration
|
| 5 |
+
$host = '127.0.o.1';
|
| 6 |
+
$db_name = 'jweb'; // Using your existing database name
|
| 7 |
+
$username = 'root'; // Change to your database username
|
| 8 |
+
$password = 'YourStrongPassword123'; // Change to your database password
|
| 9 |
+
|
| 10 |
+
try {
|
| 11 |
+
// Connect to MySQL server
|
| 12 |
+
$pdo = new PDO("mysql:host=$host", $username, $password);
|
| 13 |
+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
| 14 |
+
|
| 15 |
+
// Select the database
|
| 16 |
+
$pdo->exec("USE $db_name");
|
| 17 |
+
echo "Using database: $db_name<br>";
|
| 18 |
+
|
| 19 |
+
// Users table
|
| 20 |
+
$sql = "CREATE TABLE IF NOT EXISTS users (
|
| 21 |
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
| 22 |
+
username VARCHAR(50) UNIQUE NOT NULL,
|
| 23 |
+
email VARCHAR(100) UNIQUE NOT NULL,
|
| 24 |
+
password_hash VARCHAR(255) NOT NULL,
|
| 25 |
+
tier ENUM('Basic', 'Premium', 'Gold') DEFAULT 'Basic',
|
| 26 |
+
package ENUM('NOVA', 'SUPERIOR', 'GOLD') DEFAULT 'NOVA',
|
| 27 |
+
balance DECIMAL(10, 2) DEFAULT 0.00,
|
| 28 |
+
total_deposits DECIMAL(10, 2) DEFAULT 0.00,
|
| 29 |
+
total_withdrawals DECIMAL(10, 2) DEFAULT 0.00,
|
| 30 |
+
rewards DECIMAL(10, 2) DEFAULT 0.00,
|
| 31 |
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
| 32 |
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
| 33 |
+
)";
|
| 34 |
+
$pdo->exec($sql);
|
| 35 |
+
echo "Users table created successfully<br>";
|
| 36 |
+
|
| 37 |
+
// Transactions table
|
| 38 |
+
$sql = "CREATE TABLE IF NOT EXISTS transactions (
|
| 39 |
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
| 40 |
+
user_id INT NOT NULL,
|
| 41 |
+
type ENUM('deposit', 'withdrawal', 'bonus', 'purchase', 'transfer', 'earning') NOT NULL,
|
| 42 |
+
amount DECIMAL(10, 2) NOT NULL,
|
| 43 |
+
description VARCHAR(255),
|
| 44 |
+
status ENUM('pending', 'completed', 'failed') DEFAULT 'pending',
|
| 45 |
+
reference VARCHAR(100),
|
| 46 |
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
| 47 |
+
)";
|
| 48 |
+
$pdo->exec($sql);
|
| 49 |
+
echo "Transactions table created successfully<br>";
|
| 50 |
+
|
| 51 |
+
// Packages table
|
| 52 |
+
$sql = "CREATE TABLE IF NOT EXISTS packages (
|
| 53 |
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
| 54 |
+
name VARCHAR(50) NOT NULL,
|
| 55 |
+
price DECIMAL(10, 2) NOT NULL,
|
| 56 |
+
award DECIMAL(10, 2) NOT NULL,
|
| 57 |
+
features TEXT,
|
| 58 |
+
is_active BOOLEAN DEFAULT TRUE,
|
| 59 |
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
| 60 |
+
)";
|
| 61 |
+
$pdo->exec($sql);
|
| 62 |
+
echo "Packages table created successfully<br>";
|
| 63 |
+
|
| 64 |
+
// Insert default packages
|
| 65 |
+
$sql = "INSERT IGNORE INTO packages (name, price, award, features) VALUES
|
| 66 |
+
('NOVA', 1000.00, 3000.00, 'Auto Deposit'),
|
| 67 |
+
('SUPERIOR', 2500.00, 7500.00, 'Auto Deposit'),
|
| 68 |
+
('GOLD', 5500.00, 16500.00, 'Auto Deposit')";
|
| 69 |
+
$pdo->exec($sql);
|
| 70 |
+
echo "Default packages inserted successfully<br>";
|
| 71 |
+
|
| 72 |
+
// Create a test user if none exists
|
| 73 |
+
$sql = "SELECT COUNT(*) FROM users";
|
| 74 |
+
$result = $pdo->query($sql);
|
| 75 |
+
$count = $result->fetchColumn();
|
| 76 |
+
|
| 77 |
+
if ($count == 0) {
|
| 78 |
+
$password_hash = password_hash('password123', PASSWORD_DEFAULT);
|
| 79 |
+
$sql = "INSERT INTO users (username, email, password_hash, tier, package, balance, total_deposits, total_withdrawals, rewards)
|
| 80 |
+
VALUES ('testuser', 'test@example.com', '$password_hash', 'Premium', 'NOVA', 5000.00, 10000.00, 5000.00, 1000.00)";
|
| 81 |
+
$pdo->exec($sql);
|
| 82 |
+
echo "Test user created successfully<br>";
|
| 83 |
+
|
| 84 |
+
// Add some sample transactions
|
| 85 |
+
$user_id = $pdo->lastInsertId();
|
| 86 |
+
$transactions = [
|
| 87 |
+
['user_id' => $user_id, 'type' => 'deposit', 'amount' => 1000.00, 'description' => 'Initial deposit', 'status' => 'completed'],
|
| 88 |
+
['user_id' => $user_id, 'type' => 'withdrawal', 'amount' => 500.00, 'description' => 'Cash withdrawal', 'status' => 'completed'],
|
| 89 |
+
['user_id' => $user_id, 'type' => 'bonus', 'amount' => 100.00, 'description' => 'Welcome bonus', 'status' => 'completed'],
|
| 90 |
+
['user_id' => $user_id, 'type' => 'purchase', 'amount' => 250.00, 'description' => 'Product purchase', 'status' => 'completed'],
|
| 91 |
+
['user_id' => $user_id, 'type' => 'earning', 'amount' => 150.00, 'description' => 'Daily earnings', 'status' => 'completed']
|
| 92 |
+
];
|
| 93 |
+
|
| 94 |
+
foreach ($transactions as $transaction) {
|
| 95 |
+
$sql = "INSERT INTO transactions (user_id, type, amount, description, status)
|
| 96 |
+
VALUES (:user_id, :type, :amount, :description, :status)";
|
| 97 |
+
$stmt = $pdo->prepare($sql);
|
| 98 |
+
$stmt->execute($transaction);
|
| 99 |
+
}
|
| 100 |
+
echo "Sample transactions created successfully<br>";
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
echo "Database setup completed successfully!";
|
| 104 |
+
|
| 105 |
+
} catch (PDOException $e) {
|
| 106 |
+
die("Database error: " . $e->getMessage());
|
| 107 |
+
}
|
| 108 |
+
?>
|
jweb/ac1/shake it.html
ADDED
|
@@ -0,0 +1,1313 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>MetaWave Marketing Platform</title>
|
| 7 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
| 8 |
+
<style>
|
| 9 |
+
:root {
|
| 10 |
+
--sidebar-bg: #1e293b;
|
| 11 |
+
--main-bg: #f9fafb;
|
| 12 |
+
--text-dark: #1e293b;
|
| 13 |
+
--text-light: #64748b;
|
| 14 |
+
--accent-primary: #7c3aed;
|
| 15 |
+
--accent-secondary: #a855f7;
|
| 16 |
+
--success-green: #22c55e;
|
| 17 |
+
--warning-yellow: #f59e0b;
|
| 18 |
+
--premium-gold: #d97706;
|
| 19 |
+
--card-bg: #ffffff;
|
| 20 |
+
--shadow-light: 0 4px 12px rgba(0, 0, 0, 0.05);
|
| 21 |
+
--shadow-hover: 0 6px 18px rgba(0, 0, 0, 0.1);
|
| 22 |
+
--transition-speed: 0.3s;
|
| 23 |
+
--spacing-unit: 1rem;
|
| 24 |
+
--font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap');
|
| 28 |
+
|
| 29 |
+
* {
|
| 30 |
+
margin: 0;
|
| 31 |
+
padding: 0;
|
| 32 |
+
box-sizing: border-box;
|
| 33 |
+
font-family: var(--font-family);
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
body {
|
| 37 |
+
background: linear-gradient(135deg, #f3f4f6, #e5e7eb);
|
| 38 |
+
color: var(--text-dark);
|
| 39 |
+
display: flex;
|
| 40 |
+
min-height: 100vh;
|
| 41 |
+
overflow-x: hidden;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
.sidebar {
|
| 45 |
+
width: 260px;
|
| 46 |
+
background: var(--sidebar-bg);
|
| 47 |
+
padding: var(--spacing-unit) calc(var(--spacing-unit) * 1.5);
|
| 48 |
+
position: fixed;
|
| 49 |
+
height: 100vh;
|
| 50 |
+
overflow-y: auto;
|
| 51 |
+
z-index: 1000;
|
| 52 |
+
display: flex;
|
| 53 |
+
flex-direction: column;
|
| 54 |
+
box-shadow: var(--shadow-light);
|
| 55 |
+
transition: transform var(--transition-speed) ease;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
.sidebar.collapsed {
|
| 59 |
+
transform: translateX(-100%);
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
.sidebar .logo {
|
| 63 |
+
display: flex;
|
| 64 |
+
align-items: center;
|
| 65 |
+
margin-bottom: calc(var(--spacing-unit) * 2);
|
| 66 |
+
padding-bottom: var(--spacing-unit);
|
| 67 |
+
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
.sidebar .logo img {
|
| 71 |
+
width: 50px;
|
| 72 |
+
height: 50px;
|
| 73 |
+
border-radius: 50%;
|
| 74 |
+
margin-right: calc(var(--spacing-unit) * 0.75);
|
| 75 |
+
transition: transform var(--transition-speed) ease;
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
.sidebar .logo img:hover {
|
| 79 |
+
transform: scale(1.1);
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
.sidebar .logo-text {
|
| 83 |
+
font-size: 1.5rem;
|
| 84 |
+
font-weight: 700;
|
| 85 |
+
color: var(--premium-gold);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
.sidebar .logo-subtext {
|
| 89 |
+
font-size: 0.75rem;
|
| 90 |
+
color: var(--text-light);
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
.sidebar ul {
|
| 94 |
+
list-style: none;
|
| 95 |
+
flex: 1;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
.sidebar ul li {
|
| 99 |
+
margin-bottom: calc(var(--spacing-unit) * 0.75);
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
.sidebar ul li a {
|
| 103 |
+
display: flex;
|
| 104 |
+
align-items: center;
|
| 105 |
+
color: var(--text-light);
|
| 106 |
+
text-decoration: none;
|
| 107 |
+
padding: calc(var(--spacing-unit) * 0.5) var(--spacing-unit);
|
| 108 |
+
border-radius: 8px;
|
| 109 |
+
transition: background var(--transition-speed), color var(--transition-speed);
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
.sidebar ul li a:hover {
|
| 113 |
+
background: rgba(255, 255, 255, 0.1);
|
| 114 |
+
color: var(--accent-primary);
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
.sidebar ul li a i {
|
| 118 |
+
margin-right: calc(var(--spacing-unit) * 0.75);
|
| 119 |
+
width: 20px;
|
| 120 |
+
text-align: center;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
.sidebar .user-info {
|
| 124 |
+
display: flex;
|
| 125 |
+
align-items: center;
|
| 126 |
+
padding: var(--spacing-unit);
|
| 127 |
+
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
| 128 |
+
background: rgba(255, 255, 255, 0.05);
|
| 129 |
+
border-radius: 8px;
|
| 130 |
+
margin-top: calc(var(--spacing-unit) * 1.5);
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
.sidebar .user-avatar {
|
| 134 |
+
background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
|
| 135 |
+
color: #ffffff;
|
| 136 |
+
width: 40px;
|
| 137 |
+
height: 40px;
|
| 138 |
+
border-radius: 50%;
|
| 139 |
+
display: flex;
|
| 140 |
+
align-items: center;
|
| 141 |
+
justify-content: center;
|
| 142 |
+
font-weight: 700;
|
| 143 |
+
margin-right: calc(var(--spacing-unit) * 0.75);
|
| 144 |
+
box-shadow: 0 0 8px rgba(124, 58, 237, 0.3);
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
.sidebar .user-text {
|
| 148 |
+
font-size: 1rem;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
.sidebar .user-status {
|
| 152 |
+
font-size: 0.75rem;
|
| 153 |
+
color: var(--text-light);
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
.main-content {
|
| 157 |
+
flex: 1;
|
| 158 |
+
margin-left: 260px;
|
| 159 |
+
padding: calc(var(--spacing-unit) * 1.5);
|
| 160 |
+
transition: margin-left var(--transition-speed) ease;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
.main-content.expanded {
|
| 164 |
+
margin-left: 0;
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
.topbar {
|
| 168 |
+
display: flex;
|
| 169 |
+
align-items: center;
|
| 170 |
+
justify-content: space-between;
|
| 171 |
+
margin-bottom: calc(var(--spacing-unit) * 2);
|
| 172 |
+
padding: var(--spacing-unit);
|
| 173 |
+
background: var(--card-bg);
|
| 174 |
+
border-radius: 12px;
|
| 175 |
+
box-shadow: var(--shadow-light);
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
.topbar .logo {
|
| 179 |
+
display: flex;
|
| 180 |
+
align-items: center;
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
.topbar .logo img {
|
| 184 |
+
width: 40px;
|
| 185 |
+
height: 40px;
|
| 186 |
+
margin-right: calc(var(--spacing-unit) * 0.75);
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
.topbar .logo-text {
|
| 190 |
+
font-size: 1.5rem;
|
| 191 |
+
font-weight: 700;
|
| 192 |
+
color: var(--accent-primary);
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
.topbar nav {
|
| 196 |
+
display: flex;
|
| 197 |
+
gap: calc(var(--spacing-unit) * 1.5);
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
.topbar nav a {
|
| 201 |
+
color: var(--text-dark);
|
| 202 |
+
text-decoration: none;
|
| 203 |
+
font-weight: 500;
|
| 204 |
+
transition: color var(--transition-speed);
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
.topbar nav a:hover {
|
| 208 |
+
color: var(--accent-secondary);
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
.topbar .right {
|
| 212 |
+
display: flex;
|
| 213 |
+
align-items: center;
|
| 214 |
+
gap: calc(var(--spacing-unit) * 1.25);
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
.topbar .toggle-btn {
|
| 218 |
+
background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
|
| 219 |
+
color: #ffffff;
|
| 220 |
+
border: none;
|
| 221 |
+
border-radius: 50%;
|
| 222 |
+
width: 45px;
|
| 223 |
+
height: 45px;
|
| 224 |
+
font-size: 1.25rem;
|
| 225 |
+
cursor: pointer;
|
| 226 |
+
box-shadow: var(--shadow-light);
|
| 227 |
+
transition: transform var(--transition-speed), background var(--transition-speed);
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
.topbar .toggle-btn:hover {
|
| 231 |
+
transform: scale(1.1);
|
| 232 |
+
background: linear-gradient(90deg, #6b21a8, #9333ea);
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
.topbar .notification {
|
| 236 |
+
position: relative;
|
| 237 |
+
cursor: pointer;
|
| 238 |
+
}
|
| 239 |
+
|
| 240 |
+
.topbar .notification i {
|
| 241 |
+
color: var(--text-light);
|
| 242 |
+
font-size: 1.25rem;
|
| 243 |
+
transition: color var(--transition-speed);
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
.topbar .notification i:hover {
|
| 247 |
+
color: var(--warning-yellow);
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
.topbar .notification .dot {
|
| 251 |
+
position: absolute;
|
| 252 |
+
top: -2px;
|
| 253 |
+
right: -2px;
|
| 254 |
+
width: 8px;
|
| 255 |
+
height: 8px;
|
| 256 |
+
background-color: #ef4444;
|
| 257 |
+
border-radius: 50%;
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
.topbar .user {
|
| 261 |
+
display: flex;
|
| 262 |
+
align-items: center;
|
| 263 |
+
gap: calc(var(--spacing-unit) * 0.5);
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
.topbar .user-avatar {
|
| 267 |
+
background: var(--premium-gold);
|
| 268 |
+
color: #ffffff;
|
| 269 |
+
width: 30px;
|
| 270 |
+
height: 30px;
|
| 271 |
+
border-radius: 50%;
|
| 272 |
+
display: flex;
|
| 273 |
+
align-items: center;
|
| 274 |
+
justify-content: center;
|
| 275 |
+
font-weight: 700;
|
| 276 |
+
font-size: 0.875rem;
|
| 277 |
+
box-shadow: 0 0 6px rgba(217, 119, 6, 0.4);
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
.topbar .user-name {
|
| 281 |
+
font-weight: 500;
|
| 282 |
+
color: var(--text-dark);
|
| 283 |
+
}
|
| 284 |
+
|
| 285 |
+
.topbar .premium {
|
| 286 |
+
background: var(--premium-gold);
|
| 287 |
+
color: #ffffff;
|
| 288 |
+
padding: 0.25rem 0.75rem;
|
| 289 |
+
border-radius: 4px;
|
| 290 |
+
font-size: 0.75rem;
|
| 291 |
+
font-weight: 700;
|
| 292 |
+
text-transform: uppercase;
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
.topbar .logout i {
|
| 296 |
+
color: var(--text-light);
|
| 297 |
+
font-size: 1.25rem;
|
| 298 |
+
transition: color var(--transition-speed);
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
.topbar .logout i:hover {
|
| 302 |
+
color: #dc2626;
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
.topbar .clock {
|
| 306 |
+
font-size: 0.9rem;
|
| 307 |
+
color: var(--text-light);
|
| 308 |
+
margin-left: calc(var(--spacing-unit) * 1.25);
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
.banner {
|
| 312 |
+
max-width: 450px;
|
| 313 |
+
margin: 0 auto calc(var(--spacing-unit) * 2);
|
| 314 |
+
background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
|
| 315 |
+
border-radius: 12px;
|
| 316 |
+
padding: calc(var(--spacing-unit) * 1.5);
|
| 317 |
+
text-align: center;
|
| 318 |
+
box-shadow: var(--shadow-hover);
|
| 319 |
+
animation: fadeIn 0.5s ease;
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
@keyframes fadeIn {
|
| 323 |
+
from { opacity: 0; transform: translateY(20px); }
|
| 324 |
+
to { opacity: 1; transform: translateY(0); }
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
@keyframes blink {
|
| 328 |
+
0% { opacity: 1; }
|
| 329 |
+
50% { opacity: 0.3; }
|
| 330 |
+
100% { opacity: 1; }
|
| 331 |
+
}
|
| 332 |
+
|
| 333 |
+
.banner .title {
|
| 334 |
+
font-size: 1.25rem;
|
| 335 |
+
margin-bottom: calc(var(--spacing-unit) * 1);
|
| 336 |
+
color: #ffffff;
|
| 337 |
+
font-weight: 700;
|
| 338 |
+
animation: blink 1.5s infinite;
|
| 339 |
+
}
|
| 340 |
+
|
| 341 |
+
.banner p {
|
| 342 |
+
font-size: 0.95rem;
|
| 343 |
+
line-height: 1.6;
|
| 344 |
+
margin-bottom: calc(var(--spacing-unit) * 1);
|
| 345 |
+
color: var(--premium-gold);
|
| 346 |
+
animation: blink 1.5s infinite;
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
.banner .footer {
|
| 350 |
+
font-size: 0.75rem;
|
| 351 |
+
color: rgba(255, 255, 255, 0.9);
|
| 352 |
+
font-style: italic;
|
| 353 |
+
animation: blink 1.5s infinite;
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
.packages-section {
|
| 357 |
+
text-align: center;
|
| 358 |
+
margin-bottom: calc(var(--spacing-unit) * 2);
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
.packages-section h1 {
|
| 362 |
+
font-size: 1.75rem;
|
| 363 |
+
margin-bottom: var(--spacing-unit);
|
| 364 |
+
color: var(--accent-primary);
|
| 365 |
+
}
|
| 366 |
+
|
| 367 |
+
.packages-section .subtitle {
|
| 368 |
+
font-size: 0.95rem;
|
| 369 |
+
color: var(--text-light);
|
| 370 |
+
margin-bottom: calc(var(--spacing-unit) * 1.5);
|
| 371 |
+
}
|
| 372 |
+
|
| 373 |
+
.packages {
|
| 374 |
+
display: flex;
|
| 375 |
+
justify-content: center;
|
| 376 |
+
gap: var(--spacing-unit);
|
| 377 |
+
flex-wrap: wrap;
|
| 378 |
+
}
|
| 379 |
+
|
| 380 |
+
.package-card {
|
| 381 |
+
background: var(--card-bg);
|
| 382 |
+
border-radius: 10px;
|
| 383 |
+
padding: calc(var(--spacing-unit) * 1.25);
|
| 384 |
+
width: 220px;
|
| 385 |
+
text-align: left;
|
| 386 |
+
box-shadow: var(--shadow-light);
|
| 387 |
+
transition: transform var(--transition-speed), box-shadow var(--transition-speed);
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
.package-card:hover {
|
| 391 |
+
transform: translateY(-5px);
|
| 392 |
+
box-shadow: var(--shadow-hover);
|
| 393 |
+
}
|
| 394 |
+
|
| 395 |
+
.package-header {
|
| 396 |
+
display: flex;
|
| 397 |
+
align-items: center;
|
| 398 |
+
margin-bottom: calc(var(--spacing-unit) * 1);
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
.package-header i {
|
| 402 |
+
color: var(--text-light);
|
| 403 |
+
margin-right: calc(var(--spacing-unit) * 0.75);
|
| 404 |
+
font-size: 1.25rem;
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
.package-header .name {
|
| 408 |
+
font-size: 1.25rem;
|
| 409 |
+
font-weight: 700;
|
| 410 |
+
color: var(--accent-primary);
|
| 411 |
+
}
|
| 412 |
+
|
| 413 |
+
.package-features {
|
| 414 |
+
list-style: none;
|
| 415 |
+
margin-bottom: calc(var(--spacing-unit) * 1);
|
| 416 |
+
}
|
| 417 |
+
|
| 418 |
+
.package-features li {
|
| 419 |
+
display: flex;
|
| 420 |
+
align-items: center;
|
| 421 |
+
margin-bottom: calc(var(--spacing-unit) * 0.5);
|
| 422 |
+
color: var(--text-dark);
|
| 423 |
+
font-size: 0.9rem;
|
| 424 |
+
}
|
| 425 |
+
|
| 426 |
+
.package-features li i {
|
| 427 |
+
margin-right: calc(var(--spacing-unit) * 0.75);
|
| 428 |
+
}
|
| 429 |
+
|
| 430 |
+
.package-features .checked i {
|
| 431 |
+
color: var(--success-green);
|
| 432 |
+
}
|
| 433 |
+
|
| 434 |
+
.package-features .unchecked i {
|
| 435 |
+
color: var(--text-light);
|
| 436 |
+
}
|
| 437 |
+
|
| 438 |
+
.package-award {
|
| 439 |
+
font-size: 1.1rem;
|
| 440 |
+
font-weight: 700;
|
| 441 |
+
color: var(--premium-gold);
|
| 442 |
+
margin-bottom: calc(var(--spacing-unit) * 0.75);
|
| 443 |
+
}
|
| 444 |
+
|
| 445 |
+
.package-button {
|
| 446 |
+
background: var(--premium-gold);
|
| 447 |
+
color: #ffffff;
|
| 448 |
+
padding: calc(var(--spacing-unit) * 0.5) calc(var(--spacing-unit) * 1);
|
| 449 |
+
border: none;
|
| 450 |
+
border-radius: 6px;
|
| 451 |
+
font-weight: 600;
|
| 452 |
+
cursor: pointer;
|
| 453 |
+
width: 100%;
|
| 454 |
+
transition: background var(--transition-speed), transform var(--transition-speed);
|
| 455 |
+
}
|
| 456 |
+
|
| 457 |
+
.package-button:hover {
|
| 458 |
+
background: #b45309;
|
| 459 |
+
transform: translateY(-2px);
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
.welcome {
|
| 463 |
+
display: flex;
|
| 464 |
+
align-items: center;
|
| 465 |
+
margin-bottom: calc(var(--spacing-unit) * 1.5);
|
| 466 |
+
padding: calc(var(--spacing-unit) * 0.75);
|
| 467 |
+
background: rgba(255, 255, 255, 0.9);
|
| 468 |
+
border-radius: 10px;
|
| 469 |
+
box-shadow: var(--shadow-light);
|
| 470 |
+
}
|
| 471 |
+
|
| 472 |
+
.user-avatar {
|
| 473 |
+
width: 50px;
|
| 474 |
+
height: 50px;
|
| 475 |
+
border-radius: 50%;
|
| 476 |
+
background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
|
| 477 |
+
display: flex;
|
| 478 |
+
align-items: center;
|
| 479 |
+
justify-content: center;
|
| 480 |
+
color: #ffffff;
|
| 481 |
+
font-size: 1.25rem;
|
| 482 |
+
margin-right: calc(var(--spacing-unit) * 1);
|
| 483 |
+
box-shadow: 0 0 8px rgba(124, 58, 237, 0.2);
|
| 484 |
+
}
|
| 485 |
+
|
| 486 |
+
.welcome-text h2 {
|
| 487 |
+
font-size: 1.25rem;
|
| 488 |
+
margin-bottom: 0.25rem;
|
| 489 |
+
color: var(--text-dark);
|
| 490 |
+
}
|
| 491 |
+
|
| 492 |
+
.welcome-text p {
|
| 493 |
+
color: var(--text-light);
|
| 494 |
+
font-size: 0.9rem;
|
| 495 |
+
}
|
| 496 |
+
|
| 497 |
+
.profile-summary {
|
| 498 |
+
background: var(--card-bg);
|
| 499 |
+
border-radius: 10px;
|
| 500 |
+
padding: calc(var(--spacing-unit) * 1.25);
|
| 501 |
+
box-shadow: var(--shadow-light);
|
| 502 |
+
margin-bottom: calc(var(--spacing-unit) * 2);
|
| 503 |
+
display: flex;
|
| 504 |
+
align-items: center;
|
| 505 |
+
gap: var(--spacing-unit);
|
| 506 |
+
}
|
| 507 |
+
|
| 508 |
+
.profile-summary .avatar {
|
| 509 |
+
width: 60px;
|
| 510 |
+
height: 60px;
|
| 511 |
+
border-radius: 50%;
|
| 512 |
+
background: var(--premium-gold);
|
| 513 |
+
display: flex;
|
| 514 |
+
align-items: center;
|
| 515 |
+
justify-content: center;
|
| 516 |
+
font-size: 1.5rem;
|
| 517 |
+
color: #ffffff;
|
| 518 |
+
box-shadow: 0 0 6px rgba(217, 119, 6, 0.2);
|
| 519 |
+
}
|
| 520 |
+
|
| 521 |
+
.profile-summary .details h3 {
|
| 522 |
+
font-size: 1.25rem;
|
| 523 |
+
color: var(--text-dark);
|
| 524 |
+
}
|
| 525 |
+
|
| 526 |
+
.profile-summary .details p {
|
| 527 |
+
color: var(--text-light);
|
| 528 |
+
font-size: 0.9rem;
|
| 529 |
+
}
|
| 530 |
+
|
| 531 |
+
.balance-cards {
|
| 532 |
+
display: grid;
|
| 533 |
+
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
| 534 |
+
gap: var(--spacing-unit);
|
| 535 |
+
margin-bottom: calc(var(--spacing-unit) * 2);
|
| 536 |
+
}
|
| 537 |
+
|
| 538 |
+
.card {
|
| 539 |
+
background: var(--card-bg);
|
| 540 |
+
border-radius: 10px;
|
| 541 |
+
padding: calc(var(--spacing-unit) * 1.25);
|
| 542 |
+
box-shadow: var(--shadow-light);
|
| 543 |
+
transition: transform var(--transition-speed);
|
| 544 |
+
}
|
| 545 |
+
|
| 546 |
+
.card:hover {
|
| 547 |
+
transform: translateY(-5px);
|
| 548 |
+
}
|
| 549 |
+
|
| 550 |
+
.card-title {
|
| 551 |
+
font-size: 1rem;
|
| 552 |
+
color: var(--text-light);
|
| 553 |
+
margin-bottom: calc(var(--spacing-unit) * 1);
|
| 554 |
+
}
|
| 555 |
+
|
| 556 |
+
.meta-balance {
|
| 557 |
+
display: flex;
|
| 558 |
+
justify-content: space-between;
|
| 559 |
+
align-items: center;
|
| 560 |
+
}
|
| 561 |
+
|
| 562 |
+
.balance-amount {
|
| 563 |
+
font-size: 1.75rem;
|
| 564 |
+
font-weight: 700;
|
| 565 |
+
color: var(--accent-primary);
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
.balance-actions {
|
| 569 |
+
display: flex;
|
| 570 |
+
gap: calc(var(--spacing-unit) * 0.75);
|
| 571 |
+
}
|
| 572 |
+
|
| 573 |
+
.btn {
|
| 574 |
+
padding: calc(var(--spacing-unit) * 0.5) calc(var(--spacing-unit) * 1);
|
| 575 |
+
border-radius: 6px;
|
| 576 |
+
border: none;
|
| 577 |
+
font-weight: 600;
|
| 578 |
+
cursor: pointer;
|
| 579 |
+
transition: background var(--transition-speed), transform var(--transition-speed);
|
| 580 |
+
}
|
| 581 |
+
|
| 582 |
+
.btn-primary {
|
| 583 |
+
background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
|
| 584 |
+
color: #ffffff;
|
| 585 |
+
}
|
| 586 |
+
|
| 587 |
+
.btn-primary:hover {
|
| 588 |
+
background: linear-gradient(90deg, #6b21a8, #9333ea);
|
| 589 |
+
transform: translateY(-2px);
|
| 590 |
+
}
|
| 591 |
+
|
| 592 |
+
.btn-outline {
|
| 593 |
+
background: transparent;
|
| 594 |
+
border: 2px solid var(--accent-primary);
|
| 595 |
+
color: var(--accent-primary);
|
| 596 |
+
}
|
| 597 |
+
|
| 598 |
+
.btn-outline:hover {
|
| 599 |
+
background: var(--accent-primary);
|
| 600 |
+
color: #ffffff;
|
| 601 |
+
transform: translateY(-2px);
|
| 602 |
+
}
|
| 603 |
+
|
| 604 |
+
.stats {
|
| 605 |
+
display: grid;
|
| 606 |
+
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
| 607 |
+
gap: var(--spacing-unit);
|
| 608 |
+
margin-bottom: calc(var(--spacing-unit) * 2);
|
| 609 |
+
}
|
| 610 |
+
|
| 611 |
+
.stat-card {
|
| 612 |
+
background: var(--card-bg);
|
| 613 |
+
border-radius: 10px;
|
| 614 |
+
padding: calc(var(--spacing-unit) * 1.25);
|
| 615 |
+
text-align: center;
|
| 616 |
+
box-shadow: var(--shadow-light);
|
| 617 |
+
transition: transform var(--transition-speed);
|
| 618 |
+
}
|
| 619 |
+
|
| 620 |
+
.stat-card:hover {
|
| 621 |
+
transform: translateY(-5px);
|
| 622 |
+
}
|
| 623 |
+
|
| 624 |
+
.stat-value {
|
| 625 |
+
font-size: 1.5rem;
|
| 626 |
+
font-weight: 700;
|
| 627 |
+
margin: calc(var(--spacing-unit) * 0.75) 0;
|
| 628 |
+
color: var(--accent-primary);
|
| 629 |
+
}
|
| 630 |
+
|
| 631 |
+
.stat-label {
|
| 632 |
+
color: var(--text-light);
|
| 633 |
+
font-size: 0.9rem;
|
| 634 |
+
}
|
| 635 |
+
|
| 636 |
+
.dashboard-cards {
|
| 637 |
+
display: grid;
|
| 638 |
+
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
| 639 |
+
gap: var(--spacing-unit);
|
| 640 |
+
margin-bottom: calc(var(--spacing-unit) * 2);
|
| 641 |
+
}
|
| 642 |
+
|
| 643 |
+
.dashboard-card {
|
| 644 |
+
background: var(--card-bg);
|
| 645 |
+
border-radius: 10px;
|
| 646 |
+
padding: calc(var(--spacing-unit) * 1.25);
|
| 647 |
+
color: var(--text-dark);
|
| 648 |
+
text-align: center;
|
| 649 |
+
box-shadow: var(--shadow-light);
|
| 650 |
+
transition: transform var(--transition-speed);
|
| 651 |
+
}
|
| 652 |
+
|
| 653 |
+
.dashboard-card:hover {
|
| 654 |
+
transform: translateY(-5px);
|
| 655 |
+
}
|
| 656 |
+
|
| 657 |
+
.dashboard-card h2 {
|
| 658 |
+
margin: calc(var(--spacing-unit) * 0.75) 0;
|
| 659 |
+
font-size: 1.375rem;
|
| 660 |
+
color: var(--accent-primary);
|
| 661 |
+
}
|
| 662 |
+
|
| 663 |
+
.dashboard-card p {
|
| 664 |
+
font-size: 0.9rem;
|
| 665 |
+
color: var(--text-light);
|
| 666 |
+
}
|
| 667 |
+
|
| 668 |
+
.dashboard-btn {
|
| 669 |
+
background: var(--premium-gold);
|
| 670 |
+
color: #ffffff;
|
| 671 |
+
padding: calc(var(--spacing-unit) * 0.5) calc(var(--spacing-unit) * 1);
|
| 672 |
+
border: none;
|
| 673 |
+
border-radius: 6px;
|
| 674 |
+
cursor: pointer;
|
| 675 |
+
font-weight: 600;
|
| 676 |
+
margin-top: calc(var(--spacing-unit) * 0.75);
|
| 677 |
+
transition: background var(--transition-speed), transform var(--transition-speed);
|
| 678 |
+
}
|
| 679 |
+
|
| 680 |
+
.dashboard-btn:hover {
|
| 681 |
+
background: #b45309;
|
| 682 |
+
transform: translateY(-2px);
|
| 683 |
+
}
|
| 684 |
+
|
| 685 |
+
.transaction-history {
|
| 686 |
+
display: none;
|
| 687 |
+
background: var(--card-bg);
|
| 688 |
+
border-radius: 10px;
|
| 689 |
+
padding: calc(var(--spacing-unit) * 1.25);
|
| 690 |
+
box-shadow: var(--shadow-light);
|
| 691 |
+
margin-top: var(--spacing-unit);
|
| 692 |
+
}
|
| 693 |
+
|
| 694 |
+
.transaction-history.active {
|
| 695 |
+
display: block;
|
| 696 |
+
}
|
| 697 |
+
|
| 698 |
+
.transaction-list {
|
| 699 |
+
list-style: none;
|
| 700 |
+
}
|
| 701 |
+
|
| 702 |
+
.transaction-list li {
|
| 703 |
+
padding: calc(var(--spacing-unit) * 0.5);
|
| 704 |
+
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
| 705 |
+
font-size: 0.9rem;
|
| 706 |
+
color: var(--text-dark);
|
| 707 |
+
}
|
| 708 |
+
|
| 709 |
+
.modal {
|
| 710 |
+
display: none;
|
| 711 |
+
position: fixed;
|
| 712 |
+
top: 0;
|
| 713 |
+
left: 0;
|
| 714 |
+
width: 100%;
|
| 715 |
+
height: 100%;
|
| 716 |
+
background: rgba(0, 0, 0, 0.5);
|
| 717 |
+
z-index: 2000;
|
| 718 |
+
justify-content: center;
|
| 719 |
+
align-items: center;
|
| 720 |
+
}
|
| 721 |
+
|
| 722 |
+
.modal-content {
|
| 723 |
+
background: var(--card-bg);
|
| 724 |
+
padding: calc(var(--spacing-unit) * 1.5);
|
| 725 |
+
border-radius: 10px;
|
| 726 |
+
width: 90%;
|
| 727 |
+
max-width: 500px;
|
| 728 |
+
color: var(--text-dark);
|
| 729 |
+
box-shadow: var(--shadow-hover);
|
| 730 |
+
animation: fadeIn 0.3s ease;
|
| 731 |
+
}
|
| 732 |
+
|
| 733 |
+
@keyframes fadeIn {
|
| 734 |
+
from { opacity: 0; transform: scale(0.95); }
|
| 735 |
+
to { opacity: 1; transform: scale(1); }
|
| 736 |
+
}
|
| 737 |
+
|
| 738 |
+
.modal-header {
|
| 739 |
+
display: flex;
|
| 740 |
+
justify-content: space-between;
|
| 741 |
+
align-items: center;
|
| 742 |
+
margin-bottom: calc(var(--spacing-unit) * 1);
|
| 743 |
+
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
| 744 |
+
padding-bottom: var(--spacing-unit);
|
| 745 |
+
}
|
| 746 |
+
|
| 747 |
+
.close {
|
| 748 |
+
font-size: 1.5rem;
|
| 749 |
+
cursor: pointer;
|
| 750 |
+
color: var(--text-light);
|
| 751 |
+
transition: color var(--transition-speed);
|
| 752 |
+
}
|
| 753 |
+
|
| 754 |
+
.close:hover {
|
| 755 |
+
color: #dc2626;
|
| 756 |
+
}
|
| 757 |
+
|
| 758 |
+
.form-group {
|
| 759 |
+
margin-bottom: calc(var(--spacing-unit) * 1);
|
| 760 |
+
}
|
| 761 |
+
|
| 762 |
+
.form-group label {
|
| 763 |
+
display: block;
|
| 764 |
+
margin-bottom: 0.25rem;
|
| 765 |
+
font-weight: 500;
|
| 766 |
+
color: var(--text-dark);
|
| 767 |
+
}
|
| 768 |
+
|
| 769 |
+
.form-group input, .form-group select {
|
| 770 |
+
width: 100%;
|
| 771 |
+
padding: calc(var(--spacing-unit) * 0.5);
|
| 772 |
+
border: 1px solid rgba(0, 0, 0, 0.1);
|
| 773 |
+
border-radius: 6px;
|
| 774 |
+
background: #f9fafb;
|
| 775 |
+
color: var(--text-dark);
|
| 776 |
+
font-size: 0.95rem;
|
| 777 |
+
transition: border-color var(--transition-speed), box-shadow var(--transition-speed);
|
| 778 |
+
}
|
| 779 |
+
|
| 780 |
+
.form-group input:focus, .form-group select:focus {
|
| 781 |
+
border-color: var(--accent-primary);
|
| 782 |
+
box-shadow: 0 0 5px rgba(124, 58, 237, 0.2);
|
| 783 |
+
outline: none;
|
| 784 |
+
}
|
| 785 |
+
|
| 786 |
+
@media (max-width: 768px) {
|
| 787 |
+
.sidebar {
|
| 788 |
+
transform: translateX(-100%);
|
| 789 |
+
}
|
| 790 |
+
|
| 791 |
+
.sidebar.active {
|
| 792 |
+
transform: translateX(0);
|
| 793 |
+
}
|
| 794 |
+
|
| 795 |
+
.main-content {
|
| 796 |
+
margin-left: 0;
|
| 797 |
+
}
|
| 798 |
+
|
| 799 |
+
.main-content.expanded {
|
| 800 |
+
margin-left: 0;
|
| 801 |
+
}
|
| 802 |
+
|
| 803 |
+
.packages {
|
| 804 |
+
flex-direction: column;
|
| 805 |
+
align-items: center;
|
| 806 |
+
}
|
| 807 |
+
|
| 808 |
+
.balance-cards, .stats, .dashboard-cards {
|
| 809 |
+
grid-template-columns: 1fr;
|
| 810 |
+
}
|
| 811 |
+
|
| 812 |
+
.balance-actions {
|
| 813 |
+
flex-direction: column;
|
| 814 |
+
gap: var(--spacing-unit);
|
| 815 |
+
}
|
| 816 |
+
|
| 817 |
+
.topbar {
|
| 818 |
+
flex-direction: column;
|
| 819 |
+
gap: var(--spacing-unit);
|
| 820 |
+
}
|
| 821 |
+
|
| 822 |
+
.topbar nav {
|
| 823 |
+
flex-direction: column;
|
| 824 |
+
gap: calc(var(--spacing-unit) * 0.75);
|
| 825 |
+
}
|
| 826 |
+
}
|
| 827 |
+
</style>
|
| 828 |
+
</head>
|
| 829 |
+
<body>
|
| 830 |
+
<button class="toggle-btn" id="menuToggle" aria-label="Toggle navigation menu" style="position: fixed; top: 1.5rem; right: 1.5rem; z-index: 1100;">☰</button>
|
| 831 |
+
|
| 832 |
+
<nav class="sidebar" id="sidebar" aria-label="Main navigation">
|
| 833 |
+
<div class="logo">
|
| 834 |
+
<img src="https://via.placeholder.com/50?text=MW" alt="MetaWave Logo">
|
| 835 |
+
<div>
|
| 836 |
+
<div class="logo-text">METAWAVE</div>
|
| 837 |
+
<div class="logo-subtext">Marketing Platform</div>
|
| 838 |
+
</div>
|
| 839 |
+
</div>
|
| 840 |
+
<ul>
|
| 841 |
+
<li><a href="#transactions" aria-label="Go to Transactions"><i class="fas fa-arrows-alt-h"></i> Transactions</a></li>
|
| 842 |
+
<li><a href="#transfer" aria-label="Go to Transfer"><i class="fas fa-exchange-alt"></i> Transfer</a></li>
|
| 843 |
+
<li><a href="#daily-product" aria-label="Go to Daily Product"><i class="fas fa-shopping-cart"></i> Daily Product</a></li>
|
| 844 |
+
<li><a href="#withdraw" aria-label="Go to Withdraw"><i class="fas fa-money-bill-wave"></i> Withdraw</a></li>
|
| 845 |
+
<li><a href="#packages" aria-label="Go to Packages"><i class="fas fa-box"></i> Packages</a></li>
|
| 846 |
+
<li><a href="#loan" aria-label="Go to Loan"><i class="fas fa-hand-holding-usd"></i> Loan</a></li>
|
| 847 |
+
<li><a href="#recharge" aria-label="Go to Recharge"><i class="fas fa-battery-full"></i> Recharge</a></li>
|
| 848 |
+
<li><a href="#agent-approval" aria-label="Go to Agent Approval"><i class="fas fa-user-check"></i> Agent Approval</a></li>
|
| 849 |
+
<li><a href="#access-token" aria-label="Go to Access Token"><i class="fas fa-key"></i> Access Token</a></li>
|
| 850 |
+
<li><a href="#agent-claim" aria-label="Go to Agent Claim"><i class="fas fa-tag"></i> Agent Claim</a></li>
|
| 851 |
+
<li><a href="#team" aria-label="Go to Team"><i class="fas fa-users"></i> Team</a></li>
|
| 852 |
+
<li><a href="#profile" aria-label="Go to Profile"><i class="fas fa-user"></i> Profile</a></li>
|
| 853 |
+
<li><a href="#settings" aria-label="Go to Settings"><i class="fas fa-cog"></i> Settings</a></li>
|
| 854 |
+
<li><a href="#whatsapp-channel" aria-label="Go to Whatsapp Channel"><i class="fab fa-whatsapp"></i> Whatsapp Channel</a></li>
|
| 855 |
+
<li><a href="#customer-care" aria-label="Go to Customer Care"><i class="fas fa-headset"></i> Customer Care</a></li>
|
| 856 |
+
</ul>
|
| 857 |
+
<div class="user-info">
|
| 858 |
+
<div class="user-avatar">Mi</div>
|
| 859 |
+
<div class="user-text">
|
| 860 |
+
Milly <br>
|
| 861 |
+
<span class="user-status">Dormant - Marketer</span>
|
| 862 |
+
</div>
|
| 863 |
+
<i class="fas fa-ellipsis-h" style="margin-left: auto; color: var(--text-light);"></i>
|
| 864 |
+
</div>
|
| 865 |
+
</nav>
|
| 866 |
+
|
| 867 |
+
<main class="main-content" id="mainContent" role="main">
|
| 868 |
+
<header class="topbar">
|
| 869 |
+
<div class="logo">
|
| 870 |
+
<img src="https://via.placeholder.com/40?text=MW" alt="MetaWave">
|
| 871 |
+
<div class="logo-text">MetaWave</div>
|
| 872 |
+
</div>
|
| 873 |
+
<nav>
|
| 874 |
+
<a href="#" aria-label="Go to Transfer">Transfer</a>
|
| 875 |
+
<a href="#" aria-label="Go to Loans">Loans</a>
|
| 876 |
+
<a href="#" aria-label="Go to New Product">New Product</a>
|
| 877 |
+
</nav>
|
| 878 |
+
<div class="right">
|
| 879 |
+
<div class="notification" aria-label="Notifications">
|
| 880 |
+
<i class="fas fa-bell"></i>
|
| 881 |
+
<div class="dot"></div>
|
| 882 |
+
</div>
|
| 883 |
+
<div class="user">
|
| 884 |
+
<div class="user-avatar">Mi</div>
|
| 885 |
+
<span class="user-name">Milly v</span>
|
| 886 |
+
<span class="premium">Premium</span>
|
| 887 |
+
</div>
|
| 888 |
+
<div class="logout" aria-label="Logout">
|
| 889 |
+
<i class="fas fa-sign-out-alt"></i>
|
| 890 |
+
</div>
|
| 891 |
+
<div class="clock" id="clock">01:42 PM EAT, September 08, 2025</div>
|
| 892 |
+
</div>
|
| 893 |
+
</header>
|
| 894 |
+
|
| 895 |
+
<div class="welcome">
|
| 896 |
+
<div class="user-avatar">
|
| 897 |
+
<i class="fas fa-user"></i>
|
| 898 |
+
</div>
|
| 899 |
+
<div class="welcome-text">
|
| 900 |
+
<h2>Welcome back, Milly!</h2>
|
| 901 |
+
<p>User | Meta Package: None</p>
|
| 902 |
+
</div>
|
| 903 |
+
</div>
|
| 904 |
+
|
| 905 |
+
<div class="profile-summary">
|
| 906 |
+
<div class="avatar">Mi</div>
|
| 907 |
+
<div class="details">
|
| 908 |
+
<h3>Milly</h3>
|
| 909 |
+
<p>Joined: March 15, 2024 | Level: Beginner</p>
|
| 910 |
+
</div>
|
| 911 |
+
</div>
|
| 912 |
+
|
| 913 |
+
<div id="dynamic-content">
|
| 914 |
+
<div class="banner">
|
| 915 |
+
<div class="title">Monday Giveaway Cashback! Only at MetaWave</div>
|
| 916 |
+
<p>
|
| 917 |
+
Buy the ♦ NOVA at KES 1,000.00 get Awarded Instantly KES 3,000.00. Buy the ♦ SUPERIOR at KES 2,500.00 get Awarded Instantly KES 7,500.00. Buy the ♦ GOLD at KES 5,500.00 get Awarded Instantly KES 16,500.00.
|
| 918 |
+
</p>
|
| 919 |
+
<div class="footer">♦ Fast payouts via M-Pesa ♦ Powered by MetaWave</div>
|
| 920 |
+
</div>
|
| 921 |
+
|
| 922 |
+
<div class="packages-section">
|
| 923 |
+
<h1>Investment Packages</h1>
|
| 924 |
+
<div class="subtitle">Grow your funds with our automated investment solutions.</div>
|
| 925 |
+
<div class="packages">
|
| 926 |
+
<div class="package-card">
|
| 927 |
+
<div class="package-header">
|
| 928 |
+
<i class="fas fa-coins"></i>
|
| 929 |
+
<div class="name">NOVA 1,000.00 KES</div>
|
| 930 |
+
</div>
|
| 931 |
+
<ul class="package-features">
|
| 932 |
+
<li class="checked"><i class="fas fa-circle-check"></i> Auto Deposit</li>
|
| 933 |
+
<li class="unchecked"><i class="far fa-circle"></i> Auto Withdrawal</li>
|
| 934 |
+
<li class="unchecked"><i class="far fa-circle"></i> Instant Cashback</li>
|
| 935 |
+
</ul>
|
| 936 |
+
<div class="package-award">Award Returns 3,000.00 KES</div>
|
| 937 |
+
<button class="package-button" data-price="1000" data-return="3000">Purchase Now</button>
|
| 938 |
+
</div>
|
| 939 |
+
<div class="package-card">
|
| 940 |
+
<div class="package-header">
|
| 941 |
+
<i class="fas fa-coins"></i>
|
| 942 |
+
<div class="name">SUPERIOR 2,500.00 KES</div>
|
| 943 |
+
</div>
|
| 944 |
+
<ul class="package-features">
|
| 945 |
+
<li class="checked"><i class="fas fa-circle-check"></i> Auto Deposit</li>
|
| 946 |
+
<li class="unchecked"><i class="far fa-circle"></i> Auto Withdrawal</li>
|
| 947 |
+
<li class="unchecked"><i class="far fa-circle"></i> Instant Cashback</li>
|
| 948 |
+
</ul>
|
| 949 |
+
<div class="package-award">Award Returns 7,500.00 KES</div>
|
| 950 |
+
<button class="package-button" data-price="2500" data-return="7500">Purchase Now</button>
|
| 951 |
+
</div>
|
| 952 |
+
<div class="package-card">
|
| 953 |
+
<div class="package-header">
|
| 954 |
+
<i class="fas fa-coins"></i>
|
| 955 |
+
<div class="name">GOLD 5,500.00 KES</div>
|
| 956 |
+
</div>
|
| 957 |
+
<ul class="package-features">
|
| 958 |
+
<li class="checked"><i class="fas fa-circle-check"></i> Auto Deposit</li>
|
| 959 |
+
<li class="unchecked"><i class="far fa-circle"></i> Auto Withdrawal</li>
|
| 960 |
+
<li class="unchecked"><i class="far fa-circle"></i> Instant Cashback</li>
|
| 961 |
+
</ul>
|
| 962 |
+
<div class="package-award">Award Returns 16,500.00 KES</div>
|
| 963 |
+
<button class="package-button" data-price="5500" data-return="16500">Purchase Now</button>
|
| 964 |
+
</div>
|
| 965 |
+
</div>
|
| 966 |
+
</div>
|
| 967 |
+
</div>
|
| 968 |
+
|
| 969 |
+
<div class="balance-cards">
|
| 970 |
+
<div class="card">
|
| 971 |
+
<div class="card-title">Meta Balance</div>
|
| 972 |
+
<div class="meta-balance">
|
| 973 |
+
<div class="balance-amount" id="balance">0 KES</div>
|
| 974 |
+
<div class="balance-actions">
|
| 975 |
+
<button class="btn btn-primary" id="depositBtn">Deposit</button>
|
| 976 |
+
<button class="btn btn-outline" id="withdrawBtn">Withdraw</button>
|
| 977 |
+
</div>
|
| 978 |
+
</div>
|
| 979 |
+
</div>
|
| 980 |
+
</div>
|
| 981 |
+
|
| 982 |
+
<button class="btn btn-outline" id="toggleHistory" style="margin-bottom: var(--spacing-unit);">Toggle Transaction History</button>
|
| 983 |
+
<div class="transaction-history" id="transactionHistory">
|
| 984 |
+
<h3>Transaction History</h3>
|
| 985 |
+
<ul class="transaction-list" id="transactionList">
|
| 986 |
+
<li>No transactions yet.</li>
|
| 987 |
+
</ul>
|
| 988 |
+
</div>
|
| 989 |
+
|
| 990 |
+
<div class="stats">
|
| 991 |
+
<div class="stat-card">
|
| 992 |
+
<div class="stat-label">Total Withdrawals</div>
|
| 993 |
+
<div class="stat-value" id="withdrawals">0 KES</div>
|
| 994 |
+
</div>
|
| 995 |
+
<div class="stat-card">
|
| 996 |
+
<div class="stat-label">Total Deposits</div>
|
| 997 |
+
<div class="stat-value" id="deposits">0 KES</div>
|
| 998 |
+
</div>
|
| 999 |
+
<div class="stat-card">
|
| 1000 |
+
<div class="stat-label">Meta Earnings</div>
|
| 1001 |
+
<div class="stat-value" id="earnings">0 KES</div>
|
| 1002 |
+
</div>
|
| 1003 |
+
<div class="stat-card">
|
| 1004 |
+
<div class="stat-label">Rewards</div>
|
| 1005 |
+
<div class="stat-value" id="rewards">0 KES</div>
|
| 1006 |
+
</div>
|
| 1007 |
+
</div>
|
| 1008 |
+
|
| 1009 |
+
<div class="dashboard-cards">
|
| 1010 |
+
<div class="dashboard-card">
|
| 1011 |
+
<h4>Welcome back, Milly!</h4>
|
| 1012 |
+
<p>Meta Balance</p>
|
| 1013 |
+
<h2 id="dashboard-balance">0 KES</h2>
|
| 1014 |
+
<button class="dashboard-btn" id="redeemBtn">Redeem</button>
|
| 1015 |
+
</div>
|
| 1016 |
+
<div class="dashboard-card">
|
| 1017 |
+
<p>Total Deposits</p>
|
| 1018 |
+
<h2 id="dashboard-deposits">0 KES</h2>
|
| 1019 |
+
<button class="btn btn-primary" id="dashboard-depositBtn">Deposit</button>
|
| 1020 |
+
</div>
|
| 1021 |
+
<div class="dashboard-card">
|
| 1022 |
+
<p>Total Withdrawals</p>
|
| 1023 |
+
<h2 id="dashboard-withdrawals">0 KES</h2>
|
| 1024 |
+
<button class="btn btn-primary" id="dashboard-withdrawBtn">Withdraw</button>
|
| 1025 |
+
</div>
|
| 1026 |
+
<div class="dashboard-card">
|
| 1027 |
+
<p>Meta Earnings</p>
|
| 1028 |
+
<h2 id="dashboard-earnings">0 KES</h2>
|
| 1029 |
+
</div>
|
| 1030 |
+
<div class="dashboard-card">
|
| 1031 |
+
<p>Rewards</p>
|
| 1032 |
+
<h2 id="dashboard-rewards">0 KES</h2>
|
| 1033 |
+
</div>
|
| 1034 |
+
</div>
|
| 1035 |
+
</main>
|
| 1036 |
+
|
| 1037 |
+
<div class="modal" id="depositModal">
|
| 1038 |
+
<div class="modal-content">
|
| 1039 |
+
<div class="modal-header">
|
| 1040 |
+
<h3>Deposit Funds</h3>
|
| 1041 |
+
<span class="close" id="closeDeposit">×</span>
|
| 1042 |
+
</div>
|
| 1043 |
+
<div class="form-group">
|
| 1044 |
+
<label for="depositAmount">Amount (KES)</label>
|
| 1045 |
+
<input type="number" id="depositAmount" placeholder="Enter amount" aria-label="Deposit amount">
|
| 1046 |
+
</div>
|
| 1047 |
+
<div class="form-group">
|
| 1048 |
+
<label for="depositMethod">Payment Method</label>
|
| 1049 |
+
<select id="depositMethod" aria-label="Payment method">
|
| 1050 |
+
<option value="mpesa">M-Pesa</option>
|
| 1051 |
+
<option value="card">Credit Card</option>
|
| 1052 |
+
<option value="bank">Bank Transfer</option>
|
| 1053 |
+
</select>
|
| 1054 |
+
</div>
|
| 1055 |
+
<button class="btn btn-primary" style="width: 100%;" id="confirmDeposit">Confirm Deposit</button>
|
| 1056 |
+
</div>
|
| 1057 |
+
</div>
|
| 1058 |
+
|
| 1059 |
+
<div class="modal" id="withdrawModal">
|
| 1060 |
+
<div class="modal-content">
|
| 1061 |
+
<div class="modal-header">
|
| 1062 |
+
<h3>Withdraw Funds</h3>
|
| 1063 |
+
<span class="close" id="closeWithdraw">×</span>
|
| 1064 |
+
</div>
|
| 1065 |
+
<div class="form-group">
|
| 1066 |
+
<label for="withdrawAmount">Amount (KES)</label>
|
| 1067 |
+
<input type="number" id="withdrawAmount" placeholder="Enter amount" aria-label="Withdraw amount">
|
| 1068 |
+
</div>
|
| 1069 |
+
<div class="form-group">
|
| 1070 |
+
<label for="withdrawMethod">Withdrawal Method</label>
|
| 1071 |
+
<select id="withdrawMethod" aria-label="Withdrawal method">
|
| 1072 |
+
<option value="mpesa">M-Pesa</option>
|
| 1073 |
+
<option value="bank">Bank Transfer</option>
|
| 1074 |
+
</select>
|
| 1075 |
+
</div>
|
| 1076 |
+
<button class="btn btn-primary" style="width: 100%;" id="confirmWithdraw">Confirm Withdrawal</button>
|
| 1077 |
+
</div>
|
| 1078 |
+
</div>
|
| 1079 |
+
|
| 1080 |
+
<div class="modal" id="logoutModal">
|
| 1081 |
+
<div class="modal-content">
|
| 1082 |
+
<div class="modal-header">
|
| 1083 |
+
<h3>Confirm Logout</h3>
|
| 1084 |
+
<span class="close" id="closeLogout">×</span>
|
| 1085 |
+
</div>
|
| 1086 |
+
<p>Are you sure you want to logout?</p>
|
| 1087 |
+
<div style="display: flex; gap: var(--spacing-unit);">
|
| 1088 |
+
<button class="btn btn-primary" id="confirmLogout" style="width: 100%;">Yes</button>
|
| 1089 |
+
<button class="btn btn-outline" id="cancelLogout" style="width: 100%;">No</button>
|
| 1090 |
+
</div>
|
| 1091 |
+
</div>
|
| 1092 |
+
</div>
|
| 1093 |
+
|
| 1094 |
+
<script>
|
| 1095 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 1096 |
+
const menuToggle = document.getElementById('menuToggle');
|
| 1097 |
+
const sidebar = document.getElementById('sidebar');
|
| 1098 |
+
const mainContent = document.querySelector('.main-content');
|
| 1099 |
+
const dynamicContent = document.getElementById('dynamic-content');
|
| 1100 |
+
const clock = document.getElementById('clock');
|
| 1101 |
+
const logoutIcon = document.querySelector('.logout');
|
| 1102 |
+
const logoutModal = document.getElementById('logoutModal');
|
| 1103 |
+
const closeLogout = document.getElementById('closeLogout');
|
| 1104 |
+
const confirmLogout = document.getElementById('confirmLogout');
|
| 1105 |
+
const cancelLogout = document.getElementById('cancelLogout');
|
| 1106 |
+
|
| 1107 |
+
menuToggle.addEventListener('click', function() {
|
| 1108 |
+
sidebar.classList.toggle('collapsed');
|
| 1109 |
+
mainContent.classList.toggle('expanded');
|
| 1110 |
+
menuToggle.innerHTML = sidebar.classList.contains('collapsed') ? '☰' : '×';
|
| 1111 |
+
});
|
| 1112 |
+
|
| 1113 |
+
const sections = {
|
| 1114 |
+
'#transactions': '<h2>Transactions</h2><p>View your recent transactions here. Last updated: 01:42 PM EAT, September 08, 2025.</p>',
|
| 1115 |
+
'#transfer': '<h2>Transfer</h2><p>Initiate a transfer to another account. Ensure funds are available.</p>',
|
| 1116 |
+
'#daily-product': '<h2>Daily Product</h2><p>Check today\'s featured product for investment. Updated: 01:42 PM EAT, September 08, 2025.</p>',
|
| 1117 |
+
'#withdraw': '<h2>Withdraw</h2><p>Withdraw your funds instantly via M-Pesa.</p>',
|
| 1118 |
+
'#packages': '<div class="packages-section"><h1>Investment Packages</h1><div class="subtitle">Grow your funds with our automated investment solutions.</div><div class="packages"><div class="package-card"><div class="package-header"><i class="fas fa-coins"></i><div class="name">NOVA 1,000.00 KES</div></div><ul class="package-features"><li class="checked"><i class="fas fa-circle-check"></i> Auto Deposit</li><li class="unchecked"><i class="far fa-circle"></i> Auto Withdrawal</li><li class="unchecked"><i class="far fa-circle"></i> Instant Cashback</li></ul><div class="package-award">Award Returns 3,000.00 KES</div><button class="package-button" data-price="1000" data-return="3000">Purchase Now</button></div><div class="package-card"><div class="package-header"><i class="fas fa-coins"></i><div class="name">SUPERIOR 2,500.00 KES</div></div><ul class="package-features"><li class="checked"><i class="fas fa-circle-check"></i> Auto Deposit</li><li class="unchecked"><i class="far fa-circle"></i> Auto Withdrawal</li><li class="unchecked"><i class="far fa-circle"></i> Instant Cashback</li></ul><div class="package-award">Award Returns 7,500.00 KES</div><button class="package-button" data-price="2500" data-return="7500">Purchase Now</button></div><div class="package-card"><div class="package-header"><i class="fas fa-coins"></i><div class="name">GOLD 5,500.00 KES</div></div><ul class="package-features"><li class="checked"><i class="fas fa-circle-check"></i> Auto Deposit</li><li class="unchecked"><i class="far fa-circle"></i> Auto Withdrawal</li><li class="unchecked"><i class="far fa-circle"></i> Instant Cashback</li></ul><div class="package-award">Award Returns 16,500.00 KES</div><button class="package-button" data-price="5500" data-return="16500">Purchase Now</button></div></div></div>',
|
| 1119 |
+
'#loan': '<h2>Loan</h2><p>Apply for a loan with flexible repayment options.</p>',
|
| 1120 |
+
'#recharge': '<h2>Recharge</h2><p>Recharge your account for continued access.</p>',
|
| 1121 |
+
'#agent-approval': '<h2>Agent Approval</h2><p>Review and approve agent requests.</p>',
|
| 1122 |
+
'#access-token': '<h2>Access Token</h2><p>Manage your access tokens securely.</p>',
|
| 1123 |
+
'#agent-claim': '<h2>Agent Claim</h2><p>Claim your agent rewards and bonuses.</p>',
|
| 1124 |
+
'#team': '<h2>Team</h2><p>Manage your team members and roles.</p>',
|
| 1125 |
+
'#profile': '<h2>Profile</h2><p>Update your personal information and settings. Last updated: 01:42 PM EAT, September 08, 2025.</p>',
|
| 1126 |
+
'#settings': '<h2>Settings</h2><p>Customize your account preferences.</p>',
|
| 1127 |
+
'#whatsapp-channel': '<h2>Whatsapp Channel</h2><p>Join our Whatsapp community for updates.</p>',
|
| 1128 |
+
'#customer-care': '<h2>Customer Care</h2><p>Contact support for assistance. Available 24/7.</p>'
|
| 1129 |
+
};
|
| 1130 |
+
|
| 1131 |
+
document.querySelectorAll('.sidebar ul li a').forEach(link => {
|
| 1132 |
+
link.addEventListener('click', function(e) {
|
| 1133 |
+
e.preventDefault();
|
| 1134 |
+
const sectionId = this.getAttribute('href');
|
| 1135 |
+
if (sections[sectionId]) {
|
| 1136 |
+
dynamicContent.innerHTML = sections[sectionId];
|
| 1137 |
+
document.querySelectorAll('.package-button').forEach(button => {
|
| 1138 |
+
button.addEventListener('click', handlePurchase);
|
| 1139 |
+
});
|
| 1140 |
+
}
|
| 1141 |
+
});
|
| 1142 |
+
});
|
| 1143 |
+
|
| 1144 |
+
function updateClock() {
|
| 1145 |
+
const now = new Date();
|
| 1146 |
+
const options = { hour: '2-digit', minute: '2-digit', hour12: true, timeZone: 'Africa/Nairobi' };
|
| 1147 |
+
const time = now.toLocaleTimeString('en-US', options);
|
| 1148 |
+
const date = now.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
|
| 1149 |
+
clock.textContent = `${time} EAT, ${date}`;
|
| 1150 |
+
}
|
| 1151 |
+
updateClock();
|
| 1152 |
+
setInterval(updateClock, 1000);
|
| 1153 |
+
|
| 1154 |
+
function handlePurchase(e) {
|
| 1155 |
+
const price = parseFloat(e.target.getAttribute('data-price'));
|
| 1156 |
+
const reward = parseFloat(e.target.getAttribute('data-return'));
|
| 1157 |
+
if (balance >= price) {
|
| 1158 |
+
balance -= price;
|
| 1159 |
+
rewards += reward;
|
| 1160 |
+
const transaction = `Purchased ${e.target.closest('.package-card').querySelector('.name').textContent} at ${price} KES - Awarded ${reward} KES | ${new Date().toLocaleString('en-US', { timeZone: 'Africa/Nairobi' })}`;
|
| 1161 |
+
addTransaction(transaction);
|
| 1162 |
+
updateUI();
|
| 1163 |
+
alert(`Successfully purchased ${e.target.closest('.package-card').querySelector('.name').textContent} with ${price} KES! Awarded ${reward} KES.`);
|
| 1164 |
+
} else {
|
| 1165 |
+
alert('Insufficient balance to purchase this package.');
|
| 1166 |
+
}
|
| 1167 |
+
}
|
| 1168 |
+
|
| 1169 |
+
document.querySelectorAll('.package-button').forEach(button => {
|
| 1170 |
+
button.addEventListener('click', handlePurchase);
|
| 1171 |
+
});
|
| 1172 |
+
|
| 1173 |
+
const toggleHistory = document.getElementById('toggleHistory');
|
| 1174 |
+
const transactionHistory = document.getElementById('transactionHistory');
|
| 1175 |
+
const transactionList = document.getElementById('transactionList');
|
| 1176 |
+
function addTransaction(text) {
|
| 1177 |
+
const li = document.createElement('li');
|
| 1178 |
+
li.textContent = text;
|
| 1179 |
+
transactionList.insertBefore(li, transactionList.firstChild);
|
| 1180 |
+
if (transactionList.children.length > 5) {
|
| 1181 |
+
transactionList.removeChild(transactionList.lastChild);
|
| 1182 |
+
}
|
| 1183 |
+
}
|
| 1184 |
+
toggleHistory.addEventListener('click', () => {
|
| 1185 |
+
transactionHistory.classList.toggle('active');
|
| 1186 |
+
});
|
| 1187 |
+
|
| 1188 |
+
let balance = 0;
|
| 1189 |
+
let totalDeposits = 0;
|
| 1190 |
+
let totalWithdrawals = 0;
|
| 1191 |
+
let rewards = 0;
|
| 1192 |
+
const balanceEl = document.getElementById('balance');
|
| 1193 |
+
const depositsEl = document.getElementById('deposits');
|
| 1194 |
+
const withdrawalsEl = document.getElementById('withdrawals');
|
| 1195 |
+
const rewardsEl = document.getElementById('rewards');
|
| 1196 |
+
const earningsEl = document.getElementById('earnings');
|
| 1197 |
+
const dashboardBalanceEl = document.getElementById('dashboard-balance');
|
| 1198 |
+
const dashboardDepositsEl = document.getElementById('dashboard-deposits');
|
| 1199 |
+
const dashboardWithdrawalsEl = document.getElementById('dashboard-withdrawals');
|
| 1200 |
+
const dashboardRewardsEl = document.getElementById('dashboard-rewards');
|
| 1201 |
+
const dashboardEarningsEl = document.getElementById('dashboard-earnings');
|
| 1202 |
+
|
| 1203 |
+
const depositBtn = document.getElementById('depositBtn');
|
| 1204 |
+
const dashboardDepositBtn = document.getElementById('dashboard-depositBtn');
|
| 1205 |
+
const depositModal = document.getElementById('depositModal');
|
| 1206 |
+
const closeDeposit = document.getElementById('closeDeposit');
|
| 1207 |
+
const confirmDeposit = document.getElementById('confirmDeposit');
|
| 1208 |
+
|
| 1209 |
+
depositBtn.addEventListener('click', () => depositModal.style.display = 'flex');
|
| 1210 |
+
dashboardDepositBtn.addEventListener('click', () => depositModal.style.display = 'flex');
|
| 1211 |
+
closeDeposit.addEventListener('click', () => depositModal.style.display = 'none');
|
| 1212 |
+
confirmDeposit.addEventListener('click', () => {
|
| 1213 |
+
const amount = parseFloat(document.getElementById('depositAmount').value);
|
| 1214 |
+
const method = document.getElementById('depositMethod').value;
|
| 1215 |
+
if (!isNaN(amount) && amount > 0) {
|
| 1216 |
+
totalDeposits += amount;
|
| 1217 |
+
balance += amount;
|
| 1218 |
+
rewards += amount * 0.1;
|
| 1219 |
+
const transaction = `Deposited ${amount} KES via ${method} | ${new Date().toLocaleString('en-US', { timeZone: 'Africa/Nairobi' })}`;
|
| 1220 |
+
addTransaction(transaction);
|
| 1221 |
+
updateUI();
|
| 1222 |
+
depositModal.style.display = 'none';
|
| 1223 |
+
document.getElementById('depositAmount').value = '';
|
| 1224 |
+
alert(`Successfully deposited ${amount} KES via ${method}`);
|
| 1225 |
+
} else {
|
| 1226 |
+
alert('Please enter a valid amount');
|
| 1227 |
+
}
|
| 1228 |
+
});
|
| 1229 |
+
|
| 1230 |
+
const withdrawBtn = document.getElementById('withdrawBtn');
|
| 1231 |
+
const dashboardWithdrawBtn = document.getElementById('dashboard-withdrawBtn');
|
| 1232 |
+
const withdrawModal = document.getElementById('withdrawModal');
|
| 1233 |
+
const closeWithdraw = document.getElementById('closeWithdraw');
|
| 1234 |
+
const confirmWithdraw = document.getElementById('confirmWithdraw');
|
| 1235 |
+
|
| 1236 |
+
withdrawBtn.addEventListener('click', () => withdrawModal.style.display = 'flex');
|
| 1237 |
+
dashboardWithdrawBtn.addEventListener('click', () => withdrawModal.style.display = 'flex');
|
| 1238 |
+
closeWithdraw.addEventListener('click', () => withdrawModal.style.display = 'none');
|
| 1239 |
+
confirmWithdraw.addEventListener('click', () => {
|
| 1240 |
+
const amount = parseFloat(document.getElementById('withdrawAmount').value);
|
| 1241 |
+
const method = document.getElementById('withdrawMethod').value;
|
| 1242 |
+
if (!isNaN(amount) && amount > 0) {
|
| 1243 |
+
if (amount > balance) {
|
| 1244 |
+
alert('Insufficient balance');
|
| 1245 |
+
return;
|
| 1246 |
+
}
|
| 1247 |
+
totalWithdrawals += amount;
|
| 1248 |
+
balance -= amount;
|
| 1249 |
+
const transaction = `Withdrew ${amount} KES via ${method} | ${new Date().toLocaleString('en-US', { timeZone: 'Africa/Nairobi' })}`;
|
| 1250 |
+
addTransaction(transaction);
|
| 1251 |
+
updateUI();
|
| 1252 |
+
withdrawModal.style.display = 'none';
|
| 1253 |
+
document.getElementById('withdrawAmount').value = '';
|
| 1254 |
+
alert(`Successfully withdrew ${amount} KES via ${method}`);
|
| 1255 |
+
} else {
|
| 1256 |
+
alert('Please enter a valid amount');
|
| 1257 |
+
}
|
| 1258 |
+
});
|
| 1259 |
+
|
| 1260 |
+
const redeemBtn = document.getElementById('redeemBtn');
|
| 1261 |
+
redeemBtn.addEventListener('click', () => {
|
| 1262 |
+
if (rewards > 0) {
|
| 1263 |
+
balance += rewards;
|
| 1264 |
+
const transaction = `Redeemed ${rewards} KES rewards | ${new Date().toLocaleString('en-US', { timeZone: 'Africa/Nairobi' })}`;
|
| 1265 |
+
addTransaction(transaction);
|
| 1266 |
+
rewards = 0;
|
| 1267 |
+
updateUI();
|
| 1268 |
+
alert("Rewards redeemed successfully!");
|
| 1269 |
+
} else {
|
| 1270 |
+
alert("No rewards available!");
|
| 1271 |
+
}
|
| 1272 |
+
});
|
| 1273 |
+
|
| 1274 |
+
window.addEventListener('click', (event) => {
|
| 1275 |
+
if (event.target === depositModal) depositModal.style.display = 'none';
|
| 1276 |
+
if (event.target === withdrawModal) withdrawModal.style.display = 'none';
|
| 1277 |
+
if (event.target === logoutModal) logoutModal.style.display = 'none';
|
| 1278 |
+
});
|
| 1279 |
+
|
| 1280 |
+
function updateUI() {
|
| 1281 |
+
balanceEl.textContent = balance.toLocaleString() + ' KES';
|
| 1282 |
+
depositsEl.textContent = totalDeposits.toLocaleString() + ' KES';
|
| 1283 |
+
withdrawalsEl.textContent = totalWithdrawals.toLocaleString() + ' KES';
|
| 1284 |
+
rewardsEl.textContent = rewards.toLocaleString() + ' KES';
|
| 1285 |
+
earningsEl.textContent = (totalDeposits - totalWithdrawals).toLocaleString() + ' KES';
|
| 1286 |
+
dashboardBalanceEl.textContent = balance.toLocaleString() + ' KES';
|
| 1287 |
+
dashboardDepositsEl.textContent = totalDeposits.toLocaleString() + ' KES';
|
| 1288 |
+
dashboardWithdrawalsEl.textContent = totalWithdrawals.toLocaleString() + ' KES';
|
| 1289 |
+
dashboardRewardsEl.textContent = rewards.toLocaleString() + ' KES';
|
| 1290 |
+
dashboardEarningsEl.textContent = (totalDeposits - totalWithdrawals).toLocaleString() + ' KES';
|
| 1291 |
+
}
|
| 1292 |
+
|
| 1293 |
+
setTimeout(() => {
|
| 1294 |
+
balance = 5250;
|
| 1295 |
+
totalDeposits = 6450;
|
| 1296 |
+
totalWithdrawals = 1200;
|
| 1297 |
+
rewards = 1050;
|
| 1298 |
+
updateUI();
|
| 1299 |
+
addTransaction('Initial balance loaded: 5250 KES | 01:42 PM EAT, September 08, 2025');
|
| 1300 |
+
}, 1000);
|
| 1301 |
+
|
| 1302 |
+
logoutIcon.addEventListener('click', () => logoutModal.style.display = 'flex');
|
| 1303 |
+
closeLogout.addEventListener('click', () => logoutModal.style.display = 'none');
|
| 1304 |
+
cancelLogout.addEventListener('click', () => logoutModal.style.display = 'none');
|
| 1305 |
+
confirmLogout.addEventListener('click', () => {
|
| 1306 |
+
alert('Logging out...');
|
| 1307 |
+
logoutModal.style.display = 'none';
|
| 1308 |
+
window.location.href = '/login';
|
| 1309 |
+
});
|
| 1310 |
+
});
|
| 1311 |
+
</script>
|
| 1312 |
+
</body>
|
| 1313 |
+
</html>
|
jweb/ac1/signup.php
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// signup.php - Enhanced user registration with session tracking
|
| 3 |
+
session_start();
|
| 4 |
+
include_once 'db.php';
|
| 5 |
+
|
| 6 |
+
// Check if database connection is available
|
| 7 |
+
if (!$db) {
|
| 8 |
+
http_response_code(503);
|
| 9 |
+
echo json_encode(array("success" => false, "message" => "Service temporarily unavailable."));
|
| 10 |
+
exit;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
// Get posted data
|
| 14 |
+
$input = file_get_contents("php://input");
|
| 15 |
+
$data = json_decode($input);
|
| 16 |
+
|
| 17 |
+
if (json_last_error() !== JSON_ERROR_NONE) {
|
| 18 |
+
http_response_code(400);
|
| 19 |
+
echo json_encode(array("success" => false, "message" => "Invalid JSON data."));
|
| 20 |
+
exit;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
// Check if data is not empty
|
| 24 |
+
if (
|
| 25 |
+
!empty($data->username) &&
|
| 26 |
+
!empty($data->email) &&
|
| 27 |
+
!empty($data->country) &&
|
| 28 |
+
!empty($data->phone) &&
|
| 29 |
+
!empty($data->password) &&
|
| 30 |
+
!empty($data->confirm_password)
|
| 31 |
+
) {
|
| 32 |
+
// Validate input
|
| 33 |
+
if ($data->password !== $data->confirm_password) {
|
| 34 |
+
http_response_code(400);
|
| 35 |
+
echo json_encode(array("success" => false, "message" => "Passwords do not match."));
|
| 36 |
+
exit;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
if (strlen($data->password) < 6) {
|
| 40 |
+
http_response_code(400);
|
| 41 |
+
echo json_encode(array("success" => false, "message" => "Password must be at least 6 characters."));
|
| 42 |
+
exit;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
if (!filter_var($data->email, FILTER_VALIDATE_EMAIL)) {
|
| 46 |
+
http_response_code(400);
|
| 47 |
+
echo json_encode(array("success" => false, "message" => "Invalid email format."));
|
| 48 |
+
exit;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
// Check if user already exists
|
| 52 |
+
$query = "SELECT id FROM users WHERE username = :username OR email = :email";
|
| 53 |
+
$stmt = $db->prepare($query);
|
| 54 |
+
$stmt->bindParam(":username", $data->username);
|
| 55 |
+
$stmt->bindParam(":email", $data->email);
|
| 56 |
+
|
| 57 |
+
try {
|
| 58 |
+
$stmt->execute();
|
| 59 |
+
} catch(PDOException $e) {
|
| 60 |
+
error_log("Database error: " . $e->getMessage());
|
| 61 |
+
http_response_code(500);
|
| 62 |
+
echo json_encode(array("success" => false, "message" => "Database error occurred."));
|
| 63 |
+
exit;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
if ($stmt->rowCount() > 0) {
|
| 67 |
+
http_response_code(409);
|
| 68 |
+
echo json_encode(array("success" => false, "message" => "User already exists with this username or email."));
|
| 69 |
+
exit;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
// Hash password
|
| 73 |
+
$hashed_password = password_hash($data->password, PASSWORD_DEFAULT);
|
| 74 |
+
|
| 75 |
+
// Generate referral code
|
| 76 |
+
$referral_code = strtoupper(substr($data->username, 0, 3) . bin2hex(random_bytes(3)));
|
| 77 |
+
|
| 78 |
+
// Insert new user
|
| 79 |
+
$query = "INSERT INTO users
|
| 80 |
+
SET username = :username, email = :email, country = :country,
|
| 81 |
+
phone_number = :phone, password_hash = :password, referral_code = :referral_code,
|
| 82 |
+
user_type = 'marketer', tier = 'Basic', package = 'None', balance = 0.00,
|
| 83 |
+
total_deposits = 0.00, total_withdrawals = 0.00, rewards = 0.00, meta_earnings = 0.00,
|
| 84 |
+
pin_hash = '', is_active = 1, account_status = 'active'";
|
| 85 |
+
|
| 86 |
+
$stmt = $db->prepare($query);
|
| 87 |
+
|
| 88 |
+
// Sanitize and bind values
|
| 89 |
+
$username = htmlspecialchars(strip_tags($data->username));
|
| 90 |
+
$email = htmlspecialchars(strip_tags($data->email));
|
| 91 |
+
$country = htmlspecialchars(strip_tags($data->country));
|
| 92 |
+
$phone = htmlspecialchars(strip_tags($data->phone));
|
| 93 |
+
|
| 94 |
+
$stmt->bindParam(":username", $username);
|
| 95 |
+
$stmt->bindParam(":email", $email);
|
| 96 |
+
$stmt->bindParam(":country", $country);
|
| 97 |
+
$stmt->bindParam(":phone", $phone);
|
| 98 |
+
$stmt->bindParam(":password", $hashed_password);
|
| 99 |
+
$stmt->bindParam(":referral_code", $referral_code);
|
| 100 |
+
|
| 101 |
+
// Execute query
|
| 102 |
+
try {
|
| 103 |
+
if ($stmt->execute()) {
|
| 104 |
+
$user_id = $db->lastInsertId();
|
| 105 |
+
|
| 106 |
+
// Create session
|
| 107 |
+
$ip_address = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
| 108 |
+
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
|
| 109 |
+
$session_id = $sessionManager->createSession($user_id, $ip_address, $user_agent);
|
| 110 |
+
|
| 111 |
+
if ($session_id) {
|
| 112 |
+
// Log activity
|
| 113 |
+
$sessionManager->logActivity($user_id, 'registration', 'User registered successfully', $ip_address, $user_agent);
|
| 114 |
+
$sessionManager->updateLastLogin($user_id);
|
| 115 |
+
|
| 116 |
+
// Set session variables
|
| 117 |
+
$_SESSION['user_id'] = $user_id;
|
| 118 |
+
$_SESSION['username'] = $username;
|
| 119 |
+
$_SESSION['email'] = $email;
|
| 120 |
+
$_SESSION['tier'] = 'Basic';
|
| 121 |
+
$_SESSION['package'] = 'None';
|
| 122 |
+
$_SESSION['balance'] = 0.00;
|
| 123 |
+
$_SESSION['total_deposits'] = 0.00;
|
| 124 |
+
$_SESSION['total_withdrawals'] = 0.00;
|
| 125 |
+
$_SESSION['rewards'] = 0.00;
|
| 126 |
+
$_SESSION['session_id'] = $session_id;
|
| 127 |
+
$_SESSION['logged_in'] = true;
|
| 128 |
+
$_SESSION['login_time'] = time();
|
| 129 |
+
|
| 130 |
+
http_response_code(201);
|
| 131 |
+
echo json_encode(array(
|
| 132 |
+
"success" => true,
|
| 133 |
+
"message" => "User registered successfully.",
|
| 134 |
+
"redirect" => "src/pages/index.php",
|
| 135 |
+
"user_data" => [
|
| 136 |
+
"user_id" => $user_id,
|
| 137 |
+
"username" => $username,
|
| 138 |
+
"email" => $email,
|
| 139 |
+
"tier" => "Basic"
|
| 140 |
+
]
|
| 141 |
+
));
|
| 142 |
+
} else {
|
| 143 |
+
throw new Exception("Failed to create session");
|
| 144 |
+
}
|
| 145 |
+
} else {
|
| 146 |
+
http_response_code(503);
|
| 147 |
+
echo json_encode(array("success" => false, "message" => "Unable to create user."));
|
| 148 |
+
}
|
| 149 |
+
} catch(PDOException $e) {
|
| 150 |
+
error_log("Insert error: " . $e->getMessage());
|
| 151 |
+
http_response_code(500);
|
| 152 |
+
echo json_encode(array("success" => false, "message" => "Database error occurred."));
|
| 153 |
+
} catch(Exception $e) {
|
| 154 |
+
error_log("Session error: " . $e->getMessage());
|
| 155 |
+
http_response_code(500);
|
| 156 |
+
echo json_encode(array("success" => false, "message" => "Session creation failed."));
|
| 157 |
+
}
|
| 158 |
+
} else {
|
| 159 |
+
http_response_code(400);
|
| 160 |
+
echo json_encode(array("success" => false, "message" => "Unable to create user. Data is incomplete."));
|
| 161 |
+
}
|
| 162 |
+
?>
|
jweb/ac1/src/admin/admin-approval.php
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
session_start();
|
| 3 |
+
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true || $_SESSION['user_type'] !== 'admin') {
|
| 4 |
+
header('Location: ../../index.php');
|
| 5 |
+
exit;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
require_once '../api/agent-functions.php';
|
| 9 |
+
|
| 10 |
+
// Handle form submissions
|
| 11 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
| 12 |
+
if (isset($_POST['action'])) {
|
| 13 |
+
if ($_POST['action'] === 'review_agent') {
|
| 14 |
+
$agentId = $_POST['agent_id'];
|
| 15 |
+
$status = $_POST['status'];
|
| 16 |
+
$notes = $_POST['notes'] ?? '';
|
| 17 |
+
|
| 18 |
+
if (reviewAgentApplication($agentId, $_SESSION['user_id'], $status, $notes)) {
|
| 19 |
+
$message = "Agent application " . ($status === 'approved' ? 'approved' : 'rejected') . " successfully!";
|
| 20 |
+
} else {
|
| 21 |
+
$error = "Failed to update agent application.";
|
| 22 |
+
}
|
| 23 |
+
} elseif ($_POST['action'] === 'review_advertisement') {
|
| 24 |
+
$adId = $_POST['advertisement_id'];
|
| 25 |
+
$status = $_POST['status'];
|
| 26 |
+
$notes = $_POST['notes'] ?? '';
|
| 27 |
+
|
| 28 |
+
if (reviewAdvertisement($adId, $_SESSION['user_id'], $status, $notes)) {
|
| 29 |
+
$message = "Advertisement " . ($status === 'approved' ? 'approved' : 'rejected') . " successfully!";
|
| 30 |
+
} else {
|
| 31 |
+
$error = "Failed to update advertisement.";
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
}
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
// Get data for admin
|
| 38 |
+
$pendingAgents = getPendingAgents(0); // Get all pending agents
|
| 39 |
+
$pendingAds = getAdvertisementsForApproval('pending');
|
| 40 |
+
$adStats = getAdvertisementStats();
|
| 41 |
+
?>
|
| 42 |
+
|
| 43 |
+
<!DOCTYPE html>
|
| 44 |
+
<html lang="en">
|
| 45 |
+
<head>
|
| 46 |
+
<meta charset="UTF-8">
|
| 47 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 48 |
+
<title>Admin - Approval System</title>
|
| 49 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 50 |
+
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700;800&display=swap" rel="stylesheet">
|
| 51 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 52 |
+
</head>
|
| 53 |
+
<body class="bg-gray-100 font-sans">
|
| 54 |
+
<div class="container mx-auto p-4">
|
| 55 |
+
<h1 class="text-3xl font-bold mb-6">Admin Approval System</h1>
|
| 56 |
+
|
| 57 |
+
<?php if (isset($message)): ?>
|
| 58 |
+
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded mb-4">
|
| 59 |
+
<?php echo $message; ?>
|
| 60 |
+
</div>
|
| 61 |
+
<?php endif; ?>
|
| 62 |
+
|
| 63 |
+
<?php if (isset($error)): ?>
|
| 64 |
+
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4">
|
| 65 |
+
<?php echo $error; ?>
|
| 66 |
+
</div>
|
| 67 |
+
<?php endif; ?>
|
| 68 |
+
|
| 69 |
+
<!-- Statistics -->
|
| 70 |
+
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
|
| 71 |
+
<div class="bg-white p-4 rounded shadow">
|
| 72 |
+
<h3 class="font-bold">Pending Agents</h3>
|
| 73 |
+
<p class="text-2xl"><?php echo count($pendingAgents); ?></p>
|
| 74 |
+
</div>
|
| 75 |
+
<div class="bg-white p-4 rounded shadow">
|
| 76 |
+
<h3 class="font-bold">Pending Ads</h3>
|
| 77 |
+
<p class="text-2xl"><?php echo count($pendingAds); ?></p>
|
| 78 |
+
</div>
|
| 79 |
+
<div class="bg-white p-4 rounded shadow">
|
| 80 |
+
<h3 class="font-bold">Total Revenue</h3>
|
| 81 |
+
<p class="text-2xl">KES <?php echo number_format($adStats['total_revenue'], 2); ?></p>
|
| 82 |
+
</div>
|
| 83 |
+
<div class="bg-white p-4 rounded shadow">
|
| 84 |
+
<h3 class="font-bold">Pending Revenue</h3>
|
| 85 |
+
<p class="text-2xl">KES <?php echo number_format($adStats['pending_revenue'], 2); ?></p>
|
| 86 |
+
</div>
|
| 87 |
+
</div>
|
| 88 |
+
|
| 89 |
+
<!-- Pending Advertisements -->
|
| 90 |
+
<div class="bg-white rounded shadow mb-6">
|
| 91 |
+
<div class="p-4 border-b">
|
| 92 |
+
<h2 class="text-xl font-bold">Pending Advertisements</h2>
|
| 93 |
+
</div>
|
| 94 |
+
<div class="p-4">
|
| 95 |
+
<?php if (empty($pendingAds)): ?>
|
| 96 |
+
<p class="text-gray-500">No pending advertisements</p>
|
| 97 |
+
<?php else: ?>
|
| 98 |
+
<?php foreach ($pendingAds as $ad): ?>
|
| 99 |
+
<div class="border rounded p-4 mb-4">
|
| 100 |
+
<div class="flex justify-between items-start">
|
| 101 |
+
<div>
|
| 102 |
+
<h3 class="font-bold"><?php echo htmlspecialchars($ad['title']); ?></h3>
|
| 103 |
+
<p class="text-gray-600">By: <?php echo htmlspecialchars($ad['advertiser_name']); ?></p>
|
| 104 |
+
<p class="text-gray-600">Budget: KES <?php echo number_format($ad['budget'], 2); ?></p>
|
| 105 |
+
<p class="text-gray-600">Platform: <?php echo ucfirst($ad['target_platform']); ?></p>
|
| 106 |
+
<?php if ($ad['agent_name']): ?>
|
| 107 |
+
<p class="text-gray-600">Agent: <?php echo htmlspecialchars($ad['agent_name']); ?></p>
|
| 108 |
+
<?php endif; ?>
|
| 109 |
+
</div>
|
| 110 |
+
<div class="flex gap-2">
|
| 111 |
+
<button onclick="reviewAd(<?php echo $ad['id']; ?>, 'approved')"
|
| 112 |
+
class="bg-green-500 text-white px-3 py-1 rounded">Approve</button>
|
| 113 |
+
<button onclick="reviewAd(<?php echo $ad['id']; ?>, 'rejected')"
|
| 114 |
+
class="bg-red-500 text-white px-3 py-1 rounded">Reject</button>
|
| 115 |
+
</div>
|
| 116 |
+
</div>
|
| 117 |
+
</div>
|
| 118 |
+
<?php endforeach; ?>
|
| 119 |
+
<?php endif; ?>
|
| 120 |
+
</div>
|
| 121 |
+
</div>
|
| 122 |
+
|
| 123 |
+
<!-- Pending Agents -->
|
| 124 |
+
<div class="bg-white rounded shadow">
|
| 125 |
+
<div class="p-4 border-b">
|
| 126 |
+
<h2 class="text-xl font-bold">Pending Agent Applications</h2>
|
| 127 |
+
</div>
|
| 128 |
+
<div class="p-4">
|
| 129 |
+
<?php if (empty($pendingAgents)): ?>
|
| 130 |
+
<p class="text-gray-500">No pending agent applications</p>
|
| 131 |
+
<?php else: ?>
|
| 132 |
+
<?php foreach ($pendingAgents as $agent): ?>
|
| 133 |
+
<div class="border rounded p-4 mb-4">
|
| 134 |
+
<div class="flex justify-between items-start">
|
| 135 |
+
<div>
|
| 136 |
+
<h3 class="font-bold"><?php echo htmlspecialchars($agent['full_name']); ?></h3>
|
| 137 |
+
<p class="text-gray-600">Phone: <?php echo htmlspecialchars($agent['phone']); ?></p>
|
| 138 |
+
<p class="text-gray-600">Location: <?php echo htmlspecialchars($agent['location']); ?></p>
|
| 139 |
+
<p class="text-gray-600">Sponsor: <?php echo htmlspecialchars($agent['username']); ?></p>
|
| 140 |
+
</div>
|
| 141 |
+
<div class="flex gap-2">
|
| 142 |
+
<button onclick="reviewAgent(<?php echo $agent['id']; ?>, 'approved')"
|
| 143 |
+
class="bg-green-500 text-white px-3 py-1 rounded">Approve</button>
|
| 144 |
+
<button onclick="reviewAgent(<?php echo $agent['id']; ?>, 'rejected')"
|
| 145 |
+
class="bg-red-500 text-white px-3 py-1 rounded">Reject</button>
|
| 146 |
+
</div>
|
| 147 |
+
</div>
|
| 148 |
+
</div>
|
| 149 |
+
<?php endforeach; ?>
|
| 150 |
+
<?php endif; ?>
|
| 151 |
+
</div>
|
| 152 |
+
</div>
|
| 153 |
+
</div>
|
| 154 |
+
|
| 155 |
+
<!-- Review Forms -->
|
| 156 |
+
<form id="agent-review-form" method="POST" class="hidden">
|
| 157 |
+
<input type="hidden" name="action" value="review_agent">
|
| 158 |
+
<input type="hidden" id="agent-id" name="agent_id">
|
| 159 |
+
<input type="hidden" id="agent-status" name="status">
|
| 160 |
+
<textarea id="agent-notes" name="notes" placeholder="Review notes..."></textarea>
|
| 161 |
+
</form>
|
| 162 |
+
|
| 163 |
+
<form id="ad-review-form" method="POST" class="hidden">
|
| 164 |
+
<input type="hidden" name="action" value="review_advertisement">
|
| 165 |
+
<input type="hidden" id="ad-id" name="advertisement_id">
|
| 166 |
+
<input type="hidden" id="ad-status" name="status">
|
| 167 |
+
<textarea id="ad-notes" name="notes" placeholder="Review notes..."></textarea>
|
| 168 |
+
</form>
|
| 169 |
+
|
| 170 |
+
<script>
|
| 171 |
+
function reviewAgent(agentId, status) {
|
| 172 |
+
if (confirm(`Are you sure you want to ${status} this agent application?`)) {
|
| 173 |
+
document.getElementById('agent-id').value = agentId;
|
| 174 |
+
document.getElementById('agent-status').value = status;
|
| 175 |
+
document.getElementById('agent-review-form').submit();
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
function reviewAd(adId, status) {
|
| 180 |
+
if (confirm(`Are you sure you want to ${status} this advertisement?`)) {
|
| 181 |
+
document.getElementById('ad-id').value = adId;
|
| 182 |
+
document.getElementById('ad-status').value = status;
|
| 183 |
+
document.getElementById('ad-review-form').submit();
|
| 184 |
+
}
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
feather.replace();
|
| 188 |
+
</script>
|
| 189 |
+
</body>
|
| 190 |
+
</html>
|
jweb/ac1/src/admin/payments.php
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
session_start();
|
| 3 |
+
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
|
| 4 |
+
header('Location: login.php');
|
| 5 |
+
exit;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
require_once '../../db.php';
|
| 9 |
+
require_once '../api/main_account.php';
|
| 10 |
+
|
| 11 |
+
$mainAccount = new MainAccount();
|
| 12 |
+
$pendingPayments = $mainAccount->getPendingPayments();
|
| 13 |
+
|
| 14 |
+
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
| 15 |
+
$payment_id = $_POST['payment_id'];
|
| 16 |
+
$action = $_POST['action'];
|
| 17 |
+
$notes = $_POST['notes'] ?? '';
|
| 18 |
+
|
| 19 |
+
if ($action === 'verify') {
|
| 20 |
+
$result = $mainAccount->verifyPayment($payment_id, $_SESSION['admin_id'], $notes);
|
| 21 |
+
} else {
|
| 22 |
+
$result = $mainAccount->rejectPayment($payment_id, $_SESSION['admin_id'], $notes);
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
if ($result['success']) {
|
| 26 |
+
$message = $action === 'verify' ? "Payment verified successfully!" : "Payment rejected!";
|
| 27 |
+
} else {
|
| 28 |
+
$error = $result['error'];
|
| 29 |
+
}
|
| 30 |
+
}
|
| 31 |
+
?>
|
| 32 |
+
|
| 33 |
+
<!-- Admin Payment Verification Interface -->
|
| 34 |
+
<div class="container mx-auto p-6">
|
| 35 |
+
<h1 class="text-2xl font-bold mb-6">Payment Verification</h1>
|
| 36 |
+
|
| 37 |
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
| 38 |
+
<?php foreach ($pendingPayments as $payment): ?>
|
| 39 |
+
<div class="bg-white rounded-lg shadow p-6">
|
| 40 |
+
<div class="flex justify-between items-center mb-4">
|
| 41 |
+
<h3 class="font-bold">Payment #<?php echo $payment['id']; ?></h3>
|
| 42 |
+
<span class="bg-yellow-100 text-yellow-800 px-2 py-1 rounded text-sm">Pending</span>
|
| 43 |
+
</div>
|
| 44 |
+
|
| 45 |
+
<div class="space-y-2">
|
| 46 |
+
<p><strong>User:</strong> <?php echo $payment['username']; ?></p>
|
| 47 |
+
<p><strong>Amount:</strong> KES <?php echo number_format($payment['amount']); ?></p>
|
| 48 |
+
<p><strong>Phone:</strong> <?php echo $payment['phone_number']; ?></p>
|
| 49 |
+
<p><strong>M-Pesa Code:</strong> <?php echo $payment['mpesa_code']; ?></p>
|
| 50 |
+
<p><strong>Submitted:</strong> <?php echo date('M j, Y H:i', strtotime($payment['created_at'])); ?></p>
|
| 51 |
+
</div>
|
| 52 |
+
|
| 53 |
+
<?php if ($payment['screenshot']): ?>
|
| 54 |
+
<div class="mt-4">
|
| 55 |
+
<img src="../uploads/payments/<?php echo $payment['screenshot']; ?>"
|
| 56 |
+
alt="Payment Proof" class="rounded border max-w-full">
|
| 57 |
+
</div>
|
| 58 |
+
<?php endif; ?>
|
| 59 |
+
|
| 60 |
+
<form method="POST" class="mt-4 space-y-2">
|
| 61 |
+
<input type="hidden" name="payment_id" value="<?php echo $payment['id']; ?>">
|
| 62 |
+
<textarea name="notes" placeholder="Verification notes..." class="w-full p-2 border rounded"></textarea>
|
| 63 |
+
<div class="flex gap-2">
|
| 64 |
+
<button type="submit" name="action" value="verify"
|
| 65 |
+
class="flex-1 bg-green-500 text-white p-2 rounded hover:bg-green-600">
|
| 66 |
+
Verify
|
| 67 |
+
</button>
|
| 68 |
+
<button type="submit" name="action" value="reject"
|
| 69 |
+
class="flex-1 bg-red-500 text-white p-2 rounded hover:bg-red-600">
|
| 70 |
+
Reject
|
| 71 |
+
</button>
|
| 72 |
+
</div>
|
| 73 |
+
</form>
|
| 74 |
+
</div>
|
| 75 |
+
<?php endforeach; ?>
|
| 76 |
+
</div>
|
| 77 |
+
</div>
|
jweb/ac1/src/api/agent-functions.php
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// api/agent-functions.php
|
| 3 |
+
|
| 4 |
+
// Database connection
|
| 5 |
+
function getDBConnection() {
|
| 6 |
+
static $conn;
|
| 7 |
+
if (!$conn) {
|
| 8 |
+
$host = '127.0.0.1';
|
| 9 |
+
$dbname = 'jmdb';
|
| 10 |
+
$username = 'root';
|
| 11 |
+
$password = 'YourStrongPassword123';
|
| 12 |
+
|
| 13 |
+
try {
|
| 14 |
+
$conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
|
| 15 |
+
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
| 16 |
+
} catch(PDOException $e) {
|
| 17 |
+
die("Connection failed: " . $e->getMessage());
|
| 18 |
+
}
|
| 19 |
+
}
|
| 20 |
+
return $conn;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
// Get pending agents for a sponsor
|
| 24 |
+
function getPendingAgents($sponsorId) {
|
| 25 |
+
$conn = getDBConnection();
|
| 26 |
+
$stmt = $conn->prepare("
|
| 27 |
+
SELECT aa.*, u.username, u.email
|
| 28 |
+
FROM agent_applications aa
|
| 29 |
+
JOIN users u ON aa.user_id = u.id
|
| 30 |
+
WHERE aa.sponsor_id = ? AND aa.status = 'pending'
|
| 31 |
+
ORDER BY aa.applied_at DESC
|
| 32 |
+
");
|
| 33 |
+
$stmt->execute([$sponsorId]);
|
| 34 |
+
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
// Get agent statistics for a sponsor
|
| 38 |
+
function getAgentStats($sponsorId) {
|
| 39 |
+
$conn = getDBConnection();
|
| 40 |
+
|
| 41 |
+
// Initialize default stats
|
| 42 |
+
$stats = [
|
| 43 |
+
'pending' => 0,
|
| 44 |
+
'approved' => 0,
|
| 45 |
+
'rejected' => 0,
|
| 46 |
+
'documents_needed' => 0,
|
| 47 |
+
'total_applications' => 0,
|
| 48 |
+
'commission_this_month' => 0.00,
|
| 49 |
+
'total_commission' => 0.00
|
| 50 |
+
];
|
| 51 |
+
|
| 52 |
+
try {
|
| 53 |
+
// Count applications by status
|
| 54 |
+
$stmt = $conn->prepare("
|
| 55 |
+
SELECT
|
| 56 |
+
status,
|
| 57 |
+
COUNT(*) as count
|
| 58 |
+
FROM agent_applications
|
| 59 |
+
WHERE sponsor_id = ?
|
| 60 |
+
GROUP BY status
|
| 61 |
+
");
|
| 62 |
+
$stmt->execute([$sponsorId]);
|
| 63 |
+
$statusCounts = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
| 64 |
+
|
| 65 |
+
foreach ($statusCounts as $row) {
|
| 66 |
+
$stats[$row['status']] = $row['count'];
|
| 67 |
+
$stats['total_applications'] += $row['count'];
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
// Get commission data
|
| 71 |
+
$stmt = $conn->prepare("
|
| 72 |
+
SELECT
|
| 73 |
+
COALESCE(SUM(CASE WHEN MONTH(created_at) = MONTH(CURRENT_DATE()) THEN commission_amount ELSE 0 END), 0) as commission_this_month,
|
| 74 |
+
COALESCE(SUM(commission_amount), 0) as total_commission
|
| 75 |
+
FROM commissions
|
| 76 |
+
WHERE sponsor_id = ? AND status = 'paid'
|
| 77 |
+
");
|
| 78 |
+
$stmt->execute([$sponsorId]);
|
| 79 |
+
$commissionData = $stmt->fetch(PDO::FETCH_ASSOC);
|
| 80 |
+
|
| 81 |
+
if ($commissionData) {
|
| 82 |
+
$stats['commission_this_month'] = $commissionData['commission_this_month'];
|
| 83 |
+
$stats['total_commission'] = $commissionData['total_commission'];
|
| 84 |
+
}
|
| 85 |
+
} catch (Exception $e) {
|
| 86 |
+
error_log("Error getting agent stats: " . $e->getMessage());
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
return $stats;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
// Review agent application (admin function)
|
| 93 |
+
function reviewAgentApplication($agentId, $adminId, $status, $notes = '') {
|
| 94 |
+
$conn = getDBConnection();
|
| 95 |
+
|
| 96 |
+
try {
|
| 97 |
+
$conn->beginTransaction();
|
| 98 |
+
|
| 99 |
+
// Update agent application
|
| 100 |
+
$stmt = $conn->prepare("
|
| 101 |
+
UPDATE agent_applications
|
| 102 |
+
SET status = ?, reviewed_by = ?, reviewed_at = NOW(), review_notes = ?
|
| 103 |
+
WHERE id = ?
|
| 104 |
+
");
|
| 105 |
+
$stmt->execute([$status, $adminId, $notes, $agentId]);
|
| 106 |
+
|
| 107 |
+
// If approved, update user type to agent
|
| 108 |
+
if ($status === 'approved') {
|
| 109 |
+
$stmt = $conn->prepare("
|
| 110 |
+
UPDATE users u
|
| 111 |
+
JOIN agent_applications aa ON u.id = aa.user_id
|
| 112 |
+
SET u.user_type = 'agent'
|
| 113 |
+
WHERE aa.id = ?
|
| 114 |
+
");
|
| 115 |
+
$stmt->execute([$agentId]);
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
$conn->commit();
|
| 119 |
+
return true;
|
| 120 |
+
} catch (Exception $e) {
|
| 121 |
+
$conn->rollBack();
|
| 122 |
+
error_log("Error reviewing agent: " . $e->getMessage());
|
| 123 |
+
return false;
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
// Search agents
|
| 128 |
+
function searchAgents($sponsorId, $searchTerm) {
|
| 129 |
+
$conn = getDBConnection();
|
| 130 |
+
$searchTerm = "%$searchTerm%";
|
| 131 |
+
|
| 132 |
+
$stmt = $conn->prepare("
|
| 133 |
+
SELECT aa.*, u.username, u.email
|
| 134 |
+
FROM agent_applications aa
|
| 135 |
+
JOIN users u ON aa.user_id = u.id
|
| 136 |
+
WHERE aa.sponsor_id = ?
|
| 137 |
+
AND (aa.full_name LIKE ? OR aa.phone LIKE ? OR u.username LIKE ? OR aa.id LIKE ?)
|
| 138 |
+
ORDER BY aa.applied_at DESC
|
| 139 |
+
");
|
| 140 |
+
$stmt->execute([$sponsorId, $searchTerm, $searchTerm, $searchTerm, $searchTerm]);
|
| 141 |
+
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
// Get agent details for review
|
| 145 |
+
function getAgentDetails($agentId) {
|
| 146 |
+
$conn = getDBConnection();
|
| 147 |
+
$stmt = $conn->prepare("
|
| 148 |
+
SELECT aa.*, u.username, u.email, u.created_at as user_joined
|
| 149 |
+
FROM agent_applications aa
|
| 150 |
+
JOIN users u ON aa.user_id = u.id
|
| 151 |
+
WHERE aa.id = ?
|
| 152 |
+
");
|
| 153 |
+
$stmt->execute([$agentId]);
|
| 154 |
+
return $stmt->fetch(PDO::FETCH_ASSOC);
|
| 155 |
+
}
|
| 156 |
+
?>
|
jweb/ac1/src/api/agent_claim.php
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
class AgentClaim {
|
| 3 |
+
private $conn;
|
| 4 |
+
private $table_name = "agent_claims";
|
| 5 |
+
|
| 6 |
+
public $id;
|
| 7 |
+
public $user_id;
|
| 8 |
+
public $username;
|
| 9 |
+
public $email;
|
| 10 |
+
public $claim_type;
|
| 11 |
+
public $amount;
|
| 12 |
+
public $description;
|
| 13 |
+
public $status;
|
| 14 |
+
public $evidence_file;
|
| 15 |
+
public $created_at;
|
| 16 |
+
public $updated_at;
|
| 17 |
+
public $approved_at;
|
| 18 |
+
public $approved_by;
|
| 19 |
+
public $rejection_reason;
|
| 20 |
+
|
| 21 |
+
public function __construct($db) {
|
| 22 |
+
$this->conn = $db;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
// Create new claim
|
| 26 |
+
public function create() {
|
| 27 |
+
try {
|
| 28 |
+
$query = "INSERT INTO " . $this->table_name . "
|
| 29 |
+
(user_id, username, email, claim_type, amount, description, evidence_file)
|
| 30 |
+
VALUES (:user_id, :username, :email, :claim_type, :amount, :description, :evidence_file)";
|
| 31 |
+
|
| 32 |
+
$stmt = $this->conn->prepare($query);
|
| 33 |
+
|
| 34 |
+
// Sanitize inputs
|
| 35 |
+
$this->user_id = htmlspecialchars(strip_tags($this->user_id));
|
| 36 |
+
$this->username = htmlspecialchars(strip_tags($this->username));
|
| 37 |
+
$this->email = htmlspecialchars(strip_tags($this->email));
|
| 38 |
+
$this->claim_type = htmlspecialchars(strip_tags($this->claim_type));
|
| 39 |
+
$this->amount = htmlspecialchars(strip_tags($this->amount));
|
| 40 |
+
$this->description = htmlspecialchars(strip_tags($this->description));
|
| 41 |
+
$this->evidence_file = htmlspecialchars(strip_tags($this->evidence_file));
|
| 42 |
+
|
| 43 |
+
// Bind parameters
|
| 44 |
+
$stmt->bindParam(":user_id", $this->user_id);
|
| 45 |
+
$stmt->bindParam(":username", $this->username);
|
| 46 |
+
$stmt->bindParam(":email", $this->email);
|
| 47 |
+
$stmt->bindParam(":claim_type", $this->claim_type);
|
| 48 |
+
$stmt->bindParam(":amount", $this->amount);
|
| 49 |
+
$stmt->bindParam(":description", $this->description);
|
| 50 |
+
$stmt->bindParam(":evidence_file", $this->evidence_file);
|
| 51 |
+
|
| 52 |
+
if ($stmt->execute()) {
|
| 53 |
+
return $this->conn->lastInsertId();
|
| 54 |
+
}
|
| 55 |
+
return false;
|
| 56 |
+
|
| 57 |
+
} catch (PDOException $exception) {
|
| 58 |
+
error_log("Create Claim Error: " . $exception->getMessage());
|
| 59 |
+
return false;
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// Get claims by user ID
|
| 64 |
+
public function getClaimsByUser($user_id, $status = null) {
|
| 65 |
+
try {
|
| 66 |
+
$query = "SELECT * FROM " . $this->table_name . " WHERE user_id = :user_id";
|
| 67 |
+
|
| 68 |
+
if ($status) {
|
| 69 |
+
$query .= " AND status = :status";
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
$query .= " ORDER BY created_at DESC";
|
| 73 |
+
|
| 74 |
+
$stmt = $this->conn->prepare($query);
|
| 75 |
+
$stmt->bindParam(":user_id", $user_id);
|
| 76 |
+
|
| 77 |
+
if ($status) {
|
| 78 |
+
$stmt->bindParam(":status", $status);
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
$stmt->execute();
|
| 82 |
+
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
| 83 |
+
|
| 84 |
+
} catch (PDOException $exception) {
|
| 85 |
+
error_log("Get Claims Error: " . $exception->getMessage());
|
| 86 |
+
return [];
|
| 87 |
+
}
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
// Get claim by ID
|
| 91 |
+
public function getClaimById($id) {
|
| 92 |
+
try {
|
| 93 |
+
$query = "SELECT ac.*, u.full_name, u.phone
|
| 94 |
+
FROM " . $this->table_name . " ac
|
| 95 |
+
JOIN users u ON ac.user_id = u.id
|
| 96 |
+
WHERE ac.id = :id";
|
| 97 |
+
|
| 98 |
+
$stmt = $this->conn->prepare($query);
|
| 99 |
+
$stmt->bindParam(":id", $id);
|
| 100 |
+
$stmt->execute();
|
| 101 |
+
|
| 102 |
+
return $stmt->fetch(PDO::FETCH_ASSOC);
|
| 103 |
+
|
| 104 |
+
} catch (PDOException $exception) {
|
| 105 |
+
error_log("Get Claim Error: " . $exception->getMessage());
|
| 106 |
+
return false;
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
// Update claim status
|
| 111 |
+
public function updateStatus($id, $status, $approved_by = null, $rejection_reason = null) {
|
| 112 |
+
try {
|
| 113 |
+
$query = "UPDATE " . $this->table_name . "
|
| 114 |
+
SET status = :status,
|
| 115 |
+
updated_at = CURRENT_TIMESTAMP";
|
| 116 |
+
|
| 117 |
+
if ($status == 'approved') {
|
| 118 |
+
$query .= ", approved_at = CURRENT_TIMESTAMP, approved_by = :approved_by";
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
if ($status == 'rejected' && $rejection_reason) {
|
| 122 |
+
$query .= ", rejection_reason = :rejection_reason";
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
$query .= " WHERE id = :id";
|
| 126 |
+
|
| 127 |
+
$stmt = $this->conn->prepare($query);
|
| 128 |
+
$stmt->bindParam(":status", $status);
|
| 129 |
+
$stmt->bindParam(":id", $id);
|
| 130 |
+
|
| 131 |
+
if ($status == 'approved') {
|
| 132 |
+
$stmt->bindParam(":approved_by", $approved_by);
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
if ($status == 'rejected' && $rejection_reason) {
|
| 136 |
+
$stmt->bindParam(":rejection_reason", $rejection_reason);
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
return $stmt->execute();
|
| 140 |
+
|
| 141 |
+
} catch (PDOException $exception) {
|
| 142 |
+
error_log("Update Status Error: " . $exception->getMessage());
|
| 143 |
+
return false;
|
| 144 |
+
}
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
// Get claim statistics for user
|
| 148 |
+
public function getClaimStatistics($user_id) {
|
| 149 |
+
try {
|
| 150 |
+
$query = "SELECT
|
| 151 |
+
COUNT(*) as total_claims,
|
| 152 |
+
SUM(CASE WHEN status = 'approved' THEN 1 ELSE 0 END) as approved_claims,
|
| 153 |
+
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending_claims,
|
| 154 |
+
SUM(CASE WHEN status = 'rejected' THEN 1 ELSE 0 END) as rejected_claims,
|
| 155 |
+
SUM(CASE WHEN status = 'processing' THEN 1 ELSE 0 END) as processing_claims,
|
| 156 |
+
SUM(CASE WHEN status = 'approved' THEN amount ELSE 0 END) as approved_amount,
|
| 157 |
+
SUM(CASE WHEN status = 'pending' THEN amount ELSE 0 END) as pending_amount,
|
| 158 |
+
SUM(CASE WHEN status = 'processing' THEN amount ELSE 0 END) as processing_amount,
|
| 159 |
+
SUM(amount) as total_amount
|
| 160 |
+
FROM " . $this->table_name . "
|
| 161 |
+
WHERE user_id = :user_id";
|
| 162 |
+
|
| 163 |
+
$stmt = $this->conn->prepare($query);
|
| 164 |
+
$stmt->bindParam(":user_id", $user_id);
|
| 165 |
+
$stmt->execute();
|
| 166 |
+
|
| 167 |
+
return $stmt->fetch(PDO::FETCH_ASSOC);
|
| 168 |
+
|
| 169 |
+
} catch (PDOException $exception) {
|
| 170 |
+
error_log("Statistics Error: " . $exception->getMessage());
|
| 171 |
+
return [];
|
| 172 |
+
}
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
// Check if user has pending claims
|
| 176 |
+
public function hasPendingClaims($user_id) {
|
| 177 |
+
try {
|
| 178 |
+
$query = "SELECT COUNT(*) as pending_count
|
| 179 |
+
FROM " . $this->table_name . "
|
| 180 |
+
WHERE user_id = :user_id AND status = 'pending'";
|
| 181 |
+
|
| 182 |
+
$stmt = $this->conn->prepare($query);
|
| 183 |
+
$stmt->bindParam(":user_id", $user_id);
|
| 184 |
+
$stmt->execute();
|
| 185 |
+
|
| 186 |
+
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
| 187 |
+
return $result['pending_count'] > 0;
|
| 188 |
+
|
| 189 |
+
} catch (PDOException $exception) {
|
| 190 |
+
error_log("Pending Check Error: " . $exception->getMessage());
|
| 191 |
+
return false;
|
| 192 |
+
}
|
| 193 |
+
}
|
| 194 |
+
}
|
| 195 |
+
?>
|
jweb/ac1/src/api/check_session.php
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// check_session.php - Validate user sessions
|
| 3 |
+
session_start();
|
| 4 |
+
|
| 5 |
+
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
|
| 6 |
+
header('HTTP/1.1 401 Unauthorized');
|
| 7 |
+
echo json_encode(array("logged_in" => false));
|
| 8 |
+
exit;
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
// Return user data if logged in
|
| 12 |
+
echo json_encode(array(
|
| 13 |
+
"logged_in" => true,
|
| 14 |
+
"user_id" => $_SESSION['user_id'],
|
| 15 |
+
"username" => $_SESSION['username'],
|
| 16 |
+
"email" => $_SESSION['email'],
|
| 17 |
+
"tier" => $_SESSION['tier'],
|
| 18 |
+
"package" => $_SESSION['package'],
|
| 19 |
+
"balance" => $_SESSION['balance'],
|
| 20 |
+
"total_deposits" => $_SESSION['total_deposits'],
|
| 21 |
+
"total_withdrawals" => $_SESSION['total_withdrawals'],
|
| 22 |
+
"rewards" => $_SESSION['rewards']
|
| 23 |
+
));
|
| 24 |
+
?>
|
jweb/ac1/src/api/config.php
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Application configuration
|
| 3 |
+
define('APP_NAME', 'Japanese Motors');
|
| 4 |
+
define('APP_VERSION', '1.0.0');
|
| 5 |
+
define('UPLOAD_PATH', __DIR__ . '/uploads/claims/');
|
| 6 |
+
define('MAX_FILE_SIZE', 5 * 1024 * 1024); // 5MB
|
| 7 |
+
define('ALLOWED_FILE_TYPES', ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx']);
|
| 8 |
+
|
| 9 |
+
// Claim configuration
|
| 10 |
+
define('MAX_PENDING_CLAIMS', 3);
|
| 11 |
+
define('MIN_CLAIM_AMOUNT', 100);
|
| 12 |
+
define('MAX_CLAIM_AMOUNT', 100000);
|
| 13 |
+
?>
|
jweb/ac1/src/api/db.php
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
// Database configuration
|
| 3 |
+
$host = '127.0.0.1';
|
| 4 |
+
$dbname = 'jmdb';
|
| 5 |
+
$username = 'root'; // Change to your database username
|
| 6 |
+
$password = 'YourStrongPassword123'; // Change to your database password
|
| 7 |
+
|
| 8 |
+
try {
|
| 9 |
+
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
|
| 10 |
+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
| 11 |
+
} catch (PDOException $e) {
|
| 12 |
+
error_log("Database connection failed: " . $e->getMessage());
|
| 13 |
+
// For demo purposes, we'll create a dummy PDO object to prevent errors
|
| 14 |
+
class DummyPDO {
|
| 15 |
+
public function prepare($sql) { return new DummyPDOStatement(); }
|
| 16 |
+
public function exec($sql) { return true; }
|
| 17 |
+
public function lastInsertId() { return 1; }
|
| 18 |
+
public function beginTransaction() { return true; }
|
| 19 |
+
public function commit() { return true; }
|
| 20 |
+
public function rollBack() { return true; }
|
| 21 |
+
}
|
| 22 |
+
class DummyPDOStatement {
|
| 23 |
+
public function execute($params) { return true; }
|
| 24 |
+
public function fetch($mode) { return []; }
|
| 25 |
+
public function fetchAll($mode) { return []; }
|
| 26 |
+
}
|
| 27 |
+
$pdo = new DummyPDO();
|
| 28 |
+
}
|
| 29 |
+
// User class to handle user operations
|
| 30 |
+
class User {
|
| 31 |
+
private $conn;
|
| 32 |
+
private $table_name = "users";
|
| 33 |
+
|
| 34 |
+
public $id;
|
| 35 |
+
public $username;
|
| 36 |
+
public $email;
|
| 37 |
+
public $password_hash;
|
| 38 |
+
public $tier;
|
| 39 |
+
public $package;
|
| 40 |
+
public $balance;
|
| 41 |
+
public $total_deposits;
|
| 42 |
+
public $total_withdrawals;
|
| 43 |
+
public $rewards;
|
| 44 |
+
|
| 45 |
+
public function __construct($db) {
|
| 46 |
+
$this->conn = $db;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
// Get user by ID
|
| 50 |
+
public function getUserById($id) {
|
| 51 |
+
$query = "SELECT * FROM " . $this->table_name . " WHERE id = ? LIMIT 0,1";
|
| 52 |
+
$stmt = $this->conn->prepare($query);
|
| 53 |
+
$stmt->bindParam(1, $id);
|
| 54 |
+
$stmt->execute();
|
| 55 |
+
|
| 56 |
+
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
| 57 |
+
|
| 58 |
+
if($row) {
|
| 59 |
+
$this->id = $row['id'];
|
| 60 |
+
$this->username = $row['username'];
|
| 61 |
+
$this->email = $row['email'];
|
| 62 |
+
$this->tier = $row['tier'];
|
| 63 |
+
$this->package = $row['package'];
|
| 64 |
+
$this->balance = $row['balance'];
|
| 65 |
+
$this->total_deposits = $row['total_deposits'];
|
| 66 |
+
$this->total_withdrawals = $row['total_withdrawals'];
|
| 67 |
+
$this->rewards = $row['rewards'];
|
| 68 |
+
return true;
|
| 69 |
+
}
|
| 70 |
+
return false;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
// Get user by username
|
| 74 |
+
public function getUserByUsername($username) {
|
| 75 |
+
$query = "SELECT * FROM " . $this->table_name . " WHERE username = ? LIMIT 0,1";
|
| 76 |
+
$stmt = $this->conn->prepare($query);
|
| 77 |
+
$stmt->bindParam(1, $username);
|
| 78 |
+
$stmt->execute();
|
| 79 |
+
|
| 80 |
+
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
| 81 |
+
|
| 82 |
+
if($row) {
|
| 83 |
+
$this->id = $row['id'];
|
| 84 |
+
$this->username = $row['username'];
|
| 85 |
+
$this->email = $row['email'];
|
| 86 |
+
$this->tier = $row['tier'];
|
| 87 |
+
$this->package = $row['package'];
|
| 88 |
+
$this->balance = $row['balance'];
|
| 89 |
+
$this->total_deposits = $row['total_deposits'];
|
| 90 |
+
$this->total_withdrawals = $row['total_withdrawals'];
|
| 91 |
+
$this->rewards = $row['rewards'];
|
| 92 |
+
return true;
|
| 93 |
+
}
|
| 94 |
+
return false;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
// Update user balance
|
| 98 |
+
public function updateBalance($amount) {
|
| 99 |
+
$query = "UPDATE " . $this->table_name . " SET balance = balance + ? WHERE id = ?";
|
| 100 |
+
$stmt = $this->conn->prepare($query);
|
| 101 |
+
$stmt->bindParam(1, $amount);
|
| 102 |
+
$stmt->bindParam(2, $this->id);
|
| 103 |
+
|
| 104 |
+
if($stmt->execute()) {
|
| 105 |
+
$this->balance += $amount;
|
| 106 |
+
return true;
|
| 107 |
+
}
|
| 108 |
+
return false;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
// Update user deposits
|
| 112 |
+
public function updateDeposits($amount) {
|
| 113 |
+
$query = "UPDATE " . $this->table_name . " SET total_deposits = total_deposits + ? WHERE id = ?";
|
| 114 |
+
$stmt = $this->conn->prepare($query);
|
| 115 |
+
$stmt->bindParam(1, $amount);
|
| 116 |
+
$stmt->bindParam(2, $this->id);
|
| 117 |
+
|
| 118 |
+
if($stmt->execute()) {
|
| 119 |
+
$this->total_deposits += $amount;
|
| 120 |
+
return true;
|
| 121 |
+
}
|
| 122 |
+
return false;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
// Update user withdrawals
|
| 126 |
+
public function updateWithdrawals($amount) {
|
| 127 |
+
$query = "UPDATE " . $this->table_name . " SET total_withdrawals = total_withdrawals + ? WHERE id = ?";
|
| 128 |
+
$stmt = $this->conn->prepare($query);
|
| 129 |
+
$stmt->bindParam(1, $amount);
|
| 130 |
+
$stmt->bindParam(2, $this->id);
|
| 131 |
+
|
| 132 |
+
if($stmt->execute()) {
|
| 133 |
+
$this->total_withdrawals += $amount;
|
| 134 |
+
return true;
|
| 135 |
+
}
|
| 136 |
+
return false;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
// Update user rewards
|
| 140 |
+
public function updateRewards($amount) {
|
| 141 |
+
$query = "UPDATE " . $this->table_name . " SET rewards = rewards + ? WHERE id = ?";
|
| 142 |
+
$stmt = $this->conn->prepare($query);
|
| 143 |
+
$stmt->bindParam(1, $amount);
|
| 144 |
+
$stmt->bindParam(2, $this->id);
|
| 145 |
+
|
| 146 |
+
if($stmt->execute()) {
|
| 147 |
+
$this->rewards += $amount;
|
| 148 |
+
return true;
|
| 149 |
+
}
|
| 150 |
+
return false;
|
| 151 |
+
}
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
// Transaction class to handle transactions
|
| 155 |
+
class Transaction {
|
| 156 |
+
private $conn;
|
| 157 |
+
private $table_name = "transactions";
|
| 158 |
+
|
| 159 |
+
public $id;
|
| 160 |
+
public $user_id;
|
| 161 |
+
public $type;
|
| 162 |
+
public $amount;
|
| 163 |
+
public $description;
|
| 164 |
+
public $status;
|
| 165 |
+
public $reference;
|
| 166 |
+
public $created_at;
|
| 167 |
+
|
| 168 |
+
public function __construct($db) {
|
| 169 |
+
$this->conn = $db;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
// Create a new transaction
|
| 173 |
+
public function create() {
|
| 174 |
+
$query = "INSERT INTO " . $this->table_name . "
|
| 175 |
+
SET user_id=:user_id, type=:type, amount=:amount,
|
| 176 |
+
description=:description, status=:status, reference=:reference";
|
| 177 |
+
|
| 178 |
+
$stmt = $this->conn->prepare($query);
|
| 179 |
+
|
| 180 |
+
// Sanitize inputs
|
| 181 |
+
$this->user_id = htmlspecialchars(strip_tags($this->user_id));
|
| 182 |
+
$this->type = htmlspecialchars(strip_tags($this->type));
|
| 183 |
+
$this->amount = htmlspecialchars(strip_tags($this->amount));
|
| 184 |
+
$this->description = htmlspecialchars(strip_tags($this->description));
|
| 185 |
+
$this->status = htmlspecialchars(strip_tags($this->status));
|
| 186 |
+
$this->reference = htmlspecialchars(strip_tags($this->reference));
|
| 187 |
+
|
| 188 |
+
// Bind values
|
| 189 |
+
$stmt->bindParam(":user_id", $this->user_id);
|
| 190 |
+
$stmt->bindParam(":type", $this->type);
|
| 191 |
+
$stmt->bindParam(":amount", $this->amount);
|
| 192 |
+
$stmt->bindParam(":description", $this->description);
|
| 193 |
+
$stmt->bindParam(":status", $this->status);
|
| 194 |
+
$stmt->bindParam(":reference", $this->reference);
|
| 195 |
+
|
| 196 |
+
if($stmt->execute()) {
|
| 197 |
+
return true;
|
| 198 |
+
}
|
| 199 |
+
return false;
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
// Get transactions by user ID
|
| 203 |
+
public function getTransactionsByUserId($user_id, $limit = 10) {
|
| 204 |
+
$query = "SELECT * FROM " . $this->table_name . "
|
| 205 |
+
WHERE user_id = ?
|
| 206 |
+
ORDER BY created_at DESC
|
| 207 |
+
LIMIT ?";
|
| 208 |
+
|
| 209 |
+
$stmt = $this->conn->prepare($query);
|
| 210 |
+
$stmt->bindParam(1, $user_id);
|
| 211 |
+
$stmt->bindParam(2, $limit, PDO::PARAM_INT);
|
| 212 |
+
$stmt->execute();
|
| 213 |
+
|
| 214 |
+
return $stmt;
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
// Get transactions by type
|
| 218 |
+
public function getTransactionsByType($user_id, $type, $limit = 10) {
|
| 219 |
+
$query = "SELECT * FROM " . $this->table_name . "
|
| 220 |
+
WHERE user_id = ? AND type = ?
|
| 221 |
+
ORDER BY created_at DESC
|
| 222 |
+
LIMIT ?";
|
| 223 |
+
|
| 224 |
+
$stmt = $this->conn->prepare($query);
|
| 225 |
+
$stmt->bindParam(1, $user_id);
|
| 226 |
+
$stmt->bindParam(2, $type);
|
| 227 |
+
$stmt->bindParam(3, $limit, PDO::PARAM_INT);
|
| 228 |
+
$stmt->execute();
|
| 229 |
+
|
| 230 |
+
return $stmt;
|
| 231 |
+
}
|
| 232 |
+
}
|
| 233 |
+
?>
|
jweb/ac1/src/api/deposit.php
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
session_start();
|
| 3 |
+
header('Content-Type: application/json');
|
| 4 |
+
|
| 5 |
+
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
|
| 6 |
+
echo json_encode(['success' => false, 'message' => 'Not logged in']);
|
| 7 |
+
exit;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
// Get JSON input
|
| 11 |
+
$input = json_decode(file_get_contents('php://input'), true);
|
| 12 |
+
|
| 13 |
+
if (!isset($input['amount']) || !isset($input['method'])) {
|
| 14 |
+
echo json_encode(['success' => false, 'message' => 'Invalid input']);
|
| 15 |
+
exit;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
// Include database connection
|
| 19 |
+
require_once '../../db.php';
|
| 20 |
+
require_once '../classes/User.php';
|
| 21 |
+
require_once '../classes/Transaction.php';
|
| 22 |
+
|
| 23 |
+
$database = new Database();
|
| 24 |
+
$db = $database->getConnection();
|
| 25 |
+
$user = new User($db);
|
| 26 |
+
$transaction = new Transaction($db);
|
| 27 |
+
|
| 28 |
+
if ($user->getUserByUsername($_SESSION['username'])) {
|
| 29 |
+
// Process deposit
|
| 30 |
+
$amount = floatval($input['amount']);
|
| 31 |
+
$method = $input['method'];
|
| 32 |
+
|
| 33 |
+
// Add amount to balance and deposits
|
| 34 |
+
$user->updateBalance($amount);
|
| 35 |
+
$user->updateDeposits($amount);
|
| 36 |
+
|
| 37 |
+
// Create transaction record
|
| 38 |
+
$transaction->user_id = $user->id;
|
| 39 |
+
$transaction->type = 'deposit';
|
| 40 |
+
$transaction->amount = $amount;
|
| 41 |
+
$transaction->description = "Deposit via $method";
|
| 42 |
+
$transaction->status = 'completed';
|
| 43 |
+
|
| 44 |
+
if ($transaction->create()) {
|
| 45 |
+
echo json_encode(['success' => true, 'message' => 'Deposit successful']);
|
| 46 |
+
} else {
|
| 47 |
+
echo json_encode(['success' => false, 'message' => 'Failed to record transaction']);
|
| 48 |
+
}
|
| 49 |
+
} else {
|
| 50 |
+
echo json_encode(['success' => false, 'message' => 'User not found']);
|
| 51 |
+
}
|
| 52 |
+
?>
|
jweb/ac1/src/api/fetch_tokens.php
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
session_start();
|
| 3 |
+
require_once '../../db.php';
|
| 4 |
+
|
| 5 |
+
if (!isset($_SESSION['user_id'])) {
|
| 6 |
+
echo json_encode(['success' => false, 'message' => 'Not logged in']);
|
| 7 |
+
exit;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
$user_id = $_SESSION['user_id'];
|
| 11 |
+
|
| 12 |
+
$sql = "SELECT id, name, token, permissions, expires_at, status, created_at
|
| 13 |
+
FROM access_tokens
|
| 14 |
+
WHERE user_id = ? ORDER BY created_at DESC";
|
| 15 |
+
$stmt = $conn->prepare($sql);
|
| 16 |
+
$stmt->bind_param("i", $user_id);
|
| 17 |
+
$stmt->execute();
|
| 18 |
+
$result = $stmt->get_result();
|
| 19 |
+
|
| 20 |
+
$tokens = [];
|
| 21 |
+
while ($row = $result->fetch_assoc()) {
|
| 22 |
+
$tokens[] = $row;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
echo json_encode(['success' => true, 'tokens' => $tokens]);
|
jweb/ac1/src/api/generate-package-page.php
ADDED
|
@@ -0,0 +1,456 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
session_start();
|
| 3 |
+
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
|
| 4 |
+
header('Location: ../../index.php');
|
| 5 |
+
exit;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
// Database connection
|
| 9 |
+
require_once '../../db.php';
|
| 10 |
+
|
| 11 |
+
// Get package name from URL
|
| 12 |
+
$package_name = isset($_GET['package']) ? urldecode($_GET['package']) : '';
|
| 13 |
+
|
| 14 |
+
if (empty($package_name)) {
|
| 15 |
+
die("Package not specified.");
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
// Get package details
|
| 19 |
+
$stmt = $pdo->prepare("SELECT * FROM products WHERE name = ?");
|
| 20 |
+
$stmt->execute([$package_name]);
|
| 21 |
+
$package = $stmt->fetch(PDO::FETCH_ASSOC);
|
| 22 |
+
|
| 23 |
+
if (!$package) {
|
| 24 |
+
die("Package not found.");
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
// Check if user owns this package
|
| 28 |
+
$user_id = $_SESSION['user_id'];
|
| 29 |
+
$stmt = $pdo->prepare("SELECT * FROM user_products WHERE user_id = ? AND product_id = ?");
|
| 30 |
+
$stmt->execute([$user_id, $package['id']]);
|
| 31 |
+
$user_has_package = $stmt->fetch(PDO::FETCH_ASSOC);
|
| 32 |
+
|
| 33 |
+
if (!$user_has_package) {
|
| 34 |
+
die("You do not have access to this package.");
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
// Generate HTML for the package page
|
| 38 |
+
$page_title = $package['name'];
|
| 39 |
+
$package_content = generatePackageContent($package['name']);
|
| 40 |
+
|
| 41 |
+
// Function to generate specific content based on package
|
| 42 |
+
function generatePackageContent($package_name) {
|
| 43 |
+
switch ($package_name) {
|
| 44 |
+
case 'Diamond Package':
|
| 45 |
+
return '
|
| 46 |
+
<div class="bg-gradient-to-br from-purple-500 to-pink-500 p-6 rounded-lg text-white">
|
| 47 |
+
<h2 class="text-2xl font-bold mb-4">💎 Diamond Package Benefits</h2>
|
| 48 |
+
<ul class="list-disc list-inside space-y-2">
|
| 49 |
+
<li>Priority customer support</li>
|
| 50 |
+
<li>Exclusive investment opportunities</li>
|
| 51 |
+
<li>Higher cashback rates on all purchases</li>
|
| 52 |
+
<li>Access to premium products</li>
|
| 53 |
+
<li>Weekly market insights report</li>
|
| 54 |
+
</ul>
|
| 55 |
+
<div class="mt-6">
|
| 56 |
+
<h3 class="text-xl font-bold">Your Diamond Package Stats</h3>
|
| 57 |
+
<div class="grid grid-cols-2 gap-4 mt-4">
|
| 58 |
+
<div class="bg-white bg-opacity-20 p-4 rounded-lg">
|
| 59 |
+
<p class="text-sm">Total Earnings</p>
|
| 60 |
+
<p class="text-xl font-bold">KES 15,240.00</p>
|
| 61 |
+
</div>
|
| 62 |
+
<div class="bg-white bg-opacity-20 p-4 rounded-lg">
|
| 63 |
+
<p class="text-sm">Active Investments</p>
|
| 64 |
+
<p class="text-xl font-bold">3</p>
|
| 65 |
+
</div>
|
| 66 |
+
</div>
|
| 67 |
+
</div>
|
| 68 |
+
</div>
|
| 69 |
+
';
|
| 70 |
+
|
| 71 |
+
case 'Starlight Bundle':
|
| 72 |
+
return '
|
| 73 |
+
<div class="bg-gradient-to-br from-blue-500 to-teal-400 p-6 rounded-lg text-white">
|
| 74 |
+
<h2 class="text-2xl font-bold mb-4">✨ Starlight Bundle Benefits</h2>
|
| 75 |
+
<ul class="list-disc list-inside space-y-2">
|
| 76 |
+
<li>Standard customer support</li>
|
| 77 |
+
<li>Access to mid-range investment opportunities</li>
|
| 78 |
+
<li>Moderate cashback rates</li>
|
| 79 |
+
<li>Monthly market insights report</li>
|
| 80 |
+
</ul>
|
| 81 |
+
</div>
|
| 82 |
+
';
|
| 83 |
+
|
| 84 |
+
// Add more cases for other packages
|
| 85 |
+
|
| 86 |
+
default:
|
| 87 |
+
return '
|
| 88 |
+
<div class="bg-gray-800 p-6 rounded-lg text-white">
|
| 89 |
+
<h2 class="text-2xl font-bold mb-4">' . htmlspecialchars($package_name) . '</h2>
|
| 90 |
+
<p>Welcome to your package dashboard. Here you can monitor your investments and benefits.</p>
|
| 91 |
+
</div>
|
| 92 |
+
';
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
// Output the HTML page
|
| 97 |
+
?>
|
| 98 |
+
<!DOCTYPE html>
|
| 99 |
+
<html lang="en">
|
| 100 |
+
<head>
|
| 101 |
+
<meta charset="UTF-8">
|
| 102 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 103 |
+
<title><?php echo htmlspecialchars($page_title); ?> - Japanese Motors</title>
|
| 104 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 105 |
+
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700;800&display=swap" rel="stylesheet">
|
| 106 |
+
<style>
|
| 107 |
+
:root {
|
| 108 |
+
--bg: #7b848d;
|
| 109 |
+
--card: #7a2f3b;
|
| 110 |
+
--card-2: #6f2630;
|
| 111 |
+
--accent: #efdf2d;
|
| 112 |
+
--muted: rgba(255,255,255,0.6);
|
| 113 |
+
--glass: rgba(255,255,255,0.04);
|
| 114 |
+
--promo-gradient: linear-gradient(180deg,#a13df0 0%, #ff2a79 50%, #d70b1a 100%);
|
| 115 |
+
font-family: 'Poppins', system-ui, Arial;
|
| 116 |
+
--banner-gradient-start: #a855f7;
|
| 117 |
+
--banner-gradient-end: #ec4899;
|
| 118 |
+
--spacing-unit: 1rem;
|
| 119 |
+
--accent-primary: #7c3aed;
|
| 120 |
+
--accent-secondary: #a855f7;
|
| 121 |
+
--shadow-hover: 0 6px 18px rgba(0, 0, 0, 0.1);
|
| 122 |
+
--premium-gold: #d97706;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
body {
|
| 126 |
+
background: var(--bg);
|
| 127 |
+
font-family: 'Poppins', sans-serif;
|
| 128 |
+
transition: all 0.3s ease;
|
| 129 |
+
min-height: 100vh;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
.sidebar {
|
| 133 |
+
width: 250px;
|
| 134 |
+
height: 100vh;
|
| 135 |
+
background: #0d1321;
|
| 136 |
+
color: #fff;
|
| 137 |
+
position: fixed;
|
| 138 |
+
top: 0;
|
| 139 |
+
left: -250px;
|
| 140 |
+
transition: all 0.3s ease;
|
| 141 |
+
z-index: 1000;
|
| 142 |
+
overflow-y: auto;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
.sidebar.active {
|
| 146 |
+
left: 0;
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
#content {
|
| 150 |
+
margin-left: 0;
|
| 151 |
+
transition: all 0.3s ease;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
.sidebar.active ~ #content {
|
| 155 |
+
margin-left: 250px;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
header {
|
| 159 |
+
background: #222;
|
| 160 |
+
color: white;
|
| 161 |
+
padding: 15px 20px;
|
| 162 |
+
display: flex;
|
| 163 |
+
justify-content: space-between;
|
| 164 |
+
align-items: center;
|
| 165 |
+
position: relative;
|
| 166 |
+
z-index: 900;
|
| 167 |
+
transition: all 0.3s ease;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
.sidebar.active ~ #content header {
|
| 171 |
+
margin-left: 250px;
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
.menu-toggle {
|
| 175 |
+
background: transparent;
|
| 176 |
+
border: none;
|
| 177 |
+
color: white;
|
| 178 |
+
font-size: 1.5rem;
|
| 179 |
+
cursor: pointer;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
.logo-section {
|
| 183 |
+
padding: 15px;
|
| 184 |
+
border-bottom: 1px solid #1c2230;
|
| 185 |
+
display: flex;
|
| 186 |
+
align-items: center;
|
| 187 |
+
gap: 10px;
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
.brand {
|
| 191 |
+
font-size: 1.2rem;
|
| 192 |
+
font-weight: 700;
|
| 193 |
+
color: #ff9800;
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
.subtitle {
|
| 197 |
+
font-size: 0.75rem;
|
| 198 |
+
color: #aaa;
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
.menu {
|
| 202 |
+
list-style: none;
|
| 203 |
+
padding: 0;
|
| 204 |
+
margin: 0;
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
.menu li a {
|
| 208 |
+
display: flex;
|
| 209 |
+
align-items: center;
|
| 210 |
+
padding: 12px 20px;
|
| 211 |
+
color: white;
|
| 212 |
+
text-decoration: none;
|
| 213 |
+
transition: background 0.3s;
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
.menu li a:hover {
|
| 217 |
+
background: #1c2230;
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
.menu li a i {
|
| 221 |
+
margin-right: 12px;
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
+
.user-footer {
|
| 225 |
+
padding: 15px;
|
| 226 |
+
background: #222;
|
| 227 |
+
display: flex;
|
| 228 |
+
align-items: center;
|
| 229 |
+
gap: 10px;
|
| 230 |
+
position: sticky;
|
| 231 |
+
bottom: 0;
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
.avatar {
|
| 235 |
+
width: 35px;
|
| 236 |
+
height: 35px;
|
| 237 |
+
background: #444;
|
| 238 |
+
border-radius: 50%;
|
| 239 |
+
display: flex;
|
| 240 |
+
align-items: center;
|
| 241 |
+
justify-content: center;
|
| 242 |
+
font-weight: bold;
|
| 243 |
+
color: white;
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
.banner {
|
| 247 |
+
max-width: 450px;
|
| 248 |
+
margin: 0 auto calc(var(--spacing-unit) * 2);
|
| 249 |
+
background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
|
| 250 |
+
border-radius: 12px;
|
| 251 |
+
padding: calc(var(--spacing-unit) * 1.5);
|
| 252 |
+
text-align: center;
|
| 253 |
+
box-shadow: var(--shadow-hover);
|
| 254 |
+
animation: fadeIn 0.5s ease;
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
@keyframes fadeIn {
|
| 258 |
+
from { opacity: 0; transform: translateY(20px); }
|
| 259 |
+
to { opacity: 1; transform: translateY(0); }
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
+
@keyframes blink {
|
| 263 |
+
0% { opacity: 1; }
|
| 264 |
+
50% { opacity: 0.3; }
|
| 265 |
+
100% { opacity: 1; }
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
.banner .title {
|
| 269 |
+
font-size: 1.25rem;
|
| 270 |
+
margin-bottom: calc(var(--spacing-unit) * 1);
|
| 271 |
+
color: #ffffff;
|
| 272 |
+
font-weight: 700;
|
| 273 |
+
animation: blink 1.5s infinite;
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
.banner p {
|
| 277 |
+
font-size: 0.95rem;
|
| 278 |
+
line-height: 1.6;
|
| 279 |
+
margin-bottom: calc(var(--spacing-unit) * 1);
|
| 280 |
+
color: var(--premium-gold);
|
| 281 |
+
animation: blink 1.5s infinite;
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
.banner .footer {
|
| 285 |
+
font-size: 0.75rem;
|
| 286 |
+
color: rgba(255, 255, 255, 0.9);
|
| 287 |
+
font-style: italic;
|
| 288 |
+
animation: blink 1.5s infinite;
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
.promo .inner {
|
| 292 |
+
background: rgba(255,255,255,0.06);
|
| 293 |
+
padding: 14px;
|
| 294 |
+
border-radius: 10px;
|
| 295 |
+
margin: 6px 0;
|
| 296 |
+
}
|
| 297 |
+
|
| 298 |
+
.card {
|
| 299 |
+
background: var(--card);
|
| 300 |
+
border-radius: 12px;
|
| 301 |
+
padding: 26px;
|
| 302 |
+
color: white;
|
| 303 |
+
box-shadow: 0 6px 0 rgba(0,0,0,0.08) inset;
|
| 304 |
+
flex: 1;
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
.product-card {
|
| 308 |
+
background: rgba(255,255,255,0.05);
|
| 309 |
+
border-radius: 12px;
|
| 310 |
+
padding: 20px;
|
| 311 |
+
margin-bottom: 16px;
|
| 312 |
+
transition: all 0.3s ease;
|
| 313 |
+
}
|
| 314 |
+
|
| 315 |
+
.product-card:hover {
|
| 316 |
+
transform: translateY(-5px);
|
| 317 |
+
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
.product-badge {
|
| 321 |
+
position: absolute;
|
| 322 |
+
top: -8px;
|
| 323 |
+
right: -8px;
|
| 324 |
+
background: var(--accent);
|
| 325 |
+
color: #111;
|
| 326 |
+
padding: 4px 10px;
|
| 327 |
+
border-radius: 20px;
|
| 328 |
+
font-size: 12px;
|
| 329 |
+
font-weight: bold;
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
.btn {
|
| 333 |
+
display: inline-block;
|
| 334 |
+
padding: 14px 24px;
|
| 335 |
+
border-radius: 10px;
|
| 336 |
+
background: var(--accent);
|
| 337 |
+
color: #111;
|
| 338 |
+
font-weight: 700;
|
| 339 |
+
border: none;
|
| 340 |
+
cursor: pointer;
|
| 341 |
+
width: 100%;
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
.muted {
|
| 345 |
+
color: rgba(255,255,255,0.6);
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
@media (max-width: 768px) {
|
| 349 |
+
.promo {
|
| 350 |
+
width: 92%;
|
| 351 |
+
}
|
| 352 |
+
}
|
| 353 |
+
</style>
|
| 354 |
+
</head>
|
| 355 |
+
<body>
|
| 356 |
+
<!-- Sidebar -->
|
| 357 |
+
<aside class="sidebar" id="sidebar">
|
| 358 |
+
<div class="logo-section">
|
| 359 |
+
<i data-feather="zap" class="text-yellow-400"></i>
|
| 360 |
+
<div>
|
| 361 |
+
<h2 class="brand">JMOTORS</h2>
|
| 362 |
+
<p class="subtitle">Marketing Platform</p>
|
| 363 |
+
</div>
|
| 364 |
+
</div>
|
| 365 |
+
|
| 366 |
+
<ul class="menu">
|
| 367 |
+
<li><a href="index.php"><i data-feather="home"></i> Dashboard</a></li>
|
| 368 |
+
<li><a href="meta-uploads.php"><i data-feather="upload"></i> Meta Uploads</a></li>
|
| 369 |
+
<li><a href="transactions.php"><i data-feather="repeat"></i> Transactions</a></li>
|
| 370 |
+
<li><a href="transfer.php"><i data-feather="send"></i> Transfer</a></li>
|
| 371 |
+
<li><a href="daily-product.php"><i data-feather="shopping-bag"></i> Daily Product</a></li>
|
| 372 |
+
<li><a href="withdraw.php"><i data-feather="dollar-sign"></i> Withdraw</a></li>
|
| 373 |
+
<li><a href="packages.php"><i data-feather="package"></i> Packages</a></li>
|
| 374 |
+
<li><a href="loan.php"><i data-feather="credit-card"></i> Loan</a></li>
|
| 375 |
+
<li><a href="recharge.php"><i data-feather="battery-charging"></i> Recharge</a></li>
|
| 376 |
+
<li><a href="agent-approval.php" class="active-page"><i data-feather="user-check"></i> Agent Approval</a></li>
|
| 377 |
+
<li><a href="access-token.php"><i data-feather="key"></i> Access Token</a></li>
|
| 378 |
+
<li><a href="agent-claim.php"><i data-feather="tag"></i> Agent Claim</a></li>
|
| 379 |
+
<li><a href="team.php"><i data-feather="users"></i> Team</a></li>
|
| 380 |
+
</ul>
|
| 381 |
+
|
| 382 |
+
<ul class="menu bottom">
|
| 383 |
+
<li><a href="profile.php"><i data-feather="user"></i> Profile</a></li>
|
| 384 |
+
<li><a href="settings.php"><i data-feather="settings"></i> Settings</a></li>
|
| 385 |
+
<li><a href="whatsapp-channel.php"><i data-feather="message-square"></i> Whatsapp Channel</a></li>
|
| 386 |
+
<li><a href="customer-care.php"><i data-feather="headphones"></i> Customer Care</a></li>
|
| 387 |
+
</ul>
|
| 388 |
+
|
| 389 |
+
<div class="user-footer">
|
| 390 |
+
<div class="avatar"><?php echo substr($username, 0, 2); ?></div>
|
| 391 |
+
<div>
|
| 392 |
+
<h4><?php echo $username; ?></h4>
|
| 393 |
+
<p><?php echo $tier; ?> - Marketer</p>
|
| 394 |
+
</div>
|
| 395 |
+
</div>
|
| 396 |
+
</aside>
|
| 397 |
+
|
| 398 |
+
<!-- Main Content -->
|
| 399 |
+
<div id="content">
|
| 400 |
+
<header class="bg-gray-800 text-white p-4">
|
| 401 |
+
<div class="flex items-center">
|
| 402 |
+
<button class="menu-toggle" id="menu-toggle">
|
| 403 |
+
<i data-feather="menu"></i>
|
| 404 |
+
</button>
|
| 405 |
+
<div class="ml-4 font-bold text-xl">Jmotors</div>
|
| 406 |
+
</div>
|
| 407 |
+
<nav class="flex items-center space-x-6">
|
| 408 |
+
<a href="transfer.php" class="hover:text-yellow-300">Transfer</a>
|
| 409 |
+
<a href="loan.php" class="hover:text-yellow-300">Loans</a>
|
| 410 |
+
<a href="dailyproduct.php" class="hover:text-yellow-300">New Product</a>
|
| 411 |
+
<div class="w-9 h-9 rounded-full bg-gradient-to-r from-yellow-300 to-orange-400 flex items-center justify-center font-bold">MI</div>
|
| 412 |
+
</nav>
|
| 413 |
+
</header>
|
| 414 |
+
|
| 415 |
+
<main class="p-4">
|
| 416 |
+
<div class="max-w-4xl mx-auto">
|
| 417 |
+
<?php echo $package_content; ?>
|
| 418 |
+
|
| 419 |
+
<div class="mt-6 grid grid-cols-1 md:grid-cols-2 gap-4">
|
| 420 |
+
<div class="bg-gray-800 p-4 rounded-lg text-white">
|
| 421 |
+
<h3 class="text-lg font-bold mb-2">Package Actions</h3>
|
| 422 |
+
<button class="bg-yellow-400 text-black px-4 py-2 rounded-lg w-full mb-2 font-bold">
|
| 423 |
+
View Investment Portfolio
|
| 424 |
+
</button>
|
| 425 |
+
<button class="bg-green-500 text-white px-4 py-2 rounded-lg w-full mb-2">
|
| 426 |
+
Request Support
|
| 427 |
+
</button>
|
| 428 |
+
<button class="bg-blue-500 text-white px-4 py-2 rounded-lg w-full">
|
| 429 |
+
Upgrade Package
|
| 430 |
+
</button>
|
| 431 |
+
</div>
|
| 432 |
+
|
| 433 |
+
<div class="bg-gray-800 p-4 rounded-lg text-white">
|
| 434 |
+
<h3 class="text-lg font-bold mb-2">Performance Metrics</h3>
|
| 435 |
+
<div class="space-y-2">
|
| 436 |
+
<div>
|
| 437 |
+
<p class="text-sm text-gray-300">Return on Investment</p>
|
| 438 |
+
<div class="w-full bg-gray-700 rounded-full h-2.5">
|
| 439 |
+
<div class="bg-green-500 h-2.5 rounded-full" style="width: 75%"></div>
|
| 440 |
+
</div>
|
| 441 |
+
<p class="text-right text-sm mt-1">75%</p>
|
| 442 |
+
</div>
|
| 443 |
+
<div>
|
| 444 |
+
<p class="text-sm text-gray-300">Package Utilization</p>
|
| 445 |
+
<div class="w-full bg-gray-700 rounded-full h-2.5">
|
| 446 |
+
<div class="bg-yellow-400 h-2.5 rounded-full" style="width: 60%"></div>
|
| 447 |
+
</div>
|
| 448 |
+
<p class="text-right text-sm mt-1">60%</p>
|
| 449 |
+
</div>
|
| 450 |
+
</div>
|
| 451 |
+
</div>
|
| 452 |
+
</div>
|
| 453 |
+
</div>
|
| 454 |
+
</main>
|
| 455 |
+
</body>
|
| 456 |
+
</html>
|