authentication #14

Merged
ismail merged 2 commits from frontend into main 2025-10-14 19:27:57 +03:00
21 changed files with 688 additions and 182 deletions

View File

@ -57,12 +57,27 @@ INSTALLED_APPS = [
'django_countries',
'django_celery_results',
'django_q',
'easyaudit'
]
SITE_ID = 1
# CKEDITOR_BASEPATH = BASE_DIR/'static'
LOGIN_REDIRECT_URL = '/dashboard/'
ACCOUNT_LOGOUT_REDIRECT_URL = '/'
ACCOUNT_SIGNUP_REDIRECT_URL = '/dashboard/'
LOGIN_URL = '/accounts/login/'
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
@ -80,6 +95,7 @@ MIDDLEWARE = [
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'allauth.account.middleware.AccountMiddleware',
'easyaudit.middleware.easyaudit.EasyAuditMiddleware',
]
ROOT_URLCONF = 'NorahUniversity.urls'

View File

@ -101,4 +101,8 @@ urlpatterns = [
path('api/jobs/<slug:job_slug>/candidates/<int:candidate_pk>/reschedule-meeting/<int:interview_pk>/', views.api_reschedule_candidate_meeting, name='api_reschedule_candidate_meeting'),
# New URL for simple page-based meeting scheduling
path('jobs/<slug:job_slug>/candidates/<int:candidate_pk>/schedule-meeting-page/', views.schedule_meeting_for_candidate, name='schedule_meeting_for_candidate'),
# users urls
path('user/<int:pk>',views.user_detail,name='user_detail')
]

View File

@ -1,7 +1,7 @@
import json
import requests
from django.contrib.auth.models import User
from rich import print
from django.template.loader import render_to_string
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
@ -2327,3 +2327,9 @@ def schedule_meeting_for_candidate(request, job_slug, candidate_pk):
'job': job,
'candidate': candidate
})
def user_detail(requests,pk):
user=get_object_or_404(User,pk=pk)
return render(requests,'user/profile.html')

View File

