Car auction v1.0
This commit is contained in:
parent
7af198c681
commit
e46b2fc0b0
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +1,13 @@
|
||||
from django.contrib import admin
|
||||
from .models import CarAuction, Bid
|
||||
|
||||
# Register your models here.
|
||||
@admin.register(CarAuction)
|
||||
class CarAuctionAdmin(admin.ModelAdmin):
|
||||
list_display = ('title', 'make', 'model', 'year', 'current_bid', 'end_date', 'seller')
|
||||
list_filter = ('make', 'year', 'end_date')
|
||||
search_fields = ('title', 'make', 'model', 'description')
|
||||
|
||||
@admin.register(Bid)
|
||||
class BidAdmin(admin.ModelAdmin):
|
||||
list_display = ('auction', 'user', 'amount', 'created_at')
|
||||
list_filter = ('created_at',)
|
||||
47
core/migrations/0001_initial.py
Normal file
47
core/migrations/0001_initial.py
Normal file
@ -0,0 +1,47 @@
|
||||
# Generated by Django 5.2.7 on 2026-02-12 16:44
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CarAuction',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=200)),
|
||||
('make', models.CharField(max_length=100)),
|
||||
('model', models.CharField(max_length=100)),
|
||||
('year', models.IntegerField()),
|
||||
('description', models.TextField()),
|
||||
('image_url', models.URLField(blank=True, max_length=500, null=True)),
|
||||
('starting_bid', models.DecimalField(decimal_places=2, max_digits=10)),
|
||||
('current_bid', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('end_date', models.DateTimeField()),
|
||||
('seller', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='auctions', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Bid',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('amount', models.DecimalField(decimal_places=2, max_digits=10)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
('auction', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bids', to='core.carauction')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['-amount'],
|
||||
},
|
||||
),
|
||||
]
|
||||
BIN
core/migrations/__pycache__/0001_initial.cpython-311.pyc
Normal file
BIN
core/migrations/__pycache__/0001_initial.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
@ -1,3 +1,46 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
|
||||
# Create your models here.
|
||||
class CarAuction(models.Model):
|
||||
title = models.CharField(max_length=200)
|
||||
make = models.CharField(max_length=100)
|
||||
model = models.CharField(max_length=100)
|
||||
year = models.IntegerField()
|
||||
description = models.TextField()
|
||||
image_url = models.URLField(max_length=500, blank=True, null=True)
|
||||
starting_bid = models.DecimalField(max_digits=10, decimal_places=2)
|
||||
current_bid = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
|
||||
seller = models.ForeignKey(User, on_delete=models.CASCADE, related_name='auctions')
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
end_date = models.DateTimeField()
|
||||
|
||||
def is_active(self):
|
||||
return timezone.now() < self.end_date
|
||||
|
||||
def time_left(self):
|
||||
if not self.is_active():
|
||||
return "Closed"
|
||||
delta = self.end_date - timezone.now()
|
||||
days = delta.days
|
||||
hours = delta.seconds // 3600
|
||||
minutes = (delta.seconds // 60) % 60
|
||||
if days > 0:
|
||||
return f"{days}d {hours}h"
|
||||
return f"{hours}h {minutes}m"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.year} {self.make} {self.model}"
|
||||
|
||||
class Bid(models.Model):
|
||||
auction = models.ForeignKey(CarAuction, on_delete=models.CASCADE, related_name='bids')
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
amount = models.DecimalField(max_digits=10, decimal_places=2)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ['-amount']
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user.username} - {self.amount} on {self.auction.title}"
|
||||
@ -1,25 +1,75 @@
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block title %}Knowledge Base{% endblock %}</title>
|
||||
{% if project_description %}
|
||||
<meta name="description" content="{{ project_description }}">
|
||||
<meta property="og:description" content="{{ project_description }}">
|
||||
<meta property="twitter:description" content="{{ project_description }}">
|
||||
{% endif %}
|
||||
{% if project_image_url %}
|
||||
<meta property="og:image" content="{{ project_image_url }}">
|
||||
<meta property="twitter:image" content="{{ project_image_url }}">
|
||||
{% endif %}
|
||||
{% load static %}
|
||||
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}">
|
||||
{% block head %}{% endblock %}
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}AutoBid - Premium Car Auctions{% endblock %}</title>
|
||||
<meta name="description" content="{% block description %}Bid on premium cars and win your dream drive at AutoBid.{% endblock %}">
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<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;500;600&family=Montserrat:wght@700;800&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Bootstrap 5 CSS -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Bootstrap Icons -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v=1.0">
|
||||
|
||||
{% block extra_css %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% block content %}{% endblock %}
|
||||
</body>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark sticky-top">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="{% url 'home' %}">
|
||||
<span class="brand-auto">AUTO</span><span class="brand-bid">BID</span>
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'home' %}">Auctions</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav ms-auto align-items-center">
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<span class="nav-link text-light me-3">Welcome, {{ user.username }}</span>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="btn btn-outline-light btn-sm px-3" href="/admin/">Dashboard</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/admin/login/">Login</a>
|
||||
</li>
|
||||
<li class="nav-item ms-lg-2">
|
||||
<a class="btn btn-primary btn-sm px-4" href="/admin/">Join Now</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main>
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<footer class="py-5 mt-5">
|
||||
<div class="container text-center">
|
||||
<p class="text-muted mb-0">© 2026 AutoBid Platform. All rights reserved.</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Bootstrap 5 JS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
{% block extra_js %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
119
core/templates/core/auction_detail.html
Normal file
119
core/templates/core/auction_detail.html
Normal file
@ -0,0 +1,119 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}{{ auction.title }} | AutoBid{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="py-5">
|
||||
<div class="container">
|
||||
<nav aria-label="breadcrumb" class="mb-4">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="{% url 'home' %}" class="text-decoration-none">Home</a></li>
|
||||
<li class="breadcrumb-item active">{{ auction.make }} {{ auction.model }}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div class="row g-5">
|
||||
<!-- Left: Car Images & Details -->
|
||||
<div class="col-lg-8">
|
||||
<div class="bg-white rounded-4 overflow-hidden shadow-sm mb-4">
|
||||
{% if auction.image_url %}
|
||||
<img src="{{ auction.image_url }}" class="img-fluid w-100" alt="{{ auction.title }}">
|
||||
{% else %}
|
||||
<img src="https://images.pexels.com/photos/170811/pexels-photo-170811.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" class="img-fluid w-100" alt="Car Placeholder">
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-4 p-4 shadow-sm mb-4">
|
||||
<h2 class="h3 mb-4">Specifications</h2>
|
||||
<div class="row g-3">
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="p-3 border rounded-3 text-center">
|
||||
<span class="d-block text-muted small">Make</span>
|
||||
<span class="fw-bold">{{ auction.make }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="p-3 border rounded-3 text-center">
|
||||
<span class="d-block text-muted small">Model</span>
|
||||
<span class="fw-bold">{{ auction.model }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="p-3 border rounded-3 text-center">
|
||||
<span class="d-block text-muted small">Year</span>
|
||||
<span class="fw-bold">{{ auction.year }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="p-3 border rounded-3 text-center">
|
||||
<span class="d-block text-muted small">Bids</span>
|
||||
<span class="fw-bold">{{ bids.count }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-4 p-4 shadow-sm">
|
||||
<h2 class="h3 mb-4">Description</h2>
|
||||
<p class="mb-0 text-muted">{{ auction.description|linebreaks }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right: Bidding Widget -->
|
||||
<div class="col-lg-4">
|
||||
<div class="sticky-top" style="top: 100px;">
|
||||
<div class="bg-white rounded-4 p-4 shadow mb-4">
|
||||
<h1 class="h4 mb-1">{{ auction.title }}</h1>
|
||||
<p class="text-muted small mb-4">Listed by {{ auction.seller.username }}</p>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4 p-3 bg-light rounded-3">
|
||||
<div>
|
||||
<span class="d-block text-muted small">Current Bid</span>
|
||||
<span class="h2 mb-0 fw-bold text-danger">${{ auction.current_bid|default:auction.starting_bid }}</span>
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<span class="d-block text-muted small text-uppercase fw-bold">Ends In</span>
|
||||
<span class="text-dark fw-bold">{{ auction.time_left }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
{% if user.is_authenticated %}
|
||||
<form action="#" method="POST">
|
||||
{% csrf_token %}
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-text">$</span>
|
||||
<input type="number" class="form-control" placeholder="Enter bid amount" min="{{ auction.current_bid|default:auction.starting_bid|add:100 }}">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100 py-3">Place Bid</button>
|
||||
</form>
|
||||
<p class="text-center text-muted small mt-2">Enter at least ${{ auction.current_bid|default:auction.starting_bid|add:100 }}</p>
|
||||
{% else %}
|
||||
<div class="text-center py-3">
|
||||
<p class="mb-3">Log in to place a bid on this car.</p>
|
||||
<a href="/admin/login/" class="btn btn-outline-dark w-100">Login to Bid</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="bid-history">
|
||||
<h6 class="mb-3">Recent Bids</h6>
|
||||
{% for bid in bids|slice:":5" %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-2 small">
|
||||
<span class="text-muted">{{ bid.user.username }}</span>
|
||||
<span class="fw-bold">${{ bid.amount }}</span>
|
||||
</div>
|
||||
{% empty %}
|
||||
<p class="text-muted small text-center mb-0">No bids yet. Be the first!</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@ -1,145 +1,65 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ project_name }}{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
<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);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
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;
|
||||
inset: 0;
|
||||
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: 2.5rem 2rem;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(2.2rem, 3vw + 1.2rem, 3.2rem);
|
||||
font-weight: 700;
|
||||
margin: 0 0 1.2rem;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.5rem 0;
|
||||
font-size: 1.1rem;
|
||||
opacity: 0.92;
|
||||
}
|
||||
|
||||
.loader {
|
||||
margin: 1.5rem auto;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border: 4px solid rgba(255, 255, 255, 0.25);
|
||||
border-top-color: #fff;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.runtime code {
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
padding: 0.15rem 0.45rem;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 0.85rem;
|
||||
opacity: 0.75;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% load static %}
|
||||
|
||||
{% block content %}
|
||||
<main>
|
||||
<div class="card">
|
||||
<h1>Analyzing your requirements and generating your app…</h1>
|
||||
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
||||
<span class="sr-only">Loading…</span>
|
||||
<!-- Hero Section -->
|
||||
<section class="hero">
|
||||
<div class="container text-center hero-content">
|
||||
<h1 class="display-3 mb-3">Find Your Next <span class="text-danger">Masterpiece</span></h1>
|
||||
<p class="lead mb-5 opacity-75">Exclusive car auctions. Real-time bidding. Trusted sellers.</p>
|
||||
|
||||
<div class="search-container mx-auto">
|
||||
<form action="{% url 'home' %}" method="GET" class="d-flex">
|
||||
<input type="text" name="q" class="form-control search-input" placeholder="Search by make, model, or year..." value="{{ query|default:'' }}">
|
||||
<button type="submit" class="btn btn-primary ms-2 px-4">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<p class="hint">AppWizzy AI is collecting your requirements and applying the first changes.</p>
|
||||
<p class="hint">This page will refresh automatically as the plan is implemented.</p>
|
||||
<p class="runtime">
|
||||
Runtime: Django <code>{{ django_version }}</code> · Python <code>{{ python_version }}</code>
|
||||
— UTC <code>{{ current_time|date:"Y-m-d H:i:s" }}</code>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
Page updated: {{ current_time|date:"Y-m-d H:i:s" }} (UTC)
|
||||
</footer>
|
||||
{% endblock %}
|
||||
</section>
|
||||
|
||||
<!-- Active Auctions -->
|
||||
<section class="py-5">
|
||||
<div class="container">
|
||||
<div class="d-flex justify-content-between align-items-end mb-5">
|
||||
<div>
|
||||
<h2 class="mb-1">Featured Auctions</h2>
|
||||
<p class="text-muted mb-0">Discover top deals closing soon.</p>
|
||||
</div>
|
||||
<a href="#" class="btn btn-link text-danger text-decoration-none fw-bold">View All <i class="bi bi-arrow-right"></i></a>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
{% for auction in auctions %}
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="auction-card">
|
||||
<div class="card-img-container">
|
||||
{% if auction.image_url %}
|
||||
<img src="{{ auction.image_url }}" class="card-img-top" alt="{{ auction.title }}">
|
||||
{% else %}
|
||||
<img src="https://images.pexels.com/photos/170811/pexels-photo-170811.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" class="card-img-top" alt="Car Placeholder">
|
||||
{% endif %}
|
||||
<span class="badge-bid">${{ auction.current_bid|default:auction.starting_bid }}</span>
|
||||
<span class="badge-time"><i class="bi bi-clock"></i> {{ auction.time_left }}</span>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<h5 class="card-title mb-2">{{ auction.title }}</h5>
|
||||
<p class="text-muted small mb-3">{{ auction.make }} • {{ auction.year }} • {{ auction.model }}</p>
|
||||
<div class="d-grid">
|
||||
<a href="{% url 'auction_detail' auction.pk %}" class="btn btn-outline-dark">View Auction</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="col-12 text-center py-5">
|
||||
<div class="opacity-50 mb-3">
|
||||
<i class="bi bi-search display-1"></i>
|
||||
</div>
|
||||
<h3>No active auctions found</h3>
|
||||
<p class="text-muted">Try searching for something else or check back later.</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import home
|
||||
from .views import home, auction_detail
|
||||
|
||||
urlpatterns = [
|
||||
path("", home, name="home"),
|
||||
]
|
||||
path("auction/<int:pk>/", auction_detail, name="auction_detail"),
|
||||
]
|
||||
@ -1,25 +1,29 @@
|
||||
import os
|
||||
import platform
|
||||
|
||||
from django import get_version as django_version
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from django.utils import timezone
|
||||
|
||||
from .models import CarAuction, Bid
|
||||
from django.db.models import Max
|
||||
|
||||
def home(request):
|
||||
"""Render the landing screen with loader and environment details."""
|
||||
host_name = request.get_host().lower()
|
||||
agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic"
|
||||
now = timezone.now()
|
||||
|
||||
"""Render the landing screen with featured auctions."""
|
||||
query = request.GET.get('q')
|
||||
if query:
|
||||
auctions = CarAuction.objects.filter(title__icontains=query, end_date__gt=timezone.now())
|
||||
else:
|
||||
auctions = CarAuction.objects.filter(end_date__gt=timezone.now()).order_by('end_date')[:6]
|
||||
|
||||
context = {
|
||||
"project_name": "New Style",
|
||||
"agent_brand": agent_brand,
|
||||
"django_version": django_version(),
|
||||
"python_version": platform.python_version(),
|
||||
"current_time": now,
|
||||
"host_name": host_name,
|
||||
"project_description": os.getenv("PROJECT_DESCRIPTION", ""),
|
||||
"project_image_url": os.getenv("PROJECT_IMAGE_URL", ""),
|
||||
"auctions": auctions,
|
||||
"query": query,
|
||||
}
|
||||
return render(request, "core/index.html", context)
|
||||
|
||||
def auction_detail(request, pk):
|
||||
"""Render the auction detail page."""
|
||||
auction = get_object_or_404(CarAuction, pk=pk)
|
||||
bids = auction.bids.all()
|
||||
|
||||
context = {
|
||||
"auction": auction,
|
||||
"bids": bids,
|
||||
}
|
||||
return render(request, "core/auction_detail.html", context)
|
||||
@ -1,4 +1,154 @@
|
||||
/* Custom styles for the application */
|
||||
body {
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
:root {
|
||||
--primary-dark: #121212;
|
||||
--accent-red: #D90429;
|
||||
--accent-red-hover: #EF233C;
|
||||
--text-silver: #8D99AE;
|
||||
--bg-light: #EDF2F4;
|
||||
--white: #ffffff;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Inter', sans-serif;
|
||||
background-color: var(--bg-light);
|
||||
color: var(--primary-dark);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, .navbar-brand {
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
/* Navbar */
|
||||
.navbar {
|
||||
background-color: var(--primary-dark);
|
||||
padding: 1rem 0;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.5rem;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
.brand-auto { color: var(--white); }
|
||||
.brand-bid { color: var(--accent-red); }
|
||||
|
||||
/* Hero Section */
|
||||
.hero {
|
||||
background: linear-gradient(135deg, var(--primary-dark) 0%, #2b2d42 100%);
|
||||
padding: 100px 0;
|
||||
color: var(--white);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
right: -10%;
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
background: radial-gradient(circle, rgba(217, 4, 41, 0.15) 0%, transparent 70%);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Cards & Glassmorphism */
|
||||
.auction-card {
|
||||
border: none;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
background: var(--white);
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.auction-card:hover {
|
||||
transform: translateY(-8px);
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.card-img-container {
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-img-top {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.badge-bid {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
background: rgba(217, 4, 41, 0.9);
|
||||
backdrop-filter: blur(4px);
|
||||
color: white;
|
||||
padding: 6px 12px;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.badge-time {
|
||||
position: absolute;
|
||||
bottom: 15px;
|
||||
left: 15px;
|
||||
background: rgba(18, 18, 18, 0.7);
|
||||
backdrop-filter: blur(4px);
|
||||
color: white;
|
||||
padding: 4px 10px;
|
||||
border-radius: 6px;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.btn-primary {
|
||||
background-color: var(--accent-red);
|
||||
border-color: var(--accent-red);
|
||||
font-weight: 600;
|
||||
border-radius: 8px;
|
||||
padding: 10px 24px;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: var(--accent-red-hover);
|
||||
border-color: var(--accent-red-hover);
|
||||
}
|
||||
|
||||
/* Search Bar */
|
||||
.search-container {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
padding: 8px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: white;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
background: transparent;
|
||||
color: white;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: var(--primary-dark);
|
||||
color: var(--text-silver);
|
||||
}
|
||||
@ -1,21 +1,154 @@
|
||||
|
||||
: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);
|
||||
--primary-dark: #121212;
|
||||
--accent-red: #D90429;
|
||||
--accent-red-hover: #EF233C;
|
||||
--text-silver: #8D99AE;
|
||||
--bg-light: #EDF2F4;
|
||||
--white: #ffffff;
|
||||
}
|
||||
|
||||
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;
|
||||
background-color: var(--bg-light);
|
||||
color: var(--primary-dark);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, .navbar-brand {
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
/* Navbar */
|
||||
.navbar {
|
||||
background-color: var(--primary-dark);
|
||||
padding: 1rem 0;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.5rem;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
.brand-auto { color: var(--white); }
|
||||
.brand-bid { color: var(--accent-red); }
|
||||
|
||||
/* Hero Section */
|
||||
.hero {
|
||||
background: linear-gradient(135deg, var(--primary-dark) 0%, #2b2d42 100%);
|
||||
padding: 100px 0;
|
||||
color: var(--white);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
right: -10%;
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
background: radial-gradient(circle, rgba(217, 4, 41, 0.15) 0%, transparent 70%);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Cards & Glassmorphism */
|
||||
.auction-card {
|
||||
border: none;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
background: var(--white);
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.auction-card:hover {
|
||||
transform: translateY(-8px);
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.card-img-container {
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-img-top {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.badge-bid {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
background: rgba(217, 4, 41, 0.9);
|
||||
backdrop-filter: blur(4px);
|
||||
color: white;
|
||||
padding: 6px 12px;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.badge-time {
|
||||
position: absolute;
|
||||
bottom: 15px;
|
||||
left: 15px;
|
||||
background: rgba(18, 18, 18, 0.7);
|
||||
backdrop-filter: blur(4px);
|
||||
color: white;
|
||||
padding: 4px 10px;
|
||||
border-radius: 6px;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.btn-primary {
|
||||
background-color: var(--accent-red);
|
||||
border-color: var(--accent-red);
|
||||
font-weight: 600;
|
||||
border-radius: 8px;
|
||||
padding: 10px 24px;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: var(--accent-red-hover);
|
||||
border-color: var(--accent-red-hover);
|
||||
}
|
||||
|
||||
/* Search Bar */
|
||||
.search-container {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
padding: 8px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: white;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
background: transparent;
|
||||
color: white;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: var(--primary-dark);
|
||||
color: var(--text-silver);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user