Update Responsive and Contact Us page and function
This commit is contained in:
Binary file not shown.
104
server.py
104
server.py
@@ -2280,6 +2280,22 @@ class DonationCheckoutRequest(BaseModel):
|
||||
raise ValueError('Donation must be at least $1.00 (100 cents)')
|
||||
return v
|
||||
|
||||
# Pydantic model for contact form
|
||||
class ContactFormRequest(BaseModel):
|
||||
first_name: str = Field(..., min_length=1, max_length=100)
|
||||
last_name: str = Field(..., min_length=1, max_length=100)
|
||||
email: str = Field(..., min_length=1, max_length=255)
|
||||
subject: str = Field(..., min_length=1, max_length=200)
|
||||
message: str = Field(..., min_length=1, max_length=2000)
|
||||
|
||||
@validator('email')
|
||||
def validate_email(cls, v):
|
||||
import re
|
||||
email_regex = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
|
||||
if not re.match(email_regex, v):
|
||||
raise ValueError('Invalid email address')
|
||||
return v
|
||||
|
||||
@api_router.get("/subscriptions/plans")
|
||||
async def get_subscription_plans(db: Session = Depends(get_db)):
|
||||
"""Get all active subscription plans."""
|
||||
@@ -3320,6 +3336,94 @@ async def create_donation_checkout(
|
||||
logger.error(f"Error creating donation checkout: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail="Failed to create donation checkout")
|
||||
|
||||
@api_router.post("/contact")
|
||||
async def submit_contact_form(
|
||||
request: ContactFormRequest,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""Handle contact form submission and send email to admin."""
|
||||
|
||||
try:
|
||||
# Get admin email from environment or use default
|
||||
admin_email = os.getenv("ADMIN_EMAIL", "info@loaftx.org")
|
||||
|
||||
# Create email content
|
||||
subject = f"New Contact Form Submission: {request.subject}"
|
||||
|
||||
html_content = f"""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {{ font-family: 'Nunito Sans', Arial, sans-serif; line-height: 1.6; color: #422268; }}
|
||||
.container {{ max-width: 600px; margin: 0 auto; padding: 20px; }}
|
||||
.header {{ background: linear-gradient(135deg, #644c9f 0%, #48286e 100%); padding: 30px; text-align: center; border-radius: 10px 10px 0 0; }}
|
||||
.header h1 {{ color: white; margin: 0; font-family: 'Inter', sans-serif; }}
|
||||
.content {{ background: #FFFFFF; padding: 30px; border: 1px solid #ddd8eb; border-radius: 0 0 10px 10px; }}
|
||||
.field {{ margin-bottom: 20px; }}
|
||||
.field-label {{ font-weight: 600; color: #48286e; margin-bottom: 5px; }}
|
||||
.field-value {{ color: #664fa3; }}
|
||||
.message-box {{ background: #f1eef9; padding: 20px; border-left: 4px solid #ff9e77; margin-top: 20px; }}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>New Contact Form Submission</h1>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="field">
|
||||
<div class="field-label">From:</div>
|
||||
<div class="field-value">{request.first_name} {request.last_name}</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="field-label">Email:</div>
|
||||
<div class="field-value">{request.email}</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="field-label">Subject:</div>
|
||||
<div class="field-value">{request.subject}</div>
|
||||
</div>
|
||||
|
||||
<div class="message-box">
|
||||
<div class="field-label">Message:</div>
|
||||
<div class="field-value" style="margin-top: 10px; white-space: pre-wrap;">{request.message}</div>
|
||||
</div>
|
||||
|
||||
<p style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #ddd8eb; color: #664fa3; font-size: 14px;">
|
||||
Reply directly to this email to respond to {request.first_name}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
# Import send_email from email_service
|
||||
from email_service import send_email
|
||||
|
||||
# Send email to admin
|
||||
email_sent = await send_email(admin_email, subject, html_content)
|
||||
|
||||
if not email_sent:
|
||||
logger.error(f"Failed to send contact form email from {request.email}")
|
||||
raise HTTPException(status_code=500, detail="Failed to send contact form. Please try again later.")
|
||||
|
||||
logger.info(f"Contact form submitted by {request.first_name} {request.last_name} ({request.email})")
|
||||
|
||||
return {
|
||||
"message": "Contact form submitted successfully. We'll get back to you soon!",
|
||||
"success": True
|
||||
}
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing contact form: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail="Failed to process contact form")
|
||||
|
||||
@app.post("/api/webhooks/stripe")
|
||||
async def stripe_webhook(request: Request, db: Session = Depends(get_db)):
|
||||
"""Handle Stripe webhook events. Note: This endpoint is NOT on the api_router to avoid /api/api prefix."""
|
||||
|
||||
Reference in New Issue
Block a user