more frontend updates. Added membership only area in debug mode

This commit is contained in:
2025-04-21 10:13:01 -05:00
parent 77ccc5c2fe
commit 4c0605474c
13 changed files with 776 additions and 88 deletions

View File

@@ -95,7 +95,7 @@
<strong>Grades:</strong> 9-12<br>
<strong>Enrollment:</strong> 698<br>
<strong>Distance:</strong> 2.7 miles from community entrance<br>
<strong>Principal:</strong> TBD</p>
<strong>Principal:</strong> Raeann Huhn </p>
<a href="https://www.sfhscollegeprep.org/" target="_blank" class="btn btn-sm btn-outline-success">Visit Website</a>
</div>
</div>
@@ -111,7 +111,7 @@
<strong>Grades:</strong> 9-12<br>
<strong>Enrollment:</strong> 1265<br>
<strong>Distance:</strong> 5.9 miles from community entrance<br>
<strong>Principal:</strong> TBD</p>
<strong>Principal:</strong> Sheri Costello </p>
<a href="http://www.cusd200.org/Domain/140" target="_blank" class="btn btn-sm btn-outline-success">Visit Website</a>
</div>
</div>
@@ -260,8 +260,8 @@
<li class="list-group-item"><i class="bi bi-check text-success me-2"></i>Playground</li>
<li class="list-group-item"><i class="bi bi-check text-success me-2"></i>Baseball Field</li>
<li class="list-group-item"><i class="bi bi-check text-success me-2"></i>Tennis Court</li>
<li class="list-group-item"><i class="bi bi-check text-success me-2"></i>BasketballCourt</li>
<li class="list-group-item"><i class="bi bi-check text-success me-2"></i>Picninc Tables</li>
<li class="list-group-item"><i class="bi bi-check text-success me-2"></i>Basketball Court</li>
<li class="list-group-item"><i class="bi bi-check text-success me-2"></i>Picnic Tables</li>
<li class="list-group-item"><i class="bi bi-check text-success me-2"></i>Dogs Allowed</li>
</ul>
<p class="card-text"><small class="text-muted">Open daily from 8am to sunset</small></p>

View File

@@ -0,0 +1,125 @@
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% block pagetitle %}
{% endblock %}
<!-- Bootstrap 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.10.0/font/bootstrap-icons.css">
<!-- Custom CSS -->
<link href="{% static 'css/style2.css' %}" rel="stylesheet" type="text/css" />
<script async defer src="https://tianji.aimloperations.com/tracker.js" data-website-id="cm9qziuid9vr7v6dtdbnx8406"></script>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-success sticky-top">
<div class="container">
<a class="navbar-brand" href="index.html">Greenwood Estates</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="index.html"><i class="bi bi-speedometer2 me-1"></i>Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="directory.html"><i class="bi bi-people me-1"></i>Directory</a>
</li>
<li class="nav-item">
<a class="nav-link" href="posts/"><i class="bi bi-chat-square-text me-1"></i>Community Posts</a>
</li>
</ul>
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-bs-toggle="dropdown">
<i class="bi bi-person-circle me-1"></i>John D.
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" href="#"><i class="bi bi-person me-2"></i>Profile</a></li>
<li><a class="dropdown-item" href="#"><i class="bi bi-gear me-2"></i>Settings</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="../../auth/login.html"><i class="bi bi-box-arrow-right me-2"></i>Logout</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
{% block content %}
{% endblock %}
<!-- Footer -->
<footer class="bg-dark text-white pt-4 pb-3">
<div class="container">
<div class="row">
<div class="col-md-6">
<h5 class="text-uppercase">Greenwood Estates HOA</h5>
<p class="text-white-50">1234 Greenwood Lane<br>Anytown, ST 12345</p>
</div>
<div class="col-md-3">
<h5 class="text-uppercase">Quick Links</h5>
<ul class="list-unstyled">
<li><a href="index.html" class="text-white-50">Dashboard</a></li>
<li><a href="directory.html" class="text-white-50">Directory</a></li>
<li><a href="posts/" class="text-white-50">Community Posts</a></li>
</ul>
</div>
<div class="col-md-3">
<h5 class="text-uppercase">Account</h5>
<ul class="list-unstyled">
<li><a href="#" class="text-white-50">Profile</a></li>
<li><a href="#" class="text-white-50">Settings</a></li>
<li><a href="../../auth/login.html" class="text-white-50">Logout</a></li>
</ul>
</div>
</div>
<hr class="my-3">
<div class="row">
<div class="col-12 text-center">
<p class="mb-0 small">&copy; 2023 Greenwood Estates HOA. All rights reserved.</p>
</div>
</div>
</div>
</footer>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<!-- Directory Script -->
<script>
document.addEventListener('DOMContentLoaded', function() {
// Search functionality
const searchInput = document.getElementById('directorySearch');
const tableRows = document.querySelectorAll('tbody tr');
searchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase();
tableRows.forEach(row => {
const rowText = row.textContent.toLowerCase();
if (rowText.includes(searchTerm)) {
row.style.display = '';
} else {
row.style.display = 'none';
}
});
});
// Filter functionality
const filterSelect = document.getElementById('directoryFilter');
filterSelect.addEventListener('change', function() {
const filterValue = this.value;
// In a real implementation, this would filter the directory
console.log('Filter by:', filterValue);
});
});
</script>
</body>
</html>

