home functionality

main
Babit Shrestha 6 months ago
parent 2b8f74eb06
commit 6b9504eedb
  1. BIN
      sahara/db.sqlite3
  2. BIN
      sahara/main/__pycache__/admin.cpython-312.pyc
  3. BIN
      sahara/main/__pycache__/forms.cpython-312.pyc
  4. BIN
      sahara/main/__pycache__/models.cpython-312.pyc
  5. BIN
      sahara/main/__pycache__/urls.cpython-312.pyc
  6. BIN
      sahara/main/__pycache__/views.cpython-312.pyc
  7. 7
      sahara/main/admin.py
  8. 46
      sahara/main/forms.py
  9. 19
      sahara/main/migrations/0004_user_service_offered.py
  10. 29
      sahara/main/migrations/0005_user_login_profile_alter_servicerequest_service_and_more.py
  11. BIN
      sahara/main/migrations/__pycache__/0004_user_service_offered.cpython-312.pyc
  12. BIN
      sahara/main/migrations/__pycache__/0005_user_login_profile_alter_servicerequest_service_and_more.cpython-312.pyc
  13. 19
      sahara/main/models.py
  14. 185
      sahara/main/templates/main/home.html
  15. 115
      sahara/main/templates/main/register.html
  16. 34
      sahara/main/views.py
  17. BIN
      sahara/media/127266331_1064740373976536_6156792533421165886_n.jpg
  18. BIN
      sahara/media/profile-images/Screenshot_2024-07-17_085055.png
  19. BIN
      sahara/media/profile-images/Screenshot_2024-07-17_085055_9Hzrf4D.png
  20. BIN
      sahara/sahara/__pycache__/settings.cpython-312.pyc
  21. BIN
      sahara/sahara/__pycache__/urls.cpython-312.pyc
  22. 13
      sahara/sahara/settings.py
  23. 6
      sahara/sahara/urls.py
  24. 144
      sahara/static/css/styles.css
  25. BIN
      sahara/static/img/backgroung-form.jpg
  26. BIN
      sahara/static/img/dummypic.png
  27. BIN
      sahara/static/img/logofinal.png
  28. BIN
      sahara/static/img/pic1.jpg
  29. BIN
      sahara/static/profile-images/127266331_1064740373976536_6156792533421165886_n.jpg
  30. BIN
      sahara/static/profile-images/Screenshot_2024-07-17_085055.png
  31. BIN
      sahara/static/profile-images/Screenshot_2024-08-12_071545.png
  32. 15
      sahara/templates/base.html

Binary file not shown.

@ -1,6 +1,6 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User,ServiceRequest # Import your custom User model
from .models import User,ServiceRequest,Service # Import your custom User model
class CustomUserAdmin(UserAdmin):
model = User
@ -17,7 +17,7 @@ class CustomUserAdmin(UserAdmin):
# Fieldsets for the add and change forms in the admin
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal Info', {'fields': ('first_name', 'last_name')}),
('Personal Info', {'fields': ('first_name', 'last_name','profile','service_offered')}),
('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser')}),
('Important Dates', {'fields': ('last_login',)}), # Remove 'date_joined' if it doesn't exist
)
@ -26,7 +26,7 @@ class CustomUserAdmin(UserAdmin):
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'first_name', 'last_name', 'password1', 'password2', 'is_staff', 'is_superuser', 'is_active'),
'fields': ('email', 'first_name', 'last_name','profile','service_offered', 'password1', 'password2', 'is_staff', 'is_superuser', 'is_active'),
}),
)
@ -36,3 +36,4 @@ class CustomUserAdmin(UserAdmin):
# Register your custom User model with the custom UserAdmin class
admin.site.register(User, CustomUserAdmin)
admin.site.register(ServiceRequest)
admin.site.register(Service)

