From ea8f42f0c67351ffe2028d2a82cae46353070319 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Mon, 23 Feb 2026 09:28:37 +0000 Subject: [PATCH] Autosave: 20260223-092837 --- README.md | 64 ++++++++++++++----------- database.sql | 121 +++++++++++++++++++++++++++++++++++++++++++++++ db/seed_cars.php | 77 ------------------------------ 3 files changed, 158 insertions(+), 104 deletions(-) create mode 100644 database.sql delete mode 100644 db/seed_cars.php diff --git a/README.md b/README.md index f0493ec..7005caf 100644 --- a/README.md +++ b/README.md @@ -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. \ No newline at end of file diff --git a/database.sql b/database.sql new file mode 100644 index 0000000..fadff5e --- /dev/null +++ b/database.sql @@ -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; diff --git a/db/seed_cars.php b/db/seed_cars.php deleted file mode 100644 index f90ef58..0000000 --- a/db/seed_cars.php +++ /dev/null @@ -1,77 +0,0 @@ -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()); -}