@ -0,0 +1,186 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KAAUH ATS - Sign In (Bootstrap)</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">
<style>
/* -------------------------------------------------------------------------- */
/* CUSTOM TEAL THEME OVERRIDES FOR BOOTSTRAP */
/* -------------------------------------------------------------------------- */
:root {
/* Define TEAL as the primary color for Bootstrap overrides */
--bs-primary: #00636e; /* Dark Teal */
--bs-primary-rgb: 0, 99, 110;
--bs-primary-light: #007a88; /* Lighter Teal for hover */
/* Background and Text Colors */
--bs-body-bg: #f8f9fa; /* Light gray background */
--bs-body-color: #212529; /* Dark text */
/* Utility colors */
--bs-border-color: #dee2e6; /* Bootstrap default border */
}
body {
font-family: 'Inter', sans-serif;
background-color: var(--bs-body-bg);
}
/* Custom Left Panel (Replicating the original look) */
.left-panel {
flex: 1;
background: url("{% static 'image/kaauh_banner.png' %}") no-repeat center center;
background-size: cover;
position: relative;
display: flex;
align-items: flex-end;
padding: 3rem;
color: white;
z-index: 1;
}
.left-panel::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to top, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0) 50%);
z-index: 0;
}
.left-panel-content {
position: relative;
z-index: 2;
/* No change here */
}
/* Right Panel Styling */
.right-panel {
background-color: white;
padding: 3rem;
}
.form-fields {
max-height: 100%;
overflow-y: auto;
}
/* Component Overrides to use Teal Theme (No change) */
.btn-primary {
background-color: var(--bs-primary);
border-color: var(--bs-primary);
font-weight: 600;
border-radius: 0.5rem;
box-shadow: 0 4px 8px rgba(0, 99, 110, 0.2);
transition: all 0.2s ease;
}
.btn-primary:hover {
background-color: var(--bs-primary-light);
border-color: var(--bs-primary-light);
box-shadow: 0 6px 10px rgba(0, 99, 110, 0.3);
}
.form-control:focus {
border-color: var(--bs-primary);
box-shadow: 0 0 0 0.25rem rgba(0, 99, 110, 0.25);
}
.form-check-input:checked {
background-color: var(--bs-primary);
border-color: var(--bs-primary);
}
.text-accent {
color: var(--bs-primary) !important;
}
.text-accent:hover {
color: var(--bs-primary-light) !important;
text-decoration: underline;
}
/* ADJUSTED: Custom size adjustment for right panel on desktop */
@media (min-width: 992px) {
/* 1. Set a NARROWER fixed width for the right panel container */
.right-panel-col {
flex: 0 0 450px; /* Reduced from 800px to 450px */
}
/* 2. Vertically and horizontally center the content within the narrow panel */
.right-panel-col > .d-flex {
height: 100%;
justify-content: center;
align-items: center;
padding-top: 0;
padding-bottom: 0;
}
/* 3. Ensure the form container doesn't exceed a smaller size and is centered */
.right-panel-content-wrapper {
max-width: 350px; /* Max width of the form elements inside the panel */
width: 100%;
}
}
</style>
</head>
<body>
<div class="d-flex vh-100 w-100">
<div class="left-panel d-none d-lg-flex flex-grow-1">
<div class="left-panel-content">
<h1 class="text-4xl font-weight-bold mb-4" style="font-size: 1.5rem;">
<span class="text-white">
<div class="hospital-text text-center text-md-start me-3">
<div class="ar small">جامعة الأميرة نورة بنت عبدالرحمن الأكاديمية</div>
<div class="ar small">ومستشفى الملك عبدالله بن عبدالعزيز التخصصي</div>
<div class="en small">Princess Nourah bint Abdulrahman University</div>
<div class="en small">King Abdullah bin Abdulaziz University Hospital</div>
</div>
</span>
</h1>
<small>Powered By TENHAL | تنحل</small>
</div>
</div>
<div class="d-flex flex-column right-panel right-panel-col flex-grow-1 align-items-center justify-content-center">
<div class="right-panel-content-wrapper">
<h2 id="form-title" class="h3 fw-bold mb-4 text-center">Sign In</h2>
<div class="form-fields">
<form id="login-form" class="space-y-4" method="post" action="{% url 'account_login' %}">
{% csrf_token %}
<div class="mb-3">
<label for="id_login" class="form-label fw-semibold">Username or Email *</label>
<input type="text" name="login" id="id_login" class="form-control" placeholder="Enter username or email" required autofocus>
</div>
<div class="mb-3">
<label for="id_password" class="form-label fw-semibold">Password *</label>
<input type="password" name="password" id="id_password" class="form-control" placeholder="Password" required>
<div class="text-end mt-2">
<a href="{% url 'account_reset_password' %}" class="small text-accent fw-medium">Forgot Password?</a>
</div>
</div>
<div class="form-check pt-3">
<input class="form-check-input" type="checkbox" name="remember" id="id_remember">
<label class="form-check-label text-muted" for="id_remember">
Keep me signed in
</label>
</div>
<button type="submit" class="btn btn-primary w-100 mt-4">Sign In</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>
</body>
</html>

View File

@ -0,0 +1,46 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load crispy_forms_tags %} {% block title %}{% trans "Change Password" %} - KAAUH ATS{% endblock %}
{% block styles %}
{% endblock %}
{% block content %}
<div class="d-flex vh-80 w-100 justify-content-center align-items-center">
<div class="form-card">
<h2 id="form-title" class="h3 fw-bold mb-4 text-center">
{% trans "Change Password" %}
</h2>
<p class="text-muted small mb-4 text-center">
{% trans "Please enter your current password and a new password to secure your account." %}
</p>
<form method="post" action="{% url 'account_change_password' %}" class="space-y-4">
{% csrf_token %}
{{ form|crispy }}
{% if form.non_field_errors %}
<div class="alert alert-danger p-3 small mt-3" role="alert">
{% for error in form.non_field_errors %}{{ error }}{% endfor %}
</div>
{% endif %}
<button type="submit" class="btn btn-danger w-100 mt-3">
{% trans "Change Password" %}
</button>
</form>
<div class="pt-5 mt-4 text-center border-top border-light-subtle">
<p class="text-muted small mb-0">
<i class="fas fa-arrow-left me-1"></i>
<a href="{% url 'user_detail' request.user.pk %}" class="text-accent text-decoration-none text-secondary">{% trans "Return to Profile" %}</a>
</p>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,198 @@
{% load static i18n %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KAAUH ATS - Sign In (Bootstrap)</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">
<style>
/* -------------------------------------------------------------------------- */
/* CUSTOM TEAL THEME OVERRIDES FOR BOOTSTRAP */
/* -------------------------------------------------------------------------- */
:root {
/* Define TEAL as the primary color for Bootstrap overrides */
--bs-primary: #00636e; /* Dark Teal */
--bs-primary-rgb: 0, 99, 110;
--bs-primary-light: #007a88; /* Lighter Teal for hover */
/* Background and Text Colors */
--bs-body-bg: #f8f9fa; /* Light gray background */
--bs-body-color: #212529; /* Dark text */
/* Utility colors */
--bs-border-color: #dee2e6; /* Bootstrap default border */
}
body {
font-family: 'Inter', sans-serif;
background-color: var(--bs-body-bg);
}
/* Custom Left Panel (Replicating the original look) */
.left-panel {
flex: 1;
background: url("{% static 'image/kaauh_banner.png' %}") no-repeat center center;
background-size: cover;
position: relative;
display: flex;
align-items: flex-end;
padding: 3rem;
color: white;
z-index: 1;
}
.left-panel::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to top, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0) 50%);
z-index: 0;
}
.left-panel-content {
position: relative;
z-index: 2;
/* No change here */
}
/* Right Panel Styling */
.right-panel {
background-color: white;
padding: 3rem;
}
.form-fields {
max-height: 100%;
overflow-y: auto;
}
/* Component Overrides to use Teal Theme (No change) */
.btn-primary {
background-color: var(--bs-primary);
border-color: var(--bs-primary);
font-weight: 600;
border-radius: 0.5rem;
box-shadow: 0 4px 8px rgba(0, 99, 110, 0.2);
transition: all 0.2s ease;
}
.btn-primary:hover {
background-color: var(--bs-primary-light);
border-color: var(--bs-primary-light);
box-shadow: 0 6px 10px rgba(0, 99, 110, 0.3);
}
.form-control:focus {
border-color: var(--bs-primary);
box-shadow: 0 0 0 0.25rem rgba(0, 99, 110, 0.25);
}
.form-check-input:checked {
background-color: var(--bs-primary);
border-color: var(--bs-primary);
}
.text-accent {
color: var(--bs-primary) !important;
}
.text-accent:hover {
color: var(--bs-primary-light) !important;
text-decoration: underline;
}
/* ADJUSTED: Custom size adjustment for right panel on desktop */
@media (min-width: 992px) {
/* 1. Set a NARROWER fixed width for the right panel container */
.right-panel-col {
flex: 0 0 450px; /* Reduced from 800px to 450px */
}
/* 2. Vertically and horizontally center the content within the narrow panel */
.right-panel-col > .d-flex {
height: 100%;
justify-content: center;
align-items: center;
padding-top: 0;
padding-bottom: 0;
}
/* 3. Ensure the form container doesn't exceed a smaller size and is centered */
.right-panel-content-wrapper {
max-width: 350px; /* Max width of the form elements inside the panel */
width: 100%;
}
}
</style>
</head>
<body>
<div class="d-flex vh-100 w-100">
<div class="left-panel d-none d-lg-flex flex-grow-1">
<div class="left-panel-content">
<h1 class="text-4xl font-weight-bold mb-4" style="font-size: 1.5rem;">
<span class="text-white">
<div class="hospital-text text-center text-md-start me-3">
<div class="ar small">جامعة الأميرة نورة بنت عبدالرحمن الأكاديمية</div>
<div class="ar small">ومستشفى الملك عبدالله بن عبدالعزيز التخصصي</div>
<div class="en small">Princess Nourah bint Abdulrahman University</div>
<div class="en small">King Abdullah bin Abdulaziz University Hospital</div>
</div>
</span>
</h1>
<small>Powered By TENHAL | تنحل</small>
</div>
</div>
<div class="d-flex flex-column right-panel right-panel-col flex-grow-1 align-items-center justify-content-center">
<div class="right-panel-content-wrapper">
<h2 id="form-title" class="h3 fw-bold mb-4 text-center">
{% trans "Forgot Password?" %}
</h2>
<p class="text-muted small mb-4 text-center">
{% trans "Enter your e-mail address to reset your password." %}
</p>
{% url 'account_reset_password' as password_reset_url %}
<form method="post" action="{{ password_reset_url }}" class="space-y-4">
{% csrf_token %}
<div class="mb-4">
<label for="id_email" class="form-label fw-semibold">{% trans "E-mail Address" %} *</label>
{% if form.email.errors %}
<div class="alert alert-danger p-2 small" role="alert">
{% for error in form.email.errors %}{{ error }}{% endfor %}
</div>
{% endif %}
<input type="email" name="email" id="id_email" class="form-control" placeholder="Enter your email address" required autofocus>
{% if form.non_field_errors %}
<div class="alert alert-danger p-2 small mt-3" role="alert">
{% for error in form.non_field_errors %}{{ error }}{% endfor %}
</div>
{% endif %}
</div>
<button type="submit" class="btn btn-primary w-100 mt-3">
{% trans "Reset My Password" %}
</button>
</form>
<div class="pt-5 text-center">
<p class="text-muted small mb-0">
{% trans "Remember your password?" %}
<a href="{% url 'account_login' %}" class="text-accent fw-medium">{% trans "Log In" %}</a>
</p>
</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>
</body>
</html>

View File

View File

@ -242,6 +242,18 @@
html[dir="rtl"] .ms-2 { margin-left: 0 !important; margin-right: 0.5rem !important; }
html[dir="rtl"] .ms-auto { margin-left: 0 !important; margin-right: auto !important; }
html[dir="rtl"] .me-auto { margin-right: 0 !important; margin-left: auto !important; }
.form-control-sm,
.btn-sm {
/* Reduce vertical padding even more than default Bootstrap 'sm' */
padding-top: 0.2rem !important;
padding-bottom: 0.2rem !important;
/* Ensure a consistent, small height for both */
height: 35px !important;
font-size: 2 rem !important; /* Slightly smaller font */
}
</style>
{% block customCSS %}{% endblock %}
</head>
@ -462,7 +474,7 @@
</div>
</li>
<li><hr class="dropdown-divider my-1"></li>
<li><a class="dropdown-item py-2 px-4 d-flex align-items-center text-decoration-none" href="#"><i class="fas fa-user-circle me-3 text-primary fs-5"></i> <span>{% trans "My Profile" %}</span></a></li>
<li><a class="dropdown-item py-2 px-4 d-flex align-items-center text-decoration-none" href="{% url 'user_detail' request.user.pk %}"><i class="fas fa-user-circle me-3 text-primary fs-5"></i> <span>{% trans "My Profile" %}</span></a></li>
<li><a class="dropdown-item py-2 px-4 d-flex align-items-center text-decoration-none" href="#"><i class="fas fa-cog me-3 text-primary fs-5"></i> <span>{% trans "Settings" %}</span></a></li>
<li><a class="dropdown-item py-2 px-4 d-flex align-items-center text-decoration-none" href="#"><i class="fas fa-history me-3 text-primary fs-5"></i> <span>{% trans "Activity Log" %}</span></a></li>
<li><a class="dropdown-item py-2 px-4 d-flex align-items-center text-decoration-none" href="#"><i class="fas fa-question-circle me-3 text-primary fs-5"></i> <span>{% trans "Help & Support" %}</span></a></li>
@ -485,7 +497,7 @@
<li><hr class="dropdown-divider my-1"></li>
<li>
<form method="post" action="" class="d-inline">
<form method="post" action="{% url 'account_logout'%}" class="d-inline">
{% csrf_token %}
<button
type="submit"

View File

@ -1,4 +1,7 @@
{% load i18n %}
<style>
</style>
<form method="get" class="d-flex gap-2 align-items-center">
<div class="input-group flex-grow-1" style="max-width: 300px;">
<span class="input-group-text bg-white border-end-0">
@ -7,7 +10,7 @@
</svg>
</span>
<input type="text" name="search"
class="form-control border-start-0"
class="form-control-sm border-start-0"
placeholder="{% trans 'Search...' %}"
value="{{ search_query }}"
aria-label="{% trans 'Search' %}">

View File

@ -174,129 +174,6 @@
.job-timeline-container {
padding: 10px 0;
overflow-x: auto;
margin: 10px 0;
background-color: #f8f9fa;
border-radius: 0.5rem;
}
.job-timeline {
display: flex;
justify-content: space-between;
list-style: none;
padding: 0 10px;
margin: 0;
position: relative;
min-width: 1000px;
}
/* 🛑 NO CONNECTING LINE: Removed .job-timeline::before and .timeline-stage.is-complete + .timeline-stage::before */
/* ------------------ Stage & Marker Basics ------------------ */
.timeline-stage {
flex: 1 1 auto;
text-align: center;
position: relative;
z-index: 2;
padding-top: 50px;
}
.status-marker {
position: absolute;
top: 10px;
left: 50%;
transform: translateX(-50%);
width: 40px;
height: 40px;
border-radius: 50%;
/* DEFAULT (Inactive/Not Current Status) */
background-color: white;
border: 3px solid var(--color-line-default);
color: var(--color-line-default);
font-size: 18px;
line-height: 34px;
z-index: 3;
transition: all 0.3s ease, box-shadow 0.3s ease;
box-shadow: 0 0 0 2px white;
}
/* ------------------ ACTIVE/CURRENT Status Indicator ------------------ */
/* The 'is-active' class now completely defines the current status color and highlight */
.timeline-stage.is-active .status-marker {
transform: translateX(-50%) scale(1.15); /* Keep the pop effect */
color: white; /* Default text color for all active markers */
}
/* 1. CREATED (Active) */
.timeline-stage[data-stage="created"].is-active .status-marker {
background-color: var(--color-created);
border-color: var(--color-created);
box-shadow: 0 0 0 4px rgba(108, 117, 125, 0.5);
}
/* 2. MADE ACTIVE (Active) */
.timeline-stage[data-stage="active"].is-active .status-marker {
background-color: var(--color-active);
border-color: var(--color-active);
box-shadow: 0 0 0 4px var(--kaauh-teal-light);
}
/* 3. POSTED TO LINKEDIN (Active) */
.timeline-stage[data-stage="posted"].is-active .status-marker {
background-color: var(--color-posted);
border-color: var(--color-posted);
box-shadow: 0 0 0 4px rgba(23, 162, 184, 0.5);
}
/* 4. CANCELED (Active/Terminal) */
.timeline-stage[data-stage="canceled"].is-active .status-marker {
background-color: var(--color-canceled);
border-color: var(--color-canceled);
box-shadow: 0 0 0 4px rgba(220, 53, 69, 0.5);
}
/* 5. CLOSED (Active/Terminal) */
.timeline-stage[data-stage="closed"].is-active .status-marker {
background-color: var(--color-closed);
border-color: var(--color-closed);
color: #343a40; /* Dark icon for contrast on yellow */
box-shadow: 0 0 0 4px rgba(255, 193, 7, 0.5);
}
/* 6. ARCHIVED (Active/Terminal) */
.timeline-stage[data-stage="archived"].is-active .status-marker {
background-color: var(--color-archived);
border-color: var(--color-archived);
box-shadow: 0 0 0 4px rgba(52, 58, 64, 0.5);
}
/* ------------------ Text Labels ------------------ */
.status-label {
font-size: 0.85rem;
font-weight: 600;
color: #343a40;
margin-top: 5px;
}
/* Highlight text label for the active status */
.timeline-stage.is-active .status-label {
color: var(--kaauh-teal);
}
.status-date {
font-size: 0.75rem;
color: #6c757d;
}
</style>
{% endblock %}
@ -306,49 +183,7 @@
<div class="container-fluid py-4">
<div class="job-timeline-container shadow-sm">
<div class="card-body">
<ul class="job-timeline">
<li class="timeline-stage" data-stage="created">
<div class="status-marker"><i class="fas fa-hammer"></i></div>
<div class="status-label">Created</div>
<div class="status-date">Jan 1</div>
</li>
<li class="timeline-stage" data-stage="active">
<div class="status-marker"><i class="fas fa-play-circle"></i></div>
<div class="status-label">Made Active</div>
<div class="status-date">Jan 5</div>
</li>
<li class="timeline-stage" data-stage="posted">
<div class="status-marker"><i class="fab fa-linkedin"></i></div>
<div class="status-label">Posted to LinkedIn</div>
<div class="status-date">Jan 6</div>
</li>
<li class="timeline-stage is-active" data-stage="canceled">
<div class="status-marker"><i class="fas fa-times-circle"></i></div>
<div class="status-label">Canceled</div>
<div class="status-date">Jan 15</div>
</li>
<li class="timeline-stage" data-stage="closed">
<div class="status-marker"><i class="fas fa-lock"></i></div>
<div class="status-label">Closed</div>
<div class="status-date"></div>
</li>
<li class="timeline-stage" data-stage="archived">
<div class="status-marker"><i class="fas fa-archive"></i></div>
<div class="status-label">Archived</div>
<div class="status-date"></div>
</li>
</ul>
</div>
</div>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'dashboard' %}" class="text-secondary">Home</a></li>

