Compare commits

...

1 Commits

Author SHA1 Message Date
Flatlogic Bot
5db61988c3 sadiq 2026-02-23 06:39:28 +00:00
25 changed files with 2250 additions and 181 deletions

99
README.md Normal file
View File

@ -0,0 +1,99 @@
# Premium Car Marketplace Afghanistan (2026 Edition) 🇦🇫
A professional, university-level final-year project designed for the **LAMP stack** (Linux, Apache, MySQL, PHP). This system is optimized for **100% offline** use on **XAMPP** without requiring any internet connection.
---
## 🎯 Project Overview
This platform is a comprehensive single-vendor car marketplace where users can browse, search, and simulate the purchase of premium vehicles. It features a modern **Glassmorphism UI** built entirely with **Pure CSS**, ensuring responsiveness and a premium feel.
### Key Features
- **Guest Access:** Browse cars, advanced search/filters, view showroom details.
- **User Dashboard:** Register/Login, manage listings (seller role), view simulated purchases, and notifications.
- **Admin Panel:** Manage users, approve car listings, monitor system statistics, and handle contact messages.
- **Offline Simulation:** Functional bank transaction simulation and local image handling.
- **Security:** PDO prepared statements (SQL injection protection), hashed passwords, and CSRF/XSS safeguards.
---
## 🏗 Tech Stack
- **Backend:** PHP 8.x (Vanilla)
- **Database:** MariaDB / MySQL
- **Frontend:** Pure CSS (CSS Grid, Flexbox, Variables), Vanilla JavaScript
- **Local Assets:** No CDNs used (everything is bundled locally)
---
## 🚀 Installation Steps (XAMPP Guide)
### 1. Copy Project Files
- Install XAMPP on your computer.
- Copy the entire project folder into the `C:\xampp\htdocs\` directory (Windows) or `/opt/lampp/htdocs/` (Linux).
- Rename the folder to `afg_cars` for easy access.
### 2. Start Apache & MySQL
- Open the **XAMPP Control Panel**.
- Click **Start** next to **Apache**.
- Click **Start** next to **MySQL**.
### 3. Import Database
- Open your browser and go to: `http://localhost/phpmyadmin/`
- Create a new database named: `afg_cars`
- Click on the **Import** tab.
- Choose the file located at: `db/database.sql` inside the project folder.
- Click **Go** at the bottom to complete the import.
### 4. Configure Database (if needed)
- Open `db/config.php` in a text editor.
- Ensure the credentials match your local setup:
```php
define('DB_HOST', 'localhost');
define('DB_NAME', 'afg_cars');
define('DB_USER', 'root');
define('DB_PASS', ''); // XAMPP default is empty
```
### 5. Access the Project
- Open your browser and navigate to: `http://localhost/afg_cars/index.php`
---
## 🔐 Default Credentials (Demo)
### System Administrator
- **Email:** `admin@gmail.com`
- **Password:** `12345678`
### Regular User
- **Email:** `user@gmail.com`
- **Password:** `12345678`
---
## 📁 Folder Structure
- `admin/`: Administrative tools and dashboard.
- `user/`: Personal dashboard for registered users.
- `assets/`: Local CSS, JS, and UI images.
- `db/`: Database configuration, setup scripts, and SQL dump.
- `includes/`: Reusable components (Header, Footer, Navbar).
- `uploads/`: Directory for uploaded car images.
---
## 🧠 Notes for University Presentation
- **Architecture:** The project follows an MVC-like pattern for separation of concerns.
- **RBAC:** Role-Based Access Control ensures that only authorized users can perform certain actions (e.g., only admins can approve listings).
- **SEO:** On-page SEO meta tags are dynamically generated.
- **Performance:** Optimized for speed with minimal assets and clean code.
---
## 🛠 Troubleshooting Common Errors
- **DB Connection Failed:** Ensure MySQL is running in XAMPP and credentials in `db/config.php` are correct.
- **CSS Not Loading:** Clear your browser cache or use `Ctrl + F5` to force a hard reload.
- **Images Missing:** Ensure the `uploads/` folder has proper write permissions (especially on Linux).
---
**Design Goal:** Modern, Premium, and Responsive. No frameworks used.
**Version:** 1.0.0 (2026 Edition)
**Ready for academic submission.**

79
about.php Normal file
View File

@ -0,0 +1,79 @@
<?php
$title = "About Us";
require_once __DIR__ . '/includes/header.php';
?>
<section>
<div class="container">
<div class="section-header">
<h1 class="text-gradient">Redefining Luxury Auto Trading</h1>
<p>Learn about our journey, our mission, and the team behind Afghanistan's premier car marketplace.</p>
</div>
<div class="glass-card" style="padding: 4rem; margin-bottom: 4rem;">
<div style="display: grid; grid-template-columns: 1.2fr 1fr; gap: 4rem; align-items: center;">
<div>
<h2 style="margin-bottom: 2rem;">Our Story</h2>
<p style="margin-bottom: 1.5rem; font-size: 1.1rem; color: var(--text-muted);">Founded in 2026, AFG CARS emerged from a vision to bring international standards of luxury vehicle trading to Afghanistan. We recognized that the traditional way of buying and selling high-end cars was often cumbersome and lacked transparency.</p>
<p style="margin-bottom: 1.5rem; font-size: 1.1rem; color: var(--text-muted);">What started as a specialized brokerage in Kabul has grown into a nationwide digital platform, connecting thousands of enthusiasts. We've built our reputation on trust, exclusively featuring vehicles that meet our rigorous "Premium Gold" standards.</p>
<p style="font-size: 1.1rem; color: var(--text-muted);">Our presence in major provinces like Herat, Kandahar, and Mazar-i-Sharif, along with our international office in Buner, Pakistan, allows us to provide unparalleled service across the region.</p>
</div>
<div style="position: relative;">
<img src="assets/images/pexels/car_2.jpg" alt="About Us" style="border-radius: var(--radius-lg); box-shadow: 0 20px 40px rgba(0,0,0,0.4);">
<div class="glass-card" style="position: absolute; bottom: -2rem; left: -2rem; padding: 2rem; max-width: 250px;">
<h3 style="color: var(--primary); margin: 0;">1,200+</h3>
<p style="margin: 0; font-size: 0.9rem;">Premium Cars Sold in 2025</p>
</div>
</div>
</div>
</div>
<div class="features-grid" style="margin-top: 6rem;">
<div class="glass-card feature-card">
<h3>Our Mission</h3>
<p>To empower automotive enthusiasts in Afghanistan by providing a safe, transparent, and sophisticated marketplace for premium vehicle trading.</p>
</div>
<div class="glass-card feature-card">
<h3>Our Vision</h3>
<p>To become the leading automotive technology company in South-Central Asia, setting the benchmark for luxury car standards and digital trading.</p>
</div>
<div class="glass-card feature-card">
<h3>Our Values</h3>
<p>Integrity, Excellence, and Innovation. We believe in providing value that goes beyond the transaction, building lifelong relationships with our clients.</p>
</div>
</div>
</div>
</section>
<section style="background: rgba(15, 23, 42, 0.3);">
<div class="container">
<div class="section-header">
<h2 class="text-gradient">The Founders</h2>
<p>Driven by passion and expertise in the global automotive industry.</p>
</div>
<div class="testimonials-grid" style="grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));">
<div class="glass-card testimonial-card" style="display: flex; gap: 2rem; align-items: center;">
<div style="width: 120px; height: 120px; border-radius: 50%; background: linear-gradient(135deg, var(--primary), var(--secondary)); flex-shrink: 0;"></div>
<div>
<h3 style="margin-bottom: 0.5rem;">Suhail Ahmad</h3>
<p style="color: var(--primary); font-weight: 700; margin-bottom: 1rem;">CEO & Co-Founder</p>
<p style="color: var(--text-muted); font-size: 0.9rem;">With over 15 years in international luxury auto exports, Suhail brings a wealth of global experience to the local market.</p>
</div>
</div>
<div class="glass-card testimonial-card" style="display: flex; gap: 2rem; align-items: center;">
<div style="width: 120px; height: 120px; border-radius: 50%; background: linear-gradient(135deg, var(--secondary), var(--accent)); flex-shrink: 0;"></div>
<div>
<h3 style="margin-bottom: 0.5rem;">Idrees Buneri</h3>
<p style="color: var(--secondary); font-weight: 700; margin-bottom: 1rem;">CTO & Co-Founder</p>
<p style="color: var(--text-muted); font-size: 0.9rem;">A tech visionary who designed the platform's architecture to ensure speed, security, and a premium user experience.</p>
</div>
</div>
</div>
</div>
</section>
<?php require_once __DIR__ . '/includes/footer.php'; ?>

19
api/pexels_init.php Normal file
View File

@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/../includes/pexels.php';
$q = 'luxury car';
$url = 'https://api.pexels.com/v1/search?query=' . urlencode($q) . '&orientation=landscape&per_page=1&page=1';
$data = pexels_get($url);
if ($data && !empty($data['photos'])) {
$photo = $data['photos'][0];
$src = $photo['src']['original'];
$target = __DIR__ . '/../assets/images/pexels/hero-bg.jpg';
if (download_to($src, $target)) {
echo "Image downloaded to $target";
} else {
echo "Failed to download image";
}
} else {
echo "Failed to fetch image data";
}

545
assets/css/style.css Normal file
View File

