diff --git a/__pycache__/server.cpython-312.pyc b/__pycache__/server.cpython-312.pyc index 04465dc..fde6485 100644 Binary files a/__pycache__/server.cpython-312.pyc and b/__pycache__/server.cpython-312.pyc differ diff --git a/server.py b/server.py index eb0fcc9..e51023a 100644 --- a/server.py +++ b/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""" + + + + + + +
+
+

New Contact Form Submission

+
+
+
+
From:
+
{request.first_name} {request.last_name}
+
+ +
+
Email:
+
{request.email}
+
+ +
+
Subject:
+
{request.subject}
+
+ +
+
Message:
+
{request.message}
+
+ +

+ Reply directly to this email to respond to {request.first_name}. +

+
+
+ + + """ + + # 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."""