Dedicated to Japanese automotive excellence for over two decades
+
+
+
+
+
+
+
+
+
+
Welcome to Japanese Motors
+
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.
+
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.
+
+
+
+ 2000+ Vehicles Sold
+
+
+
+ 1500+ Happy Clients
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Our History
+
+
A journey of passion for Japanese automotive excellence
+
+
+
+
+
+
+
1999
+
+
Foundation
+
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.
+
+
+
+
+
+
2005
+
+
First Showroom
+
Opened our first dedicated showroom in Osaka, allowing customers to experience vehicles firsthand. Expanded inventory to include rare JDM models.
+
+
+
+
+
+
2012
+
+
Service Department
+
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.
+
+
+
+
+
+
2018
+
+
Global Expansion
+
Established international shipping partnerships, enabling us to serve customers across North America, Europe, and Australia. Featured in multiple automotive publications.
+
+
+
+
+
+
2023
+
+
Digital Innovation
+
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.
+
+
+
+
+
+
+
+
+
+
+
+
Our Values
+
+
The principles that guide everything we do
+
+
+
+
+
+
+
+
Quality
+
We are committed to delivering the highest quality vehicles and services, with meticulous attention to detail in everything we do.
+
+
+
+
+
+
+
Integrity
+
We believe in transparency and honesty, building trust through clear communication and ethical business practices.
+
+
+
+
+
+
+
Passion
+
Our team shares a genuine passion for Japanese automotive culture, which drives our dedication to excellence.
+
+
+
+
+
+
+
Community
+
We foster a vibrant community of Japanese car enthusiasts through events, knowledge sharing, and mutual appreciation.
+
+
+
+
+
+
+
+
+
+
Meet Our Team
+
+
Experts passionate about Japanese automotive excellence
+
+
+
+
+
+
+
Takashi Yamamoto
+
Founder & CEO
+
With over 30 years in the automotive industry, Takashi's vision established Japanese Motors as a global leader in JDM vehicles.
+
+
+
+
+
+
+
+
+
+
+
+
Yuki Tanaka
+
Head of Sales
+
Yuki's expertise in JDM vehicles and customer service ensures our clients find their perfect Japanese performance vehicle.
+
+
+
+
+
+
+
+
+
+
+
+
Kenji Sato
+
Master Technician
+
Kenji brings 25 years of technical expertise specializing in Nissan GT-R and Toyota Supra performance modifications.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What Our Clients Say
+
+
Hear from enthusiasts who have experienced the Japanese Motors difference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
"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!"
+
+
+
+
+
+
Michael Chen
+
California, USA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
"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!"
+
+
+
+
+
+
Sarah Johnson
+
London, UK
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
"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."
+
+
+
+
+
+
David Müller
+
Berlin, Germany
+
+
+
+
+
+
+
+
+
+
+
Experience the Japanese Motors Difference
+
Join our community of enthusiasts and discover why we're the trusted name in Japanese performance vehicles.
Quick answers to common questions about contacting us
+
+
+
+
+
What's the best way to reach you quickly?
+
For the fastest response, use our WhatsApp chat or call us directly during business hours. We typically respond to WhatsApp messages within minutes.
+
+
+
+
Do you respond to inquiries after hours?
+
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.
+
+
+
+
Can I schedule a test drive online?
+
Absolutely! Use our contact form and select "Schedule Test Drive" as your subject. We'll contact you within 24 hours to confirm your appointment.
+
+
+
+
Do you ship vehicles internationally?
+
Yes, we ship vehicles worldwide. Contact our sales team via email or WhatsApp to discuss shipping options to your location.
+
+
+
+
+
+
+
+
+
+
Visit Our Showroom
+
+
Come see our collection of Japanese performance vehicles in person
+
+
+
+
+
+
+
+
Japanese Motors Showroom
+
123 Automotive Way, Chuo-ku, Tokyo, Japan 104-0061
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jweb/1a/gallery.html b/jweb/1a/gallery.html
new file mode 100644
index 0000000000000000000000000000000000000000..ca3bba0a9ade16f3ad28af09a077b4776d41c570
--- /dev/null
+++ b/jweb/1a/gallery.html
@@ -0,0 +1,926 @@
+
+
+
+
+
+ Inventory - Japanese Motors
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Our Premium Inventory
+
Explore our exclusive collection of Japanese performance vehicles
+
+
+
+
+
+
+
+
Select Motor Type
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Find Your Perfect Vehicle
+
+
+
+
+
+
+
+
+
+
Available Vehicles
+
+ Sort by:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Virtual Showroom
+
+
Experience our vehicles in immersive 360° virtual reality
+
+
+
+
+
+
+
+
Explore From Anywhere
+
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.
Be the first to know when we add new vehicles to our inventory. Sign up for our exclusive newsletter.
+
+
+
+
+
+
+
+
+ ×
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jweb/1a/services.html b/jweb/1a/services.html
new file mode 100644
index 0000000000000000000000000000000000000000..7e254f3baed0f92a85bb983f8683ec11c9235056
--- /dev/null
+++ b/jweb/1a/services.html
@@ -0,0 +1,855 @@
+
+
+
+
+
+ Services - Japanese Motors
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Premium Services
+
Expert care for your Japanese performance vehicle
+
+
+
+
+
+
+
+
Our Services
+
From routine maintenance to performance upgrades, our certified technicians provide exceptional service for your Japanese vehicle.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Oil Change Service
+
Complete oil and filter change using premium synthetic oils specifically formulated for Japanese performance engines.
+
+
+
+ Full synthetic oil change
+
+
+
+ OEM oil filter replacement
+
+
+
+ Multi-point inspection
+
+
+
+ From $89
+
+
+
+
+
+
+
+
+
Scheduled Maintenance
+
Factory-recommended service intervals to keep your vehicle performing at its best and maintain warranty coverage.
+
+
+
+ 30,000/60,000/90,000 mile services
+
+
+
+ Fluid changes and inspections
+
+
+
+ Comprehensive vehicle health report
+
+
+
+ From $249
+
+
+
+
+
+
+
+
+
Brake Service
+
Complete brake inspection and service to ensure your safety and optimal stopping performance.
+
+
+
+ Brake pad replacement
+
+
+
+ Rotor resurfacing or replacement
+
+
+
+ Brake fluid flush
+
+
+
+ From $199
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Engine Repair
+
Expert diagnosis and repair of engine issues, from minor tune-ups to major overhauls.
+
+
+
+ Diagnostic testing
+
+
+
+ Timing belt replacement
+
+
+
+ Engine rebuilds
+
+
+
+ From $299
+
+
+
+
+
+
+
+
+
Transmission Service
+
Specialized service for manual, automatic, and CVT transmissions found in Japanese performance vehicles.
+
+
+
+ Transmission fluid change
+
+
+
+ Clutch replacement
+
+
+
+ Transmission rebuild
+
+
+
+ From $349
+
+
+
+
+
+
+
+
+
Electrical Systems
+
Diagnosis and repair of complex electrical systems in modern Japanese vehicles.
+
+
+
+ Battery replacement
+
+
+
+ Alternator and starter service
+
+
+
+ Wiring diagnostics
+
+
+
+ From $159
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ECU Tuning
+
Custom engine tuning to unlock hidden performance while maintaining reliability.
+
+
+
+ Dyno tuning sessions
+
+
+
+ Custom ECU mapping
+
+
+
+ Performance optimization
+
+
+
+ From $499
+
+
+
+
+
+
+
+
+
Turbocharger Services
+
Installation, maintenance, and upgrade services for turbocharged vehicles.
+
+
+
+ Turbo installation
+
+
+
+ Turbo rebuilds
+
+
+
+ Intercooler upgrades
+
+
+
+ From $799
+
+
+
+
+
+
+
+
+
Suspension Upgrades
+
Performance suspension systems to improve handling and driving dynamics.
+
+
+
+ Coilover installation
+
+
+
+ Alignment and corner balancing
+
+
+
+ Handling packages
+
+
+
+ From $599
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Premium Detailing
+
Showroom-quality detailing to restore and protect your vehicle's appearance.
+
+
+
+ Paint correction
+
+
+
+ Ceramic coating
+
+
+
+ Interior deep cleaning
+
+
+
+ From $299
+
+
+
+
+
+
+
+
+
Paint Protection
+
Advanced protection solutions to keep your vehicle looking new for years to come.
+
+
+
+ Paint protection film
+
+
+
+ Ceramic coating pro
+
+
+
+ Window tinting
+
+
+
+ From $999
+
+
+
+
+
+
+
+
+
Interior Renewal
+
Complete interior restoration and protection services.
+
+
+
+ Leather conditioning
+
+
+
+ Fabric protection
+
+
+
+ Odor elimination
+
+
+
+ From $199
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Book Service
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Why Choose Japanese Motors
+
+
+
+
+
+
+
+
+
Certified Technicians
+
Our technicians are factory-trained and certified to work on Japanese performance vehicles.
+
+
+
+
+
+
+
Genuine Parts
+
We use only genuine OEM parts or premium aftermarket equivalents for all repairs.
+
+
+
+
+
+
+
Quick Turnaround
+
Most services completed same-day with our efficient workflow and ample resources.
+
+
+
+
+
+
+
Fair Pricing
+
Competitive pricing with no hidden fees and upfront estimates for all work.
+
+
+
+
+
+
+
+
+
+
Frequently Asked Questions
+
+
+
+
+
+
+
+
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.
+
+
+
+
+
+
+
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.
+
+
+
+
+
+
+
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.
+
+
+
+
+
+
+
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.
+
+
+
+
+
+
+
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.
+
+
+
+
+
+
+
+
+
+
Ready to Service Your Vehicle?
+
Schedule your appointment today and experience the Japanese Motors difference.
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.
+
+
+
+
+
+
Why is my withdrawal pending?
+
+
+
+
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.
+
+
+
+
+
+
How do I join the affiliate program?
+
+
+
+
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.
+
+
+
+
+
+
What are the minimum withdrawal requirements?
+
+
+
+
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.
+
+
+
+
+
+
How do I upgrade my account level?
+
+
+
+
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.
+
+
+
+
+
+
What should I do if my uploads are rejected?
+
+
+
+
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.
+
+
+
+
+
+
+
+ Support Hours
+
+
+
+ WhatsApp Support:
+ 24/7
+
+
+ Email Support:
+ Mon-Sun, 6am-11pm EAT
+
+
+ Phone Support:
+ 24/7 for urgent issues
+
+
+ Average Response Time:
+ Under 30 minutes
+
+
+ Ticket Resolution Time:
+ Within 24 hours
+
+
+
+
+
+
+ Support Tickets
+
+
+
+
No active support tickets
+
+
+
You can check the status of previous support requests
+
+
+
+
+
+ Community Support
+
+
Join our community of marketers to get help from experienced members and share insights:
+
+
+
+
Community Forum
+
Get answers from other marketers in our community forum
+ 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.
+
+
+
+
+
+
Investment Packages
+
Grow your funds with our automated investment solutions.
+
+
+
+
+
\ No newline at end of file
diff --git a/jweb/ac1/src/api/packages-backend.php b/jweb/ac1/src/api/packages-backend.php
new file mode 100644
index 0000000000000000000000000000000000000000..f5e0f7911a997db5ee6e1d54253ef4f58cfaa897
--- /dev/null
+++ b/jweb/ac1/src/api/packages-backend.php
@@ -0,0 +1,202 @@
+prepare("SELECT * FROM packages WHERE id = ?");
+ $stmt->execute([$package_id]);
+ return $stmt->fetch(PDO::FETCH_ASSOC);
+ } catch (PDOException $e) {
+ error_log("Error getting package details: " . $e->getMessage());
+ return false;
+ }
+}
+
+// Function to get all packages
+function getAllPackages() {
+ global $pdo;
+ try {
+ $stmt = $pdo->prepare("SELECT * FROM packages ORDER BY min_investment ASC");
+ $stmt->execute();
+ return $stmt->fetchAll(PDO::FETCH_ASSOC);
+ } catch (PDOException $e) {
+ error_log("Error getting all packages: " . $e->getMessage());
+ return [];
+ }
+}
+
+// Function to check if user can invest in a package
+function canUserInvest($user_id, $package_id, $amount) {
+ // Get package details
+ $package = getPackageDetails($package_id);
+ if (!$package) return false;
+
+ // Check if amount is within package limits
+ if ($amount < $package['min_investment'] || $amount > $package['max_investment']) {
+ return false;
+ }
+
+ return true;
+}
+
+// Function to create a new investment
+function createInvestment($user_id, $package_id, $amount, $payment_method) {
+ global $pdo;
+
+ // Start transaction
+ $pdo->beginTransaction();
+
+ try {
+ // Get package details
+ $package = getPackageDetails($package_id);
+ if (!$package) {
+ throw new Exception("Package not found");
+ }
+
+ // Calculate end date
+ $start_date = date('Y-m-d H:i:s');
+ $end_date = date('Y-m-d H:i:s', strtotime("+{$package['duration_days']} days"));
+
+ // Calculate total expected earnings
+ $total_earnings = $amount * ($package['daily_return'] / 100) * $package['duration_days'];
+
+ // Insert investment record
+ $stmt = $pdo->prepare("INSERT INTO user_investments (user_id, package_id, amount, start_date, end_date, total_earnings) VALUES (?, ?, ?, ?, ?, ?)");
+ $stmt->execute([$user_id, $package_id, $amount, $start_date, $end_date, $total_earnings]);
+ $investment_id = $pdo->lastInsertId();
+
+ // Update user's current package if this is their first or highest investment
+ $stmt = $pdo->prepare("SELECT MAX(amount) as max_investment FROM user_investments WHERE user_id = ? AND status = 'active'");
+ $stmt->execute([$user_id]);
+ $result = $stmt->fetch(PDO::FETCH_ASSOC);
+ $max_investment = $result ? $result['max_investment'] : 0;
+
+ if ($amount >= $max_investment) {
+ $stmt = $pdo->prepare("UPDATE users SET current_package_id = ?, package_start_date = ?, package_end_date = ? WHERE id = ?");
+ $stmt->execute([$package_id, $start_date, $end_date, $user_id]);
+ }
+
+ // Update user's total invested amount
+ $stmt = $pdo->prepare("UPDATE users SET total_invested = total_invested + ? WHERE id = ?");
+ $stmt->execute([$amount, $user_id]);
+
+ // Process payment based on method
+ if ($payment_method === 'wallet') {
+ // Deduct from user's balance
+ $stmt = $pdo->prepare("UPDATE users SET balance = balance - ? WHERE id = ? AND balance >= ?");
+ $stmt->execute([$amount, $user_id, $amount]);
+
+ if ($stmt->rowCount() === 0) {
+ throw new Exception("Insufficient balance");
+ }
+
+ // Update session balance
+ $_SESSION['balance'] -= $amount;
+ } else if ($payment_method === 'mpesa') {
+ // For demo purposes, we'll just log this
+ error_log("M-Pesa payment initiated for user $user_id, amount: $amount");
+ } else if ($payment_method === 'bank') {
+ // For demo purposes, we'll just log this
+ error_log("Bank transfer initiated for user $user_id, amount: $amount");
+ }
+
+ // Commit transaction
+ $pdo->commit();
+
+ return $investment_id;
+
+ } catch (Exception $e) {
+ $pdo->rollBack();
+ error_log("Investment creation failed: " . $e->getMessage());
+ throw $e;
+ }
+}
+
+// Function to get user's active investment
+function getUserActiveInvestment($user_id) {
+ global $pdo;
+ try {
+ $stmt = $pdo->prepare("
+ SELECT ui.*, p.name as package_name, p.daily_return, p.duration_days
+ FROM user_investments ui
+ JOIN packages p ON ui.package_id = p.id
+ WHERE ui.user_id = ? AND ui.status = 'active' AND ui.end_date > NOW()
+ ORDER BY ui.amount DESC
+ LIMIT 1
+ ");
+ $stmt->execute([$user_id]);
+ return $stmt->fetch(PDO::FETCH_ASSOC);
+ } catch (PDOException $e) {
+ error_log("Error getting user active investment: " . $e->getMessage());
+ return false;
+ }
+}
+
+// Function to get user's daily products
+function getUserDailyProducts($user_id) {
+ global $pdo;
+ try {
+ $stmt = $pdo->prepare("
+ SELECT up.*, p.name as product_name, p.description, p.value, p.image_url
+ FROM user_products up
+ JOIN products p ON up.product_id = p.id
+ WHERE up.user_id = ?
+ ORDER BY up.assigned_date DESC
+ ");
+ $stmt->execute([$user_id]);
+ return $stmt->fetchAll(PDO::FETCH_ASSOC);
+ } catch (PDOException $e) {
+ error_log("Error getting user daily products: " . $e->getMessage());
+ return [];
+ }
+}
+
+// Handle package investment request
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
+ $response = ['success' => false, 'message' => ''];
+
+ try {
+ if ($_POST['action'] === 'invest') {
+ $package_id = intval($_POST['package_id']);
+ $amount = floatval($_POST['amount']);
+ $payment_method = $_POST['payment_method'];
+ $user_id = $_SESSION['user_id'];
+
+ // Validate investment
+ if (canUserInvest($user_id, $package_id, $amount)) {
+ $investment_id = createInvestment($user_id, $package_id, $amount, $payment_method);
+
+ $response['success'] = true;
+ $response['message'] = 'Investment successful!';
+ $response['investment_id'] = $investment_id;
+
+ // Update session data
+ $_SESSION['total_deposits'] += $amount;
+ } else {
+ $response['message'] = 'Invalid investment amount or package selection';
+ }
+ }
+ } catch (Exception $e) {
+ $response['message'] = $e->getMessage();
+ }
+
+ header('Content-Type: application/json');
+ echo json_encode($response);
+ exit;
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/api/process_claim.php b/jweb/ac1/src/api/process_claim.php
new file mode 100644
index 0000000000000000000000000000000000000000..bfe7d6c5aa98eb5b91a756abffc5989589cd4a74
--- /dev/null
+++ b/jweb/ac1/src/api/process_claim.php
@@ -0,0 +1,114 @@
+ false, 'message' => ''];
+
+try {
+ $database = new Database();
+ $db = $database->getConnection();
+ $claim = new AgentClaim($db);
+
+ $action = $_POST['action'] ?? '';
+
+ switch ($action) {
+ case 'submit_claim':
+ // Validate and submit new claim
+ $required_fields = ['claim_type', 'amount', 'description'];
+ foreach ($required_fields as $field) {
+ if (empty($_POST[$field])) {
+ throw new Exception("Missing required field: $field");
+ }
+ }
+
+ $claim->user_id = $_SESSION['user_id'];
+ $claim->username = $_SESSION['username'];
+ $claim->email = $_SESSION['email'];
+ $claim->claim_type = $_POST['claim_type'];
+ $claim->amount = floatval($_POST['amount']);
+ $claim->description = $_POST['description'];
+ $claim->evidence_file = $_POST['evidence_file'] ?? null;
+
+ // Validate amount
+ if ($claim->amount <= 0) {
+ throw new Exception("Invalid claim amount");
+ }
+
+ // Check for duplicate pending claims
+ if ($claim->hasPendingClaims($claim->user_id)) {
+ throw new Exception("You already have a pending claim. Please wait for it to be processed.");
+ }
+
+ $claim_id = $claim->create();
+ if ($claim_id) {
+ $response['success'] = true;
+ $response['message'] = 'Claim submitted successfully! It will be reviewed within 3-5 business days.';
+ $response['claim_id'] = $claim_id;
+ } else {
+ throw new Exception("Failed to submit claim");
+ }
+ break;
+
+ case 'approve_claim':
+ // Admin approval
+ if ($_SESSION['role'] !== 'admin') {
+ throw new Exception("Insufficient permissions");
+ }
+
+ $claim_id = $_POST['claim_id'] ?? 0;
+ if (!$claim_id) {
+ throw new Exception("Invalid claim ID");
+ }
+
+ if ($claim->updateStatus($claim_id, 'approved', $_SESSION['user_id'])) {
+ $response['success'] = true;
+ $response['message'] = 'Claim approved successfully';
+ } else {
+ throw new Exception("Failed to approve claim");
+ }
+ break;
+
+ case 'reject_claim':
+ // Admin rejection
+ if ($_SESSION['role'] !== 'admin') {
+ throw new Exception("Insufficient permissions");
+ }
+
+ $claim_id = $_POST['claim_id'] ?? 0;
+ $rejection_reason = $_POST['rejection_reason'] ?? '';
+
+ if (!$claim_id) {
+ throw new Exception("Invalid claim ID");
+ }
+
+ if (empty($rejection_reason)) {
+ throw new Exception("Rejection reason is required");
+ }
+
+ if ($claim->updateStatus($claim_id, 'rejected', null, $rejection_reason)) {
+ $response['success'] = true;
+ $response['message'] = 'Claim rejected successfully';
+ } else {
+ throw new Exception("Failed to reject claim");
+ }
+ break;
+
+ default:
+ throw new Exception("Invalid action");
+ }
+
+} catch (Exception $e) {
+ $response['message'] = $e->getMessage();
+ error_log("Process Claim Error: " . $e->getMessage());
+}
+
+echo json_encode($response);
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/api/profile_handler.php b/jweb/ac1/src/api/profile_handler.php
new file mode 100644
index 0000000000000000000000000000000000000000..9bfef647e938cdbd415683e51a6f2d352d08697b
--- /dev/null
+++ b/jweb/ac1/src/api/profile_handler.php
@@ -0,0 +1,145 @@
+setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+} catch(PDOException $e) {
+ echo json_encode(['success' => false, 'message' => 'Database connection failed']);
+ exit;
+}
+
+if (!isset($_SESSION['user_id'])) {
+ echo json_encode(['success' => false, 'message' => 'Not authenticated']);
+ exit;
+}
+
+$user_id = $_SESSION['user_id'];
+$action = $_POST['action'] ?? '';
+
+switch($action) {
+ case 'get_profile':
+ getProfile($pdo, $user_id);
+ break;
+ case 'update_profile':
+ updateProfile($pdo, $user_id);
+ break;
+ case 'change_password':
+ changePassword($pdo, $user_id);
+ break;
+ case 'get_activity':
+ getActivity($pdo, $user_id);
+ break;
+ default:
+ echo json_encode(['success' => false, 'message' => 'Invalid action']);
+}
+
+function getProfile($pdo, $user_id) {
+ $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
+ $stmt->execute([$user_id]);
+ $user = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if ($user) {
+ unset($user['password_hash']);
+ echo json_encode(['success' => true, 'profile' => $user]);
+ } else {
+ echo json_encode(['success' => false, 'message' => 'User not found']);
+ }
+}
+
+function updateProfile($pdo, $user_id) {
+ $allowed_fields = ['first_name', 'last_name', 'email', 'phone_number', 'country_code'];
+ $updates = [];
+ $params = [];
+
+ foreach ($allowed_fields as $field) {
+ if (isset($_POST[$field]) && $_POST[$field] !== '') {
+ $updates[] = "$field = ?";
+ $params[] = $_POST[$field];
+ }
+ }
+
+ if (empty($updates)) {
+ echo json_encode(['success' => false, 'message' => 'No valid fields to update']);
+ return;
+ }
+
+ $params[] = $user_id;
+ $sql = "UPDATE users SET " . implode(', ', $updates) . ", last_updated = CURRENT_TIMESTAMP WHERE id = ?";
+
+ try {
+ $stmt = $pdo->prepare($sql);
+ $stmt->execute($params);
+
+ // Log the activity
+ logActivity($pdo, $user_id, 'profile_update', 'Updated profile information');
+
+ echo json_encode(['success' => true, 'message' => 'Profile updated successfully']);
+ } catch (PDOException $e) {
+ echo json_encode(['success' => false, 'message' => 'Update failed: ' . $e->getMessage()]);
+ }
+}
+
+function changePassword($pdo, $user_id) {
+ if (!isset($_POST['current_password']) || !isset($_POST['new_password']) || !isset($_POST['confirm_password'])) {
+ echo json_encode(['success' => false, 'message' => 'All password fields are required']);
+ return;
+ }
+
+ $current_password = $_POST['current_password'];
+ $new_password = $_POST['new_password'];
+ $confirm_password = $_POST['confirm_password'];
+
+ if ($new_password !== $confirm_password) {
+ echo json_encode(['success' => false, 'message' => 'New passwords do not match']);
+ return;
+ }
+
+ if (strlen($new_password) < 6) {
+ echo json_encode(['success' => false, 'message' => 'Password must be at least 6 characters long']);
+ return;
+ }
+
+ // Get current password hash
+ $stmt = $pdo->prepare("SELECT password_hash FROM users WHERE id = ?");
+ $stmt->execute([$user_id]);
+ $user = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if (!$user || !password_verify($current_password, $user['password_hash'])) {
+ echo json_encode(['success' => false, 'message' => 'Current password is incorrect']);
+ return;
+ }
+
+ // Update password
+ $new_password_hash = password_hash($new_password, PASSWORD_DEFAULT);
+ $stmt = $pdo->prepare("UPDATE users SET password_hash = ?, last_updated = CURRENT_TIMESTAMP WHERE id = ?");
+ $stmt->execute([$new_password_hash, $user_id]);
+
+ // Log the activity
+ logActivity($pdo, $user_id, 'password_change', 'Changed account password');
+
+ echo json_encode(['success' => true, 'message' => 'Password updated successfully']);
+}
+
+function getActivity($pdo, $user_id) {
+ $stmt = $pdo->prepare("SELECT activity_type, description, timestamp FROM user_activity WHERE user_id = ? ORDER BY timestamp DESC LIMIT 50");
+ $stmt->execute([$user_id]);
+ $activities = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+ echo json_encode(['success' => true, 'activities' => $activities]);
+}
+
+function logActivity($pdo, $user_id, $type, $description) {
+ $ip_address = $_SERVER['REMOTE_ADDR'];
+ $stmt = $pdo->prepare("INSERT INTO user_activity (user_id, activity_type, description, ip_address) VALUES (?, ?, ?, ?)");
+ $stmt->execute([$user_id, $type, $description, $ip_address]);
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/api/purchase-product.php b/jweb/ac1/src/api/purchase-product.php
new file mode 100644
index 0000000000000000000000000000000000000000..44d4d20ca3c7ebb4cc8c802f53e98da76d2fa973
--- /dev/null
+++ b/jweb/ac1/src/api/purchase-product.php
@@ -0,0 +1,109 @@
+ false, 'message' => 'Not authenticated']);
+ exit;
+}
+
+// Include database configuration
+require_once '../../db.php';
+
+// Get user data from session
+$user_id = $_SESSION['user_id'] ?? null;
+$current_balance = $_SESSION['balance'];
+
+if (!$user_id) {
+ echo json_encode(['success' => false, 'message' => 'User not identified']);
+ exit;
+}
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ $product_id = filter_input(INPUT_POST, 'product_id', FILTER_SANITIZE_NUMBER_INT);
+
+ try {
+ // Start transaction
+ $pdo->beginTransaction();
+
+ // Get product details
+ $stmt = $pdo->prepare("SELECT * FROM products WHERE id = ? AND is_active = TRUE");
+ $stmt->execute([$product_id]);
+ $product = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if (!$product) {
+ throw new Exception("Product not available.");
+ }
+
+ // Check if user has sufficient balance
+ if ($current_balance < $product['price']) {
+ throw new Exception("Insufficient balance to purchase this product. You need KES " .
+ number_format($product['price'] - $current_balance, 2) . " more.");
+ }
+
+ // Deduct product price from user's balance
+ $new_balance = $current_balance - $product['price'];
+ $stmt = $pdo->prepare("UPDATE users SET balance = ? WHERE id = ?");
+ $stmt->execute([$new_balance, $user_id]);
+
+ // Record the transaction
+ $stmt = $pdo->prepare("INSERT INTO transactions (user_id, type, amount, description, balance_after) VALUES (?, 'product_purchase', ?, ?, ?)");
+ $stmt->execute([
+ $user_id,
+ $product['price'],
+ "Purchased: " . $product['name'],
+ $new_balance
+ ]);
+
+ // Add to user's products
+ $stmt = $pdo->prepare("INSERT INTO user_products (user_id, product_id, purchase_price, cashback_received) VALUES (?, ?, ?, ?)");
+ $stmt->execute([$user_id, $product_id, $product['price'], $product['cashback_amount']]);
+
+ // If there's cashback, process it
+ if ($product['cashback_amount'] > 0) {
+ $cashback_balance = $new_balance + $product['cashback_amount'];
+ $stmt = $pdo->prepare("UPDATE users SET balance = ?, rewards = rewards + ? WHERE id = ?");
+ $stmt->execute([$cashback_balance, $product['cashback_amount'], $user_id]);
+
+ // Record cashback transaction
+ $stmt = $pdo->prepare("INSERT INTO transactions (user_id, type, amount, description, balance_after) VALUES (?, 'cashback', ?, ?, ?)");
+ $stmt->execute([
+ $user_id,
+ $product['cashback_amount'],
+ "Cashback for: " . $product['name'],
+ $cashback_balance
+ ]);
+
+ $new_balance = $cashback_balance;
+ }
+
+ // Update user package if this is a package product
+ if (stripos($product['name'], 'package') !== false || stripos($product['name'], 'bundle') !== false) {
+ $stmt = $pdo->prepare("UPDATE users SET package = ? WHERE id = ?");
+ $stmt->execute([$product['name'], $user_id]);
+
+ // Update session data
+ $_SESSION['package'] = $product['name'];
+ }
+
+ // Update session balance
+ $_SESSION['balance'] = $new_balance;
+
+ // Commit transaction
+ $pdo->commit();
+
+ // Return success response
+ echo json_encode([
+ 'success' => true,
+ 'message' => 'Product purchased successfully!',
+ 'new_balance' => $new_balance,
+ 'product_name' => $product['name'],
+ 'redirect_url' => 'package-' . strtolower(str_replace(' ', '-', $product['name'])) . '.php'
+ ]);
+
+ } catch (Exception $e) {
+ $pdo->rollBack();
+ echo json_encode(['success' => false, 'message' => $e->getMessage()]);
+ }
+ exit;
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/api/purchase.php b/jweb/ac1/src/api/purchase.php
new file mode 100644
index 0000000000000000000000000000000000000000..a2198f98d5a097553475bef159afcc1e749b5f46
--- /dev/null
+++ b/jweb/ac1/src/api/purchase.php
@@ -0,0 +1,60 @@
+ false, 'message' => 'Insufficient balance.']);
+ exit;
+ }
+
+ // Get package details
+ $stmt = $pdo->prepare("SELECT * FROM packages WHERE name = ?");
+ $stmt->execute([$package_name]);
+ $package = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if (!$package) {
+ echo json_encode(['success' => false, 'message' => 'Package not found.']);
+ exit;
+ }
+
+ // Start transaction
+ $pdo->beginTransaction();
+
+ try {
+ // Deduct amount from user balance
+ $stmt = $pdo->prepare("UPDATE users SET balance = balance - ?, package = ? WHERE id = ?");
+ $stmt->execute([$amount, $package_name, $user_id]);
+
+ // Record transaction
+ $stmt = $pdo->prepare("INSERT INTO transactions (user_id, type, amount, description, status) VALUES (?, 'purchase', ?, ?, 'completed')");
+ $stmt->execute([$user_id, $amount, "Purchased {$package_name} package"]);
+
+ // Add to user packages
+ $stmt = $pdo->prepare("INSERT INTO user_packages (user_id, package_id, investment_amount, expected_return) VALUES (?, ?, ?, ?)");
+ $stmt->execute([$user_id, $package['id'], $amount, $package['return_amount']]);
+
+ // Update user package
+ $stmt = $pdo->prepare("UPDATE users SET package = ? WHERE id = ?");
+ $stmt->execute([$package_name, $user_id]);
+
+ // Commit transaction
+ $pdo->commit();
+
+ // Update session
+ $_SESSION['balance'] -= $amount;
+ $_SESSION['package'] = $package_name;
+
+ echo json_encode(['success' => true, 'message' => 'Package purchased successfully!']);
+ } catch (Exception $e) {
+ $pdo->rollBack();
+ echo json_encode(['success' => false, 'message' => 'Purchase failed: ' . $e->getMessage()]);
+ }
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/api/redeem.php b/jweb/ac1/src/api/redeem.php
new file mode 100644
index 0000000000000000000000000000000000000000..74134a556d0f661ea414b4fb6e2c543094de898e
--- /dev/null
+++ b/jweb/ac1/src/api/redeem.php
@@ -0,0 +1,47 @@
+ false, 'message' => 'Not logged in']);
+ exit;
+}
+
+// Include database connection
+require_once '../../db.php';
+require_once '../classes/User.php';
+require_once '../classes/Transaction.php';
+
+$database = new Database();
+$db = $database->getConnection();
+$user = new User($db);
+$transaction = new Transaction($db);
+
+if ($user->getUserByUsername($_SESSION['username'])) {
+ // Process redemption
+ if ($user->rewards > 0) {
+ $amount = $user->rewards;
+
+ // Add rewards to balance and reset rewards
+ $user->updateBalance($amount);
+ $user->updateRewards(-$amount);
+
+ // Create transaction record
+ $transaction->user_id = $user->id;
+ $transaction->type = 'bonus';
+ $transaction->amount = $amount;
+ $transaction->description = "Rewards redemption";
+ $transaction->status = 'completed';
+
+ if ($transaction->create()) {
+ echo json_encode(['success' => true, 'message' => 'Rewards redeemed successfully']);
+ } else {
+ echo json_encode(['success' => false, 'message' => 'Failed to record transaction']);
+ }
+ } else {
+ echo json_encode(['success' => false, 'message' => 'No rewards to redeem']);
+ }
+} else {
+ echo json_encode(['success' => false, 'message' => 'User not found']);
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/api/register.php b/jweb/ac1/src/api/register.php
new file mode 100644
index 0000000000000000000000000000000000000000..827556b038b9442988eef0ded51973e0bf5501dd
--- /dev/null
+++ b/jweb/ac1/src/api/register.php
@@ -0,0 +1,39 @@
+getConnection();
+
+$referrer = null;
+$referral_code = isset($_GET['ref']) ? $_GET['ref'] : '';
+
+// Check if referral code is valid
+if (!empty($referral_code)) {
+ $user = new User($db);
+ $referrer = $user->getUserByReferralCode($referral_code);
+}
+
+if ($_POST) {
+ // Handle registration logic here
+ $username = $_POST['username'];
+ $email = $_POST['email'];
+ $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
+
+ // Create new user
+ $new_user = new User($db);
+ // ... your registration logic
+
+ // If registration successful and referral code was used
+ if (!empty($referral_code) && $referrer) {
+ $referral = new Referral($db);
+ $referral->createReferral($referrer['id'], $new_user_id);
+
+ $_SESSION['message'] = "Welcome! You were referred by " . $referrer['username'];
+ }
+}
+?>
+
+
\ No newline at end of file
diff --git a/jweb/ac1/src/api/revoke_token.php b/jweb/ac1/src/api/revoke_token.php
new file mode 100644
index 0000000000000000000000000000000000000000..b1489de140060cd24f67e0ac53ca8877cfda5ed0
--- /dev/null
+++ b/jweb/ac1/src/api/revoke_token.php
@@ -0,0 +1,23 @@
+ false, 'message' => 'Not logged in']);
+ exit;
+}
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ $token_id = (int) $_POST['token_id'];
+ $user_id = $_SESSION['user_id'];
+
+ $sql = "UPDATE access_tokens SET status = 'revoked' WHERE id = ? AND user_id = ?";
+ $stmt = $conn->prepare($sql);
+ $stmt->bind_param("ii", $token_id, $user_id);
+
+ if ($stmt->execute()) {
+ echo json_encode(['success' => true]);
+ } else {
+ echo json_encode(['success' => false, 'message' => 'Failed to revoke token']);
+ }
+}
diff --git a/jweb/ac1/src/api/settings_handler.php b/jweb/ac1/src/api/settings_handler.php
new file mode 100644
index 0000000000000000000000000000000000000000..d860b2b1a3aed9f956173590b2cb8c92b8d838be
--- /dev/null
+++ b/jweb/ac1/src/api/settings_handler.php
@@ -0,0 +1,77 @@
+getConnection();
+
+$user_id = $_SESSION['user_id'];
+
+if($_POST) {
+ try {
+ // Update general settings
+ if(isset($_POST['dark_mode']) || isset($_POST['language']) || isset($_POST['currency']) || isset($_POST['auto_logout'])) {
+ $dark_mode = isset($_POST['dark_mode']) ? 1 : 0;
+ $language = $_POST['language'] ?? 'en';
+ $currency = $_POST['currency'] ?? 'KES';
+ $auto_logout = isset($_POST['auto_logout']) ? 1 : 0;
+
+ $query = "INSERT INTO user_settings (user_id, dark_mode, language, currency, auto_logout)
+ VALUES (?, ?, ?, ?, ?)
+ ON DUPLICATE KEY UPDATE
+ dark_mode = VALUES(dark_mode),
+ language = VALUES(language),
+ currency = VALUES(currency),
+ auto_logout = VALUES(auto_logout)";
+
+ $stmt = $db->prepare($query);
+ $stmt->execute([$user_id, $dark_mode, $language, $currency, $auto_logout]);
+
+ $_SESSION['success'] = "Settings updated successfully!";
+ }
+
+ // Handle password change
+ if(isset($_POST['current_password']) && isset($_POST['new_password'])) {
+ $current_password = $_POST['current_password'];
+ $new_password = $_POST['new_password'];
+
+ // Verify current password
+ $query = "SELECT password_hash FROM users WHERE id = ?";
+ $stmt = $db->prepare($query);
+ $stmt->execute([$user_id]);
+ $user = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if(password_verify($current_password, $user['password_hash'])) {
+ $new_password_hash = password_hash($new_password, PASSWORD_BCRYPT);
+
+ $query = "UPDATE users SET password_hash = ? WHERE id = ?";
+ $stmt = $db->prepare($query);
+ $stmt->execute([$new_password_hash, $user_id]);
+
+ $_SESSION['success'] = "Password updated successfully!";
+ } else {
+ $_SESSION['error'] = "Current password is incorrect!";
+ }
+ }
+
+ } catch(PDOException $exception) {
+ $_SESSION['error'] = "Error updating settings: " . $exception->getMessage();
+ }
+
+ header("Location: ../pages/settings.php");
+ exit();
+}
+
+// Get user settings
+function getUserSettings($db, $user_id) {
+ $query = "SELECT * FROM user_settings WHERE user_id = ?";
+ $stmt = $db->prepare($query);
+ $stmt->execute([$user_id]);
+ return $stmt->fetch(PDO::FETCH_ASSOC) ?: [];
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/api/submit_ticket.php b/jweb/ac1/src/api/submit_ticket.php
new file mode 100644
index 0000000000000000000000000000000000000000..2129a22fe43678b681b03209c248e53301d9249d
--- /dev/null
+++ b/jweb/ac1/src/api/submit_ticket.php
@@ -0,0 +1,124 @@
+ false, 'message' => 'Unauthorized']);
+ exit;
+}
+
+// Include database and classes
+include_once '../../db.php';
+include_once '../models/User.php';
+include_once '../models/SupportTicket.php';
+
+// Define TicketHandler class properly
+class TicketHandler {
+ public static function notifyCustomerCare($ticket_number, $data) {
+ // Build message
+ $message = "New Support Ticket Created:\n";
+ $message .= "Ticket Number: $ticket_number\n";
+ $message .= "Issue Type: " . $data['issue_type'] . "\n";
+ $message .= "Subject: " . $data['subject'] . "\n";
+ $message .= "Priority: " . $data['priority'] . "\n";
+
+ // Example: Send email notification
+ $to = "customercare@jmotors.com";
+ $subject = "New Support Ticket: $ticket_number";
+ $headers = "From: support@jmotors.com\r\n";
+
+ @mail($to, $subject, $message, $headers);
+
+ // Optional: Add WhatsApp, Slack, or API integration here
+ }
+}
+
+// Get POST data
+$data = json_decode(file_get_contents('php://input'), true);
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ try {
+ // Validate required fields
+ $required = ['issue_type', 'subject', 'description', 'priority'];
+ foreach ($required as $field) {
+ if (empty($data[$field])) {
+ throw new Exception("Missing required field: $field");
+ }
+ }
+
+ // Initialize database connection
+ $database = new Database();
+ $db = $database->getConnection();
+
+ // Sync user data
+ $user = new User($db);
+ $user_id = $user->syncUser(
+ $_SESSION['username'],
+ $_SESSION['email'],
+ $_SESSION['tier'],
+ $_SESSION['package']
+ );
+
+ if (!$user_id) {
+ throw new Exception("Failed to sync user data");
+ }
+
+ // Handle file uploads
+ $attachments = [];
+ if (!empty($_FILES['attachments'])) {
+ $upload_dir = '../uploads/support/';
+ if (!is_dir($upload_dir)) {
+ mkdir($upload_dir, 0755, true);
+ }
+
+ foreach ($_FILES['attachments']['tmp_name'] as $key => $tmp_name) {
+ if ($_FILES['attachments']['error'][$key] === UPLOAD_ERR_OK) {
+ $file_name = time() . '_' . basename($_FILES['attachments']['name'][$key]);
+ $file_path = $upload_dir . $file_name;
+
+ if (move_uploaded_file($tmp_name, $file_path)) {
+ $attachments[] = $file_path;
+ }
+ }
+ }
+ }
+
+ // Create support ticket
+ $ticket = new SupportTicket($db);
+ $ticket->user_id = $user_id;
+ $ticket->issue_type = $data['issue_type'];
+ $ticket->subject = $data['subject'];
+ $ticket->description = $data['description'];
+ $ticket->priority = $data['priority'];
+ $ticket->attachments = json_encode($attachments);
+
+ $ticket_number = $ticket->create();
+
+ if ($ticket_number) {
+ // ✅ Correct way to call notification
+ TicketHandler::notifyCustomerCare($ticket_number, $data);
+
+ echo json_encode([
+ 'success' => true,
+ 'message' => 'Support ticket submitted successfully',
+ 'ticket_number' => $ticket_number
+ ]);
+ } else {
+ throw new Exception("Failed to create support ticket");
+ }
+
+
+ } catch (Exception $e) {
+ http_response_code(400);
+ echo json_encode([
+ 'success' => false,
+ 'message' => $e->getMessage()
+ ]);
+ }
+} else {
+ http_response_code(405);
+ echo json_encode(['success' => false, 'message' => 'Method not allowed']);
+}
+?>
diff --git a/jweb/ac1/src/api/upload-functions.php b/jweb/ac1/src/api/upload-functions.php
new file mode 100644
index 0000000000000000000000000000000000000000..e438569b169c8632f548ae11e9e5d5f55d4e9d17
--- /dev/null
+++ b/jweb/ac1/src/api/upload-functions.php
@@ -0,0 +1,114 @@
+prepare("SELECT * FROM uploads WHERE user_id = ? AND created_at >= ? ORDER BY created_at DESC");
+ $stmt->bind_param("is", $userId, $today);
+ $stmt->execute();
+ $result = $stmt->get_result();
+
+ $uploads = [];
+ while ($row = $result->fetch_assoc()) {
+ $uploads[] = $row;
+ }
+ return $uploads;
+}
+
+// ===================================
+// Get today's upload stats for a user
+// ===================================
+function getTodaysUploadStats($userId) {
+ global $conn;
+ $today = date('Y-m-d 00:00:00');
+
+ $stmt = $conn->prepare("
+ SELECT
+ COUNT(*) AS total_uploads,
+ SUM(CASE WHEN status = 'approved' THEN 1 ELSE 0 END) AS approved_uploads,
+ IFNULL(SUM(reward_amount), 0) AS total_earnings
+ FROM uploads
+ WHERE user_id = ? AND created_at >= ?
+ ");
+ $stmt->bind_param("is", $userId, $today);
+ $stmt->execute();
+ $result = $stmt->get_result();
+
+ return $result->fetch_assoc();
+}
+
+// ===================================
+// Process file upload
+// ===================================
+function processFileUpload($userId, $fileData) {
+ global $conn;
+
+ $uploadDir = __DIR__ . '/../uploads/';
+ if (!is_dir($uploadDir)) {
+ if (!mkdir($uploadDir, 0775, true)) {
+ return ['success' => false, 'error' => 'Failed to create upload directory.'];
+ }
+ }
+
+ $fileName = uniqid() . '_' . basename($fileData['name']);
+ $filePath = $uploadDir . $fileName;
+
+ if (move_uploaded_file($fileData['tmp_name'], $filePath)) {
+ // Calculate reward
+ $rewardAmount = calculateRewardAmount($fileData['type'], $fileData['size']);
+
+ // Save upload record
+ $stmt = $conn->prepare("
+ INSERT INTO uploads (user_id, file_name, file_type, file_size, status, reward_amount, created_at)
+ VALUES (?, ?, ?, ?, 'approved', ?, NOW())
+ ");
+ $stmt->bind_param("issid", $userId, $fileName, $fileData['type'], $fileData['size'], $rewardAmount);
+ $stmt->execute();
+
+ // Update user earnings
+ $stmt2 = $conn->prepare("UPDATE users SET meta_earnings = meta_earnings + ? WHERE id = ?");
+ $stmt2->bind_param("di", $rewardAmount, $userId);
+ $stmt2->execute();
+
+ return [
+ 'success' => true,
+ 'upload_id' => $conn->insert_id,
+ 'reward' => $rewardAmount
+ ];
+ } else {
+ return ['success' => false, 'error' => 'File upload failed. Check permissions.'];
+ }
+}
+
+// ===================================
+// Calculate reward amount
+// ===================================
+function calculateRewardAmount($fileType, $fileSize) {
+ $baseReward = 50; // KES per file
+ $typeBonus = 0;
+
+ if (strpos($fileType, 'image/') === 0) {
+ $typeBonus = 10;
+ } elseif (strpos($fileType, 'video/') === 0) {
+ $typeBonus = 20;
+ }
+
+ $sizeBonus = 0;
+ if ($fileSize > 10 * 1024 * 1024) {
+ $sizeBonus = 15;
+ } elseif ($fileSize > 5 * 1024 * 1024) {
+ $sizeBonus = 10;
+ } elseif ($fileSize > 1 * 1024 * 1024) {
+ $sizeBonus = 5;
+ }
+
+ return $baseReward + $typeBonus + $sizeBonus;
+}
+?>
diff --git a/jweb/ac1/src/api/upload_handler.php b/jweb/ac1/src/api/upload_handler.php
new file mode 100644
index 0000000000000000000000000000000000000000..30196e07289176707ad5bec1afcaa6d125167258
--- /dev/null
+++ b/jweb/ac1/src/api/upload_handler.php
@@ -0,0 +1,68 @@
+uploadDir)) {
+ mkdir($this->uploadDir, 0755, true);
+ }
+ }
+
+ public function upload($file) {
+ try {
+ // Check for errors
+ if ($file['error'] !== UPLOAD_ERR_OK) {
+ throw new Exception('Upload error: ' . $file['error']);
+ }
+
+ // Check file size
+ if ($file['size'] > $this->maxSize) {
+ throw new Exception('File size exceeds maximum limit of 5MB');
+ }
+
+ // Check file type
+ $fileExtension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
+ if (!in_array($fileExtension, $this->allowedTypes)) {
+ throw new Exception('Invalid file type. Allowed types: ' . implode(', ', $this->allowedTypes));
+ }
+
+ // Generate unique filename
+ $filename = uniqid() . '_' . time() . '.' . $fileExtension;
+ $filepath = $this->uploadDir . $filename;
+
+ // Move uploaded file
+ if (!move_uploaded_file($file['tmp_name'], $filepath)) {
+ throw new Exception('Failed to move uploaded file');
+ }
+
+ return $filename;
+
+ } catch (Exception $e) {
+ error_log("File Upload Error: " . $e->getMessage());
+ return false;
+ }
+ }
+}
+
+// Handle file upload via AJAX
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['evidence_file'])) {
+ $uploader = new FileUploader();
+ $filename = $uploader->upload($_FILES['evidence_file']);
+
+ if ($filename) {
+ echo json_encode(['success' => true, 'filename' => $filename]);
+ } else {
+ echo json_encode(['success' => false, 'message' => 'File upload failed']);
+ }
+ exit;
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/api/validate.php b/jweb/ac1/src/api/validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..f4d0e4f58cf41da4556293777b0e33a0691477de
--- /dev/null
+++ b/jweb/ac1/src/api/validate.php
@@ -0,0 +1,47 @@
+ 'No token provided']);
+ exit;
+}
+
+// Get request details
+$endpoint = $_SERVER['REQUEST_URI'];
+$ip_address = $_SERVER['REMOTE_ADDR'];
+$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
+$method = $_SERVER['REQUEST_METHOD'];
+
+// Validate token
+$result = $tokenManager->validateAndLogUsage($token, $endpoint, $ip_address, $user_agent, $method);
+
+if ($result['valid']) {
+ echo json_encode([
+ 'valid' => true,
+ 'user' => $result['username'],
+ 'permissions' => $result['permissions'],
+ 'timestamp' => date('c')
+ ]);
+} else {
+ http_response_code(401);
+ echo json_encode([
+ 'valid' => false,
+ 'error' => $result['error']
+ ]);
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/api/withdraw.php b/jweb/ac1/src/api/withdraw.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb12628b58a19f6efad248343429829e8e8e4701
--- /dev/null
+++ b/jweb/ac1/src/api/withdraw.php
@@ -0,0 +1,57 @@
+ false, 'message' => 'Not logged in']);
+ exit;
+}
+
+// Get JSON input
+$input = json_decode(file_get_contents('php://input'), true);
+
+if (!isset($input['amount']) || !isset($input['method'])) {
+ echo json_encode(['success' => false, 'message' => 'Invalid input']);
+ exit;
+}
+
+// Include database connection
+require_once '../../db.php';
+require_once '../classes/User.php';
+require_once '../classes/Transaction.php';
+
+$database = new Database();
+$db = $database->getConnection();
+$user = new User($db);
+$transaction = new Transaction($db);
+
+if ($user->getUserByUsername($_SESSION['username'])) {
+ // Process withdrawal
+ $amount = floatval($input['amount']);
+ $method = $input['method'];
+
+ // Check if user has enough balance
+ if ($user->balance >= $amount) {
+ // Deduct amount from balance and add to withdrawals
+ $user->updateBalance(-$amount);
+ $user->updateWithdrawals($amount);
+
+ // Create transaction record
+ $transaction->user_id = $user->id;
+ $transaction->type = 'withdrawal';
+ $transaction->amount = $amount;
+ $transaction->description = "Withdrawal via $method";
+ $transaction->status = 'pending'; // Withdrawals might need approval
+
+ if ($transaction->create()) {
+ echo json_encode(['success' => true, 'message' => 'Withdrawal request submitted']);
+ } else {
+ echo json_encode(['success' => false, 'message' => 'Failed to record transaction']);
+ }
+ } else {
+ echo json_encode(['success' => false, 'message' => 'Insufficient balance']);
+ }
+} else {
+ echo json_encode(['success' => false, 'message' => 'User not found']);
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/classes/Transaction.php b/jweb/ac1/src/classes/Transaction.php
new file mode 100644
index 0000000000000000000000000000000000000000..6222730837c838bb38b965bf86d82e68b4043a94
--- /dev/null
+++ b/jweb/ac1/src/classes/Transaction.php
@@ -0,0 +1,82 @@
+conn = $db;
+ }
+
+ // Create a new transaction
+ public function create() {
+ $query = "INSERT INTO " . $this->table_name . "
+ SET user_id=:user_id, type=:type, amount=:amount,
+ description=:description, status=:status, reference=:reference";
+
+ $stmt = $this->conn->prepare($query);
+
+ // Sanitize inputs
+ $this->user_id = htmlspecialchars(strip_tags($this->user_id));
+ $this->type = htmlspecialchars(strip_tags($this->type));
+ $this->amount = htmlspecialchars(strip_tags($this->amount));
+ $this->description = htmlspecialchars(strip_tags($this->description));
+ $this->status = htmlspecialchars(strip_tags($this->status));
+ $this->reference = htmlspecialchars(strip_tags($this->reference));
+
+ // Bind values
+ $stmt->bindParam(":user_id", $this->user_id);
+ $stmt->bindParam(":type", $this->type);
+ $stmt->bindParam(":amount", $this->amount);
+ $stmt->bindParam(":description", $this->description);
+ $stmt->bindParam(":status", $this->status);
+ $stmt->bindParam(":reference", $this->reference);
+
+ if($stmt->execute()) {
+ return true;
+ }
+ return false;
+ }
+
+ // Get transactions by user ID
+ public function getTransactionsByUserId($user_id, $limit = 10) {
+ $query = "SELECT * FROM " . $this->table_name . "
+ WHERE user_id = ?
+ ORDER BY created_at DESC
+ LIMIT ?";
+
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $user_id);
+ $stmt->bindParam(2, $limit, PDO::PARAM_INT);
+ $stmt->execute();
+
+ return $stmt;
+ }
+
+ // Get transactions by type
+ public function getTransactionsByType($user_id, $type, $limit = 10) {
+ $query = "SELECT * FROM " . $this->table_name . "
+ WHERE user_id = ? AND type = ?
+ ORDER BY created_at DESC
+ LIMIT ?";
+
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $user_id);
+ $stmt->bindParam(2, $type);
+ $stmt->bindParam(3, $limit, PDO::PARAM_INT);
+ $stmt->execute();
+
+ return $stmt;
+ }
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/classes/User.php b/jweb/ac1/src/classes/User.php
new file mode 100644
index 0000000000000000000000000000000000000000..ccd0638231b181a75f3279057d7e9afd4d775030
--- /dev/null
+++ b/jweb/ac1/src/classes/User.php
@@ -0,0 +1,127 @@
+conn = $db;
+ }
+
+ // Get user by ID
+ public function getUserById($id) {
+ $query = "SELECT * FROM " . $this->table_name . " WHERE id = ? LIMIT 0,1";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $id);
+ $stmt->execute();
+
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if($row) {
+ $this->id = $row['id'];
+ $this->username = $row['username'];
+ $this->email = $row['email'];
+ $this->tier = $row['tier'];
+ $this->package = $row['package'];
+ $this->balance = $row['balance'];
+ $this->total_deposits = $row['total_deposits'];
+ $this->total_withdrawals = $row['total_withdrawals'];
+ $this->rewards = $row['rewards'];
+ return true;
+ }
+ return false;
+ }
+
+ // Get user by username
+ public function getUserByUsername($username) {
+ $query = "SELECT * FROM " . $this->table_name . " WHERE username = ? LIMIT 0,1";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $username);
+ $stmt->execute();
+
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if($row) {
+ $this->id = $row['id'];
+ $this->username = $row['username'];
+ $this->email = $row['email'];
+ $this->tier = $row['tier'];
+ $this->package = $row['package'];
+ $this->balance = $row['balance'];
+ $this->total_deposits = $row['total_deposits'];
+ $this->total_withdrawals = $row['total_withdrawals'];
+ $this->rewards = $row['rewards'];
+ return true;
+ }
+ return false;
+ }
+
+ // Update user balance
+ public function updateBalance($amount) {
+ $query = "UPDATE " . $this->table_name . " SET balance = balance + ? WHERE id = ?";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $amount);
+ $stmt->bindParam(2, $this->id);
+
+ if($stmt->execute()) {
+ $this->balance += $amount;
+ return true;
+ }
+ return false;
+ }
+
+ // Update user deposits
+ public function updateDeposits($amount) {
+ $query = "UPDATE " . $this->table_name . " SET total_deposits = total_deposits + ? WHERE id = ?";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $amount);
+ $stmt->bindParam(2, $this->id);
+
+ if($stmt->execute()) {
+ $this->total_deposits += $amount;
+ return true;
+ }
+ return false;
+ }
+
+ // Update user withdrawals
+ public function updateWithdrawals($amount) {
+ $query = "UPDATE " . $this->table_name . " SET total_withdrawals = total_withdrawals + ? WHERE id = ?";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $amount);
+ $stmt->bindParam(2, $this->id);
+
+ if($stmt->execute()) {
+ $this->total_withdrawals += $amount;
+ return true;
+ }
+ return false;
+ }
+
+ // Update user rewards
+ public function updateRewards($amount) {
+ $query = "UPDATE " . $this->table_name . " SET rewards = rewards + ? WHERE id = ?";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $amount);
+ $stmt->bindParam(2, $this->id);
+
+ if($stmt->execute()) {
+ $this->rewards += $amount;
+ return true;
+ }
+ return false;
+ }
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/config/database.php b/jweb/ac1/src/config/database.php
new file mode 100644
index 0000000000000000000000000000000000000000..12b745365fbcfdf22689fc67ec2b833675be73f4
--- /dev/null
+++ b/jweb/ac1/src/config/database.php
@@ -0,0 +1,25 @@
+conn = null;
+
+ try {
+ $this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password);
+ $this->conn->exec("set names utf8");
+ $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ } catch(PDOException $exception) {
+ echo "Connection error: " . $exception->getMessage();
+ }
+
+ return $this->conn;
+ }
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/models/Referral.php b/jweb/ac1/src/models/Referral.php
new file mode 100644
index 0000000000000000000000000000000000000000..636f33523c85c4186dc0b20fc373e8886b448898
--- /dev/null
+++ b/jweb/ac1/src/models/Referral.php
@@ -0,0 +1,47 @@
+conn = $db;
+ }
+
+ // Create new referral
+ public function createReferral($referrer_id, $referred_id) {
+ $query = "INSERT INTO " . $this->table_name . "
+ (referrer_id, referred_id, status)
+ VALUES (?, ?, 'pending')";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $referrer_id);
+ $stmt->bindParam(2, $referred_id);
+ return $stmt->execute();
+ }
+
+ // Complete referral (when referred user makes deposit)
+ public function completeReferral($referred_id, $commission_amount) {
+ $query = "UPDATE " . $this->table_name . "
+ SET status = 'completed', commission_earned = ?
+ WHERE referred_id = ? AND status = 'pending'";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $commission_amount);
+ $stmt->bindParam(2, $referred_id);
+ return $stmt->execute();
+ }
+
+ // Get referral by referred user ID
+ public function getReferralByReferredId($referred_id) {
+ $query = "SELECT * FROM " . $this->table_name . " WHERE referred_id = ? LIMIT 1";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $referred_id);
+ $stmt->execute();
+ return $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/models/TokenManager.php b/jweb/ac1/src/models/TokenManager.php
new file mode 100644
index 0000000000000000000000000000000000000000..a02fd2b011a1e3e4869d9317b9414d9703689621
--- /dev/null
+++ b/jweb/ac1/src/models/TokenManager.php
@@ -0,0 +1,156 @@
+conn = $database->getConnection();
+
+ // Create tables if they don't exist
+ $this->createTablesIfNotExist();
+ }
+
+ private function createTablesIfNotExist() {
+ try {
+ // Create access_tokens table
+ $query = "CREATE TABLE IF NOT EXISTS access_tokens (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ user_id INT NOT NULL,
+ token_name VARCHAR(100) NOT NULL,
+ token_value VARCHAR(255) UNIQUE NOT NULL,
+ permissions JSON NOT NULL,
+ ip_restrictions TEXT,
+ expires_at TIMESTAMP NULL,
+ is_active BOOLEAN DEFAULT TRUE,
+ last_used TIMESTAMP NULL,
+ usage_count INT DEFAULT 0,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ )";
+ $this->conn->exec($query);
+
+ // Create token_usage_logs table
+ $query = "CREATE TABLE IF NOT EXISTS token_usage_logs (
+ id INT PRIMARY KEY AUTO_INCREMENT,
+ token_id INT NOT NULL,
+ user_id INT NOT NULL,
+ endpoint VARCHAR(100) NOT NULL,
+ ip_address VARCHAR(45),
+ user_agent TEXT,
+ request_method VARCHAR(10),
+ response_code INT,
+ processing_time_ms INT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ )";
+ $this->conn->exec($query);
+
+ } catch (PDOException $e) {
+ error_log("Table creation error: " . $e->getMessage());
+ }
+ }
+
+ private function generateToken() {
+ return 'jm_' . bin2hex(random_bytes(24));
+ }
+
+ public function createToken($user_id, $token_name, $permissions, $expires_in_days = 30, $ip_restrictions = null) {
+ try {
+ $token_value = $this->generateToken();
+
+ $expires_at = null;
+ if ($expires_in_days > 0) {
+ $expires_at = date('Y-m-d H:i:s', strtotime("+{$expires_in_days} days"));
+ }
+
+ $query = "INSERT INTO {$this->table_tokens}
+ (user_id, token_name, token_value, permissions, ip_restrictions, expires_at)
+ VALUES (:user_id, :token_name, :token_value, :permissions, :ip_restrictions, :expires_at)";
+
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(":user_id", $user_id);
+ $stmt->bindParam(":token_name", $token_name);
+ $stmt->bindParam(":token_value", $token_value);
+ $stmt->bindParam(":permissions", json_encode($permissions));
+ $stmt->bindParam(":ip_restrictions", $ip_restrictions);
+ $stmt->bindParam(":expires_at", $expires_at);
+
+ if ($stmt->execute()) {
+ return [
+ 'success' => true,
+ 'token' => $token_value,
+ 'id' => $this->conn->lastInsertId()
+ ];
+ }
+ } catch (PDOException $e) {
+ error_log("Token creation error: " . $e->getMessage());
+ }
+
+ return ['success' => false, 'message' => 'Failed to create token'];
+ }
+
+ public function getUserTokens($user_id) {
+ try {
+ $query = "SELECT * FROM {$this->table_tokens}
+ WHERE user_id = :user_id AND is_active = TRUE
+ ORDER BY created_at DESC";
+
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(":user_id", $user_id);
+ $stmt->execute();
+
+ $tokens = [];
+ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+ $row['permissions'] = json_decode($row['permissions'], true) ?? [];
+ $row['is_expired'] = $row['expires_at'] && strtotime($row['expires_at']) < time();
+ $tokens[] = $row;
+ }
+
+ return $tokens;
+ } catch (PDOException $e) {
+ error_log("Get tokens error: " . $e->getMessage());
+ return [];
+ }
+ }
+
+ public function revokeToken($token_id, $user_id) {
+ try {
+ $query = "UPDATE {$this->table_tokens} SET is_active = FALSE
+ WHERE id = :token_id AND user_id = :user_id";
+
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(":token_id", $token_id);
+ $stmt->bindParam(":user_id", $user_id);
+
+ return $stmt->execute();
+ } catch (PDOException $e) {
+ error_log("Revoke token error: " . $e->getMessage());
+ return false;
+ }
+ }
+
+ public function getRealtimeStats($user_id, $hours = 24) {
+ try {
+ $query = "SELECT
+ COUNT(*) as total_calls,
+ AVG(processing_time_ms) as avg_response_time
+ FROM {$this->table_usage}
+ WHERE user_id = :user_id
+ AND created_at >= DATE_SUB(NOW(), INTERVAL :hours HOUR)";
+
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(":user_id", $user_id);
+ $stmt->bindParam(":hours", $hours);
+ $stmt->execute();
+
+ return $stmt->fetch(PDO::FETCH_ASSOC) ?: ['total_calls' => 0, 'avg_response_time' => 0];
+ } catch (PDOException $e) {
+ error_log("Stats error: " . $e->getMessage());
+ return ['total_calls' => 0, 'avg_response_time' => 0];
+ }
+ }
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/models/User.php b/jweb/ac1/src/models/User.php
new file mode 100644
index 0000000000000000000000000000000000000000..d608d2adceb12b118e650c6bfe87fee8c7899c6c
--- /dev/null
+++ b/jweb/ac1/src/models/User.php
@@ -0,0 +1,116 @@
+conn = $db;
+ }
+
+ // Generate unique referral code
+ private function generateReferralCode($username) {
+ $base_code = strtoupper(substr(preg_replace('/[^a-zA-Z0-9]/', '', $username), 0, 3));
+ $random_number = mt_rand(100, 999);
+ return $base_code . $random_number;
+ }
+
+ // Get user by ID
+ public function getUserById($user_id) {
+ $query = "SELECT * FROM " . $this->table_name . " WHERE id = ? LIMIT 1";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $user_id);
+ $stmt->execute();
+
+ if ($stmt->rowCount() > 0) {
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ $this->id = $row['id'];
+ $this->username = $row['username'];
+ $this->email = $row['email'];
+ $this->tier = $row['tier'];
+ $this->package = $row['package'];
+ $this->balance = $row['balance'];
+ $this->total_deposits = $row['total_deposits'];
+ $this->total_withdrawals = $row['total_withdrawals'];
+ $this->rewards = $row['rewards'];
+ $this->referral_code = $row['referral_code'];
+ $this->referred_by = $row['referred_by'];
+ return true;
+ }
+ return false;
+ }
+
+ // Get user by referral code
+ public function getUserByReferralCode($referral_code) {
+ $query = "SELECT id, username FROM " . $this->table_name . " WHERE referral_code = ? LIMIT 1";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $referral_code);
+ $stmt->execute();
+ return $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+
+ // Create referral code for user
+ public function createReferralCode($user_id) {
+ $user = $this->getUserById($user_id);
+ if (!$user) return false;
+
+ if (empty($this->referral_code)) {
+ $referral_code = $this->generateReferralCode($this->username);
+
+ // Ensure uniqueness
+ while ($this->getUserByReferralCode($referral_code)) {
+ $referral_code = $this->generateReferralCode($this->username);
+ }
+
+ $query = "UPDATE " . $this->table_name . " SET referral_code = ? WHERE id = ?";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $referral_code);
+ $stmt->bindParam(2, $user_id);
+
+ if ($stmt->execute()) {
+ $this->referral_code = $referral_code;
+ return $referral_code;
+ }
+ }
+ return $this->referral_code;
+ }
+
+ // Get team members
+ public function getTeamMembers($user_id) {
+ $query = "SELECT u.username, u.email, u.tier, u.created_at, r.status, r.commission_earned
+ FROM users u
+ JOIN referrals r ON u.id = r.referred_id
+ WHERE r.referrer_id = ?
+ ORDER BY u.created_at DESC";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $user_id);
+ $stmt->execute();
+ return $stmt->fetchAll(PDO::FETCH_ASSOC);
+ }
+
+ // Get team statistics
+ public function getTeamStats($user_id) {
+ $query = "SELECT
+ COUNT(*) as total_members,
+ SUM(CASE WHEN DATE(r.created_at) = CURDATE() THEN 1 ELSE 0 END) as active_today,
+ COALESCE(SUM(r.commission_earned), 0) as team_earnings
+ FROM referrals r
+ WHERE r.referrer_id = ? AND r.status = 'completed'";
+ $stmt = $this->conn->prepare($query);
+ $stmt->bindParam(1, $user_id);
+ $stmt->execute();
+ return $stmt->fetch(PDO::FETCH_ASSOC);
+ }
+}
+?>
\ No newline at end of file
diff --git a/jweb/ac1/src/pages/access-token.php b/jweb/ac1/src/pages/access-token.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a071a4db7ab42cf8260ba4d00e6e5deaed004c3
--- /dev/null
+++ b/jweb/ac1/src/pages/access-token.php
@@ -0,0 +1,927 @@
+createToken($user_id, $token_name, $permissions, $expiry_days, $ip_restrictions);
+
+ if ($result['success']) {
+ $_SESSION['new_token'] = $result['token'];
+ $_SESSION['token_details'] = [
+ 'name' => $token_name,
+ 'expiry' => $expiry_days == 0 ? 'Never' : $expiry_days . ' days',
+ 'permissions' => implode(', ', $permissions)
+ ];
+ header('Location: access-token.php?success=1');
+ exit;
+ }
+ }
+
+ if (isset($_POST['revoke_token'])) {
+ $token_id = $_POST['token_id'];
+ $tokenManager->revokeToken($token_id, $user_id);
+ header('Location: access-token.php?revoked=1');
+ exit;
+ }
+}
+
+// Get user's active tokens
+$user_tokens = $tokenManager->getUserTokens($user_id);
+$active_tokens_count = count($user_tokens);
+$token_limit = 5;
+
+// Get real-time stats
+$realtime_stats = $tokenManager->getRealtimeStats($user_id, 24);
+?>
+
+
+
+
+
+
+ Japanese Motors — Access Token
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
jmotors
+
+
+
+
+
+
+
+
+ Token generated successfully!
+
+
+
+
+
+ Token revoked successfully!
+
+
+
+
+
🔑 API Access Tokens
+
Generate and manage access tokens for API integration and secure authentication
+
+
+
+
+
+
+ Generate New Token
+
+
+
+
+
Active Tokens
+
/
+
+
+
Token Limit
+
Maximum
+
+
+
+ = $token_limit): ?>
+
+
+ You've reached the maximum number of active tokens. Please revoke an existing token to create a new one.
+
+
+
+
+
+
+
+
+ Active Tokens
+
+
+
+
+
Last 24 Hours
+
+
+
API Calls
+
+
+
+
Avg. Response
+
ms
+
+
+
+
+
+
+
+
No active tokens
+
+
+
+
+
+
+
+
+
permissions
+
+
+
+
+
+
+
+
+
+
+
+
Created:
+
Used: times
+
+
+
+
+
+
+
+
+
+
+
+ Token Security
+
+
+
+
+ Never share tokens in public repositories
+
+
+
+ Rotate tokens regularly
+
+
+
+ Use IP restrictions when possible
+
+
+
+
+
+
+
+
+ Token Information
+
+
+
+
+
What are access tokens used for?
+
+
+
+
Access tokens allow third-party applications to interact with the Jmotors API on your behalf. They provide a secure way to authenticate requests without sharing your password.
+
+
+
+
+
+
How do I use an access token?
+
+
+
+
Include the token in the Authorization header: Authorization: Bearer YOUR_TOKEN_HERE. Always use HTTPS for security.
+
+
+
+
+
+
What if my token is compromised?
+
+
+
+
Revoke it immediately from this page and generate a new one. Monitor your account for suspicious activity.
+
+
+
+
+
+
+
+
+
+
+
+ New Access Token Created
+
+
+
+
Please copy your token now. You won't be able to see it again!
+
+
+
+
+
+
+
+
Name:
+
Expires:
+
Permissions:
+
+
+
+
+
+
For security reasons, this token will only be displayed once. Please store it in a secure location.
Review and approve new agent applications to grow your network
+
+
+
+
+
+
+ Pending Approvals
+
+
+
+
+
Pending Applications
+
+
+
+
Approved This Month
+
Agents
+
+
+
+
+
+
+
+
+
No pending agent applications
+
New agent applications will appear here for review
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Applied On
+
+
+
+
Location
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Approval Stats
+
+
+
+
+ Total Applications
+
+
+
+
+
+
+
+
+
+ Approved
+
+
+
+
+
+
+
+
+
+ Rejected
+
+
+
+
+
+
+
+
+
+ Pending
+
+
+
+
+
+
+
+
+
+ Commission Earnings
+
+
+
+ This Month
+ KES
+
+
+ Total Earned
+ KES
+
+
+
+
+
+
+
+
+
+
+ Agent Approval Guidelines
+
+
+
+
+
What are the requirements for agent approval?
+
+
+
+
Agents must meet the following criteria: valid government ID, minimum age of 18 years, completed training program, and minimum initial deposit of 1,000 KES. Additional verification may be required based on location and other factors.
+
+
+
+
+
+
How long does the approval process take?
+
+
+
+
The standard approval process takes 24-48 hours after all required documents are submitted. Delays may occur if additional verification is needed. You will receive a notification once the application has been processed.
+
+
+
+
+
+
What commissions do I earn from approved agents?
+
+
+
+
You earn 10% commission on your direct agents' earnings for the first 3 months, then 5% ongoing. Additionally, you receive 2% override commission on your team's second level agents. Commissions are paid weekly every Monday.
+
+
+
+
+
+
+
+
+
+
+ Review Agent Application
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jweb/ac1/src/pages/agent-claim.php b/jweb/ac1/src/pages/agent-claim.php
new file mode 100644
index 0000000000000000000000000000000000000000..1ea1f98b3cc64f44095f0ac1215fc1a30dbeabce
--- /dev/null
+++ b/jweb/ac1/src/pages/agent-claim.php
@@ -0,0 +1,1357 @@
+getConnection();
+
+// Initialize variables with default values
+$username = $_SESSION['username'] ?? 'User';
+$email = $_SESSION['email'] ?? '';
+$tier = $_SESSION['tier'] ?? 'basic';
+$package = $_SESSION['package'] ?? 'Starter';
+$balance = $_SESSION['balance'] ?? 0;
+$total_deposits = $_SESSION['total_deposits'] ?? 0;
+$total_withdrawals = $_SESSION['total_withdrawals'] ?? 0;
+$rewards = $_SESSION['rewards'] ?? 0;
+$earnings = $total_deposits - $total_withdrawals;
+
+
+try {
+ // Query to get user data
+ $query = "SELECT u.*, up.first_name, up.last_name, up.profile_picture
+ FROM users u
+ LEFT JOIN user_profiles up ON u.id = up.user_id
+ WHERE u.id = :user_id";
+
+ $stmt = $db->prepare($query);
+ $stmt->bindParam(':user_id', $user_id);
+ $stmt->execute();
+
+ if ($stmt->rowCount() > 0) {
+ $user = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ // Assign session variables and local variables
+ $username = $_SESSION['username'] = $user['username'];
+ $email = $_SESSION['email'] = $user['email'];
+ $tier = $_SESSION['tier'] = $user['tier'];
+ $package = $_SESSION['package'] = $user['package'];
+ $balance = $_SESSION['balance'] = $user['balance'];
+ $total_deposits = $_SESSION['total_deposits'] = $user['total_deposits'];
+ $total_withdrawals = $_SESSION['total_withdrawals'] = $user['total_withdrawals'];
+ $rewards = $_SESSION['rewards'] = $user['rewards'];
+ $earnings = $total_deposits - $total_withdrawals;
+
+ // Get active package info
+ $package_query = "SELECT p.* FROM user_packages up
+ JOIN packages p ON up.package_id = p.id
+ WHERE up.user_id = :user_id AND up.status = 'active'
+ ORDER BY up.end_date DESC LIMIT 1";
+
+ $package_stmt = $db->prepare($package_query);
+ $package_stmt->bindParam(':user_id', $user_id);
+ $package_stmt->execute();
+
+ if ($package_stmt->rowCount() > 0) {
+ $active_package = $package_stmt->fetch(PDO::FETCH_ASSOC);
+ $_SESSION['package_details'] = $active_package;
+ }
+
+ // Get claim statistics
+ $claims_stats_query = "
+ SELECT
+ COUNT(*) as total_claims,
+ SUM(CASE WHEN status = 'approved' THEN 1 ELSE 0 END) as approved_claims,
+ SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending_claims,
+ SUM(CASE WHEN status = 'rejected' THEN 1 ELSE 0 END) as rejected_claims,
+ SUM(CASE WHEN status = 'approved' THEN amount ELSE 0 END) as approved_amount,
+ SUM(CASE WHEN status = 'pending' THEN amount ELSE 0 END) as pending_amount,
+ SUM(amount) as total_amount
+ FROM agent_claims
+ WHERE user_id = :user_id
+ ";
+
+ $stats_stmt = $db->prepare($claims_stats_query);
+ $stats_stmt->bindParam(':user_id', $user_id);
+ $stats_stmt->execute();
+ $claims_stats = $stats_stmt->fetch(PDO::FETCH_ASSOC);
+
+ // Get pending claims
+ $pending_claims_query = "
+ SELECT ac.*, u.username, u.email
+ FROM agent_claims ac
+ JOIN users u ON ac.user_id = u.id
+ WHERE ac.user_id = :user_id AND ac.status = 'pending'
+ ORDER BY ac.created_at DESC
+ ";
+
+ $pending_stmt = $db->prepare($pending_claims_query);
+ $pending_stmt->bindParam(':user_id', $user_id);
+ $pending_stmt->execute();
+ $pending_claims = $pending_stmt->fetchAll(PDO::FETCH_ASSOC);
+
+ // Get approved claims
+ $approved_claims_query = "
+ SELECT ac.*, u.username, u.email
+ FROM agent_claims ac
+ JOIN users u ON ac.user_id = u.id
+ WHERE ac.user_id = :user_id AND ac.status = 'approved'
+ ORDER BY ac.approved_at DESC
+ ";
+
+ $approved_stmt = $db->prepare($approved_claims_query);
+ $approved_stmt->bindParam(':user_id', $user_id);
+ $approved_stmt->execute();
+ $approved_claims = $approved_stmt->fetchAll(PDO::FETCH_ASSOC);
+
+ // Get rejected claims
+ $rejected_claims_query = "
+ SELECT ac.*, u.username, u.email
+ FROM agent_claims ac
+ JOIN users u ON ac.user_id = u.id
+ WHERE ac.user_id = :user_id AND ac.status = 'rejected'
+ ORDER BY ac.updated_at DESC
+ ";
+
+ $rejected_stmt = $db->prepare($rejected_claims_query);
+ $rejected_stmt->bindParam(':user_id', $user_id);
+ $rejected_stmt->execute();
+ $rejected_claims = $rejected_stmt->fetchAll(PDO::FETCH_ASSOC);
+
+ } else {
+ $error_message = "User not found in database.";
+ }
+} catch(PDOException $exception) {
+ $error_message = "Database error: " . $exception->getMessage();
+}
+
+// Initialize empty arrays if queries failed
+if (!isset($claims_stats)) {
+ $claims_stats = [
+ 'total_claims' => 0,
+ 'approved_claims' => 0,
+ 'pending_claims' => 0,
+ 'rejected_claims' => 0,
+ 'approved_amount' => 0,
+ 'pending_amount' => 0,
+ 'total_amount' => 0
+ ];
+}
+
+if (!isset($pending_claims)) {
+ $pending_claims = [];
+}
+
+if (!isset($approved_claims)) {
+ $approved_claims = [];
+}
+
+if (!isset($rejected_claims)) {
+ $rejected_claims = [];
+}
+?>
+
+
+
+
+
+
+ Japanese Motors — Agent Claims
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Jmotors
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
🏷️ Agent Claim Requests
+
Manage commission claims and track your agent earnings
+
+
+
+
+
Pending Claims
+
Approved Claims
+
Rejected Claims
+
New Claim
+
+
+
+
+
+
+ Pending Claims
+
+
+
+
+
Total Pending Claims
+
+
+
+
Total Amount
+
KES
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Claim ID: JM-
+
+
+
+
+
+
+
+
Claim Amount
+
KES
+
+
+
Submitted
+
+
+
+
+
Description
+
+
+
+
Claim Type
+
+
+
+
+
+
+
+
+
+
+
+
No pending claims to display
+
All your claims have been processed
+
+
+
+
+
+
+
+ Claims Statistics
+
+
+
+
+ Total Claims
+
+
+
+
+
+
+
+
+
+ Approved
+
+
+
+
+
+
+
+
+
+ Pending
+
+
+
+
+
+
+
+
+
+ Rejected
+
+
+
+
+
+
+
+
+
+ Amount Summary
+
+
+
+ Total Approved
+ KES
+
+
+ Pending Approval
+ KES
+
+
+ Total Processed
+ KES
+
+
+
+
+
+
+
+
+
+
+
+
+ Approved Claims
+
+
+
+
+
+
+
+
+
+
+
+
+
Claim ID: JM-
+
+ Approved
+
+
+
+
Claim Amount
+
KES
+
+
+
Approved On
+
+
+
+
+
Description
+
+
+
+
+
Approval Notes
+
+
+
+
+
+
+
+
+
+
No approved claims to display
+
Approved claims will appear here
+
+
+
+
+
+
+
+
+ Rejected Claims
+
+
+
+
+
+
+
+
+
+
+
+
+
Claim ID: JM-
+
+ Rejected
+
+
+
+
Claim Amount
+
KES
+
+
+
Rejected On
+
+
+
+
+
Description
+
+
+
+
+
Rejection Reason
+
+
+
+
+
+
+
+
+
+
No rejected claims to display
+
Rejected claims will appear here
+
+
+
+
+
+
+
+
+
+ Submit New Claim
+
+
+
+
+
+
+
+ Claim Guidelines
+
+
+
+
Commission Structure
+
+
+
+ Direct Sales: 15% commission
+
+
+
+ Team Override: 5% on level 1 agents
+
+
+
+ Referral Bonus: 1,000 KES per agent
+
+
+
+
+
+
+
Claims are processed within 3-5 business days. Ensure all information is accurate to avoid delays.
+
+
+
+
Need Help?
+
Contact support if you have questions about your claim
+
+
+
+
+
+
+
+
+ Claims FAQ
+
+
+
+
+
How long does claim processing take?
+
+
+
+
Standard claims are processed within 3-5 business days. Complex claims or those requiring additional verification may take up to 10 business days. You will receive a notification once your claim has been processed.
+
+
+
+
+
+
What documents do I need to submit with my claim?
+
+
+
+
For commission claims: sales reports and transaction IDs. For bonus claims: performance metrics and achievement proof. For referral claims: agent IDs and signup dates. All claims benefit from supporting documentation like screenshots or exported reports.
+
+
+
+
+
+
When will I receive payment for approved claims?
+
+
+
+
Approved claims are paid out every Friday via your selected payment method. Payments are processed by 5 PM EAT. If your claim is approved on Thursday, you can expect payment the following day. Delays may occur during holidays or system maintenance.
+
+
+
+
+
+
+
+
+
+
+ Review Claim
+
+
+
+
John Kamau
+
+
+
+
Claim ID
+
JM-28746
+
+
+
Claim Amount
+
3,500 KES
+
+
+
+
+
Description
+
Q3 Commission - Team Sales Bonus
+
+
+
+
Submitted On
+
15 Nov 2023
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jweb/ac1/src/pages/customer-care.php b/jweb/ac1/src/pages/customer-care.php
new file mode 100644
index 0000000000000000000000000000000000000000..46c071509aae7508cf87141d8ab48432b76607e7
--- /dev/null
+++ b/jweb/ac1/src/pages/customer-care.php
@@ -0,0 +1,924 @@
+setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+ // Get user's support tickets
+ $stmt = $pdo->prepare("SELECT * FROM support_tickets WHERE user_id = :user_id ORDER BY created_at DESC");
+ $stmt->bindParam(':user_id', $_SESSION['user_id']);
+ $stmt->execute();
+ $tickets = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+ // Count tickets by status
+ $open_tickets = 0;
+ $in_progress_tickets = 0;
+ $resolved_tickets = 0;
+
+ foreach ($tickets as $ticket) {
+ switch ($ticket['status']) {
+ case 'open':
+ $open_tickets++;
+ break;
+ case 'in_progress':
+ $in_progress_tickets++;
+ break;
+ case 'resolved':
+ $resolved_tickets++;
+ break;
+ }
+ }
+
+} catch(PDOException $e) {
+ // If database connection fails, set empty values
+ $tickets = [];
+ $open_tickets = 0;
+ $in_progress_tickets = 0;
+ $resolved_tickets = 0;
+ $db_error = "Database connection failed: " . $e->getMessage();
+}
+?>
+
+
+
+
+
+ Japanese Motors — Customer Care
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Jmotors
+
+
+
+
+
+
+
🛎️ Customer Care Support
+
We're here to help you with any issues or questions about your Japanese Motors account
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Open Tickets
+
+
+
+
+
+
+
+
+
+
+
+
In Progress
+
+
+
+
+
+
+
+
+
+
+
+
Resolved
+
+
+
+
+
+
+
+
+ Submit a Support Request
+
+
+
+
+
+
+
+ Contact Options
+
+
+
+
+ Direct WhatsApp Support
+
+
Chat directly with our support team for instant assistance
No support tickets yet. Submit your first request above.
+
+
+
+
+
+
+
+
+
+
+
...
+
+
+ Ticket #:
+ •
+ Type:
+ •
+ Priority:
+
+
+
+
+
+
+
+
+
+
+
+ Frequently Asked Questions
+
+
+
+
+
How do I reset my password?
+
+
+
+
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.
+
+
+
+
+
+
Why is my withdrawal pending?
+
+
+
+
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.
+
+
+
+
+
+
How do I join the affiliate program?
+
+
+
+
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.
+
+
+
+
+
+
What are the minimum withdrawal requirements?
+
+
+
+
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.
+
+
+
+
+
+
How do I upgrade my account level?
+
+
+
+
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.
+
+
+
+
+
+
What should I do if my uploads are rejected?
+
+
+
+
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.
+
+
+
+
+
+
+
+ Support Hours
+
+
+
+ WhatsApp Support:
+ 24/7
+
+
+ Email Support:
+ Mon-Sun, 6am-11pm EAT
+
+
+ Phone Support:
+ 24/7 for urgent issues
+
+
+ Average Response Time:
+ Under 30 minutes
+
+
+ Ticket Resolution Time:
+ Within 24 hours
+
+
+
+
+
+
+ Community Support
+
+
Join our community of marketers to get help from experienced members and share insights:
+
+
+
+
Community Forum
+
Get answers from other marketers in our community forum
+
+
+
+
\ No newline at end of file
diff --git a/jweb/ac1/src/pages/daily-product.php b/jweb/ac1/src/pages/daily-product.php
new file mode 100644
index 0000000000000000000000000000000000000000..1dcfae391314abbcd7953ddeea4c339bcb959373
--- /dev/null
+++ b/jweb/ac1/src/pages/daily-product.php
@@ -0,0 +1,498 @@
+
+
+
+
+
+
+ Japanese Motors— Daily Product
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Jmotors
+
+
+
+
+
+
+
🔥 Tuesday Special Offer! Limited Time Only
+
Purchase the 💎 DIAMOND PACKAGE at KES 2,500.00 and receive KES 7,500.00 cashback instantly!
+
+
+
+
+
+
+
+
🛍️
+
+
Today's Featured Products
+ Special offers updated daily
+
+
+
+
+
+
+
+
💎
+
+
Diamond Package
+
Premium investment with high returns
+
+ KES 2,500
+
+
+
+
+
+
+
+
+
+
✨
+
+
Starlight Bundle
+
Mid-range investment option
+
+ KES 1,000
+
+
+
+
+
+
+
+
+
+
🌱
+
+
Starter Pack
+
Perfect for new investors
+
+ KES 500
+
+
+
+
+
+
+
+
+
+
🔥
+
+
Hot Deal
+
Limited time exclusive offer
+
+ KES 3,500
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jweb/ac1/src/pages/index.php b/jweb/ac1/src/pages/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..8aaa18a8608d48573a8cf409800dc3185c53f71d
--- /dev/null
+++ b/jweb/ac1/src/pages/index.php
@@ -0,0 +1,1301 @@
+
+
+
+
+
+
+ Japanese Motors Marketing Platform
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Jmotors
+
+
+
+
+
+
+
+
+
+ v
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Welcome back, !
+
User | Meta Package:
+
+
+
+
+
+
+
Monday Giveaway Cashback! Only at Jmotors
+
+ 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.
+
+
+
+
+
+
+
Investment Packages
+
Grow your funds with our automated investment solutions.
+
+
+
+
+
NOVA 1,000.00 KES
+
+
+
Auto Deposit
+
Auto Withdrawal
+
Instant Cashback
+
+
Award Returns 3,000.00 KES
+
+
+
+
+
+
SUPERIOR 2,500.00 KES
+
+
+
Auto Deposit
+
Auto Withdrawal
+
Instant Cashback
+
+
Award Returns 7,500.00 KES
+
+
+
+
+
+
GOLD 5,500.00 KES
+
+
+
Auto Deposit
+
Auto Withdrawal
+
Instant Cashback
+
+
Award Returns 16,500.00 KES
+
+
+
+
+
+
+
+
+
+
Meta Balance
+
+
KES
+
+
+
+
+
+
+
+
+
+
+
+
Total Withdrawals
+
KES
+
+
+
Total Deposits
+
KES
+
+
+
Meta Earnings
+
KES
+
+
+
Rewards
+
KES
+
+
+
+
+
+
+
Welcome back, !
+
Meta Balance
+
KES
+
+
+
+
Total Deposits
+
KES
+
+
+
+
Total Withdrawals
+
KES
+
+
+
+
Meta Earnings
+
KES
+
+
+
Rewards
+
KES
+
+
+
+
+
+
+
+
+
Deposit Funds
+ ×
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Withdraw Funds
+ ×
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jweb/ac1/src/pages/loan.php b/jweb/ac1/src/pages/loan.php
new file mode 100644
index 0000000000000000000000000000000000000000..0876514cfd89d260e18167952ccfbf3b0e60d905
--- /dev/null
+++ b/jweb/ac1/src/pages/loan.php
@@ -0,0 +1,1119 @@
+
+
+
+
+
+
+ Japanese Motors — Loan Services
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Jmotors
+
+
+
+
+
+
+
💰 Instant Loan Services
+
Get quick access to funds with our flexible loan options
+
+
+
+
+
+
Apply for Loan
+
Active Loans
+
Loan History
+
+
+
+
+
+
+ Loan Application
+
+
+
+
+
Loan Limit
+
50,000 KES
+
+
+
Available
+
35,000 KES
+
+
+
+
+
+
+
+
+ Loan Summary
+
+
+
+
+ Loan Amount
+ 0 KES
+
+
+
+
+
+ Processing Fee (2%)
+ 0 KES
+
+
+
+
+
+ Total Repayment
+ 0 KES
+
+
+
+
+
+ Due Date
+ --
+
+
+
+
+
+ Repayment Schedule
+
+
+
+ Monthly Installment
+ 0 KES
+
+
+ Number of Payments
+ --
+
+
+
+
+
+
Eligibility Criteria
+
+
+
+ Minimum deposits of 20,000 KES OR
+
+
+
+ Account age of 6+ months with sufficient activity
+
+
+
+ No overdue loans
+
+
+
+
+
+
+
+
+
+
+ Active Loans
+
+
+
+
No active loans
+
You don't have any active loans at the moment
+
+
+
+
+
+
+
+ Loan History
+
+
+
+
No loan history
+
Your loan history will appear here
+
+
+
+
+
+
+ Loan FAQ
+
+
+
+
+
How long does loan approval take?
+
+
+
+
Loan applications are typically processed within 2-4 hours during business hours. For M-Pesa disbursement, funds are sent immediately after approval. Bank transfers may take 1-2 business days. You'll receive an SMS notification once your loan is approved and disbursed.
+
+
+
+
+
+
What are the interest rates and fees?
+
+
+
+
Our loans have a 5% monthly interest rate with a 2% processing fee. For example, a loan of 10,000 KES for 30 days would have a 500 KES interest charge and 200 KES processing fee, totaling 10,700 KES repayment. There are no hidden fees, and we clearly display all costs before you apply.
+
+
+
+
+
+
What happens if I can't repay on time?
+
+
+
+
If you're unable to repay on time, please contact our support team before the due date to discuss options. We may offer a repayment extension with revised terms. Late payments incur a 1% daily penalty fee. Consistent communication helps us work with you to find a solution.
+
+
+
+
+
+
+
+
+
+
+ SMS Notification Preview
+
+
+
+
+ To:
+ 0722 XXX XXX
+
+
+
Your loan application for 5,000 KES has been received and is being processed. You will receive another SMS once approved. Thank you for choosing JMotors.
+
+
+ From:
+ Jmotors
+
+
+
+
This SMS will be sent to the phone number you provided for loan status updates.
Upload marketing content and earn KES 50-85 per file based on quality and type!
+
+
+
+
+
+
📤
+
+
Meta Uploads
+ Upload content for rewards
+
+
+
+
+
+
+
Upload Instructions
+
+
Upload at least 5 high-quality marketing content daily
+
Files should be in JPEG, PNG, MP4, or PDF format
+
Minimum resolution of 1280x720 for images/videos
+
Maximum file size: 50MB per file
+
Content must be original or properly licensed
+
Earn KES 50-85 per file based on type and quality
+
+
+
+
+
+
+
Today's Uploads (/5)
+
KES earned
+
+
+
+
+
+
+
No uploads today
+
+
+
+
+
+
+
+
+
+ •
+
+
+
+
+
+ KES
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jweb/ac1/src/pages/packages.php b/jweb/ac1/src/pages/packages.php
new file mode 100644
index 0000000000000000000000000000000000000000..65c5253e036739f89c598ed3bf9c28567f6c17f9
--- /dev/null
+++ b/jweb/ac1/src/pages/packages.php
@@ -0,0 +1,1157 @@
+prepare("SELECT * FROM packages WHERE id = ?");
+ $stmt->execute([$package_id]);
+ return $stmt->fetch(PDO::FETCH_ASSOC);
+ } catch (PDOException $e) {
+ error_log("Error getting package details: " . $e->getMessage());
+ return false;
+ }
+}
+
+// Function to get all packages
+function getAllPackages() {
+ global $pdo;
+ try {
+ $stmt = $pdo->prepare("SELECT * FROM packages ORDER BY min_investment ASC");
+ $stmt->execute();
+ return $stmt->fetchAll(PDO::FETCH_ASSOC);
+ } catch (PDOException $e) {
+ error_log("Error getting all packages: " . $e->getMessage());
+ return [];
+ }
+}
+
+// Function to get user's active investment
+function getUserActiveInvestment($user_id) {
+ global $pdo;
+ try {
+ $stmt = $pdo->prepare("
+ SELECT ui.*, p.name as package_name, p.daily_return, p.duration_days
+ FROM user_investments ui
+ JOIN packages p ON ui.package_id = p.id
+ WHERE ui.user_id = ? AND ui.status = 'active' AND ui.end_date > NOW()
+ ORDER BY ui.amount DESC
+ LIMIT 1
+ ");
+ $stmt->execute([$user_id]);
+ return $stmt->fetch(PDO::FETCH_ASSOC);
+ } catch (PDOException $e) {
+ error_log("Error getting user active investment: " . $e->getMessage());
+ return false;
+ }
+}
+
+// Get user data from session
+$username = $_SESSION['username'];
+$email = $_SESSION['email'];
+$tier = $_SESSION['tier'];
+$package = $_SESSION['package'];
+$balance = $_SESSION['balance'];
+$total_deposits = $_SESSION['total_deposits'];
+$total_withdrawals = $_SESSION['total_withdrawals'];
+$rewards = $_SESSION['rewards'];
+$earnings = $total_deposits - $total_withdrawals;
+$user_id = $_SESSION['user_id'];
+
+// Get currency settings (default to KES if not set)
+$currency = isset($_SESSION['currency']) ? $_SESSION['currency'] : 'KES';
+$currency_symbol = 'KSh';
+$exchange_rate = 1;
+
+// Set exchange rates and symbols based on currency
+if ($currency === 'USD') {
+ $currency_symbol = '$';
+ $exchange_rate = 0.0078; // 1 KES = 0.0078 USD
+} elseif ($currency === 'EUR') {
+ $currency_symbol = '€';
+ $exchange_rate = 0.0072; // 1 KES = 0.0072 EUR
+} elseif ($currency === 'GBP') {
+ $currency_symbol = '£';
+ $exchange_rate = 0.0062; // 1 KES = 0.0062 GBP
+}
+
+// Package configurations
+$package_configs = [
+ 'Nova' => [
+ 'min_investment' => 1000,
+ 'max_investment' => 50000,
+ 'daily_return' => 5,
+ 'duration_days' => 7,
+ 'features' => 'Basic Support,2% Referral Bonus'
+ ],
+ 'Superior' => [
+ 'min_investment' => 2500,
+ 'max_investment' => 100000,
+ 'daily_return' => 7,
+ 'duration_days' => 14,
+ 'features' => 'Standard Support,3% Referral Bonus,Priority Withdrawal'
+ ],
+ 'Gold' => [
+ 'min_investment' => 5500,
+ 'max_investment' => 250000,
+ 'daily_return' => 10,
+ 'duration_days' => 21,
+ 'features' => 'Priority Support,5% Referral Bonus,Instant Withdrawal,Advanced Tools'
+ ],
+ 'Diamond' => [
+ 'min_investment' => 10000,
+ 'max_investment' => 500000,
+ 'daily_return' => 15,
+ 'duration_days' => 30,
+ 'features' => '24/7 Dedicated Support,7% Referral Bonus,Instant Withdrawal,All Advanced Tools'
+ ]
+];
+
+// Convert package amounts to selected currency
+foreach ($package_configs as $name => $config) {
+ $package_configs[$name]['min_investment'] = $config['min_investment'] * $exchange_rate;
+ $package_configs[$name]['max_investment'] = $config['max_investment'] * $exchange_rate;
+}
+
+// Get all available packages from database
+$packages = getAllPackages();
+
+// Get user's active investment
+$active_investment = getUserActiveInvestment($user_id);
+
+// Map package names to IDs for JavaScript
+$package_ids = [];
+foreach ($packages as $pkg) {
+ $package_ids[strtolower($pkg['name'])] = $pkg['id'];
+}
+?>
+
+
+
+
+
+ Japanese Motors — Packages
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Jmotors
+
+
+
+
+
+
+
+
+
+
+
Active Investment:
+
Amount: |
+ Daily Earnings:
+
Ends on:
+
+
+
+
+
+
📦 Investment Packages
+
Choose from our range of investment packages to maximize your earnings
+
+
+
+
+
+
All Packages
+
Nova
+
Superior
+
Gold
+
Diamond
+
+
+
+
+ $config): ?>
+
+
+
+
+
+
+
+
+
+
Minimum Investment
+
+
+
% Daily Earnings
+
Day Duration
+
+
+
+
+
Priority Support
+
Advanced Tools
+
+
Advanced Tools
+
+
+
+
+
+
Total Return
+
+
+
+
+
+
+
+
+
+ Package Comparison
+
+
+
+
+
+
Feature
+
Nova
+
Superior
+
Gold
+
Diamond
+
+
+
+
+
Daily Return
+
5%
+
7%
+
10%
+
15%
+
+
+
Contract Duration
+
7 days
+
14 days
+
21 days
+
30 days
+
+
+
Referral Bonus
+
2%
+
3%
+
5%
+
7%
+
+
+
Withdrawal Speed
+
24-48 hours
+
12-24 hours
+
Instant
+
Instant
+
+
+
Support
+
Basic
+
Standard
+
Priority
+
24/7 Dedicated
+
+
+
Minimum Investment
+
+
+
+
+
+
+
+
+
+
+
+
+ Packages FAQ
+
+
+
+
+
How do I earn from these packages?
+
+
+
+
When you invest in a package, you earn daily returns based on the percentage for that package. For example, if you invest 5,000 KES in the Standard package with 7% daily returns, you'll earn 350 KES per day. Earnings are credited to your account daily and can be withdrawn or reinvested.
+
+
+
+
+
+
When can I withdraw my earnings?
+
+
+
+
You can withdraw your earnings anytime after they are credited to your account. However, your initial investment is locked for the duration of the package contract. Higher-tier packages offer faster withdrawal processing times.
+
+
+
+
+
+
What happens when my package expires?
+
+
+
+
When your package contract expires, your initial investment is returned to your account balance along with any remaining earnings. You can then withdraw the full amount or reinvest in a new package to continue earning.
+
+
+
+
+
+
Can I upgrade my package?
+
+
+
+
Yes, you can upgrade your package at any time by investing additional funds. The new investment will be treated as a separate package contract with its own terms and earning schedule. You can have multiple packages active simultaneously.
+
+
+
+
+
+
+
+
+
+
+
+ Confirm Package Selection
+
+
+
+
Superior Package
+
+
+
+
Daily Return
+
7%
+
+
+
Duration
+
14 days
+
+
+
+
+
Total Return
+
+
+
+
+
+
+
Min: | Max:
+
+
+
+
+
+
+
+
+
+
+
Your investment will be locked for the contract duration. Earnings are paid daily and can be withdrawn anytime.
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jweb/ac1/src/pages/profile.php b/jweb/ac1/src/pages/profile.php
new file mode 100644
index 0000000000000000000000000000000000000000..974ef31d4ba7769c4081577f35bc6d01295ba553
--- /dev/null
+++ b/jweb/ac1/src/pages/profile.php
@@ -0,0 +1,1081 @@
+setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+} catch(PDOException $e) {
+ die("Database connection failed: " . $e->getMessage());
+}
+
+if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
+ header('Location: ../../index.php');
+ exit;
+}
+
+// Check if user_id is set in session
+if (!isset($_SESSION['user_id']) && isset($_SESSION['username'])) {
+ $stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?");
+ $stmt->execute([$_SESSION['username']]);
+ $user = $stmt->fetch(PDO::FETCH_ASSOC);
+ if ($user) {
+ $_SESSION['user_id'] = $user['id'];
+ }
+}
+
+if (!isset($_SESSION['user_id'])) {
+ header('Location: ../../index.php');
+ exit;
+}
+
+// Fetch user data from database
+$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
+$stmt->execute([$_SESSION['user_id']]);
+$user = $stmt->fetch(PDO::FETCH_ASSOC);
+
+if (!$user) {
+ session_destroy();
+ header('Location: ../../index.php');
+ exit;
+}
+
+// Get user data from database
+$username = $user['username'] ?? $_SESSION['username'];
+$email = $user['email'] ?? $_SESSION['email'];
+$tier = $user['tier'] ?? $_SESSION['tier'];
+$package = $user['package'] ?? $_SESSION['package'];
+$balance = $user['balance'] ?? $_SESSION['balance'];
+$total_deposits = $user['total_deposits'] ?? $_SESSION['total_deposits'];
+$total_withdrawals = $user['total_withdrawals'] ?? $_SESSION['total_withdrawals'];
+$rewards = $user['rewards'] ?? $_SESSION['rewards'];
+
+// Get profile-specific data
+$first_name = $user['first_name'] ?? 'Maha';
+$last_name = $user['last_name'] ?? 'Ibrahim';
+$phone_number = $user['phone_number'] ?? '254712345678';
+$country_code = $user['country_code'] ?? 'KE';
+$status = $user['status'] ?? 'Dormant';
+$member_since = $user['member_since'] ?? '2023-01-15';
+
+// Format member since date
+$member_since_formatted = date('d M Y', strtotime($member_since));
+$earnings = $total_deposits - $total_withdrawals;
+
+// Update session data
+$_SESSION['username'] = $username;
+$_SESSION['email'] = $email;
+$_SESSION['tier'] = $tier;
+$_SESSION['package'] = $package;
+$_SESSION['balance'] = $balance;
+$_SESSION['total_deposits'] = $total_deposits;
+$_SESSION['total_withdrawals'] = $total_withdrawals;
+$_SESSION['rewards'] = $rewards;
+?>
+
+
+
+
+
+ Profile | Japanese Motors
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Jmotors
+
+
+
+
+
+
+
+
+
+
+
+
Marketer
+
Member since:
+
+
+
+
+
+
Personal Info
+
Security
+
Activity
+
+
+
+
+
Personal Information
+
+
+
+
+
+
+
Security Settings
+
+
+
+
+
Security Recommendations
+
+
• Use a strong, unique password
+
• Enable two-factor authentication if available
+
• Regularly update your password
+
• Never share your password with anyone
+
+
+
+
+
+
+
Recent Activity
+
+
+
+
+
Loading activity history...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jweb/ac1/src/pages/recharge.php b/jweb/ac1/src/pages/recharge.php
new file mode 100644
index 0000000000000000000000000000000000000000..4220e802beb642a40960af8012420158a33ebf89
--- /dev/null
+++ b/jweb/ac1/src/pages/recharge.php
@@ -0,0 +1,641 @@
+initiateSTKPush($phone_number, $amount, $user_id);
+
+ if (isset($result['success'])) {
+ $success = "M-Pesa prompt sent to your phone! Please enter your PIN to complete payment.";
+
+ // Record pending transaction
+ $mainAccount = new MainAccount();
+ $mainAccount->recordPendingTransaction($user_id, $amount, $phone_number, $result['CheckoutRequestID']);
+
+ // Add detailed success message
+ $success .= " Check your phone for the M-Pesa prompt. Transaction ID: " . $result['CheckoutRequestID'];
+
+ } else {
+ $error = "Payment initiation failed: " . ($result['message'] ?? 'Please try again later.');
+
+ // Log detailed error for debugging
+ error_log("M-Pesa Error: " . print_r($result, true));
+ }
+ } elseif ($payment_method === 'Manual') {
+ // Redirect to manual payment page
+ $_SESSION['payment_amount'] = $amount;
+ $_SESSION['payment_phone'] = $phone_number;
+ header('Location: ../api/manual_payment.php');
+ exit;
+ }
+ }
+}
+
+// Get currency rates for display
+require_once '../../db.php';
+$db = new Database();
+$conn = $db->getConnection();
+$currency_rates = [];
+try {
+ $stmt = $conn->prepare("SELECT target_currency, exchange_rate FROM currency_rates");
+ $stmt->execute();
+ $currency_rates = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
+} catch (PDOException $e) {
+ error_log("Currency rates error: " . $e->getMessage());
+}
+?>
+
+
+
+
+
+ Recharge | Japanese Motors
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Jmotors
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Check your phone for M-Pesa prompt. Enter your PIN to complete payment.
Minimum withdrawal: 100 KES | Maximum per transaction: 70,000 KES | Daily limit: 70,000 KES | Weekly limit: 140,000 KES. Limits may vary based on your account level and verification status.
+
+
+
+
+
+
How long do withdrawals take?
+
+
+
+
M-Pesa withdrawals are typically processed within 24-72 hours. Bank transfers may take 1-3 business days. Delays can occur during weekends, holidays, or system maintenance.
+
+
+
+
+
+
Why was my withdrawal declined?
+
+
+
+
Withdrawals may be declined due to: insufficient balance, incorrect recipient details, security checks, exceeded limits, or account restrictions. Contact support if you need assistance.
+
+
+
+
+
+
+
+
+
+
+ Confirm Withdrawal
+
+
+
+
+ Amount:
+ 0 KES
+
+
+ Fee:
+ 0 KES
+
+
+ You'll Receive:
+ 0 KES
+
+
+ To:
+ Not selected
+
+
+
+
Your withdrawal will be processed within 24-72 hours. You'll receive a confirmation message when completed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jweb/index.html b/jweb/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..6cb72e9df1618bf01bf2eb106a1507447f654aa2
--- /dev/null
+++ b/jweb/index.html
@@ -0,0 +1,1016 @@
+
+
+
+
+
+ Japanese Motors - Premium Automotive Excellence
+
+
+
+
+
+
+
+
+
+
+
+
Directly sourced from Japan with full documentation and service history.
+
+
+
+
+
+
+
Rigorous Inspection
+
Each vehicle undergoes 150-point inspection by certified technicians.
+
+
+
+
+
+
+
Premium Warranty
+
Comprehensive 3-year warranty on all vehicles for your peace of mind.
+
+
+
+
+
+
+
+
+
+
Stay Updated
+
Subscribe to our newsletter for exclusive offers, new arrivals, and automotive insights.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What Our Clients Say
+
+
Hear from our satisfied customers worldwide
+
+
+
+
+
+
+
+
+
+
Michael R.
+
+
+
+
+
+
+
+
+
+
"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."
+
+
+ 32 people found this helpful
+
+
+
+
+
+
+
+
+
+
Sarah K.
+
+
+
+
+
+
+
+
+
+
"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."