@ -2,7 +2,11 @@ from django import forms
from django.contrib.auth.forms import AuthenticationForm
from .models import User
from django import forms
from .models import User, Service
class UserRegistrationForm(forms.ModelForm):
# Password and confirm password fields with custom classes
password = forms.CharField(
widget=forms.PasswordInput(attrs={
'class': 'form-control',
@ -18,7 +22,7 @@ class UserRegistrationForm(forms.ModelForm):
class Meta:
model = User
fields = ['first_name', 'last_name', 'email', 'password']
fields = ['email', 'first_name', 'last_name', 'profile', 'price', 'bio', 'service_offered', 'login_profile']
widgets = {
'first_name': forms.TextInput(attrs={
'class': 'form-control',
@ -32,8 +36,39 @@ class UserRegistrationForm(forms.ModelForm):
'class': 'form-control',
'placeholder': 'Enter your email address',
}),
'profile': forms.ClearableFileInput(attrs={
'class': 'form-control',
'placeholder': 'Upload your profile image',
}),
'bio': forms.Textarea(attrs={
'class': 'form-control',
'placeholder': 'Enter your bio',
'rows': 4, # You can customize the rows and columns as needed
}),
'price': forms.NumberInput(attrs={
'class': 'form-control',
'placeholder': 'Enter your price',
}),
'service_offered': forms.Select(attrs={
'class': 'form-control',
}),
'login_profile': forms.Select(attrs={
'class': 'form-control',
}),
}
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get('password')
confirm_password = cleaned_data.get('confirm_password')
# Check if passwords match
if password != confirm_password:
self.add_error('confirm_password', 'Passwords do not match')
return cleaned_data
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get('password')
@ -41,12 +76,3 @@ class UserRegistrationForm(forms.ModelForm):
if password and confirm_password and password != confirm_password:
raise forms.ValidationError("Passwords do not match.")
class UserLoginForm(AuthenticationForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(UserLoginForm, self).__init__(*args, **kwargs)
# Change the username field label and placeholder to 'Email'
self.fields['username'].label = 'Email'
self.fields['username'].widget.attrs.update({'placeholder': 'Enter your email'})
self.fields['password'].widget.attrs.update({'placeholder': 'Enter your password'})

@ -0,0 +1,19 @@
# Generated by Django 5.1.4 on 2025-01-11 20:13
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0003_service_alter_user_bio_alter_user_price_and_more'),
]
operations = [
migrations.AddField(
model_name='user',
name='service_offered',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='main.service'),
),
]

@ -0,0 +1,29 @@
# Generated by Django 5.1.4 on 2025-01-12 01:26
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0004_user_service_offered'),
]
operations = [
migrations.AddField(
model_name='user',
name='login_profile',
field=models.CharField(choices=[('NORMAL', 'Normal User'), ('SERVICE', 'Service Provider'), ('ADMIN', 'Admin User')], default='NORMAL', max_length=15),
),
migrations.AlterField(
model_name='servicerequest',
name='service',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='service_offered', to='main.service'),
),
migrations.AlterField(
model_name='user',
name='profile',
field=models.ImageField(blank=True, null=True, upload_to='profile-images/'),
),
]

@ -32,7 +32,6 @@ class UserManager(BaseUserManager):
user.set_password(password)
user.save(using=self._db)
# Send verification email
try:
self.send_verification_email(user)
except:
@ -76,6 +75,12 @@ class UserManager(BaseUserManager):
)
OPTIONS = [
('NORMAL','Normal User'),
('SERVICE', 'Service Provider'),
('ADMIN', 'Admin User'),
]
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=30)
@ -83,13 +88,19 @@ class User(AbstractBaseUser, PermissionsMixin):
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
profile = models.ImageField(blank=True,null=True)
profile = models.ImageField(blank=True,null=True, upload_to="profile-images/")
price = models.PositiveBigIntegerField(blank=True, null=True)
bio = models.CharField(max_length=200, blank=True, null=True)
member_since = models.DateTimeField(auto_now_add=True)
updated_on = models.DateField(auto_now=True)
service_offered = models.ForeignKey(Service, on_delete=models.CASCADE,blank=True,null=True)
login_profile = models.CharField(
max_length=15,
choices=OPTIONS,
default='NORMAL',
)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']
REQUIRED_FIELDS = ['first_name', 'last_name','price','bio']
objects = UserManager()
@ -112,7 +123,7 @@ class ServiceRequest(models.Model):
remarks = models.TextField(blank=True, null=True)
is_completed = models.BooleanField(default=False)
completed_date = models.DateTimeField(null=True,blank=True)
service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name="service")
service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name="service_offered")
def __str__(self):
return self.service.name

@ -1,63 +1,152 @@
{% extends 'base.html' %}
{% load static %}
{% block content %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login Form</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.login-container {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: #f4f7fc;
}
.login-card {
padding: 2rem;
border-radius: 8px;
background: white;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
}
.login-card h2 {
text-align: center;
margin-bottom: 1rem;
}
</style>
</head>
<body>
<div class="login-container">
<div class="login-card">
<h2>Login</h2>
<form action="#" method="post">
{% csrf_token %}
<header class="bg-primary text-white text-center py-5">
<div class="container">
<h1>Welcome to Sahara</h1>
<p>Your one-stop platform for elder care services.</p>
</div>
</header>
<div class="search-bar">
<input type="text" class="form-control" name=search id=search placeholder="Search Your Caretaker...">
<button class="btn btn-primary ms-1" onclick=sendSearch()>Search</button>
</div>
<section class="container my-5">
<div class="row">
<div class="col-md-3">
<div class="category-bar">
<h4>Services</h4>
<ul class="list-unstyled">
{% for service in services %}
<li><a href="{% url 'home' %}?category={{ service.id }}" class="category-link">{{ service.name }}</a></li>
{% endfor %}
</ul>
<h4>Price</h4>
<input
type="number"
class="form-control"
id="basePriceInput"
value="100"
min="1"
step="0.01">
<input
type="range"
class="form-range"
min="0.5"
max="2"
step="0.01"
value="1"
id="ratioSlider">
<p class="fs-5">
<strong>Price:</strong> Rs.<span id="price">100.00</span>
(<span id="ratio">1.00</span>x)
</p>
</div>
</div>
<div class="col-md-9">
<h2 class="text-center mb-4">Available Caretakers</h2>
<div class="row row-cols-1 row-cols-md-3 g-4">
{% for user in service_providers %}
<div class="col">
<div class="profile-card">
{% if user.profile %}
<img src="{{ user.profile.url }}" alt="{{ user.first_name }} {{ user.last_name }}'s Image" class="img-fluid">
{% else %}
<img src="{% static 'img/dummypic.png' %}" alt="Avatar Image" class="img-fluid">
{% endif %}
<div class="card-body">
<h5 class="card-title">{{ user.first_name|capfirst }} {{ user.last_name|capfirst }}</h5>
<p class="card-text">Bio: {{ user.bio }}</p>
<p class="availability">Member Since: {{ user.member_since|date:"F j, Y" }}</p>
<div class="d-flex align-items-center">
<p class="price mb-0">Rs. {{ user.price|floatformat:2 }}</p>
<!-- Hire button -->
<button class="btn btn-primary btn-sm ms-auto" data-bs-toggle="modal" data-bs-target="#hireModal" data-name="{{ user.first_name }} {{ user.last_name }}" data-bio="{{ user.bio }}" data-price="{{ user.price|floatformat:2 }}" data-id="{{ user.id }}">Hire</button>
</div>
</div>
</div>
</div>
{% empty %}
<div class="mx-auto">Oops! No Caretaker Found Currently.</div>
{% endfor %}
</div>
</div>
</div>
</section>
<!-- Modal -->
<div class="modal fade" id="hireModal" tabindex="-1" aria-labelledby="hireModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="hireModalLabel">Hire Caretaker</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="hireForm">
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="text" class="form-control" id="email" name="email" placeholder="Enter your email" required>
<label for="caretakerName" class="form-label">Caretaker Name</label>
<input type="text" class="form-control" id="caretakerName" disabled>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" placeholder="Enter your password" required>
<label for="caretakerBio" class="form-label">Bio</label>
<textarea class="form-control" id="caretakerBio" rows="3" disabled></textarea>
</div>
<div class="d-flex justify-content-between align-items-center">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="rememberMe">
<label class="form-check-label" for="rememberMe">Remember Me</label>
<div class="mb-3">
<label for="caretakerPrice" class="form-label">Price</label>
<input type="text" class="form-control" id="caretakerPrice" disabled>
</div>
<a href="#" class="small">Forgot password?</a>
<div class="mb-3">
<label for="caretakerService" class="form-label">Service</label>
<input type="text" class="form-control" id="caretakerService" disabled>
</div>
<button type="submit" class="btn btn-primary w-100 mt-3">Login</button>
<button type="submit" class="btn btn-primary">Confirm Hire</button>
</form>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<script>
// Handle the modal data population
const hireModal = document.getElementById('hireModal');
hireModal.addEventListener('show.bs.modal', function (event) {
// Button that triggered the modal
const button = event.relatedTarget;
// Extract information from data-* attributes
const name = button.getAttribute('data-name');
const bio = button.getAttribute('data-bio');
const price = button.getAttribute('data-price');
const serviceId = button.getAttribute('data-id');
// Populate the modal fields
document.getElementById('caretakerName').value = name;
document.getElementById('caretakerBio').value = bio;
document.getElementById('caretakerPrice').value = price;
// Fetch service name based on service ID (optional, if needed)
fetch(`/get-service-name/${serviceId}/`)
.then(response => response.json())
.then(data => {
document.getElementById('caretakerService').value = data.service_name;
});
});
const sendSearch = () => {
let url = window.location.href;
const searchTerm = document.getElementById("search").value;
url = url.split('?')[0] + "?search=" + encodeURIComponent(searchTerm);
window.location.href = url;
}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
</script>
{% endblock %}

@ -3,32 +3,129 @@
{% block content %}
<div class="container">
<h2>Register</h2>
<form method="post">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<div class="form-group mb-3">
<label for="{{ form.first_name.id_for_label }}">First Name</label>
{{ form.first_name }}
{% if form.first_name.errors %}
<div class="invalid-feedback">
{% for error in form.first_name.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<div class="form-group">
<div class="form-group mb-3">
<label for="{{ form.last_name.id_for_label }}">Last Name</label>
{{ form.last_name }}
{% if form.last_name.errors %}
<div class="invalid-feedback">
{% for error in form.last_name.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
<div class="form-group">
<label for="{{ form.username.id_for_label }}">Username</label>
{{ form.username }}
{% endif %}
</div>
<div class="form-group">
<div class="form-group mb-3">
<label for="{{ form.email.id_for_label }}">Email</label>
{{ form.email }}
{% if form.email.errors %}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
<div class="form-group">
{% endif %}
</div>
<div class="form-group mb-3">
<label for="{{ form.password.id_for_label }}">Password</label>
{{ form.password }}
{% if form.password.errors %}
<div class="invalid-feedback">
{% for error in form.password.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<div class="form-group">
<div class="form-group mb-3">
<label for="{{ form.confirm_password.id_for_label }}">Confirm Password</label>
{{ form.confirm_password }}
{% if form.confirm_password.errors %}
<div class="invalid-feedback">
{% for error in form.confirm_password.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<div class="form-group mb-3">
<label for="{{ form.profile.id_for_label }}">Profile Image</label>
{{ form.profile }}
{% if form.profile.errors %}
<div class="invalid-feedback">
{% for error in form.profile.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<div class="form-group mb-3">
<label for="{{ form.price.id_for_label }}">Price</label>
{{ form.price }}
{% if form.price.errors %}
<div class="invalid-feedback">
{% for error in form.price.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<div class="form-group mb-3">
<label for="{{ form.bio.id_for_label }}">Bio</label>
{{ form.bio }}
{% if form.bio.errors %}
<div class="invalid-feedback">
{% for error in form.bio.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<div class="form-group mb-3">
<label for="{{ form.service_offered.id_for_label }}">Service Offered</label>
{{ form.service_offered }}
{% if form.service_offered.errors %}
<div class="invalid-feedback">
{% for error in form.service_offered.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<div class="form-group mb-3">
<label for="{{ form.login_profile.id_for_label }}">Login Profile</label>
{{ form.login_profile }}
{% if form.login_profile.errors %}
<div class="invalid-feedback">
{% for error in form.login_profile.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
<p>Already have an account? <a href="{% url 'login' %}">Login here</a>.</p>

@ -1,22 +1,37 @@
from django.shortcuts import render, redirect,HttpResponse
from django.shortcuts import render, redirect,HttpResponse,get_list_or_404
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_decode
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .models import User
from .forms import UserRegistrationForm, UserLoginForm
from .models import User,Service
from .forms import UserRegistrationForm
import logging
logger = logging.getLogger('main')
def home(request):
return render(request,"main/home.html")
category = request.GET.get('category')
services = Service.objects.all()
if category:
try:
service = Service.objects.get(id=category)
service_providers = User.objects.filter(service_offered=service)
except Service.DoesNotExist:
service_providers = []
else:
service_providers = User.objects.filter(service_offered__isnull=False)
context = {
'service_providers': service_providers,
'services': services
}
return render(request, "main/home.html", context)
def register(request):
if request.method == 'POST':
form = UserRegistrationForm(request.POST)
if request.method == 'POST' and request.FILES:
form = UserRegistrationForm(request.POST,request.FILES, instance=request.user)
if form.is_valid():
user = form.save(commit=False)
user.set_password(form.cleaned_data['password'])
@ -27,11 +42,12 @@ def register(request):
messages.success(request, 'Registration successful! Please check your email to activate your account.')
except Exception as e:
logger.error(f"Error sending verification email: {e}")
messages.error(request, 'Error sending verification email. Please try again later.')
messages.error(request, e)
return redirect('login')
else:
form = UserRegistrationForm()
messages.error(request, 'email already exists')
return render(request, 'main/register.html', {'form': form})
def activate_account(request, uidb64, token):
@ -54,7 +70,7 @@ def user_login(request):
print(request.user.is_authenticated)
if request.user.is_authenticated:
return redirect('home')
else:
if request.method == 'POST':
email = request.POST['email']
password = request.POST['password']
@ -64,7 +80,7 @@ def user_login(request):
messages.success(request, f' welcome {user} !!')
return redirect('home')
else:
messages.info(request, f'account done not exit plz sign in')
messages.info(request, f'Something went wrong')
messages.info(request, f'You are Already Logged in as {request.user}')
return render(request, 'main/login.html', {'title':'log in'})

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

@ -118,8 +118,6 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.1/howto/static-files/
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
@ -134,8 +132,6 @@ EMAIL_PORT = 587
EMAIL_HOST_USER = os.environ.get("EMAIL_ADDRESS")
EMAIL_HOST_PASSWORD = os.environ.get("EMAIL_PASSWORD")
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
@ -144,8 +140,11 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
AUTH_USER_MODEL = 'main.User'
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = 'static/'
STATICFILES_DIRS = [
BASE_DIR / "static",
]
STATIC_ROOT = BASE_DIR / "staticfiles"
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_ROOT = BASE_DIR / "static"

@ -1,7 +1,13 @@
from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('main.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

@ -0,0 +1,144 @@
body {
background-color:#ffffff;
}
.navbar .navbar-brand {
margin-right: auto;
}
.navbar .nav {
margin: 0 auto;
text-align: center;
}
.navbar .login {
margin-left: auto;
}
.search-bar {
margin-top: 20px;
display: flex;
justify-content: center;
align-items: center;
}
.search-bar input {
width: 50%;
border-radius: 50px;
}
.profile-card {
border: 1px solid #ddd;
border-radius: 10px;
overflow: hidden;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.profile-card:hover {
transform: translateY(-10px);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}
.profile-card img {
width: 100%;
height: 200px;
object-fit: cover;
object-position: 10%;
}
.profile-card .card-body {
padding: 15px;
}
.profile-card .card-title {
font-size: 1.25rem;
font-weight: bold;
margin-bottom: 10px;
}
.profile-card .card-text {
font-size: 0.9rem;
color: #555;
}
.profile-card .price {
font-size: 1.1rem;
font-weight: bold;
color: #007bff;
}
.profile-card .availability {
font-size: 0.9rem;
color: #28a745;
}
.category-bar {
background-color: #f8f9fa; /* Light background */
padding: 20px;
border-radius: 10px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); /* Subtle shadow */
}
.category-bar h4 {
font-size: 1.25rem;
font-weight: bold;
margin-bottom: 15px;
color: #333;
}
.category-bar ul {
padding-left: 0;
}
.category-bar .category-link {
display: block;
padding: 10px 15px;
margin: 5px 0;
color: #555;
text-decoration: none;
border-radius: 5px;
transition: background-color 0.3s ease, color 0.3s ease;
}
.category-bar .category-link:hover {
background-color: #007bff; /* Highlight on hover */
color: #fff;
}
/* odd */
.form-container {
font-family: Arial, sans-serif;
margin: auto;
padding: 30px;
background: rgba(255, 255, 255, 0.9);
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 600px;
}
.form-container h2 {
margin-bottom: 20px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input,
.form-group textarea,
.form-group select {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
.form-group input[type="file"] {
padding: 5px;
}
.form-group button {
width: 100%;
padding: 10px;
background-color: #007BFF;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
}
.form-group button:hover {
background-color: #0056b3;
}
.form-wrapper {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: url('img/backgroung-form.jpg') no-repeat center center/cover;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

@ -1,3 +1,4 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
@ -5,12 +6,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sahara</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#"><img src="img/logofinal.png" height="50px" width="75px" alt="Logo"></a>
<a class="navbar-brand" href="#"><img src="{% static 'img/logofinal.png' %}" height="50px" width="75px" alt="Logo"></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@ -32,6 +34,15 @@
</div>
</div>
</nav>
<div class="container mt-3">
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endfor %}
</div>
{% block content %}

Loading…
Cancel
Save