Updates with a sign in page

This commit is contained in:
2025-04-25 10:12:16 -05:00
parent 5bd7a37e52
commit b9964b22a9
7 changed files with 187 additions and 25 deletions

View File

@@ -2,6 +2,7 @@ from django.db import models
from phonenumber_field.modelfields import PhoneNumberField
import datetime
from django.utils import timezone
from django.conf import settings
class TimeInfoBase(models.Model):
@@ -181,6 +182,11 @@ class CommunityParks(TimeInfoBase):
distance = models.DecimalField(max_digits=3, decimal_places=1)
description = models.CharField(max_length=1024)
### Member only models
class CommunityMember(TimeInfoBase):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
membership_person = models.OneToOneField(MembershipPerson, on_delete=models.CASCADE)
class CommunityPost(TimeInfoBase):
@@ -188,12 +194,20 @@ class CommunityPost(TimeInfoBase):
category = models.CharField(max_length=255)
content = models.CharField(max_length=1024*8)
likes = models.IntegerField(default=0)
author = models.OneToOneField(CommunityMember, on_delete=models.CASCADE)
class CommunityPostReports(TimeInfoBase):
# for anyone who reports a post
post = models.ForeignKey(CommunityPost, on_delete=models.CASCADE)
# user = something
reporter = models.OneToOneField(CommunityMember, on_delete=models.CASCADE)
class CommunityPostLikes(TimeInfoBase):
# for anyone who likes a post
post = models.ForeignKey(CommunityPost, on_delete=models.CASCADE)
reporter = models.OneToOneField(CommunityMember, on_delete=models.CASCADE)
class CommunityComment(TimeInfoBase):
post = models.ForeignKey(CommunityPost, on_delete=models.CASCADE)
content = models.CharField(max_length=1024*8)
likes = models.IntegerField(default=0)
likes = models.IntegerField(default=0)
author = models.OneToOneField(CommunityMember, on_delete=models.CASCADE)

View File

@@ -16,7 +16,7 @@
<script async defer src="https://tianji.aimloperations.com/tracker.js" data-website-id="cm9qziuid9vr7v6dtdbnx8406"></script>
</head>
<body>
<p><img src=https://tianji.aimloperations.com/telemetry/cm7w8087y020lddswyhamadj2/cm9u1ehxeajxmv6dtajx4f9yn/badge.svg"></p>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-success sticky-top">
<div class="container">

View File

@@ -78,34 +78,39 @@
<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>
<h3 class="h5 mb-0"><i class="bi bi-activity me-2"></i>Your Recently Updated Posts</h3>
</div>
<div class="card-body">
<div class="list-group">
{% for recent_post in member_recent_posts %}
<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>
<h5 class="mb-1">{{ recent_post.title }}</h5>
<small>3 days ago</small>
</div>
<p class="mb-1">The community picnic is scheduled for June 15th. RSVP now!</p>
<p class="mb-1">{{ recent_post.content }}</p>
<small>Posted by Sarah Johnson</small>
</a>
{% endfor %}
</div>
</div>
</div>
<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 Posts</h3>
</div>
<div class="card-body">
<div class="list-group">
{% for recent_post in recent_posts %}
<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>
<h5 class="mb-1">{{ recent_post.title }}</h5>
<small>3 days 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>
<p class="mb-1">{{ recent_post.content }}</p>
<small>Posted by Sarah Johnson</small>
</a>
{% endfor %}
</div>
</div>
</div>

View File

@@ -52,12 +52,12 @@
</div>
<div class="mt-3 text-center">
<a href="reset-password.html" class="text-decoration-none">Forgot password?</a>
<a href="{% url 'password_reset' %}" 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>
Not a member? <a href="{% url 'signup' %}" class="text-success">Join our community</a>
</div>
</div>
</div>

View File

@@ -0,0 +1,104 @@
{% 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 Signup</h2>
</div>
<div class="card-body p-4">
<form id="loginForm" class="needs-validation" novalidate>
<div class="card-body">
<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">
</div>
<div class="col-md-6">
<label class="form-label">Last Name</label>
<input type="text" class="form-control" value="Doe">
</div>
<div class="col-md-6">
<label class="form-label">Email</label>
<input type="email" class="form-control" value="john.doe@example.com">
</div>
<div class="col-md-6">
<label class="form-label">Phone</label>
<input type="tel" class="form-control" value="(555) 123-4567">
</div>
<div class="col-12">
<label class="form-label">Street Address</label>
<input type="text" class="form-control" value="123 Oak Drive">
</div>
<div class="col-md-4">
<label class="form-label">City</label>
<input type="text" class="form-control" value="Anytown">
</div>
<div class="col-md-4">
<label class="form-label">State</label>
<input type="text" class="form-control" value="ST">
</div>
<div class="col-md-4">
<label class="form-label">ZIP Code</label>
<input type="text" class="form-control" value="12345" >
</div>
<div class="col-md-12">
<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="col-md-12">
<label for="loginPassword" class="form-label">Confirm 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 confirm your password. </div>
</div>
</div>
</div>
</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 Up
</button>
</div>
<div class="mt-3 text-center">
<a href="{% url 'login' %}" class="text-decoration-none">Back to Log In</a>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -8,6 +8,7 @@ if settings.DEBUG:
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('signup/',views.signup, name="signup"),
path('directory/',views.member_directory, name="directory"),
path('dashboard/',views.member_dashboard, name="dashboard"),
path('posts/',views.member_posts, name="posts"),

View File

@@ -1,5 +1,6 @@
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 (
ChildrenForm,
CommunityPostForm,
@@ -15,6 +16,8 @@ from django.db import transaction, IntegrityError
from django.conf import settings # new
from django.http.response import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt # new
from django.contrib.auth import logout, authenticate, login
from django.contrib.auth.decorators import login_required
import stripe
"""
@@ -472,13 +475,25 @@ def membership_form(request):
def scha_board(request):
return render(request, "schasite/scha_board.html", {})
def login(request):
if request.method == "POST":
raise NotImplementedError()
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(request, username=username, password=password)
if user is not None:
return redirect('dashboard')
else:
return render(request, "schasite/signin.html",{'error_msg': "Invalid username/password"})
else:
return render(request, "schasite/signin.html",{})
def logout(request):
if request.method == "POST":
logout(request)
return redirect('index2')
def password_reset(request):
if request.method == "POST":
raise NotImplementedError()
@@ -488,29 +503,48 @@ def password_reset(request):
def set_password(request):
if request.method == "POST":
raise NotImplementedError()
return redirect('login')
else:
return render(request, "schasite/set_password.html",{})
def signup(request):
if request.method == "POST":
raise NotImplementedError()
return redirect('login')
else:
return render(request, "schasite/signup.html",{})
@login_required(login_url="/login")
def member_directory(request):
if request.method == "POST":
# these should be filters
raise NotImplementedError()
else:
return render(request, "schasite/member_directory.html",{})
members = MembershipPerson.objects.all()
return render(request, "schasite/member_directory.html",{'members':members})
@login_required(login_url="/login")
def member_dashboard(request):
current_member = CommunityMember.objects.get(user=request.user)
if request.method == "POST":
raise NotImplementedError()
else:
return render(request, "schasite/member_dashboard.html",{})
recent_posts = CommunityPost.objects.all()[:5]
member_recent_posts = CommunityPost.objects.filter(author=current_member)[:5]
return render(request, "schasite/member_dashboard.html",{"recent_posts":recent_posts, "member_recent_posts": member_recent_posts, "current_member": current_member})
@login_required(login_url="/login")
def member_posts(request):
current_member = CommunityMember.objects.get(user=request.user)
if request.method == "POST":
raise NotImplementedError()
else:
posts = CommunityPost.objects.all()[:5]
return render(request, "schasite/member_posts.html",{"posts":posts})
@login_required(login_url="/login")
def member_posts_create(request):
current_member = CommunityMember.objects.get(user=request.user)
if request.method == "POST":
community_post_form = CommunityPostForm(request.POST)
if community_post_form.is_valid():
@@ -523,13 +557,17 @@ def member_posts_create(request):
else:
return render(request, "schasite/member_posts_create.html",{"community_post": CommunityPostForm()})
@login_required(login_url="/login")
def member_posts_detail(request, post_id):
current_member = CommunityMember.objects.get(user=request.user)
if request.method == "POST":
raise NotImplementedError()
else:
return render(request, "schasite/member_posts_detail.html",{})
#@login_required(login_url="/login")
def profile(request):
#current_member = CommunityMember.objects.get(user=request.user)
if request.method == "POST":
raise NotImplementedError()
else: