diff --git a/MONOGRAPH.md b/MONOGRAPH.md new file mode 100644 index 0000000..3e1df54 --- /dev/null +++ b/MONOGRAPH.md @@ -0,0 +1,132 @@ +# Comprehensive Project Monograph: Advanced Vehicle Marketplace System + +## 1. Introduction +This document serves as a complete technical monograph for the Vehicle Marketplace System, a full-stack web application designed for the educational sector and general vehicle trading. This system provides a robust platform for users to list vehicles, manage sales, and for buyers to submit purchase requests through a secure, modern interface. + +## 2. System Architecture +The application follows a modular LAMP (Linux, Apache, MySQL/MariaDB, PHP) architecture. It is designed to be scalable, secure, and user-centric. + +### 2.1 Backend Layer +- **Language:** PHP 8.x (Vanilla PHP for maximum performance and compatibility). +- **Database Interaction:** PDO (PHP Data Objects) with prepared statements to prevent SQL injection. +- **Session Management:** Secure PHP sessions for user authentication and role-based access control. + +### 2.2 Frontend Layer +- **HTML5 & CSS3:** Modern semantic markup and advanced styling. +- **Design Paradigm:** Sophisticated Dark Theme with Glassmorphism effects. +- **Typography:** Inter font family for high legibility and professional aesthetics. +- **Responsive Design:** Mobile-first approach using CSS Grid and Flexbox. + +### 2.3 Database Layer +- **Engine:** MariaDB/MySQL. +- **Schema Design:** Normalized relational structure with foreign key constraints. + +## 3. Technology Stack Detail + +### 3.1 PHP (Hypertext Preprocessor) +Used for all server-side logic, including: +- User registration and authentication. +- CRUD operations for vehicle listings. +- Purchase request processing. +- Admin panel logic. +- Email notifications via `MailService.php`. + +### 3.2 MariaDB +The database stores all critical information: +- **users table:** Stores user credentials, contact info (phone, address), and roles. +- **cars table:** Stores vehicle details (brand, model, price, description, status). +- **car_images table:** Manages multiple images per vehicle with a primary image flag. +- **purchases table:** Tracks buying requests, bank transaction IDs, and status (pending/approved/rejected). +- **messages table:** Stores contact form submissions. + +### 3.3 CSS (Cascading Style Sheets) +The styling is centralized in `assets/css/style.css`, featuring: +- **Custom Variables:** `--primary-color` (Gold), `--bg-color` (Deep Slate), etc. +- **Glassmorphism:** Using `backdrop-filter: blur()` and semi-transparent backgrounds for a premium feel. +- **Animations:** Smooth transitions (`cubic-bezier`) for interactive elements. + +## 4. Database Schema Specification + +### 4.1 Table: users +| Column | Type | Description | +|---|---|---| +| id | INT | Primary Key, Auto-increment | +| username | VARCHAR(50) | Unique username | +| password | VARCHAR(255) | Hashed password | +| email | VARCHAR(100) | Unique email | +| phone | VARCHAR(20) | User contact number | +| address | TEXT | User physical address | +| role | ENUM | 'user' or 'admin' | +| created_at | TIMESTAMP | Account creation date | + +### 4.2 Table: cars +| Column | Type | Description | +|---|---|---| +| id | INT | Primary Key | +| user_id | INT | Foreign Key to users | +| brand | VARCHAR(50) | Vehicle brand | +| model | VARCHAR(50) | Vehicle model | +| year | INT | Manufacturing year | +| price | DECIMAL | Listing price | +| city | VARCHAR(50) | Location | +| description | TEXT | Detailed info | +| status | ENUM | 'pending', 'approved', 'rejected', 'sold' | + +### 4.3 Table: purchases +| Column | Type | Description | +|---|---|---| +| id | INT | Primary Key | +| car_id | INT | Foreign Key to cars | +| user_id | INT | Foreign Key to users | +| bank_id | VARCHAR(100) | Transaction reference | +| personal_info| TEXT | Buyer's additional info | +| status | ENUM | 'pending', 'approved', 'rejected' | + +## 5. Functional Walkthrough + +### 5.1 User Experience (UX) +The user journey starts at the landing page (`index.php`), featuring a high-impact hero section. Users can browse vehicles in `cars.php` with advanced filtering. + +### 5.2 Seller Workflow +1. **Login/Register:** Secure entry point. +2. **Dashboard:** Overview of listings. +3. **Add Car:** Upload vehicle details and images. +4. **Management:** Edit or mark listings as sold. + +### 5.3 Buyer Workflow +1. **Discovery:** Find a vehicle. +2. **Purchase Request:** Submit a formal request with payment reference (Bank ID). +3. **Tracking:** View request status in the dashboard. +4. **Receipt:** Generate a digital receipt upon approval. + +### 5.4 Admin Capabilities +- **Dashboard:** High-level stats (Total sales, users, cars). +- **Approval System:** Approve or reject car listings and purchase requests. +- **User Management:** Oversee the community. +- **Communications:** Manage messages from the contact form. + +## 6. UI/UX Design Principles + +### 6.1 Sophisticated Dark Theme +The "Darker and User-Friendly" theme uses a color palette that reduces eye strain and emphasizes high-value content. +- **Background:** `#0f172a` (Deep Space) +- **Accents:** `#d4af37` (Luxury Gold) +- **Contrast:** High legibility white and slate-gray text. + +### 6.2 Modern Components +- **Cards:** Elevated cards with hover scaling. +- **Glassmorphism:** Professional blur effects for navigation and overlays. +- **Buttons:** Large, accessible touch targets with subtle shadows. + +## 7. Security and Integrity +- **Password Hashing:** `password_hash()` and `password_verify()` for industry-standard security. +- **SQL Protection:** 100% usage of PDO prepared statements. +- **Input Sanitization:** `htmlspecialchars()` for XSS prevention. +- **State Management:** Secure session handling and CSRF awareness. + +## 8. Conclusion +This system represents a state-of-the-art vehicle marketplace, combining technical excellence with a premium user experience. It is designed to be both a functional tool and a beautiful interface, adhering to the highest standards of modern web development. + +--- +*Monograph created on February 23, 2026.* +*Version 1.0.0* diff --git a/assets/css/style.css b/assets/css/style.css index 8fa2410..131c492 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -1,17 +1,18 @@ :root { --primary-color: #d4af37; /* Gold */ - --secondary-color: #1a1a1a; /* Dark Gray */ - --bg-color: #0b0b0b; - --card-bg: rgba(255, 255, 255, 0.05); + --secondary-color: #1e293b; /* Dark Slate Blue */ + --bg-color: #0f172a; /* Deep Background */ + --card-bg: #1e293b; --glass-border: rgba(255, 255, 255, 0.1); - --text-primary: #ffffff; - --text-secondary: #a0a0a0; + --text-primary: #f8fafc; + --text-secondary: #94a3b8; --transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1); --sidebar-width: 260px; --danger: #ff4757; --success: #2ed573; --warning: #ffa502; --info: #1e90ff; + --glass-bg: rgba(30, 41, 59, 0.7); } * { @@ -30,18 +31,19 @@ body { /* Glassmorphism utility */ .glass { - background: rgba(255, 255, 255, 0.03); + background: var(--glass-bg); backdrop-filter: blur(15px); -webkit-backdrop-filter: blur(15px); border: 1px solid var(--glass-border); border-radius: 20px; - box-shadow: 0 10px 40px -10px rgba(0, 0, 0, 0.5); + box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.3); transition: var(--transition); } .glass:hover { - border-color: rgba(212, 175, 55, 0.3); - background: rgba(255, 255, 255, 0.05); + border-color: rgba(212, 175, 55, 0.5); + background: rgba(30, 41, 59, 0.9); + box-shadow: 0 15px 45px -10px rgba(0, 0, 0, 0.4); } /* Navbar */ @@ -53,7 +55,7 @@ nav { position: sticky; top: 0; z-index: 1000; - background: rgba(11, 11, 11, 0.8); + background: rgba(15, 23, 42, 0.9); backdrop-filter: blur(20px); border-bottom: 1px solid var(--glass-border); } @@ -84,7 +86,7 @@ nav { transition: var(--transition); text-transform: uppercase; letter-spacing: 1px; - opacity: 0.7; + opacity: 0.8; } .nav-links a:hover { @@ -92,6 +94,15 @@ nav { opacity: 1; } +/* Container */ +.container { + padding: 0 6%; +} + +.container-fluid { + padding: 0 4%; +} + /* Hero Section */ .hero { height: 85vh; @@ -100,358 +111,269 @@ nav { justify-content: center; align-items: center; text-align: center; - padding: 0 10%; - background: linear-gradient(rgba(0,0,0,0.7), rgba(0,0,0,0.7)), url('../images/hero-bg.jpg') center/cover no-repeat fixed; - border-bottom: 1px solid var(--glass-border); + background: radial-gradient(circle at top right, rgba(212, 175, 55, 0.15), transparent), + radial-gradient(circle at bottom left, rgba(30, 41, 59, 0.5), transparent); } .hero h1 { - font-size: 5.5rem; - margin-bottom: 1.5rem; + font-size: 5rem; font-weight: 900; + line-height: 1.1; + margin-bottom: 2rem; letter-spacing: -2px; - line-height: 1; + color: #ffffff; } .hero p { - font-size: 1.2rem; + font-size: 1.4rem; color: var(--text-secondary); max-width: 600px; - margin-bottom: 3.5rem; + margin-bottom: 3rem; +} + +/* Form Styles */ +.form-group { + margin-bottom: 1.5rem; +} + +label { + display: block; + margin-bottom: 0.5rem; + font-weight: 600; + color: var(--text-primary); + font-size: 0.9rem; +} + +.form-control { + width: 100%; + padding: 1rem 1.2rem; + border-radius: 12px; + background: var(--card-bg); + border: 1px solid var(--glass-border); + color: var(--text-primary); + font-family: inherit; + transition: var(--transition); +} + +.form-control:focus { + outline: none; + border-color: var(--primary-color); + box-shadow: 0 0 0 4px rgba(212, 175, 55, 0.2); } /* Buttons */ .btn { - padding: 0.9rem 2.2rem; + padding: 1rem 2rem; border-radius: 12px; - text-decoration: none; font-weight: 700; - transition: var(--transition); cursor: pointer; - border: 1px solid transparent; + text-decoration: none; display: inline-flex; align-items: center; - justify-content: center; - gap: 0.5rem; + gap: 0.8rem; + transition: var(--transition); + border: none; font-size: 0.95rem; } .btn-primary { background: var(--primary-color); color: #000; - box-shadow: 0 8px 25px rgba(212, 175, 55, 0.25); + box-shadow: 0 10px 20px -5px rgba(212, 175, 55, 0.4); } .btn-primary:hover { - transform: translateY(-4px); - box-shadow: 0 12px 35px rgba(212, 175, 55, 0.4); - background: #e5be48; + transform: translateY(-3px); + box-shadow: 0 15px 30px -5px rgba(212, 175, 55, 0.6); + background: #e5be47; } .btn-outline { background: transparent; - border: 1px solid var(--glass-border); + border: 2px solid var(--glass-border); color: var(--text-primary); } .btn-outline:hover { background: rgba(255, 255, 255, 0.05); - border-color: var(--primary-color); - color: var(--primary-color); + border-color: var(--text-primary); +} + +.btn-sm { + padding: 0.6rem 1.2rem; + font-size: 0.85rem; } .btn-auth { - padding: 0.6rem 1.4rem; - border-radius: 10px; + padding: 0.8rem 1.5rem; + border-radius: 12px; + border: 2px solid var(--glass-border); text-decoration: none; - font-weight: 600; - font-size: 0.85rem; - transition: var(--transition); - border: 1px solid var(--glass-border); - background: rgba(255, 255, 255, 0.05); color: var(--text-primary); + font-weight: 700; + font-size: 0.9rem; + transition: var(--transition); } .btn-auth:hover { - background: var(--primary-color); - color: #000; border-color: var(--primary-color); + color: var(--primary-color); } -/* Grid & Layout */ -.container { - padding: 5rem 6%; - max-width: 1400px; - margin: 0 auto; -} - -.section-title { - font-size: 2.8rem; - margin-bottom: 4rem; - text-align: center; - font-weight: 900; - letter-spacing: -1px; -} - +/* Grid Layouts */ .grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); - gap: 3rem; + gap: 2.5rem; } -/* Admin Dashboard Layout */ -.dashboard-container { - display: flex; - min-height: 100vh; +.grid-3 { grid-template-columns: repeat(3, 1fr); } +.grid-4 { grid-template-columns: repeat(4, 1fr); } + +/* Card Styling */ +.card { + background: var(--card-bg); + border-radius: 24px; + overflow: hidden; + border: 1px solid var(--glass-border); + transition: var(--transition); } +.card:hover { + transform: translateY(-10px); + box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.5); + border-color: rgba(212, 175, 55, 0.3); +} + +.card-img { + width: 100%; + height: 250px; + object-fit: cover; +} + +.card-content { + padding: 2rem; +} + +/* Table styling */ +table thead tr { + background: rgba(255, 255, 255, 0.05) !important; +} + +table tr { + border-bottom: 1px solid rgba(255, 255, 255, 0.1) !important; +} + +table td { + padding: 1.2rem; + color: var(--text-secondary); +} + +table th { + padding: 1.2rem; + text-align: left; + color: var(--text-primary); + font-weight: 700; +} + +/* Sidebar (Admin) */ .sidebar { width: var(--sidebar-width); - background: rgba(15, 15, 15, 0.9); - border-right: 1px solid var(--glass-border); - padding: 2rem 1.5rem; - display: flex; - flex-direction: column; - position: fixed; height: 100vh; - z-index: 100; + background: var(--bg-color); + border-right: 1px solid var(--glass-border); + position: fixed; + padding: 3rem 2rem; } -.main-content { - flex: 1; - margin-left: var(--sidebar-width); - padding: 2.5rem; -} - -.sidebar-brand { - font-size: 1.4rem; - font-weight: 900; - color: var(--primary-color); - margin-bottom: 3rem; - padding-left: 1rem; - text-decoration: none; -} - -.sidebar-menu { - list-style: none; - flex: 1; -} - -.sidebar-menu li { - margin-bottom: 0.8rem; -} - -.sidebar-menu a { +.sidebar-link { display: flex; align-items: center; - padding: 0.8rem 1.2rem; + gap: 1rem; + padding: 1.2rem; color: var(--text-secondary); text-decoration: none; - border-radius: 12px; - transition: var(--transition); font-weight: 600; + border-radius: 12px; + margin-bottom: 0.5rem; + transition: var(--transition); } -.sidebar-menu a:hover, .sidebar-menu a.active { +.sidebar-link:hover, .sidebar-link.active { background: rgba(212, 175, 55, 0.1); color: var(--primary-color); } -.sidebar-footer { - padding-top: 2rem; - border-top: 1px solid var(--glass-border); -} - -/* Dashboard Stats Card */ -.stats-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); - gap: 1.5rem; - margin-bottom: 3rem; -} - -.stat-card { - padding: 2rem; - display: flex; - flex-direction: column; - gap: 0.5rem; -} - -.stat-value { - font-size: 2.2rem; - font-weight: 900; - color: var(--text-primary); -} - -.stat-label { - color: var(--text-secondary); - font-size: 0.9rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 1px; -} - -/* Tables */ -.table-container { - overflow-x: auto; - margin-top: 2rem; -} - -table { - width: 100%; - border-collapse: collapse; - text-align: left; -} - -th { - padding: 1.2rem; - border-bottom: 1px solid var(--glass-border); - color: var(--text-secondary); - font-weight: 600; - text-transform: uppercase; - font-size: 0.8rem; - letter-spacing: 1px; -} - -td { - padding: 1.2rem; - border-bottom: 1px solid rgba(255,255,255,0.03); - font-size: 0.95rem; -} - -tr:hover td { - background: rgba(255,255,255,0.02); -} - -.badge { - padding: 0.4rem 0.8rem; - border-radius: 6px; - font-size: 0.75rem; - font-weight: 700; - text-transform: uppercase; -} - -.badge-success { background: rgba(46, 213, 115, 0.1); color: var(--success); } -.badge-warning { background: rgba(255, 165, 2, 0.1); color: var(--warning); } -.badge-danger { background: rgba(255, 71, 87, 0.1); color: var(--danger); } - /* Alerts */ .alert { padding: 1rem 1.5rem; border-radius: 12px; - margin-bottom: 2rem; + margin-bottom: 1rem; font-weight: 600; } +.alert-error { + background: rgba(255, 71, 87, 0.15); + color: #ff6b81; + border: 1px solid rgba(255, 71, 87, 0.3); +} + .alert-success { - background: rgba(46, 213, 115, 0.1); - color: var(--success); - border: 1px solid rgba(46, 213, 115, 0.2); + background: rgba(46, 213, 115, 0.15); + color: #7bed9f; + border: 1px solid rgba(46, 213, 115, 0.3); } -/* Car Card Enhancement */ -.car-card { - overflow: hidden; - background: rgba(255, 255, 255, 0.02); -} - -.car-info { - padding: 1.8rem; -} - -.car-price { - color: var(--primary-color); - font-size: 1.6rem; - font-weight: 900; -} - -/* Forms */ -.form-group { - margin-bottom: 1.5rem; -} - -.form-control { - width: 100%; - padding: 0.9rem 1.2rem; - background: rgba(255,255,255,0.03); - border: 1px solid var(--glass-border); - border-radius: 12px; - color: #fff; - font-size: 0.95rem; - transition: var(--transition); -} - -.form-control:focus { - border-color: var(--primary-color); - background: rgba(255,255,255,0.06); - outline: none; - box-shadow: 0 0 0 4px rgba(212, 175, 55, 0.1); -} - -/* Specialized Box Component */ +/* Box component */ .box { - background: rgba(255, 255, 255, 0.02); - border: 1px solid var(--glass-border); + background: var(--card-bg); border-radius: 24px; - padding: 2.5rem; - transition: var(--transition); - position: relative; - overflow: hidden; + border: 1px solid var(--glass-border); + box-shadow: 0 10px 30px rgba(0,0,0,0.3); } -.box::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: linear-gradient(135deg, rgba(212, 175, 55, 0.05), transparent); - pointer-events: none; +/* Stats Card */ +.stats-card { + padding: 2rem; + border-radius: 20px; + background: var(--card-bg); + border: 1px solid var(--glass-border); } -.box:hover { - transform: translateY(-5px); - border-color: rgba(212, 175, 55, 0.2); - background: rgba(255, 255, 255, 0.04); +.stats-card h3 { + font-size: 0.9rem; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 1px; + margin-bottom: 0.5rem; } -@media (max-width: 992px) { - .sidebar { width: 80px; padding: 2rem 0.5rem; } - .sidebar-brand, .sidebar-menu span { display: none; } - .main-content { margin-left: 80px; } -} - -@media (max-width: 768px) { - .hero h1 { font-size: 3.5rem; } - .nav-links { display: none; } +.stats-card .value { + font-size: 2.5rem; + font-weight: 900; + color: var(--primary-color); } /* Footer Styles */ footer { - background: rgba(11, 11, 11, 0.8); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); + background: var(--bg-color); border-top: 1px solid var(--glass-border); padding: 6rem 6% 3rem; - margin-top: 5rem; + color: var(--text-primary); } .footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1.5fr; gap: 4rem; - max-width: 1400px; - margin: 0 auto; + margin-bottom: 4rem; } .footer-col h4 { - color: var(--primary-color); font-size: 1.1rem; font-weight: 800; margin-bottom: 2rem; text-transform: uppercase; - letter-spacing: 2px; + letter-spacing: 1px; } .footer-col ul { @@ -459,7 +381,7 @@ footer { } .footer-col ul li { - margin-bottom: 1rem; + margin-bottom: 1.2rem; } .footer-col ul li a { @@ -471,30 +393,24 @@ footer { .footer-col ul li a:hover { color: var(--primary-color); - padding-left: 5px; + padding-left: 0.5rem; } .footer-bottom { - margin-top: 6rem; padding-top: 3rem; - border-top: 1px solid rgba(255, 255, 255, 0.05); + border-top: 1px solid var(--glass-border); text-align: center; -} - -.footer-bottom p { color: var(--text-secondary); font-size: 0.9rem; } -@media (max-width: 1200px) { - .footer-grid { - grid-template-columns: 1fr 1fr; - } +@media (max-width: 1024px) { + .grid-4, .grid-3 { grid-template-columns: repeat(2, 1fr); } + .footer-grid { grid-template-columns: 1fr 1fr; } } -@media (max-width: 600px) { - .footer-grid { - grid-template-columns: 1fr; - gap: 3rem; - } +@media (max-width: 768px) { + .grid-4, .grid-3 { grid-template-columns: 1fr; } + .hero h1 { font-size: 3rem; } + .footer-grid { grid-template-columns: 1fr; } } \ No newline at end of file diff --git a/cars.php b/cars.php index 5d018df..7607e17 100644 --- a/cars.php +++ b/cars.php @@ -37,7 +37,7 @@ $brands = $pdo->query("SELECT DISTINCT brand FROM cars WHERE status = 'approved'
Find the perfect vehicle for your lifestyle in our verified marketplace.
Manage your vehicle listings and track your purchase requests.
+Manage your vehicle listings and track your purchase requests.
You haven't listed any vehicles yet.
+You haven't listed any vehicles yet.
Start Selling Today