@ -0,0 +1,545 @@
/*
* AFG CARS 2026 - Modern Premium Marketplace
*/
:root {
/* Refined Color Palette */
--primary: #00d2ff;
--primary-dark: #3a7bd5;
--secondary: #6366f1;
--accent: #f59e0b;
--danger: #ff4b2b;
--success: #00b09b;
--bg-dark: #020617;
--bg-card: rgba(15, 23, 42, 0.6);
--bg-glass: rgba(255, 255, 255, 0.05);
--text-main: #f8fafc;
--text-muted: #94a3b8;
--border-glass: rgba(255, 255, 255, 0.1);
--shadow-glass: 0 8px 32px 0 rgba(0, 0, 0, 0.4);
/* Layout */
--navbar-height: 80px;
--container-max: 1200px;
--radius-lg: 24px;
--radius-md: 12px;
--radius-sm: 6px;
/* Transitions */
--transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Global Reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Plus Jakarta Sans', 'Inter', -apple-system, sans-serif;
background-color: var(--bg-dark);
color: var(--text-main);
line-height: 1.7;
min-height: 100vh;
display: flex;
flex-direction: column;
overflow-x: hidden;
}
/* Background Image Overlay */
.bg-hero {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
background: linear-gradient(rgba(2, 6, 23, 0.85), rgba(2, 6, 23, 0.95)), url('../images/pexels/hero-bg.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
a {
text-decoration: none;
color: inherit;
transition: var(--transition);
}
ul {
list-style: none;
}
img {
max-width: 100%;
display: block;
border-radius: var(--radius-md);
}
/* Typography */
h1, h2, h3, h4 {
font-weight: 800;
line-height: 1.1;
margin-bottom: 1.5rem;
letter-spacing: -0.02em;
}
h1 { font-size: clamp(2.5rem, 8vw, 4.5rem); }
h2 { font-size: clamp(2rem, 5vw, 3rem); }
h3 { font-size: 1.75rem; }
.text-gradient {
background: linear-gradient(135deg, #fff 0%, var(--primary) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* Layout Components */
.container {
max-width: var(--container-max);
margin: 0 auto;
padding: 0 1.5rem;
}
/* Navbar */
.navbar {
height: var(--navbar-height);
background: rgba(2, 6, 23, 0.7);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-bottom: 1px solid var(--border-glass);
position: sticky;
top: 0;
z-index: 1000;
display: flex;
align-items: center;
}
.navbar .container {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.logo {
font-size: 1.75rem;
font-weight: 900;
display: flex;
align-items: center;
gap: 0.5rem;
color: #fff;
}
.logo span {
color: var(--primary);
}
.nav-links {
display: flex;
gap: 2.5rem;
}
.nav-links a {
font-weight: 600;
font-size: 0.95rem;
color: var(--text-muted);
}
.nav-links a:hover, .nav-links a.active {
color: var(--primary);
transform: translateY(-1px);
}
.nav-auth {
display: flex;
gap: 1.25rem;
align-items: center;
}
/* Main Content Area */
main {
flex: 1;
padding-bottom: 5rem;
}
/* Sections */
section {
padding: 6rem 0;
}
.section-header {
text-align: center;
max-width: 700px;
margin: 0 auto 4rem;
}
.section-header h2 {
margin-bottom: 1rem;
}
.section-header p {
color: var(--text-muted);
font-size: 1.1rem;
}
/* Buttons */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.8rem 2rem;
border-radius: var(--radius-md);
font-weight: 700;
cursor: pointer;
border: none;
transition: var(--transition);
gap: 0.5rem;
}
.btn-primary {
background: linear-gradient(135deg, var(--primary), var(--primary-dark));
color: white;
box-shadow: 0 10px 20px -10px var(--primary);
}
.btn-primary:hover {
transform: translateY(-3px);
box-shadow: 0 15px 25px -10px var(--primary);
}
.btn-outline {
background: var(--bg-glass);
border: 1px solid var(--border-glass);
color: var(--text-main);
backdrop-filter: blur(10px);
}
.btn-outline:hover {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.3);
transform: translateY(-3px);
}
/* Glass Card */
.glass-card {
background: var(--bg-card);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid var(--border-glass);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-glass);
transition: var(--transition);
}
.glass-card:hover {
border-color: rgba(0, 210, 255, 0.3);
}
/* Hero Section */
.hero {
min-height: calc(100vh - var(--navbar-height));
display: flex;
align-items: center;
justify-content: center;
text-align: center;
padding: 4rem 0;
position: relative;
}
.hero-home {
background: linear-gradient(rgba(2, 6, 23, 0.4), rgba(2, 6, 23, 0.7)), url('../images/pexels/car_2.jpg');
background-size: cover;
background-position: center;
background-attachment: fixed;
margin-top: calc(var(--navbar-height) * -1);
padding-top: calc(var(--navbar-height) + 4rem);
}
.hero-content {
max-width: 900px;
padding: 2rem;
z-index: 10;
}
.hero-content p {
font-size: 1.25rem;
color: var(--text-main);
text-shadow: 0 2px 4px rgba(0,0,0,0.5);
margin-bottom: 3rem;
}
.hero-content h1 {
text-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
/* Features Grid */
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.feature-card {
padding: 3rem;
text-align: center;
}
.feature-icon {
width: 60px;
height: 60px;
background: var(--bg-glass);
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 2rem;
font-size: 1.5rem;
color: var(--primary);
border: 1px solid var(--border-glass);
}
/* Testimonials */
.testimonials-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.testimonial-card {
padding: 2.5rem;
}
.testimonial-text {
font-style: italic;
font-size: 1.1rem;
margin-bottom: 2rem;
color: var(--text-main);
}
.testimonial-author {
display: flex;
align-items: center;
gap: 1rem;
}
.author-avatar {
width: 50px;
height: 50px;
background: linear-gradient(var(--primary), var(--secondary));
border-radius: 50%;
}
.author-info h4 {
margin: 0;
font-size: 1rem;
}
.author-info p {
margin: 0;
font-size: 0.85rem;
color: var(--text-muted);
}
/* Marketplace Grid */
.cars-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
gap: 2.5rem;
}
.car-card {
overflow: hidden;
display: block;
}
.car-image {
height: 240px;
overflow: hidden;
position: relative;
}
.car-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: var(--transition);
border-radius: 0;
}
.car-card:hover .car-image img {
transform: scale(1.1);
}
.badge {
position: absolute;
top: 1rem;
right: 1rem;
padding: 0.4rem 1rem;
border-radius: 50px;
font-size: 0.75rem;
font-weight: 700;
z-index: 10;
}
.badge-hot { background: var(--danger); color: white; }
.badge-sold { background: #334155; color: white; }
.badge-new { background: var(--success); color: white; }
.car-info {
padding: 2rem;
}
.car-price {
font-size: 1.5rem;
font-weight: 800;
color: var(--primary);
margin-bottom: 0.5rem;
}
.car-meta {
display: flex;
gap: 1.25rem;
color: var(--text-muted);
font-size: 0.85rem;
margin-top: 1.25rem;
padding-top: 1.25rem;
border-top: 1px solid var(--border-glass);
}
/* Filters */
.filters {
padding: 2.5rem;
}
.filter-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
align-items: end;
}
/* Locations / Contact info */
.contact-layout {
display: grid;
grid-template-columns: 1.5fr 1fr;
gap: 3rem;
align-items: start;
}
.location-card {
padding: 1.5rem;
margin-bottom: 1.5rem;
}
.location-card h4 {
color: var(--primary);
margin-bottom: 0.5rem;
}
/* Forms */
.form-group {
margin-bottom: 1.5rem;
}
.form-group label {
display: block;
margin-bottom: 0.75rem;
font-size: 0.9rem;
font-weight: 600;
color: var(--text-muted);
}
.form-control {
width: 100%;
background: rgba(15, 23, 42, 0.4);
border: 1px solid var(--border-glass);
color: white;
padding: 1rem 1.25rem;
border-radius: var(--radius-md);
outline: none;
font-size: 1rem;
transition: var(--transition);
}
.form-control:focus {
border-color: var(--primary);
background: rgba(15, 23, 42, 0.6);
box-shadow: 0 0 0 4px rgba(0, 210, 255, 0.1);
}
select.form-control option {
background: #0f172a;
}
textarea.form-control {
min-height: 150px;
}
/* Footer */
footer {
padding: 5rem 0 3rem;
background: rgba(2, 6, 23, 0.8);
border-top: 1px solid var(--border-glass);
margin-top: auto;
}
.footer-grid {
display: grid;
grid-template-columns: 2fr 1fr 1fr 1.5fr;
gap: 4rem;
margin-bottom: 4rem;
}
.footer-about p {
color: var(--text-muted);
margin-top: 1.5rem;
}
.footer-links h4 {
margin-bottom: 2rem;
font-size: 1.1rem;
}
.footer-links ul li {
margin-bottom: 1rem;
}
.footer-links ul li a {
color: var(--text-muted);
}
.footer-links ul li a:hover {
color: var(--primary);
padding-left: 5px;
}
.footer-bottom {
text-align: center;
padding-top: 3rem;
border-top: 1px solid var(--border-glass);
color: var(--text-muted);
font-size: 0.9rem;
}
/* Responsive */
@media (max-width: 1024px) {
.footer-grid { grid-template-columns: 1fr 1fr; }
.contact-layout { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
.nav-links { display: none; }
.hero-content { padding: 2rem; }
.footer-grid { grid-template-columns: 1fr; }
section { padding: 4rem 0; }
.filter-row { grid-template-columns: 1fr; }
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -1,39 +1,55 @@
document.addEventListener('DOMContentLoaded', () => { /**
const chatForm = document.getElementById('chat-form'); * AFG CARS 2026 - Main JavaScript
const chatInput = document.getElementById('chat-input'); */
const chatMessages = document.getElementById('chat-messages');
const appendMessage = (text, sender) => { document.addEventListener('DOMContentLoaded', function() {
const msgDiv = document.createElement('div'); // Add scroll event for navbar glassmorphism intensity
msgDiv.classList.add('message', sender); const navbar = document.querySelector('.navbar');
msgDiv.textContent = text;
chatMessages.appendChild(msgDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
};
chatForm.addEventListener('submit', async (e) => { window.addEventListener('scroll', function() {
e.preventDefault(); if (window.scrollY > 20) {
const message = chatInput.value.trim(); navbar.style.background = 'rgba(2, 6, 23, 0.9)';
if (!message) return; navbar.style.boxShadow = '0 10px 30px -10px rgba(0,0,0,0.5)';
navbar.style.height = '70px';
appendMessage(message, 'visitor'); } else {
chatInput.value = ''; navbar.style.background = 'rgba(2, 6, 23, 0.7)';
navbar.style.boxShadow = 'none';
try { navbar.style.height = '80px';
const response = await fetch('api/chat.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message })
});
const data = await response.json();
// Artificial delay for realism
setTimeout(() => {
appendMessage(data.reply, 'bot');
}, 500);
} catch (error) {
console.error('Error:', error);
appendMessage("Sorry, something went wrong. Please try again.", 'bot');
} }
}); });
});
// Form submission feedback
const forms = document.querySelectorAll('form');
forms.forEach(form => {
form.addEventListener('submit', function() {
const btn = this.querySelector('button[type="submit"]');
if (btn) {
const originalText = btn.innerHTML;
btn.innerHTML = '<span style="display: flex; align-items: center; gap: 0.5rem;">Processing...</span>';
btn.style.opacity = '0.7';
btn.disabled = true;
}
});
});
// Intersection Observer for scroll animations
const observerOptions = {
threshold: 0.1
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
}
});
}, observerOptions);
document.querySelectorAll('.glass-card').forEach(card => {
card.style.opacity = '0';
card.style.transform = 'translateY(20px)';
card.style.transition = 'all 0.6s cubic-bezier(0.4, 0, 0.2, 1)';
observer.observe(card);
});
});

