Updates to the main page

This commit is contained in:
2025-04-22 11:46:55 -05:00
parent 4c0605474c
commit 0e1ddbcf1a
14 changed files with 1493 additions and 60 deletions

View File

@@ -2,6 +2,7 @@ from django import forms
from django.forms import ModelForm from django.forms import ModelForm
from .models import ( from .models import (
Membership, Membership,
CommunityPost,
AddressModel1, AddressModel1,
MembershipPerson, MembershipPerson,
MembershipCommittee, MembershipCommittee,
@@ -38,6 +39,10 @@ class AddressForm(ModelForm):
model = AddressModel1 model = AddressModel1
fields = ["address_1", "address_2", "city", "state", "zip_code"] fields = ["address_1", "address_2", "city", "state", "zip_code"]
class CommunityPostForm(ModelForm):
class Meta:
model = CommunityPost
fields = ['title','category','content']
class PeopleForm(ModelForm): class PeopleForm(ModelForm):
phone_number = PhoneNumberField(required=False) phone_number = PhoneNumberField(required=False)

View File

@@ -0,0 +1,290 @@
# Generated by Django 5.2 on 2025-04-21 17:42
import datetime
import django.db.models.deletion
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("schasite", "0009_schaofficer_alter_payments_date"),
]
operations = [
migrations.CreateModel(
name="CommunityParks",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created", models.DateTimeField(default=django.utils.timezone.now)),
(
"last_modified",
models.DateTimeField(default=django.utils.timezone.now),
),
("name", models.CharField(max_length=255)),
("distance", models.DecimalField(decimal_places=1, max_digits=3)),
("description", models.CharField(max_length=1024)),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="CommunityPost",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created", models.DateTimeField(default=django.utils.timezone.now)),
(
"last_modified",
models.DateTimeField(default=django.utils.timezone.now),
),
("title", models.CharField(max_length=255)),
("category", models.CharField(max_length=255)),
("content", models.CharField(max_length=8192)),
("likes", models.IntegerField(default=0)),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="CommunitySchools",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created", models.DateTimeField(default=django.utils.timezone.now)),
(
"last_modified",
models.DateTimeField(default=django.utils.timezone.now),
),
("name", models.CharField(max_length=255)),
("name_school_url", models.URLField(max_length=256)),
("rating_url", models.URLField(max_length=256)),
("rating", models.DecimalField(decimal_places=2, max_digits=5)),
("distance", models.DecimalField(decimal_places=1, max_digits=3)),
("principal", models.CharField(max_length=255)),
("grades", models.CharField(max_length=255)),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="CommunityShoppingAndDining",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created", models.DateTimeField(default=django.utils.timezone.now)),
(
"last_modified",
models.DateTimeField(default=django.utils.timezone.now),
),
("name", models.CharField(max_length=255)),
("distance", models.DecimalField(decimal_places=1, max_digits=3)),
("description", models.CharField(max_length=1024)),
],
options={
"abstract": False,
},
),
migrations.AddField(
model_name="addressmodel1",
name="created",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="addressmodel1",
name="last_modified",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="calendarevent",
name="created",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="calendarevent",
name="last_modified",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="calendareventaddressmodel",
name="created",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="calendareventaddressmodel",
name="last_modified",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="membership",
name="created",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="membership",
name="last_modified",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="membershipcommittee",
name="created",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="membershipcommittee",
name="last_modified",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="membershipperson",
name="created",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="membershipperson",
name="last_modified",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="membershipservices",
name="created",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="membershipservices",
name="last_modified",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="payments",
name="created",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="payments",
name="last_modified",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="schaofficer",
name="created",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="schaofficer",
name="last_modified",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="usefullinks",
name="created",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name="usefullinks",
name="last_modified",
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AlterField(
model_name="payments",
name="date",
field=models.DateField(
default=datetime.datetime(
2025, 4, 21, 17, 42, 47, 893058, tzinfo=datetime.timezone.utc
)
),
),
migrations.CreateModel(
name="CommunityComment",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created", models.DateTimeField(default=django.utils.timezone.now)),
(
"last_modified",
models.DateTimeField(default=django.utils.timezone.now),
),
("content", models.CharField(max_length=8192)),
("likes", models.IntegerField(default=0)),
(
"post",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="schasite.communitypost",
),
),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="CommunityPostReports",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created", models.DateTimeField(default=django.utils.timezone.now)),
(
"last_modified",
models.DateTimeField(default=django.utils.timezone.now),
),
(
"post",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="schasite.communitypost",
),
),
],
options={
"abstract": False,
},
),
]

View File

