generated from westfarn/web_django_template
Ship College Craft public site and point CI deploys at college_craft.
Replaces template branding with College Craft pages, assets, and copy, and matches Gitea deploy workflows to the server-infra catalog name and master branch so beta deploys actually run. Closes #1
This commit is contained in:
+125
-51
@@ -17,8 +17,9 @@ from contacts.consent import (
|
||||
set_channel_preferences,
|
||||
unsubscribe_all,
|
||||
)
|
||||
from public.forms import ContactForm, NotifyForm
|
||||
from public.forms import CareersForm, ContactForm, NotifyForm
|
||||
from public.notifications import notify_admins_of_contact_form
|
||||
from public.testimonials_data import FEATURED_TESTIMONIALS, TESTIMONIALS
|
||||
|
||||
|
||||
def _public_site_base(request) -> str:
|
||||
@@ -28,14 +29,89 @@ def _public_site_base(request) -> str:
|
||||
return request.build_absolute_uri("/").rstrip("/")
|
||||
|
||||
|
||||
def _postal_from_form(data: dict) -> dict:
|
||||
return Contact.make_postal_address(
|
||||
line1=data.get("address_line1") or "",
|
||||
line2=data.get("address_line2") or "",
|
||||
city=data.get("address_city") or "",
|
||||
state=data.get("address_state") or "",
|
||||
zip_code=data.get("address_zip") or "",
|
||||
)
|
||||
|
||||
|
||||
def _create_lead(
|
||||
request,
|
||||
*,
|
||||
data: dict,
|
||||
source: str,
|
||||
body: str,
|
||||
consent_reason: str,
|
||||
):
|
||||
postal = _postal_from_form(data)
|
||||
submitted_email = data["email"].lower()
|
||||
contact_obj, _created, match_reason = upsert_contact(
|
||||
email=submitted_email,
|
||||
first_name=data["first_name"],
|
||||
last_name=data.get("last_name") or "",
|
||||
phone=data.get("phone") or "",
|
||||
postal_address=postal if Contact.postal_address_has_content(postal) else None,
|
||||
source=source,
|
||||
)
|
||||
ConsentRecord.objects.update_or_create(
|
||||
contact=contact_obj,
|
||||
channel=Channel.EMAIL,
|
||||
defaults={"opted_in": True, "reason": consent_reason},
|
||||
)
|
||||
if (data.get("phone") or "").strip():
|
||||
ConsentRecord.objects.update_or_create(
|
||||
contact=contact_obj,
|
||||
channel=Channel.SMS,
|
||||
defaults={"opted_in": True, "reason": consent_reason},
|
||||
)
|
||||
if Contact.postal_address_has_content(postal):
|
||||
ConsentRecord.objects.get_or_create(
|
||||
contact=contact_obj,
|
||||
channel=Channel.POSTCARD,
|
||||
defaults={"opted_in": True, "reason": consent_reason},
|
||||
)
|
||||
if (
|
||||
match_reason in {"phone", "address"}
|
||||
and (contact_obj.email or "").lower() != submitted_email
|
||||
):
|
||||
body = (
|
||||
f"Submitted email: {submitted_email} "
|
||||
f"(merged by {match_reason} with "
|
||||
f"{contact_obj.email or 'existing contact'})\n\n{body}"
|
||||
).strip()
|
||||
lead = Lead.objects.create(
|
||||
contact=contact_obj,
|
||||
message=body,
|
||||
status=Lead.Status.NEW,
|
||||
)
|
||||
attribute_lead_from_request(request, lead)
|
||||
return lead
|
||||
|
||||
|
||||
def home(request):
|
||||
return render(request, "public/home.html")
|
||||
return render(
|
||||
request,
|
||||
"public/home.html",
|
||||
{"featured_testimonials": FEATURED_TESTIMONIALS},
|
||||
)
|
||||
|
||||
|
||||
def about(request):
|
||||
return render(request, "public/about.html")
|
||||
|
||||
|
||||
def services(request):
|
||||
return render(request, "public/services.html")
|
||||
|
||||
|
||||
def testimonials(request):
|
||||
return render(request, "public/testimonials.html", {"testimonials": TESTIMONIALS})
|
||||
|
||||
|
||||
def terms(request):
|
||||
return render(request, "public/terms.html")
|
||||
|
||||
@@ -64,7 +140,10 @@ def sitemap_xml(request):
|
||||
paths = [
|
||||
("public:home", "1.0", "weekly"),
|
||||
("public:about", "0.8", "monthly"),
|
||||
("public:services", "0.8", "monthly"),
|
||||
("public:testimonials", "0.7", "monthly"),
|
||||
("public:contact", "0.9", "monthly"),
|
||||
("public:careers", "0.6", "monthly"),
|
||||
("public:terms", "0.5", "yearly"),
|
||||
]
|
||||
from django.apps import apps as django_apps
|
||||
@@ -95,61 +174,18 @@ def contact(request):
|
||||
form = ContactForm(request.POST)
|
||||
if form.is_valid():
|
||||
data = form.cleaned_data
|
||||
postal = Contact.make_postal_address(
|
||||
line1=data.get("address_line1") or "",
|
||||
line2=data.get("address_line2") or "",
|
||||
city=data.get("address_city") or "",
|
||||
state=data.get("address_state") or "",
|
||||
zip_code=data.get("address_zip") or "",
|
||||
)
|
||||
submitted_email = data["email"].lower()
|
||||
contact_obj, _created, match_reason = upsert_contact(
|
||||
email=submitted_email,
|
||||
first_name=data["first_name"],
|
||||
last_name=data.get("last_name") or "",
|
||||
phone=data.get("phone") or "",
|
||||
postal_address=postal
|
||||
if Contact.postal_address_has_content(postal)
|
||||
else None,
|
||||
source=Contact.Source.CONTACT_FORM,
|
||||
)
|
||||
ConsentRecord.objects.update_or_create(
|
||||
contact=contact_obj,
|
||||
channel=Channel.EMAIL,
|
||||
defaults={"opted_in": True, "reason": "contact_form"},
|
||||
)
|
||||
if (data.get("phone") or "").strip():
|
||||
ConsentRecord.objects.update_or_create(
|
||||
contact=contact_obj,
|
||||
channel=Channel.SMS,
|
||||
defaults={"opted_in": True, "reason": "contact_form"},
|
||||
)
|
||||
if Contact.postal_address_has_content(postal):
|
||||
ConsentRecord.objects.get_or_create(
|
||||
contact=contact_obj,
|
||||
channel=Channel.POSTCARD,
|
||||
defaults={"opted_in": True, "reason": "contact_form"},
|
||||
)
|
||||
interest = data.get("interest") or ""
|
||||
interest_label = dict(ContactForm.INTEREST_CHOICES).get(interest, interest)
|
||||
body = data.get("message") or ""
|
||||
if interest_label:
|
||||
body = f"Interest: {interest_label}\n\n{body}".strip()
|
||||
if (
|
||||
match_reason in {"phone", "address"}
|
||||
and (contact_obj.email or "").lower() != submitted_email
|
||||
):
|
||||
body = (
|
||||
f"Submitted email: {submitted_email} "
|
||||
f"(merged by {match_reason} with "
|
||||
f"{contact_obj.email or 'existing contact'})\n\n{body}"
|
||||
).strip()
|
||||
lead = Lead.objects.create(
|
||||
contact=contact_obj,
|
||||
message=body,
|
||||
status=Lead.Status.NEW,
|
||||
lead = _create_lead(
|
||||
request,
|
||||
data=data,
|
||||
source=Contact.Source.CONTACT_FORM,
|
||||
body=body,
|
||||
consent_reason="contact_form",
|
||||
)
|
||||
attribute_lead_from_request(request, lead)
|
||||
notify_admins_of_contact_form(lead)
|
||||
messages.success(request, "Thanks — we will be in touch soon.")
|
||||
return redirect(f"{reverse('public:contact')}?sent=1")
|
||||
@@ -158,6 +194,44 @@ def contact(request):
|
||||
return render(request, "public/contact.html", {"form": form})
|
||||
|
||||
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def careers(request):
|
||||
if request.method == "POST":
|
||||
form = CareersForm(request.POST)
|
||||
if form.is_valid():
|
||||
data = form.cleaned_data
|
||||
position_labels = [
|
||||
dict(CareersForm.POSITION_CHOICES).get(value, value)
|
||||
for value in data.get("positions") or []
|
||||
]
|
||||
body_parts = [
|
||||
"Interest: Employment application",
|
||||
f"Positions: {', '.join(position_labels) or '(none)'}",
|
||||
f"Start: {data.get('start_date') or '(not specified)'}",
|
||||
f"Driver's license: {data.get('drivers_license') or '(not specified)'}",
|
||||
f"Transportation: {data.get('has_vehicle') or '(not specified)'}",
|
||||
"",
|
||||
data.get("qualifications") or "",
|
||||
]
|
||||
lead = _create_lead(
|
||||
request,
|
||||
data=data,
|
||||
source=Contact.Source.CAREERS,
|
||||
body="\n".join(body_parts).strip(),
|
||||
consent_reason="careers_form",
|
||||
)
|
||||
notify_admins_of_contact_form(
|
||||
lead, subject_prefix="New employment application"
|
||||
)
|
||||
messages.success(
|
||||
request, "Thanks — we received your application and will follow up."
|
||||
)
|
||||
return redirect(f"{reverse('public:careers')}?sent=1")
|
||||
else:
|
||||
form = CareersForm()
|
||||
return render(request, "public/careers.html", {"form": form})
|
||||
|
||||
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def under_construction(request):
|
||||
"""Direct route (also used by middleware). Accepts notify-me emails."""
|
||||
|
||||
Reference in New Issue
Block a user