View File

@ -205,7 +205,7 @@
<div class="card mb-4 shadow-sm no-hover">
<div class="card-body">
<div class="row">
<div class="col-md-4">
<div class="col-md-6">
<label for="search" class="form-label small text-muted">{% trans "Search by Title or Department" %}</label>
<div class="input-group input-group-lg mb-3">
<form method="get" action="" class="w-100">
@ -213,9 +213,9 @@
</form>
</div>
</div>
<div class="col-md-8">
<div class="col-md-6">
<form method="GET" class="row g-3 align-items-end" >
<div class="col-md-3">
<div class="col-md-4">
<label for="status" class="form-label small text-muted">{% trans "Filter by Status" %}</label>
<select name="status" id="status" class="form-select form-select-sm">
<option value="">{% trans "All Statuses" %}</option>
@ -227,12 +227,17 @@
</div>
<div class="col-md-5">
<div class="filter-buttons">
<button type="submit" class="btn btn-main-action btn-sm">
<button type="submit" class="btn btn-main-action btn-lg">
<i class="fas fa-filter me-1"></i> {% trans "Apply Filters" %}
</button>
<a href="{% url 'job_list' %}" class="btn btn-outline-secondary btn-sm">
<i class="fas fa-times me-1"></i> {% trans "Clear" %}
</a>
{% if job_filter or search_query %}
<a href="{% url 'job_list' %}" class="btn btn-outline-secondary btn-lg">
<i class="fas fa-times me-1"></i> {% trans "Clear" %}
</a>
{% endif %}
</div>
</div>
</form>

