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 import admin
from django.contrib.auth.admin import UserAdmin 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): class CustomUserAdmin(UserAdmin):
model = User model = User
@ -17,7 +17,7 @@ class CustomUserAdmin(UserAdmin):
# Fieldsets for the add and change forms in the admin # Fieldsets for the add and change forms in the admin
fieldsets = ( fieldsets = (
(None, {'fields': ('email', 'password')}), (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')}), ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser')}),
('Important Dates', {'fields': ('last_login',)}), # Remove 'date_joined' if it doesn't exist ('Important Dates', {'fields': ('last_login',)}), # Remove 'date_joined' if it doesn't exist
) )
@ -26,7 +26,7 @@ class CustomUserAdmin(UserAdmin):
add_fieldsets = ( add_fieldsets = (
(None, { (None, {
'classes': ('wide',), '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 # Register your custom User model with the custom UserAdmin class
admin.site.register(User, CustomUserAdmin) admin.site.register(User, CustomUserAdmin)
admin.site.register(ServiceRequest) admin.site.register(ServiceRequest)
admin.site.register(Service)

@ -2,7 +2,11 @@ from django import forms
from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.forms import AuthenticationForm
from .models import User from .models import User
from django import forms
from .models import User, Service
class UserRegistrationForm(forms.ModelForm): class UserRegistrationForm(forms.ModelForm):
# Password and confirm password fields with custom classes
password = forms.CharField( password = forms.CharField(
widget=forms.PasswordInput(attrs={ widget=forms.PasswordInput(attrs={
'class': 'form-control', 'class': 'form-control',
@ -18,7 +22,7 @@ class UserRegistrationForm(forms.ModelForm):
class Meta: class Meta:
model = User model = User
fields = ['first_name', 'last_name', 'email', 'password'] fields = ['email', 'first_name', 'last_name', 'profile', 'price', 'bio', 'service_offered', 'login_profile']
widgets = { widgets = {
'first_name': forms.TextInput(attrs={ 'first_name': forms.TextInput(attrs={
'class': 'form-control', 'class': 'form-control',
@ -32,8 +36,39 @@ class UserRegistrationForm(forms.ModelForm):
'class': 'form-control', 'class': 'form-control',
'placeholder': 'Enter your email address', '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): def clean(self):
cleaned_data = super().clean() cleaned_data = super().clean()
password = cleaned_data.get('password') password = cleaned_data.get('password')
@ -41,12 +76,3 @@ class UserRegistrationForm(forms.ModelForm):
if password and confirm_password and password != confirm_password: if password and confirm_password and password != confirm_password:
raise forms.ValidationError("Passwords do not match.") 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.set_password(password)
user.save(using=self._db) user.save(using=self._db)
# Send verification email
try: try:
self.send_verification_email(user) self.send_verification_email(user)
except: except:
@ -76,6 +75,12 @@ class UserManager(BaseUserManager):
) )
OPTIONS = [
('NORMAL','Normal User'),
('SERVICE', 'Service Provider'),
('ADMIN', 'Admin User'),
]
class User(AbstractBaseUser, PermissionsMixin): class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True) email = models.EmailField(unique=True)
first_name = models.CharField(max_length=30) first_name = models.CharField(max_length=30)
@ -83,13 +88,19 @@ class User(AbstractBaseUser, PermissionsMixin):
is_active = models.BooleanField(default=True) is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False) is_staff = models.BooleanField(default=False)
is_superuser = 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) price = models.PositiveBigIntegerField(blank=True, null=True)
bio = models.CharField(max_length=200, blank=True, null=True) bio = models.CharField(max_length=200, blank=True, null=True)
member_since = models.DateTimeField(auto_now_add=True) member_since = models.DateTimeField(auto_now_add=True)
updated_on = models.DateField(auto_now=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' USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name'] REQUIRED_FIELDS = ['first_name', 'last_name','price','bio']
objects = UserManager() objects = UserManager()
@ -112,7 +123,7 @@ class ServiceRequest(models.Model):
remarks = models.TextField(blank=True, null=True) remarks = models.TextField(blank=True, null=True)
is_completed = models.BooleanField(default=False) is_completed = models.BooleanField(default=False)
completed_date = models.DateTimeField(null=True,blank=True) 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): def __str__(self):
return self.service.name return self.service.name

@ -1,63 +1,152 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load static %}
{% block content %} {% block content %}
<!DOCTYPE html> <header class="bg-primary text-white text-center py-5">
<html lang="en"> <div class="container">
<head> <h1>Welcome to Sahara</h1>
<meta charset="UTF-8"> <p>Your one-stop platform for elder care services.</p>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> </div>
<title>Login Form</title> </header>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<style> <div class="search-bar">
.login-container { <input type="text" class="form-control" name=search id=search placeholder="Search Your Caretaker...">
height: 100vh; <button class="btn btn-primary ms-1" onclick=sendSearch()>Search</button>
display: flex; </div>
justify-content: center;
align-items: center; <section class="container my-5">
background: #f4f7fc; <div class="row">
} <div class="col-md-3">
.login-card { <div class="category-bar">
padding: 2rem; <h4>Services</h4>
border-radius: 8px; <ul class="list-unstyled">
background: white; {% for service in services %}
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); <li><a href="{% url 'home' %}?category={{ service.id }}" class="category-link">{{ service.name }}</a></li>
width: 100%; {% endfor %}
max-width: 400px; </ul>
} <h4>Price</h4>
.login-card h2 { <input
text-align: center; type="number"
margin-bottom: 1rem; class="form-control"
} id="basePriceInput"
</style> value="100"
</head> min="1"
<body> step="0.01">
<div class="login-container"> <input
<div class="login-card"> type="range"
<h2>Login</h2> class="form-range"
<form action="#" method="post"> min="0.5"
{% csrf_token %} 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"> <div class="mb-3">
<label for="email" class="form-label">Email</label> <label for="caretakerName" class="form-label">Caretaker Name</label>
<input type="text" class="form-control" id="email" name="email" placeholder="Enter your email" required> <input type="text" class="form-control" id="caretakerName" disabled>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="password" class="form-label">Password</label> <label for="caretakerBio" class="form-label">Bio</label>
<input type="password" class="form-control" id="password" name="password" placeholder="Enter your password" required> <textarea class="form-control" id="caretakerBio" rows="3" disabled></textarea>
</div> </div>
<div class="d-flex justify-content-between align-items-center"> <div class="mb-3">
<div class="form-check"> <label for="caretakerPrice" class="form-label">Price</label>
<input type="checkbox" class="form-check-input" id="rememberMe"> <input type="text" class="form-control" id="caretakerPrice" disabled>
<label class="form-check-label" for="rememberMe">Remember Me</label>
</div> </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> </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> </form>
</div> </div>
</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> </script>
</body>
</html>
{% endblock %} {% endblock %}

@ -3,32 +3,129 @@
{% block content %} {% block content %}
<div class="container"> <div class="container">
<h2>Register</h2> <h2>Register</h2>
<form method="post"> <form method="post" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<div class="form-group">
<div class="form-group mb-3">
<label for="{{ form.first_name.id_for_label }}">First Name</label> <label for="{{ form.first_name.id_for_label }}">First Name</label>
{{ form.first_name }} {{ 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>
<div class="form-group">
<div class="form-group mb-3">
<label for="{{ form.last_name.id_for_label }}">Last Name</label> <label for="{{ form.last_name.id_for_label }}">Last Name</label>
{{ form.last_name }} {{ 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>
<div class="form-group"> {% endif %}
<label for="{{ form.username.id_for_label }}">Username</label>
{{ form.username }}
</div> </div>
<div class="form-group">
<div class="form-group mb-3">
<label for="{{ form.email.id_for_label }}">Email</label> <label for="{{ form.email.id_for_label }}">Email</label>
{{ form.email }} {{ form.email }}
{% if form.email.errors %}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<p>{{ error }}</p>
{% endfor %}
</div> </div>
<div class="form-group"> {% endif %}
</div>
<div class="form-group mb-3">
<label for="{{ form.password.id_for_label }}">Password</label> <label for="{{ form.password.id_for_label }}">Password</label>
{{ form.password }} {{ form.password }}
{% if form.password.errors %}
<div class="invalid-feedback">
{% for error in form.password.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div> </div>
<div class="form-group">
<div class="form-group mb-3">
<label for="{{ form.confirm_password.id_for_label }}">Confirm Password</label> <label for="{{ form.confirm_password.id_for_label }}">Confirm Password</label>
{{ form.confirm_password }} {{ 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>
<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> <button type="submit" class="btn btn-primary">Register</button>
</form> </form>
<p>Already have an account? <a href="{% url 'login' %}">Login here</a>.</p> <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 import login, logout, authenticate
from django.contrib.auth.tokens import default_token_generator from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_decode from django.utils.http import urlsafe_base64_decode
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib import messages from django.contrib import messages
from .models import User from .models import User,Service
from .forms import UserRegistrationForm, UserLoginForm from .forms import UserRegistrationForm
import logging import logging
logger = logging.getLogger('main') logger = logging.getLogger('main')
def home(request): 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): def register(request):
if request.method == 'POST': if request.method == 'POST' and request.FILES:
form = UserRegistrationForm(request.POST) form = UserRegistrationForm(request.POST,request.FILES, instance=request.user)
if form.is_valid(): if form.is_valid():
user = form.save(commit=False) user = form.save(commit=False)
user.set_password(form.cleaned_data['password']) 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.') messages.success(request, 'Registration successful! Please check your email to activate your account.')
except Exception as e: except Exception as e:
logger.error(f"Error sending verification email: {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') return redirect('login')
else: else:
form = UserRegistrationForm() form = UserRegistrationForm()
messages.error(request, 'email already exists')
return render(request, 'main/register.html', {'form': form}) return render(request, 'main/register.html', {'form': form})
def activate_account(request, uidb64, token): def activate_account(request, uidb64, token):
@ -54,7 +70,7 @@ def user_login(request):
print(request.user.is_authenticated) print(request.user.is_authenticated)
if request.user.is_authenticated: if request.user.is_authenticated:
return redirect('home') return redirect('home')
else:
if request.method == 'POST': if request.method == 'POST':
email = request.POST['email'] email = request.POST['email']
password = request.POST['password'] password = request.POST['password']
@ -64,7 +80,7 @@ def user_login(request):
messages.success(request, f' welcome {user} !!') messages.success(request, f' welcome {user} !!')
return redirect('home') return redirect('home')
else: 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}') messages.info(request, f'You are Already Logged in as {request.user}')
return render(request, 'main/login.html', {'title':'log in'}) 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) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.1/howto/static-files/ # https://docs.djangoproject.com/en/5.1/howto/static-files/
STATIC_URL = 'static/'
# Default primary key field type # Default primary key field type
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field # 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_USER = os.environ.get("EMAIL_ADDRESS")
EMAIL_HOST_PASSWORD = os.environ.get("EMAIL_PASSWORD") EMAIL_HOST_PASSWORD = os.environ.get("EMAIL_PASSWORD")
STATIC_URL = 'static/'
# Default primary key field type # Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field # 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' AUTH_USER_MODEL = 'main.User'
STATIC_URL = '/static/' STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static') STATICFILES_DIRS = [
BASE_DIR / "static",
]
STATIC_ROOT = BASE_DIR / "staticfiles"
MEDIA_URL = '/media/' 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.contrib import admin
from django.urls import path,include from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('', include('main.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> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
@ -5,12 +6,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sahara</title> <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 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> </head>
<body> <body>
<nav class="navbar navbar-expand-lg bg-body-tertiary"> <nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid"> <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"> <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> <span class="navbar-toggler-icon"></span>
</button> </button>
@ -32,6 +34,15 @@
</div> </div>
</div> </div>
</nav> </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 %} {% block content %}

Loading…
Cancel
Save