View File

@@ -78,7 +78,9 @@
</div>
<hr class="my-4 text-white-50">
<div class="row align-items-center">
<div id="footer">&copy; Stonehedge Community Homeowners Association 2010-<script>document.write( new Date().getFullYear() );</script>. All rights reserved | Developed by <a href="https://aimloperations.com">AI ML Operations, LLC</a>
<div id="footer">
<p>&copy; Stonehedge Community Homeowners Association 2010-<script>document.write( new Date().getFullYear() );</script>. All rights reserved </p>
<p> Developed by <a href="https://aimloperations.com">AI ML Operations, LLC</a></p>
</div>
</div>
</footer>

View File

@@ -53,7 +53,11 @@
<img src="images/amenities.jpg" class="card-img-top" alt="Community Amenities" style="height: 200px; object-fit: cover;">
<div class="card-body">
<h5 class="card-title">Amenities</h5>
<p class="card-text">Our community features a swimming pool, playground, walking trails, and clubhouse available for resident use.</p>
<ul class="list-group list-group-flush mb-3">
<li class="list-group-item"><i class="bi bi-check text-success me-2"></i>Multiple Social Events</li>
<li class="list-group-item"><i class="bi bi-check text-success me-2"></i>Playground</li>
<li class="list-group-item"><i class="bi bi-check text-success me-2"></i>Picnic Tables</li>
</ul>
</div>
</div>
</div>
@@ -61,7 +65,7 @@
<div class="card h-100 shadow-sm">
<img src="images/board.jpg" class="card-img-top" alt="HOA Board" style="height: 200px; object-fit: cover;">
<div class="card-body">
<h5 class="card-title">HOA Board</h5>
<h5 class="card-title"><a href="{% url 'scha_board2' %}">HOA Board</a></h5>
<p class="card-text">Meet our elected board members who volunteer their time to maintain and improve our neighborhood.</p>
</div>
</div>
@@ -79,85 +83,6 @@
</div>
</section>
<!-- News Section -->
<section id="news" class="py-5 bg-success bg-opacity-10">
<div class="container">
<h2 class="text-center text-success mb-5">Community News & Events</h2>
<div class="row g-4">
<div class="col-md-6">
<div class="card h-100 shadow-sm">
<div class="card-body">
<h5 class="card-title">Annual Community Picnic</h5>
<p class="card-text">Join us on June 15th for our annual community picnic at the clubhouse. Food, games, and fun for the whole family!</p>
</div>
<div class="card-footer bg-transparent border-0">
<a href="#" class="btn btn-outline-success">RSVP Now</a>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100 shadow-sm">
<div class="card-body">
<h5 class="card-title">Landscaping Updates</h5>
<p class="card-text">New landscaping will be installed in common areas beginning next month. Expect temporary parking restrictions.</p>
</div>
<div class="card-footer bg-transparent border-0">
<a href="#" class="btn btn-outline-success">View Schedule</a>
</div>
</div>
</div>
</div>
<div class="text-center mt-4">
<a href="#" class="btn btn-success px-4">View All News</a>
</div>
</div>
</section>
<!-- Documents Section -->
<section id="documents" class="py-5">
<div class="container">
<h2 class="text-center text-success mb-5">Community Documents</h2>
<div class="row g-4">
<div class="col-md-4">
<div class="card h-100 shadow-sm">
<div class="card-header bg-success text-white">
<h5 class="mb-0">Governing Documents</h5>
</div>
<div class="list-group list-group-flush">
<a href="#" class="list-group-item list-group-item-action">CC&Rs</a>
<a href="#" class="list-group-item list-group-item-action">Bylaws</a>
<a href="#" class="list-group-item list-group-item-action">Articles of Incorporation</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 shadow-sm">
<div class="card-header bg-success text-white">
<h5 class="mb-0">Meeting Minutes</h5>
</div>
<div class="list-group list-group-flush">
<a href="#" class="list-group-item list-group-item-action">2023 Meetings</a>
<a href="#" class="list-group-item list-group-item-action">2022 Meetings</a>
<a href="#" class="list-group-item list-group-item-action">Archive</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 shadow-sm">
<div class="card-header bg-success text-white">
<h5 class="mb-0">Forms</h5>
</div>
<div class="list-group list-group-flush">
<a href="#" class="list-group-item list-group-item-action">Architectural Request</a>
<a href="#" class="list-group-item list-group-item-action">Complaint Form</a>
<a href="#" class="list-group-item list-group-item-action">Resale Certificate Request</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Contact Section -->
<!-- <section id="contact" class="py-5 bg-success bg-opacity-10">
<div class="container">

View File

@@ -0,0 +1,118 @@
{% extends 'schasite/authenticated_base.html' %}
{% load static %}
{% block pagetitle %}
<title>Dashboard | SCHA</title>
{% endblock %}
{% block content %}
<main class="py-5">
<div class="container">
<div class="row mb-4">
<div class="col-12">
<h1 class="display-6">Member Dashboard</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item active" aria-current="page">Home</li>
</ol>
</nav>
</div>
</div>
<div class="row g-4">
<!-- Welcome Card -->
<div class="col-md-6">
<div class="card shadow-sm h-100">
<div class="card-header bg-success text-white">
<h3 class="h5 mb-0"><i class="bi bi-house-door me-2"></i>Welcome</h3>
</div>
<div class="card-body">
<h4 class="card-title">Hello, John Doe!</h4>
<p class="card-text">Welcome to your Greenwood Estates member portal. From here you can access community resources, connect with neighbors, and stay informed.</p>
<div class="alert alert-success">
<i class="bi bi-info-circle-fill me-2"></i>
Your membership is active through December 31, 2024.
</div>
</div>
</div>
</div>
<!-- Quick Links -->
<div class="col-md-6">
<div class="card shadow-sm h-100">
<div class="card-header bg-success text-white">
<h3 class="h5 mb-0"><i class="bi bi-lightning me-2"></i>Quick Actions</h3>
</div>
<div class="card-body">
<div class="row g-3">
<div class="col-sm-6">
<a href="directory.html" class="btn btn-outline-success w-100 py-3">
<i class="bi bi-people display-6 d-block mb-2"></i>
Member Directory
</a>
</div>
<div class="col-sm-6">
<a href="posts/" class="btn btn-outline-success w-100 py-3">
<i class="bi bi-chat-square-text display-6 d-block mb-2"></i>
Community Posts
</a>
</div>
<div class="col-sm-6">
<a href="posts/create.html" class="btn btn-outline-success w-100 py-3">
<i class="bi bi-plus-circle display-6 d-block mb-2"></i>
Create Post
</a>
</div>
<div class="col-sm-6">
<a href="#" class="btn btn-outline-success w-100 py-3">
<i class="bi bi-calendar-event display-6 d-block mb-2"></i>
View Calendar
</a>
</div>
</div>
</div>
</div>
</div>
<!-- Recent Activity -->
<div class="col-12">
<div class="card shadow-sm">
<div class="card-header bg-success text-white">
<h3 class="h5 mb-0"><i class="bi bi-activity me-2"></i>Recent Community Activity</h3>
</div>
<div class="card-body">
<div class="list-group">
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">Annual Picnic Scheduled</h5>
<small>3 days ago</small>
</div>
<p class="mb-1">The community picnic is scheduled for June 15th. RSVP now!</p>
<small>Posted by Sarah Johnson</small>
</a>
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">Landscaping Update</h5>
<small>1 week ago</small>
</div>
<p class="mb-1">New flowers planted in common areas. Come see the improvements!</p>
<small>Posted by Robert Wilson</small>
</a>
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">Neighborhood Watch Meeting</h5>
<small>2 weeks ago</small>
</div>
<p class="mb-1">Next meeting scheduled for May 10th at the clubhouse.</p>
<small>Posted by Michael Brown</small>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
{% endblock %}
{% block extra_js %}
{% endblock %}