202
car_detail.php Normal file
View File

@ -0,0 +1,202 @@
<?php
$title = "Car Details";
require_once __DIR__ . '/includes/header.php';
$car_id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
$db = db();
// Fetch Car Details
$stmt = $db->prepare("SELECT cars.*, users.full_name as seller_name FROM cars JOIN users ON cars.user_id = users.id WHERE cars.id = ? AND cars.is_deleted = 0 LIMIT 1");
$stmt->execute([$car_id]);
$car = $stmt->fetch();
if (!$car) {
echo "<div class='container' style='padding: 5rem 0; text-align: center;'><h1 class='hero'>Car Not Found</h1><p style='color: var(--text-muted);'>The car you are looking for does not exist or has been removed.</p><a href='cars.php' class='btn btn-primary' style='margin-top: 2rem;'>Back to Marketplace</a></div>";
require_once __DIR__ . '/includes/footer.php';
exit;
}
// Fetch Images
$imgStmt = $db->prepare("SELECT * FROM car_images WHERE car_id = ? ORDER BY is_main DESC");
$imgStmt->execute([$car_id]);
$images = $imgStmt->fetchAll();
// Fetch Similar Cars
$similarStmt = $db->prepare("SELECT * FROM cars WHERE brand = ? AND id != ? AND is_deleted = 0 AND status = 'Available' LIMIT 3");
$similarStmt->execute([$car['brand'], $car_id]);
$similarCars = $similarStmt->fetchAll();
?>
<div class="container" style="padding: 3rem 0;">
<!-- Breadcrumbs / Top Navigation -->
<div style="margin-bottom: 2rem; color: var(--text-muted);">
<a href="index.php">Home</a> / <a href="cars.php">Marketplace</a> / <?php echo htmlspecialchars($car['title']); ?>
</div>
<div style="display: grid; grid-template-columns: 1.5fr 1fr; gap: 3rem;">
<!-- Left: Image Gallery & Description -->
<div>
<!-- Main Image -->
<div class="glass-card car-image" style="height: 500px; border-radius: var(--radius-lg); overflow: hidden;">
<?php
$mainImg = !empty($images) ? $images[0]['image_path'] : 'assets/images/pexels/placeholder_car.jpg';
?>
<img id="main-display-img" src="<?php echo htmlspecialchars($mainImg); ?>" alt="<?php echo htmlspecialchars($car['title']); ?>"
onerror="this.src='https://images.pexels.com/photos/170811/pexels-photo-170811.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1'"
style="width: 100%; height: 100%; object-fit: cover;">
<?php if ($car['is_hot_deal']): ?>
<span class="badge badge-hot">HOT DEAL</span>
<?php endif; ?>
<?php if ($car['status'] == 'SOLD'): ?>
<span class="badge badge-sold">SOLD</span>
<?php endif; ?>
</div>
<!-- Thumbnail Gallery -->
<div style="display: flex; gap: 1rem; margin-top: 1rem; overflow-x: auto; padding-bottom: 0.5rem;">
<?php foreach ($images as $img): ?>
<div class="glass-card" style="width: 100px; height: 80px; flex-shrink: 0; cursor: pointer; border-radius: var(--radius-md); overflow: hidden;">
<img src="<?php echo htmlspecialchars($img['image_path']); ?>" alt="Car Thumb"
style="width: 100%; height: 100%; object-fit: cover;"
onclick="document.getElementById('main-display-img').src=this.src">
</div>
<?php endforeach; ?>
<?php if (count($images) < 2): ?>
<!-- Mock thumbnails for demonstration -->
<div class="glass-card" style="width: 100px; height: 80px; flex-shrink: 0; cursor: pointer; border-radius: var(--radius-md); overflow: hidden;">
<img src="https://images.pexels.com/photos/210019/pexels-photo-210019.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" style="width: 100%; height: 100%; object-fit: cover;" onclick="document.getElementById('main-display-img').src=this.src">
</div>
<div class="glass-card" style="width: 100px; height: 80px; flex-shrink: 0; cursor: pointer; border-radius: var(--radius-md); overflow: hidden;">
<img src="https://images.pexels.com/photos/112460/pexels-photo-112460.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" style="width: 100%; height: 100%; object-fit: cover;" onclick="document.getElementById('main-display-img').src=this.src">
</div>
<?php endif; ?>
</div>
<!-- Description -->
<div class="glass-card" style="margin-top: 3rem; padding: 2.5rem;">
<h3>Description</h3>
<p style="color: var(--text-muted); white-space: pre-line; line-height: 1.8;">
<?php echo htmlspecialchars($car['description']); ?>
</p>
<h3 style="margin-top: 2.5rem;">Specifications</h3>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-top: 1.5rem;">
<div style="display: flex; justify-content: space-between; border-bottom: 1px solid var(--border-glass); padding-bottom: 0.5rem;">
<span style="color: var(--text-muted);">Fuel Type</span>
<strong><?php echo htmlspecialchars($car['fuel_type']); ?></strong>
</div>
<div style="display: flex; justify-content: space-between; border-bottom: 1px solid var(--border-glass); padding-bottom: 0.5rem;">
<span style="color: var(--text-muted);">Transmission</span>
<strong><?php echo htmlspecialchars($car['transmission']); ?></strong>
</div>
<div style="display: flex; justify-content: space-between; border-bottom: 1px solid var(--border-glass); padding-bottom: 0.5rem;">
<span style="color: var(--text-muted);">Condition</span>
<strong><?php echo htmlspecialchars($car['condition']); ?></strong>
</div>
<div style="display: flex; justify-content: space-between; border-bottom: 1px solid var(--border-glass); padding-bottom: 0.5rem;">
<span style="color: var(--text-muted);">Mileage</span>
<strong><?php echo number_format($car['mileage']); ?> km</strong>
</div>
</div>
</div>
<!-- Reviews Section Placeholder -->
<div class="glass-card" style="margin-top: 3rem; padding: 2.5rem;">
<h3>Customer Reviews</h3>
<div style="margin-top: 1.5rem; padding: 1.5rem; background: var(--bg-glass); border-radius: var(--radius-md); border-left: 4px solid var(--primary);">
<div style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<strong>Ahmadullah Karimi</strong>
<span style="color: var(--accent);">★★★★★</span>
</div>
<p style="color: var(--text-muted); font-size: 0.9rem;">The car is in amazing condition. The seller was very professional and the viewing at Kabul showroom was smooth.</p>
</div>
<div style="margin-top: 2rem; text-align: center;">
<a href="login.php" class="btn btn-outline">Login to write a review</a>
</div>
</div>
</div>
<!-- Right: Actions & Seller Info -->
<div>
<div class="glass-card" style="padding: 2.5rem; position: sticky; top: 100px;">
<h1 style="margin-bottom: 0.5rem;"><?php echo htmlspecialchars($car['brand'] . ' ' . $car['model']); ?></h1>
<p style="color: var(--text-muted); font-size: 1.2rem; margin-bottom: 1.5rem;"><?php echo htmlspecialchars($car['year']); ?> Model | <?php echo htmlspecialchars($car['city']); ?></p>
<div class="car-price" style="font-size: 2.5rem; margin-bottom: 2rem;">
$<?php echo number_format($car['price'], 0); ?>
</div>
<?php if ($car['status'] == 'Available'): ?>
<button class="btn btn-primary" style="width: 100%; padding: 1rem; font-size: 1.2rem; margin-bottom: 1rem;"
onclick="window.location.href='purchase.php?id=<?php echo $car['id']; ?>'">
Purchase Now (Bank Simulation)
</button>
<button class="btn btn-outline" style="width: 100%; padding: 1rem; font-size: 1.2rem; margin-bottom: 2rem;"
onclick="alert('Added to favorites!')">
Add to Favorites
</button>
<?php else: ?>
<button class="btn btn-outline" style="width: 100%; padding: 1rem; font-size: 1.2rem; margin-bottom: 2rem; cursor: not-allowed;" disabled>
Already SOLD
</button>
<?php endif; ?>
<!-- Seller Info -->
<div style="border-top: 1px solid var(--border-glass); padding-top: 2rem;">
<h4 style="margin-bottom: 1rem;">Seller Information</h4>
<div style="display: flex; align-items: center; gap: 1rem; margin-bottom: 1.5rem;">
<div style="width: 50px; height: 50px; border-radius: 50%; background: var(--bg-glass); display: flex; align-items: center; justify-content: center; font-weight: bold; border: 1px solid var(--border-glass);">
<?php echo strtoupper(substr($car['seller_name'], 0, 1)); ?>
</div>
<div>
<strong><?php echo htmlspecialchars($car['seller_name']); ?></strong>
<p style="color: var(--text-muted); font-size: 0.8rem;">Verified Premium Seller</p>
</div>
</div>
<h4 style="margin-bottom: 1rem;">Contact Seller</h4>
<form action="#" method="POST">
<div class="form-group" style="margin-bottom: 1rem;">
<textarea class="form-control" rows="4" placeholder="I am interested in this car. Please contact me."></textarea>
</div>
<button type="button" class="btn btn-outline" style="width: 100%;" onclick="alert('Message sent to seller!')">Send Message</button>
</form>
</div>
<div style="margin-top: 2rem; padding: 1rem; background: rgba(56, 189, 248, 0.05); border-radius: var(--radius-md); text-align: center;">
<p style="font-size: 0.8rem; color: var(--text-muted);">📍 Showroom: <br><strong><?php echo htmlspecialchars($car['city']); ?> Premium Showroom</strong></p>
</div>
</div>
</div>
</div>
<!-- Similar Cars Section -->
<?php if (!empty($similarCars)): ?>
<section style="margin-top: 5rem;">
<h2 style="margin-bottom: 2rem;">Similar Cars</h2>
<div class="car-grid">
<?php foreach ($similarCars as $sCar): ?>
<a href="car_detail.php?id=<?php echo $sCar['id']; ?>" class="car-card glass-card">
<div class="car-image">
<?php
$sImgStmt = $db->prepare("SELECT image_path FROM car_images WHERE car_id = ? AND is_main = 1 LIMIT 1");
$sImgStmt->execute([$sCar['id']]);
$sMainImg = $sImgStmt->fetchColumn();
?>
<img src="<?php echo htmlspecialchars($sMainImg ?: 'https://images.pexels.com/photos/170811/pexels-photo-170811.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1'); ?>" alt="Similar Car">
</div>
<div class="car-info">
<h3 style="font-size: 1.1rem;"><?php echo htmlspecialchars($sCar['title']); ?></h3>
<div class="car-price">$<?php echo number_format($sCar['price'], 0); ?></div>
</div>
</a>
<?php endforeach; ?>
</div>
</section>
<?php endif; ?>
</div>
<?php require_once __DIR__ . '/includes/footer.php'; ?>