@@ -3,14 +3,29 @@ from phonenumber_field.modelfields import PhoneNumberField
import datetime import datetime
from django.utils import timezone from django.utils import timezone
class TimeInfoBase(models.Model):
created = models.DateTimeField(default=timezone.now)
last_modified = models.DateTimeField(default=timezone.now)
class Meta:
abstract = True
def save(self, *args, **kwargs):
if not kwargs.pop("skip_last_modified", False) and not hasattr(self, "skip_last_modified"):
self.last_modified = timezone.now()
if kwargs.get("update_fields") is not None:
kwargs["update_fields"] = list({*kwargs["update_fields"], "last_modified"})
super().save(*args, **kwargs)
# Create your models here. # Create your models here.
class UsefulLinks(models.Model): class UsefulLinks(TimeInfoBase):
name = models.CharField(max_length=256) name = models.CharField(max_length=256)
url = models.CharField(max_length=256) url = models.CharField(max_length=256)
class Membership(models.Model): class Membership(TimeInfoBase):
children = models.CharField(max_length=256, default="", blank=True, null=True) children = models.CharField(max_length=256, default="", blank=True, null=True)
def get_address_str(self): def get_address_str(self):
@@ -37,7 +52,7 @@ class Membership(models.Model):
return self.get_address_str() + " | " + self.get_person_1() return self.get_address_str() + " | " + self.get_person_1()
class AddressModel1(models.Model): class AddressModel1(TimeInfoBase):
membership = models.OneToOneField(Membership, on_delete=models.CASCADE) membership = models.OneToOneField(Membership, on_delete=models.CASCADE)
address_1 = models.CharField(max_length=128) address_1 = models.CharField(max_length=128)
address_2 = models.CharField(max_length=128, blank=True) address_2 = models.CharField(max_length=128, blank=True)
@@ -46,7 +61,7 @@ class AddressModel1(models.Model):
zip_code = models.CharField(max_length=5) zip_code = models.CharField(max_length=5)
class CalendarEvent(models.Model): class CalendarEvent(TimeInfoBase):
event_name = models.CharField(max_length=256) event_name = models.CharField(max_length=256)
start_date = models.DateField(blank=True, null=True) start_date = models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True) end_date = models.DateField(blank=True, null=True)
@@ -75,7 +90,7 @@ class CalendarEvent(models.Model):
return not self.has_date() return not self.has_date()
class CalendarEventAddressModel(models.Model): class CalendarEventAddressModel(TimeInfoBase):
calendar_event = models.OneToOneField(CalendarEvent, on_delete=models.CASCADE) calendar_event = models.OneToOneField(CalendarEvent, on_delete=models.CASCADE)
address_1 = models.CharField(max_length=128) address_1 = models.CharField(max_length=128)
address_2 = models.CharField(max_length=128, blank=True) address_2 = models.CharField(max_length=128, blank=True)
@@ -89,7 +104,7 @@ class CalendarEventAddressModel(models.Model):
) )
class MembershipPerson(models.Model): class MembershipPerson(TimeInfoBase):
membership = models.ForeignKey( membership = models.ForeignKey(
Membership, on_delete=models.CASCADE, blank=True, null=True Membership, on_delete=models.CASCADE, blank=True, null=True
) )
@@ -102,7 +117,7 @@ class MembershipPerson(models.Model):
return self.email if self.email else "No email" return self.email if self.email else "No email"
class MembershipCommittee(models.Model): class MembershipCommittee(TimeInfoBase):
membership = models.OneToOneField(Membership, on_delete=models.CASCADE) membership = models.OneToOneField(Membership, on_delete=models.CASCADE)
block_captain = models.BooleanField(default=False, blank=True, null=True) block_captain = models.BooleanField(default=False, blank=True, null=True)
coordinator = models.BooleanField(default=False, blank=True, null=True) coordinator = models.BooleanField(default=False, blank=True, null=True)
@@ -119,7 +134,7 @@ class MembershipCommittee(models.Model):
no_preference = models.BooleanField(default=False, blank=True, null=True) no_preference = models.BooleanField(default=False, blank=True, null=True)
class MembershipServices(models.Model): class MembershipServices(TimeInfoBase):
membership = models.OneToOneField(Membership, on_delete=models.CASCADE) membership = models.OneToOneField(Membership, on_delete=models.CASCADE)
babysitting = models.BooleanField(default=False, blank=True, null=True) babysitting = models.BooleanField(default=False, blank=True, null=True)
lawn_mowing = models.BooleanField(default=False, blank=True, null=True) lawn_mowing = models.BooleanField(default=False, blank=True, null=True)
@@ -131,7 +146,7 @@ class MembershipServices(models.Model):
other_desc = models.CharField(default="", blank=True, null=True, max_length=256) other_desc = models.CharField(default="", blank=True, null=True, max_length=256)
class Payments(models.Model): class Payments(TimeInfoBase):
date = models.DateField(default=timezone.now()) date = models.DateField(default=timezone.now())
status = models.CharField(default="Completed", max_length=256) status = models.CharField(default="Completed", max_length=256)
email = models.EmailField(blank=True, null=True) email = models.EmailField(blank=True, null=True)
@@ -140,26 +155,45 @@ class Payments(models.Model):
) )
class SCHAOfficer(models.Model): class SCHAOfficer(TimeInfoBase):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
position = models.CharField(max_length=255) position = models.CharField(max_length=255)
email = models.EmailField(max_length=255) email = models.EmailField(max_length=255)
# class CommunitySchools(models.Model): ### NOT USED YET ###
# name = models.CharField(max_length=255)
# name_school_url = models.URLField(max_length=256)
# rating_url = models.URLField(max_length=256)
# rating = models.DecimalField(max_digits=5, decimal_places=2)
# distance = models.DecimalField(max_digits=3, decimal_places=1)
# principal = models.CharField(max_length=255)
# grades = models.CharField(max_length=255)
# class CommunityShoppingAndDining(models.Model): class CommunitySchools(TimeInfoBase):
# name = models.CharField(max_length=255) name = models.CharField(max_length=255)
# distance = models.DecimalField(max_digits=3, decimal_places=1) name_school_url = models.URLField(max_length=256)
# description = models.CharField(max_length=1024) rating_url = models.URLField(max_length=256)
rating = models.DecimalField(max_digits=5, decimal_places=2)
distance = models.DecimalField(max_digits=3, decimal_places=1)
principal = models.CharField(max_length=255)
grades = models.CharField(max_length=255)
# class CommunityParks(models.Model): class CommunityShoppingAndDining(TimeInfoBase):
# name = models.CharField(max_length=255) name = models.CharField(max_length=255)
# distance = models.DecimalField(max_digits=3, decimal_places=1) distance = models.DecimalField(max_digits=3, decimal_places=1)
# description = models.CharField(max_length=1024) description = models.CharField(max_length=1024)
class CommunityParks(TimeInfoBase):
name = models.CharField(max_length=255)
distance = models.DecimalField(max_digits=3, decimal_places=1)
description = models.CharField(max_length=1024)
class CommunityPost(TimeInfoBase):
title = models.CharField(max_length=255)
category = models.CharField(max_length=255)
content = models.CharField(max_length=1024*8)
likes = models.IntegerField(default=0)
class CommunityPostReports(TimeInfoBase):
post = models.ForeignKey(CommunityPost, on_delete=models.CASCADE)
# user = something
class CommunityComment(TimeInfoBase):
post = models.ForeignKey(CommunityPost, on_delete=models.CASCADE)
content = models.CharField(max_length=1024*8)
likes = models.IntegerField(default=0)

View File