View File

@@ -0,0 +1,229 @@
{% extends 'schasite/authenticated_base.html' %}
{% load static %}
{% block pagetitle %}
<title>Directory | SCHA</title>
{% endblock %}
{% block content %}
<main class="py-5">
<div class="container">
<div class="row mb-4">
<div class="col-12">
<h1 class="display-6">Member Directory</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
<li class="breadcrumb-item active" aria-current="page">Directory</li>
</ol>
</nav>
</div>
</div>
<div class="row mb-4">
<div class="col-md-6 mb-3 mb-md-0">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-search"></i></span>
<input type="text" class="form-control" placeholder="Search members..." id="directorySearch">
</div>
</div>
<div class="col-md-6">
<div class="input-group">
<span class="input-group-text">Filter</span>
<select class="form-select" id="directoryFilter">
<option selected>All Members</option>
<option>Committee Members</option>
<option>Board Members</option>
<option>By Street</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card shadow-sm">
<div class="card-header bg-success text-white">
<div class="d-flex justify-content-between align-items-center">
<h3 class="h5 mb-0"><i class="bi bi-people-fill me-2"></i>Community Members</h3>
<span class="badge bg-light text-success">142 Members</span>
</div>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="table-success">
<tr>
<th>Name</th>
<th>Address</th>
<th>Contact</th>
<th>Committees</th>
<th>Services</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="d-flex align-items-center">
<div class="flex-shrink-0">
<div class="bg-success bg-opacity-10 rounded-circle d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
<i class="bi bi-person-fill text-success"></i>
</div>
</div>
<div class="flex-grow-1 ms-3">
<h6 class="mb-0">John & Sarah Smith</h6>
<small class="text-muted">Lot #42</small>
</div>
</div>
</td>
<td>123 Oak Drive</td>
<td>
<a href="mailto:john.smith@example.com" class="text-decoration-none"><i class="bi bi-envelope me-1"></i>Email</a><br>
<a href="tel:5551234567" class="text-decoration-none"><i class="bi bi-telephone me-1"></i>555-123-4567</a>
</td>
<td>
<span class="badge bg-success bg-opacity-10 text-success mb-1">Social Committee</span>
<span class="badge bg-success bg-opacity-10 text-success">Welcoming</span>
</td>
<td>
<span class="badge bg-info bg-opacity-10 text-info">Pet Care</span>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center">
<div class="flex-shrink-0">
<div class="bg-success bg-opacity-10 rounded-circle d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
<i class="bi bi-person-fill text-success"></i>
</div>
</div>
<div class="flex-grow-1 ms-3">
<h6 class="mb-0">Robert Wilson</h6>
<small class="text-muted">Lot #18</small>
</div>
</div>
</td>
<td>456 Maple Street</td>
<td>
<a href="mailto:rwilson@example.com" class="text-decoration-none"><i class="bi bi-envelope me-1"></i>Email</a><br>
<a href="tel:5559876543" class="text-decoration-none"><i class="bi bi-telephone me-1"></i>555-987-6543</a>
</td>
<td>
<span class="badge bg-success bg-opacity-10 text-success mb-1">Architectural</span>
<span class="badge bg-success bg-opacity-10 text-success">Board</span>
</td>
<td>
<span class="badge bg-info bg-opacity-10 text-info">Lawn Mowing</span>
<span class="badge bg-info bg-opacity-10 text-info">Snow Shoveling</span>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center">
<div class="flex-shrink-0">
<div class="bg-success bg-opacity-10 rounded-circle d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
<i class="bi bi-person-fill text-success"></i>
</div>
</div>
<div class="flex-grow-1 ms-3">
<h6 class="mb-0">Emily Davis</h6>
<small class="text-muted">Lot #75</small>
</div>
</div>
</td>
<td>789 Pine Road</td>
<td>
<a href="mailto:emily.d@example.com" class="text-decoration-none"><i class="bi bi-envelope me-1"></i>Email</a><br>
<a href="tel:5554567890" class="text-decoration-none"><i class="bi bi-telephone me-1"></i>555-456-7890</a>
</td>
<td>
<span class="badge bg-success bg-opacity-10 text-success mb-1">Communications</span>
</td>
<td>
<span class="badge bg-info bg-opacity-10 text-info">Babysitting</span>
<span class="badge bg-info bg-opacity-10 text-info">House Sitting</span>
</td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center">
<div class="flex-shrink-0">
<div class="bg-success bg-opacity-10 rounded-circle d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
<i class="bi bi-person-fill text-success"></i>
</div>
</div>
<div class="flex-grow-1 ms-3">
<h6 class="mb-0">Michael & Lisa Brown</h6>
<small class="text-muted">Lot #33</small>
</div>
</div>
</td>
<td>321 Elm Avenue</td>
<td>
<a href="mailto:mbrown@example.com" class="text-decoration-none"><i class="bi bi-envelope me-1"></i>Email</a><br>
<a href="tel:5557890123" class="text-decoration-none"><i class="bi bi-telephone me-1"></i>555-789-0123</a>
</td>
<td>
<span class="badge bg-success bg-opacity-10 text-success mb-1">Landscape</span>
<span class="badge bg-success bg-opacity-10 text-success">Safety</span>
</td>
<td>
<span class="badge bg-info bg-opacity-10 text-info">Other (Handyman)</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card-footer">
<nav aria-label="Directory navigation">
<ul class="pagination justify-content-center mb-0">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">Previous</a>
</li>
<li class="page-item active"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item">
<a class="page-link" href="#">Next</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</main>
{% endblock %}
{% block extra_js %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Search functionality
const searchInput = document.getElementById('directorySearch');
const tableRows = document.querySelectorAll('tbody tr');
searchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase();
tableRows.forEach(row => {
const rowText = row.textContent.toLowerCase();
if (rowText.includes(searchTerm)) {
row.style.display = '';
} else {
row.style.display = 'none';
}
});
});
// Filter functionality
const filterSelect = document.getElementById('directoryFilter');
filterSelect.addEventListener('change', function() {
const filterValue = this.value;
// In a real implementation, this would filter the directory
console.log('Filter by:', filterValue);
});
});
</script>
{% endblock %}

View File

@@ -0,0 +1,47 @@
{% extends 'schasite/base2.html' %}
{% load static %}
{% block pagetitle %}
<title>Password Reset | SCHA</title>
{% endblock %}
{% block content %}
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-md-8 col-lg-6">
<div class="card shadow-sm">
<div class="card-header bg-success text-white text-center">
<h2><i class="bi bi-key me-2"></i>Reset Password</h2>
</div>
<div class="card-body p-4">
<form id="resetForm" class="needs-validation" novalidate>
<div class="mb-4 text-center">
<p>Enter your email address and we'll send you a link to reset your password.</p>
</div>
<div class="mb-3">
<label for="resetEmail" class="form-label">Email Address</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-envelope"></i></span>
<input type="email" class="form-control" id="resetEmail" required>
<div class="invalid-feedback">
Please provide a valid email address.
</div>
</div>
</div>
<div class="d-grid gap-2">
<button type="submit" class="btn btn-success">
<i class="bi bi-send me-2"></i>Send Reset Link
</button>
</div>
</form>
</div>
<div class="card-footer text-center">
<a href="login.html" class="text-decoration-none"><i class="bi bi-arrow-left me-1"></i>Back to Login</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,127 @@
{% extends 'schasite/base2.html' %}
{% load static %}
{% block pagetitle %}
<title>Set Password | SCHA</title>
{% endblock %}
{% block content %}
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-md-8 col-lg-6">
<div class="card shadow-sm">
<div class="card-header bg-success text-white text-center">
<h2><i class="bi bi-key me-2"></i>Set New Password</h2>
</div>
<div class="card-body p-4">
<form id="passwordForm" class="needs-validation" novalidate>
<div class="mb-3">
<label for="newPassword" class="form-label">New Password</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-lock"></i></span>
<input type="password" class="form-control" id="newPassword" required
pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}">
<button class="btn btn-outline-secondary" type="button" id="toggleNewPassword">
<i class="bi bi-eye"></i>
</button>
<div class="invalid-feedback">
Password must contain at least 8 characters with uppercase, lowercase, and a number.
</div>
</div>
<div class="form-text">
<small>Must be at least 8 characters with uppercase, lowercase, and a number.</small>
</div>
</div>
<div class="mb-4">
<label for="confirmPassword" class="form-label">Confirm Password</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-lock"></i></span>
<input type="password" class="form-control" id="confirmPassword" required>
<button class="btn btn-outline-secondary" type="button" id="toggleConfirmPassword">
<i class="bi bi-eye"></i>
</button>
<div class="invalid-feedback">
Passwords must match.
</div>
</div>
</div>
<div class="d-grid gap-2">
<button type="submit" class="btn btn-success">
<i class="bi bi-check-circle me-2"></i>Set Password
</button>
</div>
</form>
</div>
<div class="card-footer text-center">
<a href="login.html" class="text-decoration-none"><i class="bi bi-arrow-left me-1"></i>Back to Login</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Toggle password visibility
const toggleNewPassword = document.getElementById('toggleNewPassword');
const newPasswordInput = document.getElementById('newPassword');
const toggleConfirmPassword = document.getElementById('toggleConfirmPassword');
const confirmPasswordInput = document.getElementById('confirmPassword');
toggleNewPassword.addEventListener('click', function() {
const type = newPasswordInput.getAttribute('type') === 'password' ? 'text' : 'password';
newPasswordInput.setAttribute('type', type);
this.innerHTML = type === 'password' ? '<i class="bi bi-eye"></i>' : '<i class="bi bi-eye-slash"></i>';
});
toggleConfirmPassword.addEventListener('click', function() {
const type = confirmPasswordInput.getAttribute('type') === 'password' ? 'text' : 'password';
confirmPasswordInput.setAttribute('type', type);
this.innerHTML = type === 'password' ? '<i class="bi bi-eye"></i>' : '<i class="bi bi-eye-slash"></i>';
});
// Form validation
const form = document.getElementById('passwordForm');
form.addEventListener('submit', function(event) {
event.preventDefault();
event.stopPropagation();
// Check if passwords match
if (newPasswordInput.value !== confirmPasswordInput.value) {
confirmPasswordInput.setCustomValidity("Passwords must match");
} else {
confirmPasswordInput.setCustomValidity("");
}
if (form.checkValidity()) {
// In a real implementation, this would update the password
alert('Password successfully updated (simulated)');
window.location.href = "login.html";
}
form.classList.add('was-validated');
}, false);
// Live password validation
newPasswordInput.addEventListener('input', function() {
if (this.value !== confirmPasswordInput.value) {
confirmPasswordInput.setCustomValidity("Passwords must match");
} else {
confirmPasswordInput.setCustomValidity("");
}
});
confirmPasswordInput.addEventListener('input', function() {
if (this.value !== newPasswordInput.value) {
this.setCustomValidity("Passwords must match");
} else {
this.setCustomValidity("");
}
});
});
</script>
{% endblock %}

