Autosave: 20260223-092837

This commit is contained in:
Flatlogic Bot 2026-02-23 09:28:37 +00:00
parent ae8a758bba
commit ea8f42f0c6
3 changed files with 158 additions and 104 deletions

View File

@ -2,6 +2,38 @@
AfgCars is a robust, visually stunning automotive marketplace platform designed for the Afghan car market. It features a modern "glassmorphism" design, a powerful admin panel, and seamless car listing management for both individual sellers and administrators.
## 🚀 Quick Start (How to Run)
### 1. Database Setup
The application requires a MySQL/MariaDB database.
**Option A: Import SQL File (Recommended)**
1. Create a database named `app_38703` (or the name specified in `db/config.php`).
2. Import the `database.sql` file located in the root directory:
```bash
mysql -u your_username -p app_38703 < database.sql
```
**Option B: Run Setup Script**
Alternatively, you can run the PHP setup script which creates the tables automatically:
```bash
php db/setup.php
```
### 2. Configuration
Ensure your database credentials in `db/config.php` are correct:
```php
define('DB_HOST', '127.0.0.1');
define('DB_NAME', 'app_38703');
define('DB_USER', 'your_user');
define('DB_PASS', 'your_password');
```
### 3. Launch
Open your web browser and navigate to the project root (e.g., `http://localhost/`).
---
## 🚀 Key Features
- **Modern UI/UX**: Clean, youthful, and inviting design with glassmorphism effects.
- **Admin Dashboard**: Full control over users, car listings, and customer messages.
@ -16,35 +48,12 @@ AfgCars is a robust, visually stunning automotive marketplace platform designed
- **Frontend**: HTML5, CSS3 (Custom Glassmorphism Styles), JavaScript (Vanilla)
- **Email**: Integrated PHPMailer service
## 🗄️ Database Configuration
The database connection details are stored in `db/config.php`.
| Parameter | Value |
|-----------|-------|
| **Host** | `127.0.0.1` |
| **Database Name** | `app_38703` |
| **Username** | `app_38703` |
| **Password** | `9e003665-baa5-4dba-baf3-b850a58e49d7` |
To initialize the database, run:
```bash
php db/setup.php
php db/seed_cars.php
```
## 👤 Default Accounts
Use these credentials to access the platform during testing:
### Administrator
## 👤 Default Admin Account
Use these credentials to access the administrative panel:
- **Email**: `admin@gmail.com`
- **Password**: `12345678`
- **Role**: `admin`
### Regular User
- **Email**: `user@example.com` (Example - use registration to create)
- **Password**: `12345678`
- **Role**: `user`
## 📊 Entity Relationship Diagram (ERD)
```mermaid
@ -121,14 +130,15 @@ erDiagram
## 📁 Project Structure
- `index.php`: Landing page and marketplace hero.
- `cars.php`: Searchable list of all approved vehicles.
- `cars.php`: Searchable list of all vehicles.
- `car_detail.php`: Detailed view of a single car with photo gallery.
- `admin_dashboard.php`: Entry point for administrative management.
- `dashboard.php`: User-specific panel for listing management.
- `database.sql`: MySQL export for easy database import.
- `db/`: Database configuration and setup scripts.
- `assets/`: CSS, JS, and image assets.
- `includes/`: Reusable header and footer components.
- `mail/`: Built-in email service components.
## 📝 License
This project is built for educational and demonstration purposes.
This project is built for educational and demonstration purposes.

121
database.sql Normal file
View File

@ -0,0 +1,121 @@
-- AfgCars Database Schema
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,
`name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL UNIQUE,
`password` varchar(255) NOT NULL,
`role` enum('guest','user','admin') DEFAULT 'user',
`status` enum('active','inactive') DEFAULT 'active',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`name`, `email`, `password`, `role`) VALUES
('Admin', 'admin@gmail.com', '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', 'admin');
-- Default password is '12345678'
--
-- Table structure for table `cars`
--
CREATE TABLE IF NOT EXISTS `cars` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`brand` varchar(50) NOT NULL,
`model` varchar(50) NOT NULL,
`year` int(11) NOT NULL,
`price` decimal(10,2) NOT NULL,
`city` varchar(50) NOT NULL,
`description` text,
`status` enum('pending','approved','rejected','sold') DEFAULT 'pending',
`is_hot_deal` boolean DEFAULT FALSE,
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `cars_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- 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` boolean DEFAULT FALSE,
PRIMARY KEY (`id`),
KEY `car_id` (`car_id`),
CONSTRAINT `car_images_ibfk_1` FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Table structure for table `reviews`
--
CREATE TABLE IF NOT EXISTS `reviews` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`car_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`rating` int(11) DEFAULT NULL CHECK (`rating` >= 1 and `rating` <= 5),
`comment` text,
`status` enum('pending','approved') DEFAULT 'pending',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `car_id` (`car_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `reviews_ibfk_1` FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE CASCADE,
CONSTRAINT `reviews_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Table structure for table `purchases`
--
CREATE TABLE IF NOT EXISTS `purchases` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`car_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`buyer_name` varchar(100) DEFAULT NULL,
`buyer_email` varchar(100) DEFAULT NULL,
`buyer_phone` varchar(20) DEFAULT NULL,
`status` enum('pending','completed','cancelled') DEFAULT 'pending',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `car_id` (`car_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `purchases_ibfk_1` FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE CASCADE,
CONSTRAINT `purchases_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) 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) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`subject` varchar(200) DEFAULT NULL,
`message` text,
`status` enum('unread','read','answered') DEFAULT 'unread',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
COMMIT;