@@ -13,25 +13,74 @@
<!-- Custom CSS --> <!-- Custom CSS -->
<link href="{% static 'css/style2.css' %}" rel="stylesheet" type="text/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> <script async defer src="https://tianji.aimloperations.com/tracker.js" data-website-id="cm9qziuid9vr7v6dtdbnx8406"></script>
<script type="text/css">
.bg-light {
background-color: #f8f9fa!important;
}
.auth-card {
max-width: 500px;
margin: 0 auto;
}
/* Member Portal */
.member-navbar {
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.member-navbar .nav-link {
padding: 0.5rem 1rem;
}
/* Directory */
.directory-table th {
white-space: nowrap;
}
/* Posts */
.post-card {
transition: transform 0.2s ease;
}
.post-card:hover {
transform: translateY(-2px);
}
.post-avatar {
width: 40px;
height: 40px;
}
/* Responsive adjustments */
@media (max-width: 767.98px) {
.member-navbar .navbar-nav {
margin-top: 1rem;
}
.directory-table {
font-size: 0.875rem;
}
}
</script>
</head> </head>
<body> <body>
<!-- Navigation --> <!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-success sticky-top"> <nav class="navbar navbar-expand-lg navbar-dark bg-success sticky-top">
<div class="container"> <div class="container">
<a class="navbar-brand" href="index.html">Greenwood Estates</a> <a class="navbar-brand" href="{% url 'index2' %}">Stonehedge Community Homeowners Association</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="collapse navbar-collapse" id="navbarNav"> <div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto"> <ul class="navbar-nav me-auto">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="index.html"><i class="bi bi-speedometer2 me-1"></i>Dashboard</a> <a class="nav-link" href="{% url 'dashboard' %}"><i class="bi bi-speedometer2 me-1"></i>Dashboard</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" href="directory.html"><i class="bi bi-people me-1"></i>Directory</a> <a class="nav-link active" href="{% url 'directory' %}"><i class="bi bi-people me-1"></i>Directory</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="posts/"><i class="bi bi-chat-square-text me-1"></i>Community Posts</a> <a class="nav-link" href="{% url 'posts' %}"><i class="bi bi-chat-square-text me-1"></i>Community Posts</a>
</li> </li>
</ul> </ul>
<ul class="navbar-nav"> <ul class="navbar-nav">
@@ -59,8 +108,8 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<h5 class="text-uppercase">Greenwood Estates HOA</h5> <h5 class="text-uppercase mb-4">Stonehedge Community Homeowners Association</h5>
<p class="text-white-50">1234 Greenwood Lane<br>Anytown, ST 12345</p> <p class="text-white-50">1900 Spring Rd. #200<br>Oak Brook, IL 60523</p>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<h5 class="text-uppercase">Quick Links</h5> <h5 class="text-uppercase">Quick Links</h5>

View File

@@ -61,7 +61,7 @@
<div class="row"> <div class="row">
<div class="col-lg-6 mb-4 mb-lg-0"> <div class="col-lg-6 mb-4 mb-lg-0">
<h5 class="text-uppercase mb-4">Stonehedge Community Homeowners Association</h5> <h5 class="text-uppercase mb-4">Stonehedge Community Homeowners Association</h5>
<p class="text-white-50">1234 Greenwood Lane<br>Anytown, ST 12345</p> <p class="text-white-50">1900 Spring Rd. #200<br>Oak Brook, IL 60523</p>
</div> </div>
<div class="col-lg-4 offset-lg-2 mb-4 mb-lg-0"> <div class="col-lg-4 offset-lg-2 mb-4 mb-lg-0">
<h5 class="text-uppercase mb-4">Quick Links</h5> <h5 class="text-uppercase mb-4">Quick Links</h5>

View File

@@ -48,37 +48,39 @@
<div class="container"> <div class="container">
<h2 class="text-center text-success mb-5">About Our Community</h2> <h2 class="text-center text-success mb-5">About Our Community</h2>
<div class="row g-4"> <div class="row g-4">
<div class="col-md-4">
<div class="col-md-6">
<div class="card h-100 shadow-sm"> <div class="card h-100 shadow-sm">
<img src="images/amenities.jpg" class="card-img-top" alt="Community Amenities" style="height: 200px; object-fit: cover;">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Amenities</h5> <h5 class="card-title"><a href="{% url 'dues2' %}">Pay Dues</a></h5>
<ul class="list-group list-group-flush mb-3"> <p class="card-text">Make sure to pay your dues</p>
<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> </div>
</div> </div>
<div class="col-md-4"> <div class="col-md-6">
<div class="card h-100 shadow-sm">
<div class="card-body">
<h5 class="card-title"><a href="{% url 'membership_form2' %}">Join</a></h5>
<p class="card-text">Fill out the membership form and be added to the mailing list</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100 shadow-sm">
<div class="card-body">
<h5 class="card-title"><a href="{% url 'calendar2' %}">Events</a></h5>
<p class="card-text">Checkout out the upcoming and past events!</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100 shadow-sm"> <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"> <div class="card-body">
<h5 class="card-title"><a href="{% url 'scha_board2' %}">HOA Board</a></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> <p class="card-text">Meet our elected board members who volunteer their time to maintain and improve our neighborhood.</p>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-4">
<div class="card h-100 shadow-sm">
<img src="images/rules.jpg" class="card-img-top" alt="Community Rules" style="height: 200px; object-fit: cover;">
<div class="card-body">
<h5 class="card-title">Community Rules</h5>
<p class="card-text">Learn about our community guidelines designed to maintain property values and quality of life for all residents.</p>
</div>
</div>
</div>
</div> </div>
</div> </div>
</section> </section>

View File

@@ -46,29 +46,29 @@
<div class="card-body"> <div class="card-body">
<div class="row g-3"> <div class="row g-3">
<div class="col-sm-6"> <div class="col-sm-6">
<a href="directory.html" class="btn btn-outline-success w-100 py-3"> <a href="{% url 'directory' %}" class="btn btn-outline-success w-100 py-3">
<i class="bi bi-people display-6 d-block mb-2"></i> <i class="bi bi-people display-6 d-block mb-2"></i>
Member Directory Member Directory
</a> </a>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<a href="posts/" class="btn btn-outline-success w-100 py-3"> <a href="{% url 'posts' %}" class="btn btn-outline-success w-100 py-3">
<i class="bi bi-chat-square-text display-6 d-block mb-2"></i> <i class="bi bi-chat-square-text display-6 d-block mb-2"></i>
Community Posts Community Posts
</a> </a>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<a href="posts/create.html" class="btn btn-outline-success w-100 py-3"> <a href="{% url 'posts_create' %}" class="btn btn-outline-success w-100 py-3">
<i class="bi bi-plus-circle display-6 d-block mb-2"></i> <i class="bi bi-plus-circle display-6 d-block mb-2"></i>
Create Post Create Post
</a> </a>
</div> </div>
<div class="col-sm-6"> <!-- <div class="col-sm-6">
<a href="#" class="btn btn-outline-success w-100 py-3"> <a href="#" class="btn btn-outline-success w-100 py-3">
<i class="bi bi-calendar-event display-6 d-block mb-2"></i> <i class="bi bi-calendar-event display-6 d-block mb-2"></i>
View Calendar View Calendar
</a> </a>
</div> </div> -->
</div> </div>
</div> </div>
</div> </div>

View File

@@ -13,7 +13,7 @@
<h1 class="display-6">Member Directory</h1> <h1 class="display-6">Member Directory</h1>
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.html">Home</a></li> <li class="breadcrumb-item"><a href="{% url 'dashboard' %}">Home</a></li>
<li class="breadcrumb-item active" aria-current="page">Directory</li> <li class="breadcrumb-item active" aria-current="page">Directory</li>
</ol> </ol>
</nav> </nav>

View File

@@ -0,0 +1,166 @@
{% extends 'schasite/authenticated_base.html' %}
{% load static %}
{% block pagetitle %}
<title>Posts | 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">Community Posts</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'dashboard' %}">Home</a></li>
<li class="breadcrumb-item active" aria-current="page">Community Posts</li>
</ol>
</nav>
</div>
</div>
<div class="row mb-4">
<div class="col-md-8 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 posts...">
<button class="btn btn-success" type="button">Search</button>
</div>
</div>
<div class="col-md-4 text-md-end">
<a href="{% url 'posts_create' %}" class="btn btn-success">
<i class="bi bi-plus-circle me-2"></i>New Post
</a>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card shadow-sm mb-4">
<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-pin-angle me-2"></i>Pinned Post</h3>
<span class="badge bg-light text-success">Announcement</span>
</div>
</div>
<div class="card-body">
<div class="d-flex mb-3">
<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">
<h5 class="mb-1">Annual Community Picnic</h5>
<div class="d-flex flex-wrap text-muted small mb-2">
<div class="me-3"><i class="bi bi-person me-1"></i>Sarah Johnson</div>
<div class="me-3"><i class="bi bi-calendar me-1"></i>June 5, 2023</div>
<div><i class="bi bi-chat me-1"></i>12 comments</div>
</div>
</div>
</div>
<p class="card-text">Our annual community picnic is scheduled for Saturday, June 15th from 11am-3pm at the Greenwood Park. This year we'll have a bounce house, face painting, and a pie baking contest. Please RSVP by June 10th so we can plan for food quantities.</p>
<div class="mt-3">
<a href="#" class="btn btn-sm btn-outline-success me-2"><i class="bi bi-hand-thumbs-up me-1"></i>Like (24)</a>
<a href="#" class="btn btn-sm btn-outline-success"><i class="bi bi-chat me-1"></i>Comment</a>
</div>
</div>
</div>
{% for post in posts %}
<div class="card shadow-sm mb-4">
<div class="card-body">
<div class="d-flex mb-3">
<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">
<h5 class="mb-1"><a href="{% url 'posts_detail' post_id=post.id %}">{{ post.title }}</a></h5>
<div class="d-flex flex-wrap text-muted small mb-2">
<div class="me-3"><i class="bi bi-person me-1"></i>Emily Davis</div>
<div class="me-3"><i class="bi bi-calendar me-1"></i>June 3, 2023</div>
<div><i class="bi bi-chat me-1"></i>8 comments</div>
</div>
</div>
</div>
<p class="card-text">{{ post.content }}</p>
<div class="mt-3">
<a href="#" class="btn btn-sm btn-outline-success me-2"><i class="bi bi-hand-thumbs-up me-1"></i>Like (15)</a>
<a href="#" class="btn btn-sm btn-outline-success"><i class="bi bi-chat me-1"></i>Comment</a>
</div>
</div>
</div>
{% endfor %}
<div class="card shadow-sm mb-4">
<div class="card-body">
<div class="d-flex mb-3">
<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">
<h5 class="mb-1">Lost Dog - Please Help!</h5>
<div class="d-flex flex-wrap text-muted small mb-2">
<div class="me-3"><i class="bi bi-person me-1"></i>Emily Davis</div>
<div class="me-3"><i class="bi bi-calendar me-1"></i>June 3, 2023</div>
<div><i class="bi bi-chat me-1"></i>8 comments</div>
</div>
</div>
</div>
<p class="card-text">Our golden retriever Max got out of our yard this morning around 9am. He was last seen near the corner of Oak Drive and Maple Street. He's friendly, wearing a blue collar with our contact info. Please call me at 555-456-7890 if you see him!</p>
<div class="mt-3">
<a href="#" class="btn btn-sm btn-outline-success me-2"><i class="bi bi-hand-thumbs-up me-1"></i>Like (15)</a>
<a href="#" class="btn btn-sm btn-outline-success"><i class="bi bi-chat me-1"></i>Comment</a>
</div>
</div>
</div>
<div class="card shadow-sm mb-4">
<div class="card-body">
<div class="d-flex mb-3">
<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">
<h5 class="mb-1">Yard Sale This Weekend</h5>
<div class="d-flex flex-wrap text-muted small mb-2">
<div class="me-3"><i class="bi bi-person me-1"></i>Michael Brown</div>
<div class="me-3"><i class="bi bi-calendar me-1"></i>June 1, 2023</div>
<div><i class="bi bi-chat me-1"></i>5 comments</div>
</div>
</div>
</div>
<p class="card-text">We're having a yard sale at 321 Elm Avenue this Saturday from 8am-2pm. Lots of household items, kids' clothes, and furniture. Everything must go!</p>
<div class="mt-3">
<a href="#" class="btn btn-sm btn-outline-success me-2"><i class="bi bi-hand-thumbs-up me-1"></i>Like (7)</a>
<a href="#" class="btn btn-sm btn-outline-success"><i class="bi bi-chat me-1"></i>Comment</a>
</div>
</div>
</div>
<nav aria-label="Posts navigation">
<ul class="pagination justify-content-center">
<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>
</main>
{% endblock %}
{% block extra_js %}
{% endblock %}

View File

@@ -0,0 +1,124 @@
{% extends 'schasite/authenticated_base.html' %}
{% load static %}
{% block pagetitle %}
<title>Create Post | 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">Create New Post</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'dashboard' %}">Home</a></li>
<li class="breadcrumb-item"><a href="{% url 'posts' %}">Community Posts</a></li>
<li class="breadcrumb-item active" aria-current="page">Create Post</li>
</ol>
</nav>
</div>
</div>
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card shadow-sm">
<div class="card-header bg-success text-white">
<h3 class="h5 mb-0"><i class="bi bi-pencil me-2"></i>New Community Post</h3>
</div>
<div class="card-body">
<form id="createPostForm" method="POST" action='{% url "posts_create" %}' class="needs-validation" novalidate>
{% csrf_token %}
{% if community_post.errors %}
<div class="alert alert-danger">
<i class="bi bi-info-circle-fill me-2"></i>
<p> Need to fix the following errors</p>
{{ community_post.errors | safe }}
</div>
{% endif %}
<div class="mb-3">
<label for="title" class="form-label">Title*</label>
<input type="text" class="form-control" value='{{ community_post.title.value|default_if_none:"" }}' name="title" id="title" required>
<div class="invalid-feedback">
Please provide a title for your post.
</div>
</div>
<div class="mb-3">
<label for="category" class="form-label">Category*</label>
<select class="form-select" name="category" id="category" required>
<option value='{{ community_post.category.value|default_if_none:"" }}' selected disabled>Select a category</option>
<option>Announcement</option>
<option>Discussion</option>
<option>For Sale</option>
<option>Help Needed</option>
<option>Event</option>
<option>Other</option>
</select>
<div class="invalid-feedback">
Please select a category.
</div>
</div>
<div class="mb-3">
<label for="content" class="form-label">Content*</label>
<textarea class="form-control" value='{{ community_post.content.value|default_if_none:"" }}' name="content" id="content" rows="6" required></textarea>
<div class="invalid-feedback">
Please provide content for your post.
</div>
</div>
<div class="mb-3">
<label for="postImage" class="form-label">Image (optional)</label>
<input class="form-control" type="file" id="postImage" accept="image/*">
<div class="form-text">
Maximum file size: 5MB. Allowed formats: JPG, PNG, GIF.
</div>
</div>
<div class="mb-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="notifyMembers">
<label class="form-check-label" for="notifyMembers">
Notify all members via email about this post
</label>
</div>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<a href="posts_create" class="btn btn-outline-secondary me-md-2">Cancel</a>
<button type="submit" class="btn btn-success">Post to Community</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</main>
{% endblock %}
{% block extra_js %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Form validation
const form = document.getElementById('createPostForm');
form.addEventListener('submit', function(event) {
event.preventDefault();
event.stopPropagation();
if (form.checkValidity()) {
// In a real implementation, this would submit the post
alert('Post created successfully (simulated)');
window.location.href = "../index.html";
}
form.classList.add('was-validated');
}, false);
// Image preview functionality would go here
});
</script>
{% endblock %}

View File

@@ -0,0 +1,328 @@
{% extends 'schasite/authenticated_base.html' %}
{% load static %}
{% block pagetitle %}
<title>Posts | SCHA</title>
<script type="text/css">
.post-detail .card-header {
padding: 1rem 1.25rem;
}
.comment-list {
max-height: 500px;
overflow-y: auto;
padding-right: 0.5rem;
}
.comment-list::-webkit-scrollbar {
width: 8px;
}
.comment-list::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
.comment-list::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 10px;
}
.comment-list::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}
/* Responsive adjustments */
@media (max-width: 767.98px) {
.comment-list {
max-height: none;
}
.post-detail .card-header h3 {
font-size: 1.1rem;
}
}
/* Interaction buttons */
.btn-outline-success:hover .bi-hand-thumbs-up,
.text-success .bi-hand-thumbs-up {
fill: currentColor;
}
</script>
{% endblock %}
{% block content %}
<main class="py-5">
<div class="container">
<div class="row mb-4">
<div class="col-12">
<h1 class="display-6">Community Post</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="../../index.html">Home</a></li>
<li class="breadcrumb-item"><a href="../index.html">Community Posts</a></li>
<li class="breadcrumb-item active" aria-current="page">Post Details</li>
</ol>
</nav>
</div>
</div>
<div class="row justify-content-center">
<div class="col-lg-8">
<!-- Main Post Card -->
<div class="card shadow-sm mb-4">
<div class="card-header bg-success text-white">
<div class="d-flex justify-content-between align-items-center">
<h3 class="h5 mb-0">Annual Community Picnic</h3>
<span class="badge bg-light text-success">Announcement</span>
</div>
</div>
<div class="card-body">
<div class="d-flex mb-4">
<div class="flex-shrink-0">
<div class="bg-success bg-opacity-10 rounded-circle d-flex align-items-center justify-content-center" style="width: 50px; height: 50px;">
<i class="bi bi-person-fill text-success fs-4"></i>
</div>
</div>
<div class="flex-grow-1 ms-3">
<h5 class="mb-1">Sarah Johnson</h5>
<div class="d-flex flex-wrap text-muted small">
<div class="me-3"><i class="bi bi-calendar me-1"></i>Posted on June 5, 2023</div>
<div><i class="bi bi-chat me-1"></i>12 comments</div>
</div>
</div>
</div>
<div class="mb-4">
<img src="../../../images/events/picnic.jpg" alt="Community picnic" class="img-fluid rounded mb-3">
<p>Our annual community picnic is scheduled for <strong>Saturday, June 15th from 11am-3pm</strong> at the Greenwood Park. This is always one of our most popular events, bringing together neighbors of all ages for a day of fun and community building.</p>
<h5 class="mt-4">Event Details</h5>
<ul>
<li><strong>Date:</strong> June 15, 2024</li>
<li><strong>Time:</strong> 11:00 AM - 3:00 PM</li>
<li><strong>Location:</strong> Greenwood Community Park</li>
<li><strong>Address:</strong> 1234 Greenwood Lane, Anytown, ST</li>
<li><strong>RSVP Deadline:</strong> June 10, 2024</li>
</ul>
<h5 class="mt-4">What to Expect</h5>
<p>This year we're excited to offer:</p>
<ul>
<li>Bounce house and playground activities for kids</li>
<li>Face painting and balloon animals</li>
<li>Pie baking contest (sign up below!)</li>
<li>Potluck lunch (main dishes provided by HOA)</li>
<li>Live acoustic music from 1-3pm</li>
</ul>
<div class="alert alert-success mt-4">
<h5><i class="bi bi-info-circle me-2"></i>Volunteers Needed</h5>
<p>We're looking for volunteers to help with setup (10-11am), food service (11:30am-1:30pm), and cleanup (3-4pm). Please email me if you can help!</p>
</div>
</div>
<div class="d-flex justify-content-between align-items-center">
<div>
<button class="btn btn-sm btn-outline-success me-2">
<i class="bi bi-hand-thumbs-up me-1"></i>Like (24)
</button>
<button class="btn btn-sm btn-outline-success">
<i class="bi bi-share me-1"></i>Share
</button>
</div>
<div>
<a href="#" class="text-decoration-none text-success small">
<i class="bi bi-flag me-1"></i>Report
</a>
</div>
</div>
</div>
</div>
<!-- Comments Section -->
<div class="card shadow-sm mb-4">
<div class="card-header bg-success text-white">
<h3 class="h5 mb-0"><i class="bi bi-chat-square-text me-2"></i>Comments (12)</h3>
</div>
<div class="card-body">
<!-- Comment Form -->
<div class="mb-4">
<form>
<div class="mb-3">
<label for="commentText" class="form-label">Add a comment</label>
<textarea class="form-control" id="commentText" rows="3" placeholder="Share your thoughts..."></textarea>
</div>
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-success">Post Comment</button>
</div>
</form>
</div>
<hr>
<!-- Comment List -->
<div class="comment-list">
<!-- Comment 1 -->
<div class="d-flex mb-4">
<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">
<div class="d-flex justify-content-between align-items-center mb-1">
<h6 class="mb-0">Robert Wilson</h6>
<small class="text-muted">June 5, 2023 at 2:30 PM</small>
</div>
<p class="mb-2">Looking forward to it! I'll bring my famous potato salad. Can I sign up to help with setup?</p>
<div>
<a href="#" class="text-decoration-none text-success small me-3">
<i class="bi bi-hand-thumbs-up me-1"></i>Like (5)
</a>
<a href="#" class="text-decoration-none text-success small">
<i class="bi bi-reply me-1"></i>Reply
</a>
</div>
<!-- Reply -->
<div class="d-flex mt-3">
<div class="flex-shrink-0">
<div class="bg-success bg-opacity-10 rounded-circle d-flex align-items-center justify-content-center" style="width: 32px; height: 32px;">
<i class="bi bi-person-fill text-success small"></i>
</div>
</div>
<div class="flex-grow-1 ms-3">
<div class="d-flex justify-content-between align-items-center mb-1">
<h6 class="mb-0">Sarah Johnson</h6>
<small class="text-muted">June 5, 2023 at 3:15 PM</small>
</div>
<p class="mb-2">That would be great Robert! I'll put you down for setup crew.</p>
<div>
<a href="#" class="text-decoration-none text-success small me-3">
<i class="bi bi-hand-thumbs-up me-1"></i>Like (2)
</a>
</div>
</div>
</div>
</div>
</div>
<!-- Comment 2 -->
<div class="d-flex mb-4">
<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">
<div class="d-flex justify-content-between align-items-center mb-1">
<h6 class="mb-0">Emily Davis</h6>
<small class="text-muted">June 6, 2023 at 9:45 AM</small>
</div>
<p class="mb-2">I'd love to enter the pie contest! Are there any category restrictions?</p>
<div>
<a href="#" class="text-decoration-none text-success small me-3">
<i class="bi bi-hand-thumbs-up me-1"></i>Like (3)
</a>
<a href="#" class="text-decoration-none text-success small">
<i class="bi bi-reply me-1"></i>Reply
</a>
</div>
</div>
</div>
<!-- Comment 3 -->
<div class="d-flex">
<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">
<div class="d-flex justify-content-between align-items-center mb-1">
<h6 class="mb-0">Michael Brown</h6>
<small class="text-muted">June 6, 2023 at 11:20 AM</small>
</div>
<p class="mb-2">I'll bring my guitar and play during the music time if that's okay!</p>
<div>
<a href="#" class="text-decoration-none text-success small me-3">
<i class="bi bi-hand-thumbs-up me-1"></i>Like (8)
</a>
<a href="#" class="text-decoration-none text-success small">
<i class="bi bi-reply me-1"></i>Reply
</a>
</div>
</div>
</div>
</div>
</div>
<div class="card-footer text-center">
<a href="#" class="text-decoration-none">Load more comments</a>
</div>
</div>
<!-- Related Posts -->
<div class="card shadow-sm">
<div class="card-header bg-success text-white">
<h3 class="h5 mb-0"><i class="bi bi-collection me-2"></i>Related Posts</h3>
</div>
<div class="card-body">
<div class="list-group list-group-flush">
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">Summer Pool Schedule</h6>
<small class="text-muted">May 28, 2023</small>
</div>
<p class="mb-1 small">Pool hours and rules for the summer season</p>
<small class="text-muted">Posted by Michael Brown</small>
</a>
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">Neighborhood Yard Sale</h6>
<small class="text-muted">May 15, 2023</small>
</div>
<p class="mb-1 small">Community-wide yard sale August 3-4</p>
<small class="text-muted">Posted by Emily Davis</small>
</a>
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">Landscaping Updates</h6>
<small class="text-muted">April 30, 2023</small>
</div>
<p class="mb-1 small">New plants and improvements in common areas</p>
<small class="text-muted">Posted by Robert Wilson</small>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
{% endblock %}
{% block extra_js %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Like button functionality
document.querySelectorAll('.bi-hand-thumbs-up').forEach(icon => {
icon.addEventListener('click', function() {
// In a real implementation, this would track likes
this.classList.toggle('text-success');
});
});
// Comment submission
const commentForm = document.querySelector('.comment-list').previousElementSibling.querySelector('form');
commentForm.addEventListener('submit', function(e) {
e.preventDefault();
const commentText = document.getElementById('commentText').value;
if (commentText.trim() !== '') {
// In a real implementation, this would submit the comment
alert('Comment posted successfully (simulated)');
document.getElementById('commentText').value = '';
}
});
});
</script>
{% endblock %}

View File

@@ -0,0 +1,396 @@
{% extends 'schasite/authenticated_base.html' %}
{% load static %}
{% block pagetitle %}
<title>Profile | SCHA</title>
<script type="text/css">
.profile-avatar {
width: 120px;
height: 120px;
margin: 0 auto 1rem;
}
.dues-history table {
font-size: 0.875rem;
}
.dues-history th,
.dues-history td {
padding: 0.5rem;
}
.list-group-item-action:hover {
background-color: rgba(25, 135, 84, 0.05);
}
/* Communication Preferences */
#preferencesForm .form-check {
margin-bottom: 0.5rem;
}
/* Responsive adjustments */
@media (max-width: 991.98px) {
.profile-avatar {
width: 80px;
height: 80px;
}
}
@media (max-width: 767.98px) {
.profile-avatar {
width: 100px;
height: 100px;
}
}
</script>
{% endblock %}
{% block content %}
<main class="py-5">
<div class="container">
<div class="row mb-4">
<div class="col-12">
<h1 class="display-6">My Profile</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">Profile</li>
</ol>
</nav>
</div>
</div>
<div class="row g-4">
<!-- Left Column -->
<div class="col-lg-4">
<!-- Member Card -->
<div class="card shadow-sm mb-4">
<div class="card-header bg-success text-white">
<h3 class="h5 mb-0"><i class="bi bi-person-badge me-2"></i>Profile</h3>
</div>
<div class="card-body text-center">
<div class="mb-3">
<div class="bg-success bg-opacity-10 rounded-circle d-flex align-items-center justify-content-center mx-auto" style="width: 120px; height: 120px;">
<i class="bi bi-person-fill text-success fs-1"></i>
</div>
</div>
<h4 class="card-title">John Doe</h4>
<p class="text-muted">Member since: January 15, 2020</p>
<hr>
<button class="btn btn-outline-success btn-sm mb-3">
<i class="bi bi-pencil me-1"></i>Edit Profile
</button>
<button class="btn btn-outline-success btn-sm mb-3">
<i class="bi bi-lock me-1"></i>Change Password
</button>
</div>
</div>
<!-- Dues Payment History -->
<div class="card shadow-sm">
<div class="card-header bg-success text-white">
<h3 class="h5 mb-0"><i class="bi bi-credit-card me-2"></i>Dues Payment History</h3>
</div>
<div class="card-body">
<div class="alert alert-success">
<i class="bi bi-check-circle-fill me-2"></i>
<strong>Current Status:</strong> Paid through December 2024
</div>
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Date</th>
<th>Amount</th>
<th>Method</th>
<th>Receipt</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jan 10, 2024</td>
<td>$600.00</td>
<td>Credit Card</td>
<td><a href="#" class="text-success">View</a></td>
</tr>
<tr>
<td>Jan 5, 2023</td>
<td>$550.00</td>
<td>Bank Transfer</td>
<td><a href="#" class="text-success">View</a></td>
</tr>
<tr>
<td>Jan 8, 2022</td>
<td>$525.00</td>
<td>Check</td>
<td><a href="#" class="text-success">View</a></td>
</tr>
<tr>
<td>Jan 12, 2021</td>
<td>$500.00</td>
<td>Credit Card</td>
<td><a href="#" class="text-success">View</a></td>
</tr>
<tr>
<td>Jan 15, 2020</td>
<td>$500.00</td>
<td>Check</td>
<td><a href="#" class="text-success">View</a></td>
</tr>
</tbody>
</table>
</div>
<div class="text-center mt-2">
<a href="#" class="btn btn-sm btn-success">
<i class="bi bi-printer me-1"></i>Print Full History
</a>
</div>
</div>
</div>
</div>
<!-- Right Column -->
<div class="col-lg-8">
<!-- Member Details -->
<div class="card shadow-sm mb-4">
<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-house-heart me-2"></i>Member Details</h3>
<button class="btn btn-sm btn-light" id="editDetailsBtn">
<i class="bi bi-pencil me-1"></i>Edit
</button>
</div>
</div>
<div class="card-body">
<form id="memberDetailsForm">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">First Name</label>
<input type="text" class="form-control" value="John" disabled>
</div>
<div class="col-md-6">
<label class="form-label">Last Name</label>
<input type="text" class="form-control" value="Doe" disabled>
</div>
<div class="col-md-6">
<label class="form-label">Email</label>
<input type="email" class="form-control" value="john.doe@example.com" disabled>
</div>
<div class="col-md-6">
<label class="form-label">Phone</label>
<input type="tel" class="form-control" value="(555) 123-4567" disabled>
</div>
<div class="col-12">
<label class="form-label">Street Address</label>
<input type="text" class="form-control" value="123 Oak Drive" disabled>
</div>
<div class="col-md-4">
<label class="form-label">City</label>
<input type="text" class="form-control" value="Anytown" disabled>
</div>
<div class="col-md-4">
<label class="form-label">State</label>
<input type="text" class="form-control" value="ST" disabled>
</div>
<div class="col-md-4">
<label class="form-label">ZIP Code</label>
<input type="text" class="form-control" value="12345" disabled>
</div>
<div class="col-12 mt-3" id="saveDetailsBtn" style="display: none;">
<button type="submit" class="btn btn-success me-2">Save Changes</button>
<button type="button" class="btn btn-outline-secondary" id="cancelEditBtn">Cancel</button>
</div>
</div>
</form>
</div>
</div>
<!-- My Posts -->
<div class="card shadow-sm mb-4">
<div class="card-header bg-success text-white">
<h3 class="h5 mb-0"><i class="bi bi-pencil-square me-2"></i>My Posts</h3>
</div>
<div class="card-body">
<div class="list-group list-group-flush">
<a href="../posts/detail.html" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">Looking for lawn service recommendations</h6>
<small class="text-muted">May 28, 2024</small>
</div>
<p class="mb-1 small">Does anyone have a landscaper they would recommend for weekly mowing?</p>
<small><span class="badge bg-success bg-opacity-10 text-success">Discussion</span> • 5 comments</small>
</a>
<a href="../posts/detail.html" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">Lost cat - gray tabby</h6>
<small class="text-muted">April 15, 2024</small>
</div>
<p class="mb-1 small">Our cat Mittens got out last night near Oak Drive. Please contact if seen!</p>
<small><span class="badge bg-success bg-opacity-10 text-success">Help Needed</span> • 12 comments</small>
</a>
<a href="../posts/detail.html" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">Garage sale this weekend</h6>
<small class="text-muted">March 30, 2024</small>
</div>
<p class="mb-1 small">We're having a garage sale Saturday 8am-2pm with furniture, tools, and more.</p>
<small><span class="badge bg-success bg-opacity-10 text-success">For Sale</span> • 3 comments</small>
</a>
</div>
<div class="text-center mt-3">
<a href="../posts/" class="btn btn-sm btn-outline-success">View All My Posts</a>
</div>
</div>
</div>
<!-- My Comments -->
<div class="card shadow-sm mb-4">
<div class="card-header bg-success text-white">
<h3 class="h5 mb-0"><i class="bi bi-chat-left-text me-2"></i>Posts I've Commented On</h3>
</div>
<div class="card-body">
<div class="list-group list-group-flush">
<a href="../posts/detail.html" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">Annual Community Picnic</h6>
<small class="text-muted">June 5, 2024</small>
</div>
<p class="mb-1 small"><strong>My comment:</strong> "Looking forward to it! I'll bring potato salad."</p>
<small><span class="badge bg-success bg-opacity-10 text-success">Announcement</span> • 24 comments total</small>
</a>
<a href="../posts/detail.html" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">Pool opening delayed</h6>
<small class="text-muted">May 20, 2024</small>
</div>
<p class="mb-1 small"><strong>My comment:</strong> "Thanks for the update. Any estimate on opening date?"</p>
<small><span class="badge bg-success bg-opacity-10 text-success">Announcement</span> • 8 comments total</small>
</a>
<a href="../posts/detail.html" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">Neighborhood watch meeting</h6>
<small class="text-muted">April 10, 2024</small>
</div>
<p class="mb-1 small"><strong>My comment:</strong> "I can help organize the next meeting."</p>
<small><span class="badge bg-success bg-opacity-10 text-success">Event</span> • 15 comments total</small>
</a>
</div>
<div class="text-center mt-3">
<a href="../posts/" class="btn btn-sm btn-outline-success">View All My Comments</a>
</div>
</div>
</div>
<!-- Communication Preferences -->
<div class="card shadow-sm">
<div class="card-header bg-success text-white">
<h3 class="h5 mb-0"><i class="bi bi-envelope me-2"></i>Communication Preferences</h3>
</div>
<div class="card-body">
<form id="preferencesForm">
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="emailNotifications" checked>
<label class="form-check-label" for="emailNotifications">
Receive email notifications
</label>
</div>
</div>
<div class="mb-3">
<h6 class="mb-2">Notification Types:</h6>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="postReplies" checked>
<label class="form-check-label" for="postReplies">
When someone replies to my posts
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="commentReplies" checked>
<label class="form-check-label" for="commentReplies">
When someone replies to my comments
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="communityAnnouncements" checked>
<label class="form-check-label" for="communityAnnouncements">
Community announcements
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="eventReminders">
<label class="form-check-label" for="eventReminders">
Event reminders
</label>
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="showInDirectory" checked>
<label class="form-check-label" for="showInDirectory">
Include my contact information in the member directory
</label>
</div>
<div class="form-text">
Uncheck to hide your email and phone number from other members
</div>
</div>
<div class="mt-4">
<button type="submit" class="btn btn-success">Save Preferences</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</main>
{% endblock %}
{% block extra_js %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Edit details toggle
const editBtn = document.getElementById('editDetailsBtn');
const cancelBtn = document.getElementById('cancelEditBtn');
const saveBtn = document.getElementById('saveDetailsBtn');
const formInputs = document.querySelectorAll('#memberDetailsForm input');
editBtn.addEventListener('click', function() {
formInputs.forEach(input => {
input.disabled = false;
});
saveBtn.style.display = 'block';
editBtn.style.display = 'none';
});
cancelBtn.addEventListener('click', function() {
formInputs.forEach(input => {
input.disabled = true;
});
saveBtn.style.display = 'none';
editBtn.style.display = 'block';
});
// Form submissions
document.getElementById('memberDetailsForm').addEventListener('submit', function(e) {
e.preventDefault();
// In a real implementation, this would save the changes
alert('Profile details updated successfully (simulated)');
formInputs.forEach(input => {
input.disabled = true;
});
saveBtn.style.display = 'none';
editBtn.style.display = 'block';
});
document.getElementById('preferencesForm').addEventListener('submit', function(e) {
e.preventDefault();
// In a real implementation, this would save preferences
alert('Communication preferences saved (simulated)');
});
});
</script>
{% endblock %}