View File

@@ -0,0 +1,66 @@
{% extends 'schasite/base2.html' %}
{% load static %}
{% block pagetitle %}
<title>Login | SCHA</title>
{% endblock %}
{% block content %}
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-md-8 col-lg-6">
<div class="card shadow-sm">
<div class="card-header bg-success text-white text-center">
<h2><i class="bi bi-shield-lock me-2"></i>Member Login</h2>
</div>
<div class="card-body p-4">
<form id="loginForm" class="needs-validation" novalidate>
<div class="mb-3">
<label for="loginEmail" class="form-label">Email Address</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-envelope"></i></span>
<input type="email" class="form-control" id="loginEmail" required>
<div class="invalid-feedback">
Please provide a valid email address.
</div>
</div>
</div>
<div class="mb-3">
<label for="loginPassword" class="form-label">Password</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-key"></i></span>
<input type="password" class="form-control" id="loginPassword" required>
<button class="btn btn-outline-secondary" type="button" id="togglePassword">
<i class="bi bi-eye"></i>
</button>
<div class="invalid-feedback">
Please enter your password.
</div>
</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="rememberMe">
<label class="form-check-label" for="rememberMe">Remember me</label>
</div>
<div class="d-grid gap-2">
<button type="submit" class="btn btn-success">
<i class="bi bi-box-arrow-in-right me-2"></i>Sign In
</button>
</div>
<div class="mt-3 text-center">
<a href="reset-password.html" class="text-decoration-none">Forgot password?</a>
</div>
</form>
</div>
<div class="card-footer text-center text-muted">
Not a member? <a href="../../membership.html" class="text-success">Join our community</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -1,8 +1,21 @@
from django.urls import path
from django.conf import settings
from . import views
urlpatterns = [
if settings.DEBUG:
authenticated_views = [
path('login/',views.login, name="login"),
path('set_password/',views.set_password, name="set_password"),
path('password_reset/',views.password_reset, name="password_reset"),
path('directory/',views.member_directory, name="directory"),
path('dashboard/',views.member_dashboard, name="dashboard"),
]
else:
authenticated_views = []
urlpatterns = authenticated_views + [
# path("", views.index, name="index"),
# path("useful_links", views.useful_links, name="useful_links"),
# path("about_us", views.about_us, name="about_us"),
@@ -23,4 +36,9 @@ urlpatterns = [
# stripe specific urls below
path("config/", views.stripe_config),
path("create-checkout-session/", views.create_checkout_session),
# authenticated views
]

View File

@@ -459,3 +459,34 @@ def membership_form(request):
def scha_board(request):
return render(request, "schasite/scha_board.html", {})
def login(request):
if request.method == "POST":
raise NotImplementedError()
else:
return render(request, "schasite/signin.html",{})
def password_reset(request):
if request.method == "POST":
raise NotImplementedError()
else:
return render(request, "schasite/password_reset.html",{})
def set_password(request):
if request.method == "POST":
raise NotImplementedError()
else:
return render(request, "schasite/set_password.html",{})
def member_directory(request):
if request.method == "POST":
raise NotImplementedError()
else:
return render(request, "schasite/member_directory.html",{})
def member_dashboard(request):
if request.method == "POST":
raise NotImplementedError()
else:
return render(request, "schasite/member_dashboard.html",{})