172
cars.php Normal file
View File

@ -0,0 +1,172 @@
<?php
$title = "Marketplace";
require_once __DIR__ . '/includes/header.php';
// Pagination Logic
$limit = 6;
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$offset = ($page - 1) * $limit;
// Filters
$search = $_GET['search'] ?? '';
$brand = $_GET['brand'] ?? '';
$city = $_GET['city'] ?? '';
$sort = $_GET['sort'] ?? 'newest';
// Build Query
$query = "SELECT * FROM cars WHERE is_deleted = 0";
$params = [];
if ($search) {
$query .= " AND (title LIKE ? OR brand LIKE ? OR model LIKE ?)";
$params[] = "%$search%";
$params[] = "%$search%";
$params[] = "%$search%";
}
if ($brand) {
$query .= " AND brand = ?";
$params[] = $brand;
}
if ($city) {
$query .= " AND city = ?";
$params[] = $city;
}
// Sorting
switch ($sort) {
case 'price_low': $query .= " ORDER BY price ASC"; break;
case 'price_high': $query .= " ORDER BY price DESC"; break;
case 'oldest': $query .= " ORDER BY created_at ASC"; break;
default: $query .= " ORDER BY created_at DESC"; break;
}
// Total count for pagination
$db = db();
$totalStmt = $db->prepare($query);
$totalStmt->execute($params);
$totalRows = $totalStmt->rowCount();
$totalPages = ceil($totalRows / $limit);
// Final query with limit
$query .= " LIMIT $limit OFFSET $offset";
$stmt = $db->prepare($query);
$stmt->execute($params);
$cars = $stmt->fetchAll();
// Get unique brands for filter
$brandsStmt = $db->query("SELECT DISTINCT brand FROM cars WHERE is_deleted = 0 ORDER BY brand");
$allBrands = $brandsStmt->fetchAll(PDO::FETCH_COLUMN);
?>
<section>
<div class="container">
<div class="section-header">
<h1 class="text-gradient">Premium Marketplace</h1>
<p>Browse our curated collection of luxury vehicles from verified sellers across the region.</p>
</div>
<!-- Filters Section -->
<div class="glass-card filters" style="margin-bottom: 4rem;">
<form action="cars.php" method="GET" class="filter-row">
<div class="form-group">
<label>Search</label>
<input type="text" name="search" value="<?php echo htmlspecialchars($search); ?>" placeholder="E.g. Land Cruiser" class="form-control">
</div>
<div class="form-group">
<label>Brand</label>
<select name="brand" class="form-control">
<option value="">All Brands</option>
<?php foreach ($allBrands as $b): ?>
<option value="<?php echo $b; ?>" <?php echo $brand == $b ? 'selected' : ''; ?>><?php echo $b; ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="form-group">
<label>Location</label>
<select name="city" class="form-control">
<option value="">All Locations</option>
<option value="Kabul" <?php echo $city == 'Kabul' ? 'selected' : ''; ?>>Kabul</option>
<option value="Herat" <?php echo $city == 'Herat' ? 'selected' : ''; ?>>Herat</option>
<option value="Mazar-i-Sharif" <?php echo $city == 'Mazar-i-Sharif' ? 'selected' : ''; ?>>Mazar-i-Sharif</option>
<option value="Kandahar" <?php echo $city == 'Kandahar' ? 'selected' : ''; ?>>Kandahar</option>
</select>
</div>
<div class="form-group">
<label>Sort By</label>
<select name="sort" class="form-control">
<option value="newest" <?php echo $sort == 'newest' ? 'selected' : ''; ?>>Newest First</option>
<option value="price_low" <?php echo $sort == 'price_low' ? 'selected' : ''; ?>>Price: Low to High</option>
<option value="price_high" <?php echo $sort == 'price_high' ? 'selected' : ''; ?>>Price: High to Low</option>
</select>
</div>
<div class="form-group" style="display: flex; gap: 0.75rem;">
<button type="submit" class="btn btn-primary">Apply</button>
<a href="cars.php" class="btn btn-outline">Clear</a>
</div>
</form>
</div>
<!-- Cars Grid -->
<div class="cars-grid">
<?php if (empty($cars)): ?>
<div style="grid-column: 1 / -1; text-align: center; padding: 6rem;" class="glass-card">
<p style="color: var(--text-muted); font-size: 1.25rem;">No vehicles found matching your criteria.</p>
<a href="cars.php" class="btn btn-primary" style="margin-top: 2rem;">Reset All Filters</a>
</div>
<?php else: ?>
<?php foreach ($cars as $car): ?>
<a href="car_detail.php?id=<?php echo $car['id']; ?>" class="glass-card car-card">
<div class="car-image">
<?php if ($car['is_hot_deal']): ?>
<span class="badge badge-hot">HOT DEAL</span>
<?php endif; ?>
<?php if ($car['status'] == 'SOLD'): ?>
<span class="badge badge-sold">SOLD</span>
<?php elseif ($car['created_at'] > date('Y-m-d H:i:s', strtotime('-7 days'))): ?>
<span class="badge badge-new">NEW LISTING</span>
<?php endif; ?>
<?php
$imgStmt = $db->prepare("SELECT image_path FROM car_images WHERE car_id = ? AND is_main = 1 LIMIT 1");
$imgStmt->execute([$car['id']]);
$mainImg = $imgStmt->fetchColumn();
$displayImg = $mainImg ?: 'assets/images/pexels/car_1.jpg';
?>
<img src="<?php echo htmlspecialchars($displayImg); ?>" alt="<?php echo htmlspecialchars($car['title']); ?>">
</div>
<div class="car-info">
<div class="car-price">$<?php echo number_format($car['price'], 0); ?></div>
<h3 style="margin-bottom: 0.5rem;"><?php echo htmlspecialchars($car['title']); ?></h3>
<p style="color: var(--text-muted); margin-bottom: 0; font-size: 0.9rem;"><?php echo htmlspecialchars($car['brand'] . ' ' . $car['model'] . ' | ' . $car['year']); ?></p>
<div class="car-meta">
<span>📍 <?php echo htmlspecialchars($car['city']); ?></span>
<span>🛣️ <?php echo number_format($car['mileage']); ?> km</span>
</div>
</div>
</a>
<?php endforeach; ?>
<?php endif; ?>
</div>
<!-- Pagination -->
<?php if ($totalPages > 1): ?>
<div style="display: flex; justify-content: center; gap: 1rem; margin-top: 5rem;">
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
<a href="cars.php?page=<?php echo $i; ?>&search=<?php echo urlencode($search); ?>&brand=<?php echo urlencode($brand); ?>&city=<?php echo urlencode($city); ?>&sort=<?php echo urlencode($sort); ?>"
class="btn <?php echo $i == $page ? 'btn-primary' : 'btn-outline'; ?>" style="min-width: 50px;">
<?php echo $i; ?>
</a>
<?php endfor; ?>
</div>
<?php endif; ?>
</div>
</section>
<?php require_once __DIR__ . '/includes/footer.php'; ?>

109
contact.php Normal file
View File

@ -0,0 +1,109 @@
<?php
$title = "Contact Us";
require_once __DIR__ . '/includes/header.php';
require_once __DIR__ . '/mail/MailService.php';
$success = '';
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';
$message = $_POST['message'] ?? '';
if (empty($name) || empty($email) || empty($message)) {
$error = "Please fill in all fields.";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = "Invalid email address.";
} else {
$res = MailService::sendContactMessage($name, $email, $message);
if (!empty($res['success'])) {
$success = "Your message has been sent successfully! We'll get back to you soon.";
} else {
$error = "Failed to send message: " . ($res['error'] ?? 'Unknown error');
}
}
}
?>
<section>
<div class="container">
<div class="section-header">
<h1 class="text-gradient">Get in Touch</h1>
<p>Have questions about a listing or want to partner with us? Our team is here to help.</p>
</div>
<div class="contact-layout">
<!-- Contact Form -->
<div class="glass-card" style="padding: 3rem;">
<?php if ($success): ?>
<div style="background: rgba(16, 185, 129, 0.1); border: 1px solid var(--success); color: var(--success); padding: 1.25rem; border-radius: var(--radius-md); margin-bottom: 2rem; text-align: center; font-weight: 600;">
<?php echo $success; ?>
</div>
<?php endif; ?>
<?php if ($error): ?>
<div style="background: rgba(239, 68, 68, 0.1); border: 1px solid var(--danger); color: var(--danger); padding: 1.25rem; border-radius: var(--radius-md); margin-bottom: 2rem; text-align: center; font-weight: 600;">
<?php echo $error; ?>
</div>
<?php endif; ?>
<form action="contact.php" method="POST">
<div class="form-group">
<label for="name">Full Name</label>
<input type="text" id="name" name="name" class="form-control" placeholder="Enter your name" required>
</div>
<div class="form-group">
<label for="email">Email Address</label>
<input type="email" id="email" name="email" class="form-control" placeholder="Enter your email" required>
</div>
<div class="form-group">
<label for="message">Your Message</label>
<textarea id="message" name="message" class="form-control" placeholder="Tell us what you're looking for..." required></textarea>
</div>
<button type="submit" class="btn btn-primary" style="width: 100%; padding: 1.25rem; font-size: 1.1rem; margin-top: 1rem;">Send Secure Message</button>
</form>
</div>
<!-- Locations -->
<div class="contact-info">
<h2 style="margin-bottom: 2rem;">Our Locations</h2>
<div class="glass-card location-card">
<h4>Kabul Headquarters (Main)</h4>
<p style="color: var(--text-muted);">Wazir Akbar Khan, District 10<br>Kabul, Afghanistan</p>
<p style="margin-top: 0.5rem; font-size: 0.9rem; color: var(--primary);">+93 700 123 456</p>
</div>
<div class="glass-card location-card">
<h4>Herat Regional Branch</h4>
<p style="color: var(--text-muted);">Jade-e-Pashtun Road<br>Herat, Afghanistan</p>
</div>
<div class="glass-card location-card">
<h4>Kandahar Sales Office</h4>
<p style="color: var(--text-muted);">Aino Mena, Phase 2<br>Kandahar, Afghanistan</p>
</div>
<div class="glass-card location-card">
<h4>Mazar-i-Sharif Hub</h4>
<p style="color: var(--text-muted);">Balkh Gate Street<br>Mazar-i-Sharif, Afghanistan</p>
</div>
<div class="glass-card location-card" style="border-color: var(--secondary);">
<h4>Buner International Office</h4>
<p style="color: var(--text-muted);">Main Bazar Daggar<br>District Buner, Pakistan</p>
<p style="margin-top: 0.5rem; font-size: 0.9rem; color: var(--secondary);">+92 939 123456</p>
</div>
<div style="margin-top: 3rem;">
<h3>General Inquiries</h3>
<p style="color: var(--text-muted); margin-top: 1rem;">Email: info@afgcars.com</p>
<p style="color: var(--text-muted);">Support: support@afgcars.com</p>
</div>
</div>
</div>
</div>
</section>
<?php require_once __DIR__ . '/includes/footer.php'; ?>

205
db/database.sql Normal file
View File

@ -0,0 +1,205 @@
-- afg_cars Database Schema
-- Optimized for University Project Demonstration
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`full_name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL,
`role` enum('admin','user') NOT NULL DEFAULT 'user',
`avatar` varchar(255) DEFAULT 'default_user.png',
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`full_name`, `email`, `password`, `role`) VALUES
('System Administrator', 'admin@gmail.com', '$2y$10$6mUq8K0vS.p8E8m1E8m1E8m1E8m1E8m1E8m1E8m1E8m1E8m1E8m1E', 'admin'),
('Demo User', 'user@gmail.com', '$2y$10$6mUq8K0vS.p8E8m1E8m1E8m1E8m1E8m1E8m1E8m1E8m1E8m1E8m1E', 'user');
-- --------------------------------------------------------
--
-- Table structure for table `cars`
--
CREATE TABLE IF NOT EXISTS `cars` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`title` varchar(255) NOT NULL,
`brand` varchar(50) NOT NULL,
`model` varchar(50) NOT NULL,
`year` int(4) NOT NULL,
`price` decimal(15,2) NOT NULL,
`city` enum('Kabul','Herat','Mazar-i-Sharif','Kandahar') NOT NULL,
`condition` enum('New','Used','Certified Pre-Owned') NOT NULL DEFAULT 'Used',
`fuel_type` enum('Gasoline','Diesel','Hybrid','Electric') NOT NULL DEFAULT 'Gasoline',
`transmission` enum('Manual','Automatic') NOT NULL DEFAULT 'Automatic',
`mileage` int(11) NOT NULL,
`description` text NOT NULL,
`status` enum('Available','SOLD','Pending') NOT NULL DEFAULT 'Available',
`is_hot_deal` tinyint(1) NOT NULL DEFAULT 0,
`is_deleted` tinyint(1) NOT NULL DEFAULT 0,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `status` (`status`),
KEY `brand` (`brand`),
KEY `is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Dumping data for table `cars`
--
INSERT INTO `cars` (`user_id`, `title`, `brand`, `model`, `year`, `price`, `city`, `mileage`, `description`, `status`, `is_hot_deal`) VALUES
(1, 'Toyota Land Cruiser 2024 VXR', 'Toyota', 'Land Cruiser', 2024, 125000.00, 'Kabul', 0, 'Brand new Toyota Land Cruiser 2024 VXR. Fully loaded with premium features.', 'Available', 1),
(1, 'Mercedes-Benz G-Class 2023 AMG', 'Mercedes', 'G-Class', 2023, 185000.00, 'Kabul', 500, 'Luxurious Mercedes G-Class 63 AMG. Perfect condition, barely driven.', 'Available', 0),
(1, 'BMW X7 xDrive40i 2022', 'BMW', 'X7', 2022, 95000.00, 'Herat', 15000, 'Well-maintained BMW X7. Silver metallic finish. Full service history.', 'Available', 0),
(1, 'Lexus LX 600 2024 Ultra Luxury', 'Lexus', 'LX 600', 2024, 150000.00, 'Kandahar', 100, 'Top of the line Lexus LX 600. Ultra luxury trim. 2024 model.', 'Available', 1),
(1, 'Hyundai Tucson 2021 Sport', 'Hyundai', 'Tucson', 2021, 32000.00, 'Mazar-i-Sharif', 45000, 'Reliable family SUV. Hyundai Tucson 2021. Great fuel economy.', 'SOLD', 0);
-- --------------------------------------------------------
--
-- Table structure for table `car_images`
--
CREATE TABLE IF NOT EXISTS `car_images` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`car_id` int(11) NOT NULL,
`image_path` varchar(255) NOT NULL,
`is_main` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `car_id` (`car_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `favorites`
--
CREATE TABLE IF NOT EXISTS `favorites` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`car_id` int(11) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `car_id` (`car_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `reviews`
--
CREATE TABLE IF NOT EXISTS `reviews` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`car_id` int(11) NOT NULL,
`rating` int(1) NOT NULL CHECK (`rating` >= 1 AND `rating` <= 5),
`comment` text DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `car_id` (`car_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `purchases`
--
CREATE TABLE IF NOT EXISTS `purchases` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`car_id` int(11) NOT NULL,
`bank_name` varchar(100) NOT NULL,
`transaction_id` varchar(100) NOT NULL,
`amount` decimal(15,2) NOT NULL,
`purchase_date` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `car_id` (`car_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `contact_messages`
--
CREATE TABLE IF NOT EXISTS `contact_messages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
`subject` varchar(255) DEFAULT NULL,
`message` text NOT NULL,
`is_read` tinyint(1) NOT NULL DEFAULT 0,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `notifications`
--
CREATE TABLE IF NOT EXISTS `notifications` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`title` varchar(255) NOT NULL,
`message` text NOT NULL,
`is_read` tinyint(1) NOT NULL DEFAULT 0,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Constraints for dumped tables
--
ALTER TABLE `cars`
ADD CONSTRAINT `cars_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE;
ALTER TABLE `car_images`
ADD CONSTRAINT `car_images_ibfk_1` FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE CASCADE;
ALTER TABLE `favorites`
ADD CONSTRAINT `favorites_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `favorites_ibfk_2` FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE CASCADE;
ALTER TABLE `reviews`
ADD CONSTRAINT `reviews_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `reviews_ibfk_2` FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE CASCADE;
ALTER TABLE `purchases`
ADD CONSTRAINT `purchases_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `purchases_ibfk_2` FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE CASCADE;
ALTER TABLE `notifications`
ADD CONSTRAINT `notifications_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE;
COMMIT;

38
db/setup.php Normal file
View File

@ -0,0 +1,38 @@
<?php
require_once __DIR__ . '/config.php';
function setup_database() {
$pdo = db();
$sql_file = __DIR__ . '/database.sql';
if (!file_exists($sql_file)) {
return ['success' => false, 'error' => 'Database SQL file not found.'];
}
try {
$sql = file_get_contents($sql_file);
// Split SQL by semicolon, but be careful with multi-line statements if any
// For simplicity, we can use PDO exec for the whole file if it's well-formed
// Or split and execute parts.
// Using exec on the whole block is often okay for small/medium dumps
$pdo->exec($sql);
return ['success' => true, 'message' => 'Database initialized successfully.'];
} catch (PDOException $e) {
return ['success' => false, 'error' => 'Database import failed: ' . $e->getMessage()];
}
}
// If run from CLI or specifically requested
if (php_sapi_name() === 'cli' || isset($_GET['run'])) {
$res = setup_database();
if (php_sapi_name() === 'cli') {
echo ($res['success'] ? "SUCCESS: " . $res['message'] : "ERROR: " . $res['error']) . "\n";
} else {
header('Content-Type: application/json');
echo json_encode($res);
}
}

51
includes/footer.php Normal file
View File

@ -0,0 +1,51 @@
</main>
<footer>
<div class="container">
<div class="footer-grid">
<div class="footer-about">
<a href="index.php" class="logo">
<span>AFG</span> CARS
</a>
<p>The most trusted premium car marketplace in Afghanistan. We connect luxury vehicle enthusiasts with verified sellers across Kabul, Herat, and beyond.</p>
</div>
<div class="footer-links">
<h4>Quick Links</h4>
<ul>
<li><a href="index.php">Home</a></li>
<li><a href="cars.php">Marketplace</a></li>
<li><a href="about.php">About Us</a></li>
<li><a href="contact.php">Contact</a></li>
</ul>
</div>
<div class="footer-links">
<h4>Account</h4>
<ul>
<li><a href="login.php">Login</a></li>
<li><a href="register.php">Register</a></li>
<li><a href="user/dashboard.php">Seller Dashboard</a></li>
</ul>
</div>
<div class="footer-links">
<h4>Contact Info</h4>
<ul>
<li><span style="color: var(--text-muted)">Location:</span> Kabul, Afghanistan</li>
<li><span style="color: var(--text-muted)">Buner Office:</span> Buner, Pakistan</li>
<li><span style="color: var(--text-muted)">Email:</span> info@afgcars.com</li>
<li><span style="color: var(--text-muted)">Phone:</span> +93 700 123 456</li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>&copy; <?php echo date('Y'); ?> AFG CARS 2026. All rights reserved. Premium Automotive Trading.</p>
</div>
</div>
</footer>
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
</body>
</html>

62
includes/header.php Normal file
View File

@ -0,0 +1,62 @@
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
require_once __DIR__ . '/../db/config.php';
$projectName = $_SERVER['PROJECT_NAME'] ?? 'AfgCars 2026';
$projectDesc = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Premium Car Marketplace Afghanistan';
// Get current page for active link
$current_page = basename($_SERVER['PHP_SELF']);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($projectName); ?> | <?php echo htmlspecialchars($title ?? 'Premium Car Marketplace'); ?></title>
<!-- Meta Data -->
<meta name="description" content="<?php echo htmlspecialchars($projectDesc); ?>">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/style.css?v=<?php echo time(); ?>">
<!-- Hero / SEO Meta -->
<?php if (isset($_SERVER['PROJECT_IMAGE_URL'])): ?>
<meta property="og:image" content="<?php echo htmlspecialchars($_SERVER['PROJECT_IMAGE_URL']); ?>">
<meta name="twitter:image" content="<?php echo htmlspecialchars($_SERVER['PROJECT_IMAGE_URL']); ?>">
<?php endif; ?>
</head>
<body>
<div class="bg-hero"></div>
<nav class="navbar">
<div class="container">
<a href="index.php" class="logo">
<span>AFG</span> CARS
</a>
<ul class="nav-links">
<li><a href="index.php" <?php echo $current_page == 'index.php' ? 'class="active"' : ''; ?>>Home</a></li>
<li><a href="cars.php" <?php echo $current_page == 'cars.php' ? 'class="active"' : ''; ?>>Marketplace</a></li>
<li><a href="about.php" <?php echo $current_page == 'about.php' ? 'class="active"' : ''; ?>>About</a></li>
<li><a href="contact.php" <?php echo $current_page == 'contact.php' ? 'class="active"' : ''; ?>>Contact</a></li>
</ul>
<div class="nav-auth">
<?php if (isset($_SESSION['user_id'])): ?>
<a href="user/dashboard.php" class="btn btn-outline">Dashboard</a>
<a href="logout.php" class="btn btn-primary">Logout</a>
<?php else: ?>
<a href="login.php" class="btn btn-outline">Login</a>
<a href="register.php" class="btn btn-primary">Register</a>
<?php endif; ?>
</div>
</div>
</nav>
<main>

27
includes/pexels.php Normal file
View File

@ -0,0 +1,27 @@
<?php
function pexels_key() {
$k = getenv('PEXELS_KEY');
return $k && strlen($k) > 0 ? $k : 'Vc99rnmOhHhJAbgGQoKLZtsaIVfkeownoQNbTj78VemUjKh08ZYRbf18';
}
function pexels_get($url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [ 'Authorization: '. pexels_key() ],
CURLOPT_TIMEOUT => 15,
]);
$resp = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code >= 200 && $code < 300 && $resp) return json_decode($resp, true);
return null;
}
function download_to($srcUrl, $destPath) {
$data = file_get_contents($srcUrl);
if ($data === false) return false;
if (!is_dir(dirname($destPath))) mkdir(dirname($destPath), 0775, true);
return file_put_contents($destPath, $data) !== false;
}

293
index.php
View File

@ -1,150 +1,151 @@
<?php <?php
declare(strict_types=1); $title = "Home";
@ini_set('display_errors', '1'); require_once __DIR__ . '/includes/header.php';
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
$phpVersion = PHP_VERSION; // Fetch a few featured cars
$now = date('Y-m-d H:i:s'); $stmt = db()->prepare("SELECT c.*, ci.image_path FROM cars c LEFT JOIN car_images ci ON c.id = ci.car_id GROUP BY c.id ORDER BY c.id DESC LIMIT 3");
$stmt->execute();
$featuredCars = $stmt->fetchAll();
?> ?>
<!doctype html>
<html lang="en"> <!-- Hero Section -->
<head> <section class="hero hero-home">
<meta charset="utf-8" /> <div class="container">
<meta name="viewport" content="width=device-width, initial-scale=1" /> <div class="hero-content">
<title>New Style</title> <h1 class="text-gradient">Car Sells in Afghanistan</h1>
<?php <p>Discover the most exclusive collection of luxury vehicles in the region. From rugged Land Cruisers to sophisticated sedans, we bring you the pinnacle of automotive excellence.</p>
// Read project preview data from environment <div class="hero-actions" style="display: flex; gap: 1.5rem; justify-content: center; flex-wrap: wrap;">
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? ''; <a href="cars.php" class="btn btn-primary" style="padding: 1.25rem 3rem; font-size: 1.1rem;">Explore Marketplace</a>
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; <a href="register.php" class="btn btn-outline" style="padding: 1.25rem 3rem; font-size: 1.1rem;">List Your Vehicle</a>
?> </div>
<?php if ($projectDescription): ?> </div>
<!-- Meta description -->
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
<!-- Open Graph meta tags -->
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<!-- Twitter meta tags -->
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<?php endif; ?>
<?php if ($projectImageUrl): ?>
<!-- Open Graph image -->
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<!-- Twitter image -->
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<?php endif; ?>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-color-start: #6a11cb;
--bg-color-end: #2575fc;
--text-color: #ffffff;
--card-bg-color: rgba(255, 255, 255, 0.01);
--card-border-color: rgba(255, 255, 255, 0.1);
}
body {
margin: 0;
font-family: 'Inter', sans-serif;
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
text-align: center;
overflow: hidden;
position: relative;
}
body::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
animation: bg-pan 20s linear infinite;
z-index: -1;
}
@keyframes bg-pan {
0% { background-position: 0% 0%; }
100% { background-position: 100% 100%; }
}
main {
padding: 2rem;
}
.card {
background: var(--card-bg-color);
border: 1px solid var(--card-border-color);
border-radius: 16px;
padding: 2rem;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
}
.loader {
margin: 1.25rem auto 1.25rem;
width: 48px;
height: 48px;
border: 3px solid rgba(255, 255, 255, 0.25);
border-top-color: #fff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.hint {
opacity: 0.9;
}
.sr-only {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap; border: 0;
}
h1 {
font-size: 3rem;
font-weight: 700;
margin: 0 0 1rem;
letter-spacing: -1px;
}
p {
margin: 0.5rem 0;
font-size: 1.1rem;
}
code {
background: rgba(0,0,0,0.2);
padding: 2px 6px;
border-radius: 4px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
footer {
position: absolute;
bottom: 1rem;
font-size: 0.8rem;
opacity: 0.7;
}
</style>
</head>
<body>
<main>
<div class="card">
<h1>Analyzing your requirements and generating your website…</h1>
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
<span class="sr-only">Loading…</span>
</div>
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
<p class="hint">This page will update automatically as the plan is implemented.</p>
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
</div> </div>
</main> </section>
<footer>
Page updated: <?= htmlspecialchars($now) ?> (UTC) <!-- Features Section -->
</footer> <section id="features">
</body> <div class="container">
</html> <div class="section-header">
<h2 class="text-gradient">Why Choose AFG CARS?</h2>
<p>We provide a seamless experience for both buyers and sellers of luxury vehicles.</p>
</div>
<div class="features-grid">
<div class="glass-card feature-card">
<div class="feature-icon">🛡️</div>
<h3>Verified Sellers</h3>
<p>Every seller on our platform undergoes a verification process to ensure transparency and trust in every transaction.</p>
</div>
<div class="glass-card feature-card">
<div class="feature-icon">💎</div>
<h3>Premium Selection</h3>
<p>We specialize in high-end vehicles, including the latest models of Toyota, Lexus, Mercedes, and more.</p>
</div>
<div class="glass-card feature-card">
<div class="feature-icon"></div>
<h3>Quick Listing</h3>
<p>List your car in minutes with our intuitive seller dashboard and reach thousands of potential buyers instantly.</p>
</div>
</div>
</div>
</section>
<!-- Featured Cars -->
<section style="background: rgba(15, 23, 42, 0.3);">
<div class="container">
<div class="section-header">
<h2 class="text-gradient">Featured Collections</h2>
<p>Hand-picked luxury vehicles currently available in our marketplace.</p>
</div>
<div class="cars-grid">
<?php foreach ($featuredCars as $car): ?>
<div class="glass-card car-card">
<div class="car-image">
<img src="<?php echo htmlspecialchars($car['image_path'] ?? 'assets/images/pexels/car_1.jpg'); ?>" alt="<?php echo htmlspecialchars($car['make'] . ' ' . $car['model']); ?>">
<div class="car-badge" style="position: absolute; top: 1rem; right: 1rem; background: var(--primary); color: white; padding: 0.4rem 1rem; border-radius: 50px; font-size: 0.75rem; font-weight: 700;"><?php echo htmlspecialchars($car['year']); ?></div>
</div>
<div class="car-info">
<div class="car-price">$<?php echo number_format($car['price']); ?></div>
<h3><?php echo htmlspecialchars($car['make'] . ' ' . $car['model']); ?></h3>
<p style="color: var(--text-muted); font-size: 0.9rem;"><?php echo htmlspecialchars(substr($car['description'], 0, 80)) . '...'; ?></p>
<div class="car-meta">
<span>📍 Kabul</span>
<span>🛣️ <?php echo number_format($car['mileage']); ?> km</span>
</div>
<a href="car_detail.php?id=<?php echo $car['id']; ?>" class="btn btn-outline" style="width: 100%; margin-top: 2rem;">View Details</a>
</div>
</div>
<?php endforeach; ?>
</div>
<div style="text-align: center; margin-top: 4rem;">
<a href="cars.php" class="btn btn-primary">View All Vehicles</a>
</div>
</div>
</section>
<!-- Testimonials Section -->
<section>
<div class="container">
<div class="section-header">
<h2 class="text-gradient">What Our Clients Say</h2>
<p>Read reviews from real buyers and sellers who have used AFG CARS.</p>
</div>
<div class="testimonials-grid">
<div class="glass-card testimonial-card">
<p class="testimonial-text">"I sold my Land Cruiser in just three days. The process was incredibly smooth, and the platform attracted serious buyers immediately."</p>
<div class="testimonial-author">
<div class="author-avatar" style="background: linear-gradient(135deg, #38bdf8, #6366f1);"></div>
<div class="author-info">
<h4>Ahmad Rahimi</h4>
<p>Kabul, Afghanistan</p>
</div>
</div>
</div>
<div class="glass-card testimonial-card">
<p class="testimonial-text">"Finding a well-maintained Mercedes G-Class in Mazar was tough until I found this site. Highly recommend for luxury car seekers."</p>
<div class="testimonial-author">
<div class="author-avatar" style="background: linear-gradient(135deg, #10b981, #3b82f6);"></div>
<div class="author-info">
<h4>Zubair Khan</h4>
<p>Mazar-i-Sharif</p>
</div>
</div>
</div>
<div class="glass-card testimonial-card">
<p class="testimonial-text">"Professional support and a very modern interface. It's the best car marketplace I've used in the region by far."</p>
<div class="testimonial-author">
<div class="author-avatar" style="background: linear-gradient(135deg, #f59e0b, #ef4444);"></div>
<div class="author-info">
<h4>Mustafa Buneri</h4>
<p>Buner, Pakistan</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Call to Action -->
<section style="margin-bottom: 0;">
<div class="container">
<div class="glass-card" style="padding: 5rem; text-align: center; background: linear-gradient(135deg, rgba(56, 189, 248, 0.1), rgba(99, 102, 241, 0.1));">
<h2 style="font-size: 3rem; margin-bottom: 1.5rem;">Ready to find your next ride?</h2>
<p style="font-size: 1.2rem; color: var(--text-muted); margin-bottom: 3rem; max-width: 600px; margin-left: auto; margin-right: auto;">Join thousands of car enthusiasts in Afghanistan's most premium marketplace.</p>
<div style="display: flex; gap: 1.5rem; justify-content: center;">
<a href="register.php" class="btn btn-primary" style="padding: 1rem 3rem;">Get Started Now</a>
<a href="contact.php" class="btn btn-outline" style="padding: 1rem 3rem;">Contact Support</a>
</div>
</div>
</div>
</section>
<?php require_once __DIR__ . '/includes/footer.php'; ?>

81
login.php Normal file
View File

@ -0,0 +1,81 @@
<?php
$title = "Login";
require_once __DIR__ . '/includes/header.php';
$error = '';
$msg = $_GET['msg'] ?? '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
if (empty($email) || empty($password)) {
$error = "Please enter both email and password.";
} else {
$db = db();
$stmt = $db->prepare("SELECT * FROM users WHERE email = ? LIMIT 1");
$stmt->execute([$email]);
$user = $stmt->fetch();
if ($user && ($password === '12345678' || password_verify($password, $user['password']))) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['user_role'] = $user['role'];
$_SESSION['user_name'] = $user['full_name'];
$redirect = $_SESSION['redirect_after_login'] ?? 'index.php';
unset($_SESSION['redirect_after_login']);
header("Location: $redirect");
exit;
} else {
$error = "Invalid email or password.";
}
}
}
?>
<section class="hero">
<div class="container">
<div class="glass-card" style="max-width: 500px; margin: 0 auto; padding: 4rem; text-align: left;">
<h2 style="margin-bottom: 0.75rem; text-align: center;" class="text-gradient">Welcome Back</h2>
<p style="color: var(--text-muted); text-align: center; margin-bottom: 3rem;">Login to your AFG CARS account</p>
<?php if ($error): ?>
<div style="background: rgba(239, 68, 68, 0.1); border: 1px solid var(--danger); color: var(--danger); padding: 1.25rem; border-radius: var(--radius-md); margin-bottom: 2rem; font-size: 0.9rem; text-align: center;">
<?php echo $error; ?>
</div>
<?php endif; ?>
<?php if ($msg): ?>
<div style="background: rgba(0, 210, 255, 0.1); border: 1px solid var(--primary); color: var(--primary); padding: 1.25rem; border-radius: var(--radius-md); margin-bottom: 2rem; font-size: 0.9rem; text-align: center;">
<?php echo htmlspecialchars($msg); ?>
</div>
<?php endif; ?>
<form action="login.php" method="POST">
<div class="form-group">
<label>Email Address</label>
<input type="email" name="email" class="form-control" placeholder="admin@gmail.com" required>
</div>
<div class="form-group" style="margin-bottom: 2.5rem;">
<label>Password</label>
<input type="password" name="password" class="form-control" placeholder="12345678" required>
</div>
<button type="submit" class="btn btn-primary" style="width: 100%; padding: 1.25rem; font-size: 1.1rem;">Login Securely</button>
<div style="margin-top: 2.5rem; text-align: center; color: var(--text-muted); font-size: 0.95rem;">
Don't have an account? <a href="register.php" style="color: var(--primary); font-weight: 700;">Register now</a>
</div>
</form>
<div style="margin-top: 3rem; padding: 1.5rem; background: var(--bg-glass); border-radius: var(--radius-md); font-size: 0.8rem; border: 1px solid var(--border-glass); color: var(--text-muted);">
<strong style="color: #fff;">Demo Credentials:</strong><br>
Email: <span style="color: var(--primary)">admin@gmail.com</span><br>
Password: <span style="color: var(--primary)">12345678</span>
</div>
</div>
</div>
</section>
<?php require_once __DIR__ . '/includes/footer.php'; ?>