View File

@ -156,7 +156,7 @@
<div class="card mb-4 shadow-sm no-hover">
<div class="card-body">
<div class="row">
<div class="col-md-4">
<div class="col-md-6">
<label for="search" class="form-label small text-muted">{% trans "Search by Topic" %}</label>
<div class="input-group input-group-lg mb-3">
<form method="get" action="" class="w-100">
@ -164,7 +164,7 @@
</form>
</div>
</div>
<div class="col-md-8">
<div class="col-md-6">
<form method="GET" class="row g-3 align-items-end" >
{% if search_query %}<input type="hidden" name="q" value="{{ search_query }}">{% endif %}

View File

@ -151,7 +151,7 @@
<div class="card mb-4 shadow-sm no-hover">
<div class="card-body">
<div class="row">
<div class="col-md-4">
<div class="col-md-6">
<label for="search" class="form-label small text-muted">{% trans "Search by Name or Email" %}</label>
<div class="input-group input-group-lg mb-3">
<form method="get" action="" class="w-100">
@ -159,7 +159,7 @@
</form>
</div>
</div>
<div class="col-md-8">
<div class="col-md-6">
{% url 'candidate_list' as candidate_list_url %}
<form method="GET" class="row g-3 align-items-end" >

195
templates/user/profile.html Normal file
View File

@ -0,0 +1,195 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% block title %}{% trans "User Profile" %} - KAAUH ATS{% endblock %}
{% block customCSS %}
<style>
/* Theme Variables based on Teal Accent */
:root {
--bs-primary: #00636e;
--bs-primary-rgb: 0, 99, 110;
--bs-primary-light: #007a88;
--bs-body-bg: #f3f5f8; /* Soft light gray background */
--bs-body-color: #212529;
--bs-border-color: #e9ecef; /* Lighter, softer border */
}
/* Card Refinements for Depth and Geometry */
.card {
border: none;
border-radius: 1rem;
box-shadow: 0 8px 30px rgba(0,0,0,0.08); /* Deeper, softer shadow */
transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;
}
.card:hover {
transform: translateY(-2px); /* Subtle lift on hover */
box-shadow: 0 12px 35px rgba(0,0,0,0.1);
}
/* Profile Header Consistency */
.profile-header {
border-bottom: 2px solid var(--bs-border-color);
padding-bottom: 1.5rem;
margin-bottom: 2rem;
}
/* Form Consistency */
.form-control {
border-radius: 0.5rem;
padding: 0.75rem 1rem;
border-color: var(--bs-border-color);
transition: border-color 0.2s, box-shadow 0.2s;
font-size: 0.95rem; /* Slightly larger text in fields */
}
.form-control:focus {
border-color: var(--bs-primary-light);
box-shadow: 0 0 0 0.15rem rgba(0, 99, 110, 0.15);
}
.form-label {
font-size: 0.9rem;
font-weight: 600;
color: #495057; /* Slightly darker than default mute */
margin-bottom: 0.5rem;
}
/* Button Consistency (Primary) */
.btn-primary {
background-color: var(--bs-primary);
border-color: var(--bs-primary);
font-weight: 700;
border-radius: 0.6rem;
padding: 0.65rem 1.5rem;
box-shadow: 0 5px 15px rgba(0, 99, 110, 0.3);
transition: all 0.2s ease;
}
.btn-primary:hover {
background-color: var(--bs-primary-light);
border-color: var(--bs-primary-light);
box-shadow: 0 8px 18px rgba(0, 99, 110, 0.4);
transform: translateY(-1px);
}
/* Button Consistency (Outline/Secondary) */
.btn-outline-secondary {
color: #495057;
border-color: var(--bs-border-color);
font-weight: 500;
transition: all 0.2s ease;
}
.btn-outline-secondary:hover {
color: var(--bs-primary); /* Accent text color on hover */
background-color: rgba(0, 99, 110, 0.05);
border-color: var(--bs-primary);
}
/* Accent & Info Text */
.text-accent {
color: var(--bs-primary) !important;
font-weight: 600;
}
.info-value {
font-weight: 700; /* Bolder status values */
color: var(--bs-body-color);
}
.info-label {
color: #6c757d;
font-size: 0.85rem;
margin-bottom: 0.2rem;
}
</style>
{% endblock %}
{% block content %}
<div class="container" style="max-width: 900px;">
<div class="profile-header d-flex align-items-center justify-content-between">
<div>
<h1 class="h3 fw-bold mb-1">{% trans "Account Settings" %}</h1>
<p class="text-muted mb-0">{% trans "Manage your personal details and security." %}</p>
</div>
<div class="rounded-circle bg-primary-subtle text-accent d-flex align-items-center justify-content-center" style="width: 50px; height: 50px; font-size: 1.5rem;">
{% if user.first_name %}{{ user.first_name.0 }}{% else %}<i class="fas fa-user"></i>{% endif %}
</div>
</div>
<div class="row g-4">
<div class="col-lg-7">
<div class="card p-5">
<h5 class="fw-bold mb-4 text-accent">{% trans "Personal Information" %}</h5>
<form method="post" action="#">
{% csrf_token %}
<div class="row g-4"> <div class="col-md-6">
<label for="id_first_name" class="form-label">{% trans "First Name" %}</label>
<input type="text" class="form-control" id="id_first_name" name="first_name" value="{{ user.first_name|default:'' }}">
</div>
<div class="col-md-6">
<label for="id_last_name" class="form-label">{% trans "Last Name" %}</label>
<input type="text" class="form-control" id="id_last_name" name="last_name" value="{{ user.last_name|default:'' }}">
</div>
<div class="col-12">
<label for="id_email" class="form-label">{% trans "Email Address" %}</label>
<input type="email" class="form-control" id="id_email" value="{{ user.email }}" disabled>
<div class="form-text mt-2">
<a href="#" class="small text-accent">{% trans "Manage email addresses" %}</a>
</div>
</div>
<div class="col-12 mt-4 pt-2">
<button type="submit" class="btn btn-primary">{% trans "Save Changes" %}</button>
</div>
</div>
</form>
</div>
</div>
<div class="col-lg-5">
<div class="card p-4 mb-4">
<h5 class="fw-bold mb-4 text-accent">{% trans "Security" %}</h5>
<div class="d-grid gap-3">
<a href="{% url 'account_change_password' %}" class="btn btn-outline-danger w-100 rounded-pill py-2">
<i class="fas fa-lock me-2"></i> {% trans "Change Password" %}
</a>
{% comment %} <a href="#" class="btn btn-outline-secondary w-100 rounded-pill py-2">
<i class="fas fa-shield-alt me-2"></i> {% trans "Two-Factor Auth" %}
</a> {% endcomment %}
</div>
</div>
<div class="card p-4">
<h5 class="fw-bold mb-4 text-accent">{% trans "Account Status" %}</h5>
<div class="mb-3">
<div class="info-label">{% trans "Username" %}</div>
<div class="info-value">{{ user.username }}</div>
</div>
<div class="mb-3">
<div class="info-label">{% trans "Last Login" %}</div>
<div class="info-value">
{% if user.last_login %}{{ user.last_login|date:"F d, Y P" }}{% else %}N/A{% endif %}
</div>
</div>
<div>
<div class="info-label">{% trans "Date Joined" %}</div>
<div class="info-value">{{ user.date_joined|date:"F d, Y" }}</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}