View File

@@ -10,6 +10,10 @@ if settings.DEBUG:
path('password_reset/',views.password_reset, name="password_reset"), path('password_reset/',views.password_reset, name="password_reset"),
path('directory/',views.member_directory, name="directory"), path('directory/',views.member_directory, name="directory"),
path('dashboard/',views.member_dashboard, name="dashboard"), path('dashboard/',views.member_dashboard, name="dashboard"),
path('posts/',views.member_posts, name="posts"),
path('posts_create/',views.member_posts_create, name="posts_create"),
path('posts/<int:post_id>',views.member_posts_detail, name="posts_detail"),
path('profile/',views.profile, name="profile"),
] ]
else: else:
@@ -42,3 +46,4 @@ urlpatterns = authenticated_views + [
] ]

View File

@@ -1,11 +1,13 @@
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from .models import UsefulLinks, CalendarEvent, MembershipPerson, Payments, SCHAOfficer, Membership from .models import UsefulLinks, CalendarEvent, MembershipPerson, Payments, SCHAOfficer, Membership, CommunityPost
from .forms import ( from .forms import (
ChildrenForm, ChildrenForm,
CommunityPostForm,
AddressForm, AddressForm,
PeopleForm, PeopleForm,
CommitteeForm, CommitteeForm,
ServicesForm, ServicesForm,
) # , CaptchaForm ) # , CaptchaForm
from django.db import transaction, IntegrityError from django.db import transaction, IntegrityError
@@ -489,4 +491,36 @@ def member_dashboard(request):
if request.method == "POST": if request.method == "POST":
raise NotImplementedError() raise NotImplementedError()
else: else:
return render(request, "schasite/member_dashboard.html",{}) return render(request, "schasite/member_dashboard.html",{})
def member_posts(request):
if request.method == "POST":
raise NotImplementedError()
else:
posts = CommunityPost.objects.all()[:5]
return render(request, "schasite/member_posts.html",{"posts":posts})
def member_posts_create(request):
if request.method == "POST":
community_post_form = CommunityPostForm(request.POST)
if community_post_form.is_valid():
community_post_form.save()
return render(request, "schasite/member_posts.html",{})
else:
print(f'Error creating the post: {community_post_form.errors}')
return render(request, "schasite/member_posts_create.html",{"community_post": community_post_form})
else:
return render(request, "schasite/member_posts_create.html",{"community_post": CommunityPostForm()})
def member_posts_detail(request, post_id):
if request.method == "POST":
raise NotImplementedError()
else:
return render(request, "schasite/member_posts_detail.html",{})
def profile(request):
if request.method == "POST":
raise NotImplementedError()
else:
return render(request, "schasite/profile.html",{})