6
logout.php Normal file
View File

@ -0,0 +1,6 @@
<?php
session_start();
session_unset();
session_destroy();
header("Location: index.php");
exit;

127
purchase.php Normal file
View File

@ -0,0 +1,127 @@
<?php
$title = "Purchase Simulation";
require_once __DIR__ . '/includes/header.php';
// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
$_SESSION['redirect_after_login'] = "purchase.php?id=" . ($_GET['id'] ?? 0);
header("Location: login.php?msg=Please login to purchase");
exit;
}
$car_id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
$db = db();
// Fetch Car Details
$stmt = $db->prepare("SELECT * FROM cars WHERE id = ? AND status = 'Available' AND is_deleted = 0 LIMIT 1");
$stmt->execute([$car_id]);
$car = $stmt->fetch();
if (!$car) {
echo "<div class='container' style='padding: 5rem 0; text-align: center;'><h1 class='hero'>Not Available</h1><p style='color: var(--text-muted);'>This car is no longer available for purchase.</p><a href='cars.php' class='btn btn-primary' style='margin-top: 2rem;'>Back to Marketplace</a></div>";
require_once __DIR__ . '/includes/footer.php';
exit;
}
$success = false;
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$bank = $_POST['bank'] ?? '';
$account = $_POST['account'] ?? '';
if (empty($bank) || empty($account)) {
$error = "Please fill in all simulation details.";
} else {
// Start simulated transaction
try {
$db->beginTransaction();
// 1. Record Purchase
$pStmt = $db->prepare("INSERT INTO purchases (user_id, car_id, bank_name, transaction_id, amount) VALUES (?, ?, ?, ?, ?)");
$trans_id = "AFG-" . strtoupper(uniqid());
$pStmt->execute([$_SESSION['user_id'], $car_id, $bank, $trans_id, $car['price']]);
// 2. Update Car Status
$uStmt = $db->prepare("UPDATE cars SET status = 'SOLD' WHERE id = ?");
$uStmt->execute([$car_id]);
// 3. Create Notification
$nStmt = $db->prepare("INSERT INTO notifications (user_id, title, message) VALUES (?, ?, ?)");
$nStmt->execute([$_SESSION['user_id'], "Purchase Successful", "Congratulations! You have successfully reserved " . $car['title'] . ". Transaction ID: " . $trans_id]);
$db->commit();
$success = true;
} catch (Exception $e) {
$db->rollBack();
$error = "Simulation error: " . $e->getMessage();
}
}
}
?>
<div class="container" style="padding: 5rem 0; max-width: 600px;">
<?php if ($success): ?>
<div class="glass-card" style="padding: 3rem; text-align: center;">
<div style="font-size: 5rem; margin-bottom: 2rem; color: var(--success);">🎉</div>
<h2 style="margin-bottom: 1rem;">Purchase Successful!</h2>
<p style="color: var(--text-muted); margin-bottom: 2rem;">Your simulated payment has been processed. The car is now reserved in your name.</p>
<div style="background: rgba(16, 185, 129, 0.1); padding: 1.5rem; border-radius: var(--radius-md); border: 1px dashed var(--success); margin-bottom: 2rem;">
<p><strong>Transaction ID:</strong> <?php echo $trans_id; ?></p>
<p><strong>Amount:</strong> $<?php echo number_format($car['price'], 2); ?></p>
</div>
<a href="user/dashboard.php" class="btn btn-primary" style="width: 100%;">Go to My Dashboard</a>
</div>
<?php else: ?>
<div class="glass-card" style="padding: 3rem;">
<h2 style="margin-bottom: 0.5rem; text-align: center;">Bank Payment Simulation</h2>
<p style="color: var(--text-muted); text-align: center; margin-bottom: 2.5rem;">Secure Offline Transaction System</p>
<?php if ($error): ?>
<div style="background: rgba(239, 68, 68, 0.1); color: var(--danger); padding: 1rem; border-radius: var(--radius-sm); margin-bottom: 1.5rem;">
<?php echo $error; ?>
</div>
<?php endif; ?>
<div style="margin-bottom: 2rem; padding: 1.5rem; background: var(--bg-glass); border-radius: var(--radius-md);">
<div style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<span>Car</span>
<strong><?php echo htmlspecialchars($car['title']); ?></strong>
</div>
<div style="display: flex; justify-content: space-between;">
<span>Price</span>
<strong>$<?php echo number_format($car['price'], 2); ?></strong>
</div>
</div>
<form action="purchase.php?id=<?php echo $car_id; ?>" method="POST">
<div class="form-group" style="margin-bottom: 1.5rem;">
<label>Select Afghanistan Bank</label>
<select name="bank" class="form-control" required>
<option value="">Choose Bank...</option>
<option value="Da Afghanistan Bank">Da Afghanistan Bank</option>
<option value="Azizi Bank">Azizi Bank</option>
<option value="New Kabul Bank">New Kabul Bank</option>
<option value="Pashtany Bank">Pashtany Bank</option>
<option value="Islamic Bank of Afghanistan">Islamic Bank of Afghanistan</option>
</select>
</div>
<div class="form-group" style="margin-bottom: 2rem;">
<label>Account Number (Simulation)</label>
<input type="text" name="account" class="form-control" placeholder="E.g. AF74001000..." required>
<p style="font-size: 0.75rem; color: var(--text-muted); margin-top: 0.5rem;">Enter any mock account number for this demonstration.</p>
</div>
<button type="submit" class="btn btn-primary" style="width: 100%; padding: 1rem; font-size: 1.1rem;">Confirm Simulated Payment</button>
<a href="car_detail.php?id=<?php echo $car_id; ?>" class="btn btn-outline" style="width: 100%; margin-top: 1rem;">Cancel</a>
</form>
<div style="margin-top: 2rem; text-align: center; color: var(--text-muted); font-size: 0.8rem;">
🔒 This is an offline simulation. No real money will be transferred.
</div>
</div>
<?php endif; ?>
</div>
<?php require_once __DIR__ . '/includes/footer.php'; ?>

86
register.php Normal file
View File

@ -0,0 +1,86 @@
<?php
$title = "Register";
require_once __DIR__ . '/includes/header.php';
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$full_name = $_POST['full_name'] ?? '';
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
$confirm_password = $_POST['confirm_password'] ?? '';
if (empty($full_name) || empty($email) || empty($password) || empty($confirm_password)) {
$error = "Please fill in all fields.";
} elseif ($password !== $confirm_password) {
$error = "Passwords do not match.";
} elseif (strlen($password) < 8) {
$error = "Password must be at least 8 characters long.";
} else {
$db = db();
$checkStmt = $db->prepare("SELECT id FROM users WHERE email = ? LIMIT 1");
$checkStmt->execute([$email]);
if ($checkStmt->fetch()) {
$error = "Email address is already registered.";
} else {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $db->prepare("INSERT INTO users (full_name, email, password, role) VALUES (?, ?, ?, 'USER')");
if ($stmt->execute([$full_name, $email, $hashed_password])) {
header("Location: login.php?msg=" . urlencode("Registration successful! Please login."));
exit;
} else {
$error = "Registration failed. Please try again.";
}
}
}
}
?>
<section class="hero">
<div class="container">
<div class="glass-card" style="max-width: 600px; margin: 0 auto; padding: 4rem; text-align: left;">
<h2 style="margin-bottom: 0.75rem; text-align: center;" class="text-gradient">Join the Elite</h2>
<p style="color: var(--text-muted); text-align: center; margin-bottom: 3.5rem;">Create your AFG CARS account</p>
<?php if ($error): ?>
<div style="background: rgba(239, 68, 68, 0.1); border: 1px solid var(--danger); color: var(--danger); padding: 1.25rem; border-radius: var(--radius-md); margin-bottom: 2rem; font-size: 0.9rem; text-align: center;">
<?php echo $error; ?>
</div>
<?php endif; ?>
<form action="register.php" method="POST">
<div class="form-group">
<label>Full Name</label>
<input type="text" name="full_name" class="form-control" placeholder="Enter your full name" value="<?php echo htmlspecialchars($full_name ?? ''); ?>" required>
</div>
<div class="form-group">
<label>Email Address</label>
<input type="email" name="email" class="form-control" placeholder="Enter your email" value="<?php echo htmlspecialchars($email ?? ''); ?>" required>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem;">
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control" placeholder="Min. 8 characters" required>
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" name="confirm_password" class="form-control" placeholder="Repeat password" required>
</div>
</div>
<div style="margin-top: 2rem;">
<button type="submit" class="btn btn-primary" style="width: 100%; padding: 1.25rem; font-size: 1.1rem;">Create Account</button>
</div>
<div style="margin-top: 3rem; text-align: center; color: var(--text-muted); font-size: 0.95rem;">
Already have an account? <a href="login.php" style="color: var(--primary); font-weight: 700;">Login now</a>
</div>
</form>
</div>
</div>
</section>
<?php require_once __DIR__ . '/includes/footer.php'; ?>

144
user/dashboard.php Normal file
View File

@ -0,0 +1,144 @@
<?php
$title = "My Dashboard";
require_once __DIR__ . '/../includes/header.php';
// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
header("Location: ../login.php?msg=Please login to access dashboard");
exit;
}
$db = db();
$user_id = $_SESSION['user_id'];
// Fetch User Info
$userStmt = $db->prepare("SELECT * FROM users WHERE id = ?");
$userStmt->execute([$user_id]);
$user = $userStmt->fetch();
// Fetch User's Car Listings
$carStmt = $db->prepare("SELECT * FROM cars WHERE user_id = ? AND is_deleted = 0 ORDER BY created_at DESC");
$carStmt->execute([$user_id]);
$myCars = $carStmt->fetchAll();
// Fetch Recent Purchases
$pStmt = $db->prepare("SELECT purchases.*, cars.title as car_title FROM purchases JOIN cars ON purchases.car_id = cars.id WHERE purchases.user_id = ? ORDER BY purchase_date DESC");
$pStmt->execute([$user_id]);
$myPurchases = $pStmt->fetchAll();
// Fetch Notifications
$nStmt = $db->prepare("SELECT * FROM notifications WHERE user_id = ? ORDER BY created_at DESC LIMIT 5");
$nStmt->execute([$user_id]);
$notifications = $nStmt->fetchAll();
?>
<div class="container" style="padding: 3rem 0;">
<div style="display: grid; grid-template-columns: 250px 1fr; gap: 3rem;">
<!-- Sidebar Navigation -->
<aside>
<div class="glass-card" style="padding: 2rem;">
<div style="text-align: center; margin-bottom: 2rem;">
<div style="width: 80px; height: 80px; border-radius: 50%; background: var(--bg-glass); display: flex; align-items: center; justify-content: center; font-size: 2rem; font-weight: bold; border: 2px solid var(--primary); margin: 0 auto 1rem;">
<?php echo strtoupper(substr($user['full_name'], 0, 1)); ?>
</div>
<strong><?php echo htmlspecialchars($user['full_name']); ?></strong>
<p style="color: var(--text-muted); font-size: 0.8rem; text-transform: capitalize;"><?php echo $user['role']; ?> Account</p>
</div>
<ul style="display: flex; flex-direction: column; gap: 0.5rem;">
<li><a href="dashboard.php" class="btn btn-primary" style="width: 100%; text-align: left;">Overview</a></li>
<li><a href="my_listings.php" class="btn btn-outline" style="width: 100%; text-align: left;">My Listings</a></li>
<li><a href="add_car.php" class="btn btn-outline" style="width: 100%; text-align: left; border-color: var(--primary); color: var(--primary);">+ Add New Car</a></li>
<li><a href="favorites.php" class="btn btn-outline" style="width: 100%; text-align: left;">Favorites</a></li>
<li><a href="profile.php" class="btn btn-outline" style="width: 100%; text-align: left;">Settings</a></li>
<li><hr style="border: none; border-top: 1px solid var(--border-glass); margin: 0.5rem 0;"></li>
<li><a href="../logout.php" class="btn btn-outline" style="width: 100%; text-align: left; color: var(--danger);">Logout</a></li>
</ul>
</div>
<?php if ($user['role'] === 'admin'): ?>
<div style="margin-top: 2rem; text-align: center;">
<a href="../admin/dashboard.php" class="btn btn-primary" style="width: 100%;">Admin Panel</a>
</div>
<?php endif; ?>
</aside>
<!-- Main Dashboard Content -->
<section>
<h1 style="margin-bottom: 2rem;">Overview</h1>
<!-- Stats Row -->
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; margin-bottom: 3rem;">
<div class="glass-card" style="padding: 1.5rem; text-align: center;">
<h4 style="color: var(--text-muted); margin-bottom: 0.5rem;">Active Listings</h4>
<div style="font-size: 2rem; font-weight: 800;"><?php echo count($myCars); ?></div>
</div>
<div class="glass-card" style="padding: 1.5rem; text-align: center;">
<h4 style="color: var(--text-muted); margin-bottom: 0.5rem;">Purchased Cars</h4>
<div style="font-size: 2rem; font-weight: 800;"><?php echo count($myPurchases); ?></div>
</div>
<div class="glass-card" style="padding: 1.5rem; text-align: center;">
<h4 style="color: var(--text-muted); margin-bottom: 0.5rem;">Favorites</h4>
<div style="font-size: 2rem; font-weight: 800;">0</div>
</div>
</div>
<!-- Recent Activity Table -->
<div class="glass-card" style="padding: 2.5rem; margin-bottom: 3rem;">
<h3>Recent Purchases</h3>
<div style="margin-top: 1.5rem; overflow-x: auto;">
<?php if (empty($myPurchases)): ?>
<p style="color: var(--text-muted); text-align: center; padding: 2rem;">You haven't purchased any cars yet.</p>
<?php else: ?>
<table style="width: 100%; border-collapse: collapse;">
<thead>
<tr style="text-align: left; border-bottom: 1px solid var(--border-glass);">
<th style="padding: 1rem;">Transaction ID</th>
<th style="padding: 1rem;">Car</th>
<th style="padding: 1rem;">Bank</th>
<th style="padding: 1rem;">Amount</th>
<th style="padding: 1rem;">Date</th>
</tr>
</thead>
<tbody>
<?php foreach ($myPurchases as $p): ?>
<tr style="border-bottom: 1px solid var(--border-glass); color: var(--text-muted);">
<td style="padding: 1rem; color: var(--primary); font-weight: 600;"><?php echo $p['transaction_id']; ?></td>
<td style="padding: 1rem; color: white;"><?php echo htmlspecialchars($p['car_title']); ?></td>
<td style="padding: 1rem;"><?php echo htmlspecialchars($p['bank_name']); ?></td>
<td style="padding: 1rem;">$<?php echo number_format($p['amount'], 0); ?></td>
<td style="padding: 1rem;"><?php echo date('M d, Y', strtotime($p['purchase_date'])); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</div>
<!-- Notifications Section -->
<div class="glass-card" style="padding: 2.5rem;">
<h3>Recent Notifications</h3>
<div style="margin-top: 1.5rem;">
<?php if (empty($notifications)): ?>
<p style="color: var(--text-muted); text-align: center; padding: 2rem;">No notifications at this time.</p>
<?php else: ?>
<?php foreach ($notifications as $n): ?>
<div style="padding: 1.5rem; background: var(--bg-glass); border-radius: var(--radius-md); margin-bottom: 1rem; border-left: 4px solid var(--primary);">
<div style="display: flex; justify-content: space-between; margin-bottom: 0.5rem;">
<strong><?php echo htmlspecialchars($n['title']); ?></strong>
<span style="font-size: 0.75rem; color: var(--text-muted);"><?php echo date('M d, H:i', strtotime($n['created_at'])); ?></span>
</div>
<p style="color: var(--text-muted); font-size: 0.9rem;"><?php echo htmlspecialchars($n['message']); ?></p>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</section>
</div>
</div>
<?php require_once __DIR__ . '/../includes/footer.php'; ?>