View File

@ -1,77 +0,0 @@
<?php
require_once __DIR__ . '/config.php';
try {
$pdo = db();
// Get admin user id
$adminId = $pdo->query("SELECT id FROM users WHERE role = 'admin' LIMIT 1")->fetchColumn();
if (!$adminId) {
die("Admin user not found. Please run setup.php first.");
}
// Clear existing cars to avoid duplicates during seeding if needed,
// but better to just check count or add specifically.
$stmt = $pdo->query("SELECT COUNT(*) FROM cars");
if ($stmt->fetchColumn() > 5) {
echo "Cars already seeded.";
exit;
}
$afghanCities = ['Kabul', 'Herat', 'Mazar-i-Sharif', 'Kandahar', 'Jalalabad', 'Kunduz', 'Ghazni', 'Balkh'];
$brands = [
'Toyota' => ['Corolla', 'Camry', 'Land Cruiser', 'Hilux', 'Prado', '4Runner'],
'Mercedes-Benz' => ['G-Wagon', 'S-Class', 'E-Class', 'C-Class', 'GLE'],
'Lexus' => ['LX570', 'RX350', 'GX460', 'ES350'],
'Hyundai' => ['Elantra', 'Tucson', 'Santa Fe', 'Accent'],
'Honda' => ['Civic', 'CR-V', 'Accord'],
'Ford' => ['F-150', 'Mustang', 'Explorer'],
'BMW' => ['X5', 'X6', '5 Series', '7 Series']
];
$descriptions = [
"Excellent condition, very well maintained.",
"Full option, armored, and ready for any terrain.",
"Fuel efficient, perfect for city driving.",
"Luxury interior, premium sound system, and smooth ride.",
"Recently imported, custom cleared, and plate registered.",
"Powerful engine, off-road capabilities, and spacious.",
"Very clean inside and out, low mileage.",
"Top of the line model with all modern features."
];
$insertCar = $pdo->prepare("INSERT INTO cars (user_id, brand, model, year, price, city, description, status, is_hot_deal) VALUES (?, ?, ?, ?, ?, ?, ?, 'approved', ?)");
$insertImage = $pdo->prepare("INSERT INTO car_images (car_id, image_path, is_main) VALUES (?, ?, 1)");
$carImages = [
'https://images.pexels.com/photos/170811/pexels-photo-170811.jpeg?auto=compress&cs=tinysrgb&w=600',
'https://images.pexels.com/photos/112460/pexels-photo-112460.jpeg?auto=compress&cs=tinysrgb&w=600',
'https://images.pexels.com/photos/3729464/pexels-photo-3729464.jpeg?auto=compress&cs=tinysrgb&w=600',
'https://images.pexels.com/photos/912413/pexels-photo-912413.jpeg?auto=compress&cs=tinysrgb&w=600',
'https://images.pexels.com/photos/116675/pexels-photo-116675.jpeg?auto=compress&cs=tinysrgb&w=600',
'https://images.pexels.com/photos/210019/pexels-photo-210019.jpeg?auto=compress&cs=tinysrgb&w=600',
'https://images.pexels.com/photos/337909/pexels-photo-337909.jpeg?auto=compress&cs=tinysrgb&w=600',
'https://images.pexels.com/photos/1149137/pexels-photo-1149137.jpeg?auto=compress&cs=tinysrgb&w=600'
];
for ($i = 0; $i < 20; $i++) {
$brand = array_rand($brands);
$model = $brands[$brand][array_rand($brands[$brand])];
$year = rand(2015, 2024);
$price = rand(5000, 150000);
$city = $afghanCities[array_rand($afghanCities)];
$desc = $descriptions[array_rand($descriptions)];
$isHot = (rand(1, 10) > 7) ? 1 : 0;
$insertCar->execute([$adminId, $brand, $model, $year, $price, $city, $desc, $isHot]);
$carId = $pdo->lastInsertId();
$imageUrl = $carImages[array_rand($carImages)];
$insertImage->execute([$carId, $imageUrl]);
}
echo "Successfully seeded 20 cars.";
} catch (PDOException $e) {
die("Database error: " . $e->getMessage());
}