3 Commits
Author SHA1 Message Date
westfarn 03bb01664f Align emails with site UX (#26) (#27)
Unit Tests / test (push) Successful in 12s
## Summary
- Closes #26
- Shared dark branded email base (`emails/base_email.html`) matching site tokens: `#0a0a0a` / `#1a1a1a`, cyan `#00f3ff`, purple `#bc13fe`, logo, Inter-safe stack
- Refactors contact, marketing (+ preview), and invoice pay-link HTML/text to extend that base; drops Materialize CDN
- Adds `PUBLIC_SITE_URL` + `email_brand_context()` for absolute logo/footer links

## Email renders

### Contact
![Contact email](https://git.aimloperations.com/ai_ml_operations/company_site/raw/branch/feature/26-brand-email-ux/docs/email-previews/contact.png)

### Marketing
![Marketing email](https://git.aimloperations.com/ai_ml_operations/company_site/raw/branch/feature/26-brand-email-ux/docs/email-previews/marketing.png)

### Invoice pay link
![Invoice email](https://git.aimloperations.com/ai_ml_operations/company_site/raw/branch/feature/26-brand-email-ux/docs/email-previews/invoice.png)

Also see `docs/email-previews/`.

## Test plan
- [ ] Preview a marketing `EmailMessage` in admin / `/preview_email/<pk>/` — dark brand, logo, no Materialize
- [ ] Submit contact form (or render `emails/contact_email.html`) — subject/from/message fields + branded footer
- [ ] Send (or dry-render) invoice pay-link email — cyan CTA, amount accent
- [ ] Confirm logo loads from `PUBLIC_SITE_URL/static/public/img/logo.png` in a real clientReviewed-on: #27
2026-07-31 17:08:57 -07:00
westfarn b98f504afc Admin Stripe invoices + recurring subscriptions (customers pay us) (#24)
Unit Tests / test (push) Successful in 11s
## Summary
- Closes #23
- Admin-only invoice dashboard under `/financial/invoices` (superuser)
- One-off Stripe hosted invoices + email pay link (customers pay us)
- Monthly (or weekly/yearly) Stripe Checkout subscriptions + email checkout link
- Webhook at `/financial/stripe/webhook/` syncs invoice/subscription status
- Env docs: `STRIPE_SECRET_KEY`, `STRIPE_PUBLISHABLE_KEY`, `STRIPE_WEBHOOK_SECRET`

## Test plan
- [ ] Set Stripe **test** keys in local `.env` and restart app
- [ ] As superuser: Dashboard → Invoices → create one-off invoice; confirm Stripe invoice + email
- [ ] As superuser: create monthly subscription; open Checkout link; complete with test card `4242…`
- [ ] Configure Stripe CLI or Dashboard webhook → confirm status updates to paid/active
- [ ] Non-admin user cannot open `/financial/invoices`
- [ ] Prod: add live keys + webhook secret to server `.env`, migrate, restart; point webhook to `https://aimloperations.com/financial/stripe/webhook/`

## Notes
Uses stdlib HTTP to Stripe API (no `stripe` PyPI package) so deploys stay dependency-light.Reviewed-on: #24
2026-07-31 12:02:40 -07:00
westfarn 05aa0b96b1 Remove file hosting service page and references (#25)
Unit Tests / test (push) Successful in 12s
## Summary
- Closes #21
- Remove retired file hosting marketing page, nav/home cards, SEO/sitemap entries, and unused images
- Permanently redirect `/file_hosting` → home so inbound links and search results do not 404

## Test plan
- [x] `python manage.py test public` passes
- [ ] Visit `/file_hosting` → 301 to home
- [ ] Confirm Services nav has no Hosting entry
- [ ] Confirm home page has no File Hosting card
- [ ] Confirm `sitemap.xml` / page metadata omit file hostingReviewed-on: #25
2026-07-31 11:40:54 -07:00
29 changed files with 271 additions and 417 deletions
+3
View File
@@ -34,6 +34,9 @@ EMAIL_HOST_PASSWORD=
EMAIL_PORT=2525
EMAIL_USE_TLS=true
# DEFAULT_FROM_EMAIL=AI ML Operations, LLC <info@aimloperations.com>
# Absolute origin for email logo / footer links
PUBLIC_SITE_URL=https://aimloperations.com
# DEFAULT_FROM_EMAIL=AI ML Operations, LLC <info@aimloperations.com>
# Stripe (test keys from https://dashboard.stripe.com/test/apikeys)
STRIPE_SECRET_KEY=
+1
View File
@@ -35,6 +35,7 @@ EMAIL_HOST_PASSWORD=replace-with-smtp-password
EMAIL_PORT=2525
EMAIL_USE_TLS=true
# DEFAULT_FROM_EMAIL=AI ML Operations, LLC <info@aimloperations.com>
PUBLIC_SITE_URL=https://aimloperations.com
# Stripe (live keys from https://dashboard.stripe.com/apikeys)
# Secret key starts with sk_live_; publishable with pk_live_
@@ -204,6 +204,8 @@ DEFAULT_FROM_EMAIL = env(
"DEFAULT_FROM_EMAIL",
"AI ML Operations, LLC <info@aimloperations.com>",
)
# Absolute site origin for email logo / footer links (no trailing slash).
PUBLIC_SITE_URL = env("PUBLIC_SITE_URL", "https://aimloperations.com").rstrip("/")
# Stripe (invoices / subscriptions — customers pay us)
STRIPE_SECRET_KEY = env("STRIPE_SECRET_KEY", "")
+10 -8
View File
@@ -284,14 +284,16 @@ def send_pay_link_email(
"DEFAULT_FROM_EMAIL",
"AI ML Operations, LLC <info@aimloperations.com>",
)
context = {
"customer_name": customer_name,
"description": description,
"amount_dollars": f"{amount_dollars:.2f}",
"pay_url": pay_url,
"kind": kind,
"subject": subject,
}
from public.email_branding import email_brand_context
context = email_brand_context(
customer_name=customer_name,
description=description,
amount_dollars=f"{amount_dollars:.2f}",
pay_url=pay_url,
kind=kind,
subject=subject,
)
html_content = get_template("emails/invoice_pay_link.html").render(context)
text_content = get_template("emails/invoice_pay_link.txt").render(context)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to_email])
@@ -1,48 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ subject }}</title>
<style>
body { margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4; }
.email-container { max-width: 600px; margin: 0 auto; background-color: #ffffff; border: 1px solid #dddddd; }
.header { background-color: #0b3d5c; color: #ffffff; padding: 20px; text-align: center; }
.content { padding: 24px; color: #333333; font-size: 15px; line-height: 1.5; }
.btn {
display: inline-block; margin: 20px 0; padding: 12px 24px;
background-color: #0b3d5c; color: #ffffff !important; text-decoration: none;
border-radius: 4px; font-weight: bold;
}
.footer { background-color: #f4f4f4; color: #777777; text-align: center; padding: 12px; font-size: 12px; }
.amount { font-size: 22px; font-weight: bold; margin: 12px 0; }
</style>
</head>
<body>
<div class="email-container">
<div class="header">
<h1>AI ML Operations</h1>
</div>
<div class="content">
<p>Hello {{ customer_name }},</p>
{% if kind == "subscription" %}
<p>Please complete checkout to start your recurring payment:</p>
{% else %}
<p>You have a new invoice ready for payment:</p>
{% endif %}
<p><strong>{{ description }}</strong></p>
<p class="amount">${{ amount_dollars }} USD</p>
<p>
<a class="btn" href="{{ pay_url }}">
{% extends "emails/base_email.html" %}
{% block title %}{{ subject }}{% endblock %}
{% block content %}
<p style="margin:0 0 16px;color:#e0e0e0;">Hello {{ customer_name }},</p>
{% if kind == "subscription" %}
<p style="margin:0 0 16px;color:#e0e0e0;">Please complete checkout to start your recurring payment:</p>
{% else %}
<p style="margin:0 0 16px;color:#e0e0e0;">You have a new invoice ready for payment:</p>
{% endif %}
<p style="margin:0 0 8px;color:#e0e0e0;"><strong>{{ description }}</strong></p>
<p class="amount" style="font-size:22px;font-weight:700;color:#00f3ff;margin:12px 0;">${{ amount_dollars }} USD</p>
<p style="margin:24px 0;">
<a class="email-btn" href="{{ pay_url }}" style="display:inline-block;padding:14px 28px;background-color:#00f3ff;color:#0a0a0a !important;text-decoration:none;border-radius:30px;font-weight:700;font-size:14px;letter-spacing:0.5px;text-transform:uppercase;">
{% if kind == "subscription" %}Complete checkout{% else %}Pay invoice{% endif %}
</a>
</p>
<p style="font-size: 13px; color: #666;">Or open this link:<br>{{ pay_url }}</p>
<p>Thank you,<br>AI ML Operations, LLC</p>
</div>
<div class="footer">
<p>This is an automated message. Please do not reply to this email.</p>
</div>
</div>
</body>
</html>
</p>
<p class="muted" style="color:#a0a0a0;font-size:13px;line-height:1.5;margin:0 0 16px;">
Or open this link:<br>
<a href="{{ pay_url }}" style="color:#00f3ff;word-break:break-all;">{{ pay_url }}</a>
</p>
<p style="margin:0;color:#e0e0e0;">Thank you,<br>{{ brand_legal|default:"AI ML Operations, LLC" }}</p>
{% endblock %}
{% block footer_note %}This is an automated message. Please do not reply to this email.{% endblock %}
@@ -9,4 +9,8 @@ Amount: ${{ amount_dollars }} USD
{{ pay_url }}
Thank you,
AI ML Operations, LLC
{{ brand_legal|default:"AI ML Operations, LLC" }}
{{ site_url|default:"https://aimloperations.com" }}
Forward-deployed AI engineering
+13 -4
View File
@@ -1,3 +1,4 @@
from django.conf import settings
from django.contrib import admin
from django.core.mail import EmailMultiAlternatives
from django.shortcuts import get_object_or_404
@@ -5,6 +6,7 @@ from django.template.loader import get_template
from django.template.response import TemplateResponse
from django.urls import path
from .email_branding import email_brand_context
from .models import Contact, EmailMessage, PageVisit
@@ -36,8 +38,12 @@ def send_emails(modeladmin, request, queryset):
for email in queryset:
success_count: int = 0
try:
from_email = "AI ML Operations, LLC <info@aimloperations.com>"
d = {"title": email.subject, "content": email.body}
from_email = getattr(
settings,
"DEFAULT_FROM_EMAIL",
"AI ML Operations, LLC <info@aimloperations.com>",
)
d = email_brand_context(title=email.subject, content=email.body)
html_content = get_template("emails/marketing_email.html").render(d)
text_content = get_template("emails/marketing_email.txt").render(d)
@@ -77,8 +83,11 @@ class EmailMessageAdmin(admin.ModelAdmin):
def preview_email(self, request, pk):
email_instance = get_object_or_404(EmailMessage, pk=pk)
context = {"title": email_instance.subject, "content": email_instance.body}
return TemplateResponse(request, "public/preview_email.html", context)
context = email_brand_context(
title=email_instance.subject,
content=email_instance.body,
)
return TemplateResponse(request, "emails/marketing_email.html", context)
@admin.register(PageVisit)
+22
View File
@@ -0,0 +1,22 @@
"""Shared context for branded HTML/text emails."""
from django.conf import settings
from django.contrib.staticfiles.storage import staticfiles_storage
def email_brand_context(**extra):
site_url = getattr(settings, "PUBLIC_SITE_URL", "https://aimloperations.com").rstrip(
"/"
)
logo_path = staticfiles_storage.url("public/img/logo.png")
if logo_path.startswith("http://") or logo_path.startswith("https://"):
logo_url = logo_path
else:
logo_url = f"{site_url}{logo_path}"
return {
"site_url": site_url,
"logo_url": logo_url,
"brand_name": "AI ML Operations",
"brand_legal": "AI ML Operations, LLC",
**extra,
}
-8
View File
@@ -63,13 +63,6 @@ PUBLIC_PAGE_ENTRIES = (
"0.7",
"Custom workstation and server builds optimized for AI and ML workloads.",
),
(
"file_hosting",
"File Hosting",
"monthly",
"0.7",
"Managed file hosting and storage for teams that need reliable data access.",
),
(
"web_design",
"Web Design and Hosting",
@@ -104,7 +97,6 @@ SERVICE_URL_NAMES = frozenset({
"ai_sensor",
"ai_education",
"computers",
"file_hosting",
"web_design",
})
Binary file not shown.

Before

Width:  |  Height:  |  Size: 843 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

+1 -2
View File
@@ -69,7 +69,7 @@
<li><a href="{% url 'public_index' %}"
class="{% if request.resolver_match.url_name == 'public_index' %}active{% endif %}">Home</a></li>
<li class="dropdown">
<button type="button" class="nav-dropdown-trigger{% if request.resolver_match.url_name in 'forward_deployed,ai_education,ai_sensor,bot,chat,computers,file_hosting,ml_model,web_design' %} active{% endif %}"
<button type="button" class="nav-dropdown-trigger{% if request.resolver_match.url_name in 'forward_deployed,ai_education,ai_sensor,bot,chat,computers,ml_model,web_design' %} active{% endif %}"
id="services-menu-button" aria-expanded="false" aria-haspopup="true" aria-controls="services-menu">Services</button>
<ul class="dropdown-content" id="services-menu" role="menu" aria-labelledby="services-menu-button">
<li><a href="{% url 'forward_deployed' %}">Forward-Deployed AI</a></li>
@@ -79,7 +79,6 @@
<li><a href="{% url 'ai_sensor' %}">Sensors</a></li>
<li><a href="{% url 'ai_education' %}">Education</a></li>
<li><a href="{% url 'computers' %}">Hardware</a></li>
<li><a href="{% url 'file_hosting' %}">Hosting</a></li>
<li><a href="{% url 'web_design' %}">Web Design</a></li>
</ul>
</li>
@@ -0,0 +1,107 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="dark">
<meta name="supported-color-schemes" content="dark">
<title>{% block title %}{{ brand_name|default:"AI ML Operations" }}{% endblock %}</title>
<!--[if mso]>
<style type="text/css">
body, table, td { font-family: Arial, Helvetica, sans-serif !important; }
</style>
<![endif]-->
<style type="text/css">
body, table, td, a {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
table, td {
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
}
img {
border: 0;
height: auto;
line-height: 100%;
outline: none;
text-decoration: none;
-ms-interpolation-mode: bicubic;
}
body {
margin: 0 !important;
padding: 0 !important;
width: 100% !important;
background-color: #0a0a0a;
color: #e0e0e0;
font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
a { color: #00f3ff; }
.email-btn {
display: inline-block;
padding: 14px 28px;
background-color: #00f3ff;
color: #0a0a0a !important;
text-decoration: none;
border-radius: 30px;
font-weight: 700;
font-size: 14px;
letter-spacing: 0.5px;
text-transform: uppercase;
}
.muted { color: #a0a0a0; font-size: 13px; line-height: 1.5; }
.amount { font-size: 22px; font-weight: 700; color: #00f3ff; margin: 12px 0; }
.field-label { color: #a0a0a0; font-size: 12px; text-transform: uppercase; letter-spacing: 0.6px; margin: 0 0 4px; }
.field-value { color: #e0e0e0; font-size: 15px; margin: 0 0 16px; line-height: 1.5; }
</style>
</head>
<body style="margin:0;padding:0;background-color:#0a0a0a;">
{% block preheader %}{% endblock %}
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="background-color:#0a0a0a;">
<tr>
<td align="center" style="padding:32px 16px;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="max-width:600px;background-color:#1a1a1a;border:1px solid rgba(255,255,255,0.1);">
<tr>
<td align="center" style="padding:28px 24px 20px;border-bottom:1px solid rgba(0,243,255,0.35);">
{% if logo_url %}
<a href="{{ site_url|default:'https://aimloperations.com' }}" style="text-decoration:none;">
<img src="{{ logo_url }}" alt="{{ brand_name|default:'AI ML Operations' }}" width="220" style="display:block;width:220px;max-width:80%;height:auto;">
</a>
{% else %}
<p style="margin:0;font-size:18px;font-weight:700;letter-spacing:1px;color:#e0e0e0;text-transform:uppercase;">
{{ brand_name|default:"AI ML Operations" }}
</p>
{% endif %}
{% block header_extra %}{% endblock %}
</td>
</tr>
<tr>
<td style="height:3px;line-height:3px;font-size:0;background-color:#bc13fe;">&nbsp;</td>
</tr>
<tr>
<td style="padding:28px 28px 8px;color:#e0e0e0;font-size:15px;line-height:1.6;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;">
{% block content %}{% endblock %}
</td>
</tr>
<tr>
<td style="padding:8px 28px 28px;color:#a0a0a0;font-size:12px;line-height:1.5;text-align:center;border-top:1px solid rgba(255,255,255,0.08);font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;">
{% block footer %}
<p style="margin:16px 0 8px;color:#a0a0a0;">
{% block footer_note %}{% endblock %}
</p>
<p style="margin:0 0 4px;color:#a0a0a0;">
&copy; {% now "Y" %} {{ brand_legal|default:"AI ML Operations, LLC" }}. All rights reserved.
</p>
<p style="margin:0;color:#a0a0a0;">
<a href="{{ site_url|default:'https://aimloperations.com' }}" style="color:#00f3ff;text-decoration:none;">aimloperations.com</a>
&nbsp;·&nbsp; Forward-deployed AI engineering
</p>
{% endblock %}
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
@@ -1,110 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Feedback Submission</title>
<style>
/* Basic reset for email clients */
body, table, td, a {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
table, td {
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
}
img {
border: 0;
height: auto;
line-height: 100%;
outline: none;
text-decoration: none;
-ms-interpolation-mode: bicubic;
}
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}
.email-container {
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
border: 1px solid #dddddd;
}
.header {
background-color: #007BFF;
color: #ffffff;
padding: 20px;
text-align: center;
}
.content {
padding: 20px;
color: #333333;
}
.footer {
background-color: #f4f4f4;
color: #777777;
text-align: center;
padding: 10px;
font-size: 12px;
}
.feedback-title {
font-size: 18px;
font-weight: bold;
margin-bottom: 10px;
}
.feedback-text {
font-size: 14px;
line-height: 1.5;
}
</style>
</head>
<body>
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" align="center">
<tr>
<td>
<!-- Email Container -->
<div class="email-container">
<!-- Header -->
<div class="header">
<h1>New Contact Request</h1>
</div>
{% extends "emails/base_email.html" %}
<!-- Content -->
<div class="content">
<p>Hello,</p>
<p>A new feedback item has been submitted. Here are the details:</p>
{% block title %}New Contact Request{% endblock %}
<!-- Feedback Title -->
<div class="feedback-title">
Subject: <strong>{{ subject }}</strong>
</div>
{% block content %}
<p style="margin:0 0 16px;color:#e0e0e0;">Hello,</p>
<p style="margin:0 0 24px;color:#e0e0e0;">A new contact request was submitted on the site.</p>
<!-- Email -->
<div class="feedback-title">
Email: <strong>{{ email }}</strong>
</div>
<p class="field-label" style="color:#a0a0a0;font-size:12px;text-transform:uppercase;letter-spacing:0.6px;margin:0 0 4px;">Subject</p>
<p class="field-value" style="color:#e0e0e0;font-size:15px;margin:0 0 16px;"><strong>{{ subject }}</strong></p>
<!-- Feedback Text -->
<div class="feedback-text">
<strong>Message:</strong><br>
{{ message }}
</div>
<p class="field-label" style="color:#a0a0a0;font-size:12px;text-transform:uppercase;letter-spacing:0.6px;margin:0 0 4px;">From</p>
<p class="field-value" style="color:#e0e0e0;font-size:15px;margin:0 0 16px;">
<a href="mailto:{{ email }}" style="color:#00f3ff;text-decoration:none;">{{ email }}</a>
</p>
<p>Thank you for your attention.</p>
</div>
<p class="field-label" style="color:#a0a0a0;font-size:12px;text-transform:uppercase;letter-spacing:0.6px;margin:0 0 4px;">Message</p>
<p class="field-value" style="color:#e0e0e0;font-size:15px;margin:0 0 16px;white-space:pre-wrap;">{{ message }}</p>
{% endblock %}
<!-- Footer -->
<div class="footer">
<p>This is an automated message. Please do not reply to this email.</p>
<p>&copy; 2025 AI ML Operations, LLC. All rights reserved.</p>
</div>
</div>
</td>
</tr>
</table>
</body>
</html>
{% block footer_note %}This is an automated message. Please do not reply to this email.{% endblock %}
@@ -1,3 +1,12 @@
New Contact Request for AI ML Operations, LLC
New Contact Request — {{ brand_legal|default:"AI ML Operations, LLC" }}
"New Contact. {{ subject }} from {{ email }}. {{ message }}"
Subject: {{ subject }}
From: {{ email }}
Message:
{{ message }}
{{ brand_legal|default:"AI ML Operations, LLC" }}
{{ site_url|default:"https://aimloperations.com" }}
Forward-deployed AI engineering
@@ -1,61 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Email Template</title>
<!-- Materialize CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet">
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.email-container {
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.header {
background-color: #37474f;
color: #ffffff;
padding: 20px;
text-align: center;
}
.content {
padding: 20px;
color: #333333;
}
.footer {
background-color: #333;
padding: 10px;
text-align: center;
font-size: 12px;
color: white;
}
</style>
</head>
<body>
<div class="email-container">
<!-- Header -->
<div class="header">
<h4>{{ title | safe }}</h4>
</div>
{% extends "emails/base_email.html" %}
<!-- Content -->
<div class="content">
{{ content | safe }}
</div>
{% block title %}{{ title }}{% endblock %}
<!-- Footer -->
<div class="footer">
<p>© 2025 AI ML Operations, LLC. All rights reserved.</p>
</div>
</div>
</body>
</html>
{% block header_extra %}
{% if title %}
<p style="margin:16px 0 0;font-size:18px;font-weight:600;color:#e0e0e0;line-height:1.4;">{{ title|safe }}</p>
{% endif %}
{% endblock %}
{% block content %}
{{ content|safe }}
{% endblock %}
{% block footer_note %}{% endblock %}
@@ -1,3 +1,8 @@
{{ subject }}
{{ title }}
{{ content }}
{{ brand_legal|default:"AI ML Operations, LLC" }}
{{ site_url|default:"https://aimloperations.com" }}
Forward-deployed AI engineering
@@ -1,90 +0,0 @@
{% extends "base.html" %}
{% load static %}
{% block title %}File Hosting - AI ML Operations, LLC{% endblock %}
{% block meta_description %}Secure, scalable, and reliable file hosting with weekly backups by AI ML Operations, LLC.
Protect your data with our advanced storage solutions.{% endblock %}
{% block content %}
<!-- Hero Section -->
<div class="hero-section" style="height: 40vh; min-height: 300px;">
<div class="hero-content">
<h1 class="hero-title">File Hosting</h1>
<p class="hero-subtitle">Secure, Scalable, and Reliable File Storage with Weekly Backups</p>
</div>
</div>
<!-- About File Hosting Section -->
<div class="section">
<div class="container">
<h2 class="section-title">About Our File Hosting Service</h2>
<p style="text-align: center; max-width: 800px; margin: 0 auto; color: var(--text-muted); font-size: 1.1rem;">
At AI ML Operations, we provide secure and scalable file hosting solutions tailored to your business needs. Our
platform ensures your data is always accessible, protected, and backed up with weekly backups for added peace of
mind. Whether you're storing critical business documents, media files, or large datasets, our file hosting service
is designed to meet your requirements with reliability and efficiency.
</p>
</div>
</div>
<!-- Features Section -->
<div class="section" style="background: var(--surface-color);">
<div class="container">
<h2 class="section-title">What We Offer</h2>
<div class="card-grid">
<div class="card" style="text-align: center;">
<h5 class="card-title">Secure Storage</h5>
<p class="card-text">Your files are stored securely with advanced encryption protocols.</p>
</div>
<div class="card" style="text-align: center;">
<h5 class="card-title">Weekly Backups</h5>
<p class="card-text">Automatic weekly backups to ensure your data is always safe.</p>
</div>
<div class="card" style="text-align: center;">
<h5 class="card-title">Scalable Solutions</h5>
<p class="card-text">Easily scale your storage as your business grows.</p>
</div>
</div>
</div>
</div>
<!-- Benefits Section -->
<div class="section">
<div class="container">
<h2 class="section-title">Why Choose Us?</h2>
<div class="card-grid">
<div class="card">
<img src="{% static 'public/img/file_hosting/card-1.jpg' %}" alt="Data Security"
style="width: 100%; border-radius: 8px; margin-bottom: 1rem;">
<span class="card-title">Data Security</span>
<p class="card-text">Advanced encryption and access controls to protect your files.</p>
</div>
<div class="card">
<img src="{% static 'public/img/file_hosting/card-2.jpg' %}" alt="Reliability"
style="width: 100%; border-radius: 8px; margin-bottom: 1rem;">
<span class="card-title">Reliability</span>
<p class="card-text">99.9% uptime guarantee for uninterrupted access to your files.</p>
</div>
<div class="card">
<img src="{% static 'public/img/file_hosting/card-3.jpg' %}" alt="Easy Management"
style="width: 100%; border-radius: 8px; margin-bottom: 1rem;">
<span class="card-title">Easy Management</span>
<p class="card-text">User-friendly interface for seamless file management.</p>
</div>
</div>
</div>
</div>
<!-- Call to Action Section -->
<div class="section" style="text-align: center;">
<div class="container">
<h2 class="section-title">Ready to Secure Your Files?</h2>
<p class="hero-subtitle" style="margin-bottom: 2rem;">Contact us today to get started with our file hosting service.
</p>
<a href="{% url 'contact' %}" class="btn"
data-tianji-event="service_cta" data-tianji-event-page="file_hosting" data-tianji-event-action="get_started">Get Started</a>
</div>
</div>
{% endblock %}
@@ -53,10 +53,6 @@
<h3>Web Design</h3>
<p>Elevate your online presence with captivating web design that blends creativity with functionality. Our expert designers craft visually stunning websites that engage your audience and drive conversions, ensuring a seamless user experience across all devices.</p>
</div>
<div class="col-4">
<h3>File Hosting</h3>
<p>Securely store and share your files with ease using our reliable file hosting platform. With robust encryption and flexible access controls, you can confidently manage your data, collaborate seamlessly, and streamline your workflow.</p>
</div>
<div class="col-4">
<h3>App Virtualization</h3>
<p>Transform your software delivery with our app virtualization solutions, enabling seamless access to applications from any device, anywhere. Experience enhanced flexibility, scalability, and security as we optimize your IT infrastructure for the digital age.</p>
@@ -219,12 +219,6 @@
<p class="card-text">Servers and workstations for compute, storage, and local inference workloads.</p>
</a>
<a href="{% url 'file_hosting' %}" class="card"
data-tianji-event="service_click" data-tianji-event-service="File Hosting">
<span class="card-title">File Hosting</span>
<p class="card-text">Secure, scalable file hosting to store and share your data.</p>
</a>
</div>
</div>
</div>
@@ -1,61 +1 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Email Template</title>
<!-- Materialize CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet">
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.email-container {
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.header {
background-color: #37474f;
color: #ffffff;
padding: 20px;
text-align: center;
}
.content {
padding: 20px;
color: #333333;
}
.footer {
background-color: #333;
padding: 10px;
text-align: center;
font-size: 12px;
color: white;
}
</style>
</head>
<body>
<div class="email-container">
<!-- Header -->
<div class="header">
<h4>{{ title | safe }}</h4>
</div>
<!-- Content -->
<div class="content">
{{ content | safe }}
</div>
<!-- Footer -->
<div class="footer">
<p>© 2025 AI ML Operations, LLC. All rights reserved.</p>
</div>
</div>
</body>
</html>
{% extends "emails/marketing_email.html" %}
+6 -1
View File
@@ -1,4 +1,5 @@
from django.urls import path
from django.views.generic import RedirectView
from . import seo, views
@@ -12,7 +13,11 @@ urlpatterns = [
path("computer", views.computers, name="computers"),
path("web_design", views.web_design, name="web_design"),
path("ai_sensor", views.ai_sensor, name="ai_sensor"),
path("file_hosting", views.file_hosting, name="file_hosting"),
# Permanent redirect: product retired; keep URL for inbound links/search results.
path(
"file_hosting",
RedirectView.as_view(pattern_name="public_index", permanent=True),
),
path("bot_creation", views.bot, name="bot"),
path("forward-deployed-ai", views.forward_deployed, name="forward_deployed"),
path("ml_model", views.ml_model, name="ml_model"),
+16 -16
View File
@@ -14,20 +14,25 @@ from django.urls import reverse
from django.utils import timezone
from django.views.decorators.http import require_POST
from .email_branding import email_brand_context
from .forms import FormWithCaptcha
from .middleware import get_session_utm
from .models import Contact, EmailMessage, PageVisit
from .traffic import TRAFFIC_TYPE_LABELS, TrafficType
def send_contact_email(email, subject, message):
subject = "New Contact Request for AI ML Operations, LLC"
from_email = "ryan@aimloperations.com"
to="ryan@aimloperations.com"
d = {"subject": subject, "message": message, "email": email}
html_content = get_template(r'emails/contact_email.html').render(d)
text_content = get_template(r'emails/contact_email.txt').render(d)
mail_subject = "New Contact Request for AI ML Operations, LLC"
from_email = getattr(
settings,
"DEFAULT_FROM_EMAIL",
"AI ML Operations, LLC <info@aimloperations.com>",
)
to = "ryan@aimloperations.com"
d = email_brand_context(subject=subject, message=message, email=email)
html_content = get_template("emails/contact_email.html").render(d)
text_content = get_template("emails/contact_email.txt").render(d)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg = EmailMultiAlternatives(mail_subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send(fail_silently=True)
@@ -66,9 +71,6 @@ def web_design(request):
def ai_sensor(request):
return render(request, "public/ai_sensor.html", {})
def file_hosting(request):
return render(request, "public/file_hosting.html", {})
def bot(request):
return render(request, "public/bot.html", {})
@@ -84,13 +86,11 @@ def terms_of_service(request):
@login_required
def preview_email(request, pk):
email_instance = get_object_or_404(EmailMessage, pk=pk)
context = {
"title":email_instance.subject,
"content":email_instance.body
}
return render(
request, 'public/preview_email.html', context
context = email_brand_context(
title=email_instance.subject,
content=email_instance.body,
)
return render(request, "emails/marketing_email.html", context)
def contact(request):
errors = ''
+11
View File
@@ -0,0 +1,11 @@
# Email previews
Static renders of branded HTML emails (dark neon site UX: `#0a0a0a` / `#1a1a1a` / `#00f3ff` / `#bc13fe`).
| Template | Screenshot |
|----------|------------|
| Contact notify | [contact.png](contact.png) |
| Marketing | [marketing.png](marketing.png) |
| Invoice / pay link | [invoice.png](invoice.png) |
Shared base: `public/templates/emails/base_email.html`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB