Feat: Add marketing site and switch to git-based deployment

This commit is contained in:
poduck
2025-11-30 16:18:11 -05:00
parent 2b28fc49c9
commit 0d1a3045fb
6 changed files with 90 additions and 43 deletions

View File

@@ -65,6 +65,9 @@ ssh "$SERVER" "mkdir -p ~/smoothschedule"
# Upload backend # Upload backend
rsync -avz --delete /tmp/smoothschedule-deploy/backend/ "$SERVER:~/smoothschedule/" rsync -avz --delete /tmp/smoothschedule-deploy/backend/ "$SERVER:~/smoothschedule/"
# Upload nginx config
scp "$PROJECT_DIR/frontend/nginx.conf" "$SERVER:~/smoothschedule/nginx.conf"
# Upload frontend # Upload frontend
rsync -avz --delete /tmp/smoothschedule-deploy/frontend/ "$SERVER:~/smoothschedule-frontend/" rsync -avz --delete /tmp/smoothschedule-deploy/frontend/ "$SERVER:~/smoothschedule-frontend/"

View File

@@ -45,7 +45,36 @@ http {
add_header Cache-Control "public, immutable"; add_header Cache-Control "public, immutable";
} }
# Handle SPA routing - serve index.html for all routes # Proxy API requests to Django
location /api/ {
proxy_pass http://django:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Proxy Admin requests to Django
location /admin/ {
proxy_pass http://django:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Proxy Static/Media to Django (if served by WhiteNoise/Django)
location /static/ {
proxy_pass http://django:5000;
proxy_set_header Host $host;
}
location /media/ {
proxy_pass http://django:5000;
proxy_set_header Host $host;
}
# Handle SPA routing - serve index.html for all other routes
location / { location / {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }

View File

@@ -233,14 +233,11 @@
"newTicket": "New Ticket", "newTicket": "New Ticket",
"errorLoading": "Error loading tickets", "errorLoading": "Error loading tickets",
"subject": "Subject", "subject": "Subject",
"description": "Description",
"status": "Status",
"priority": "Priority", "priority": "Priority",
"category": "Category", "category": "Category",
"ticketType": "Ticket Type", "ticketType": "Ticket Type",
"assignee": "Assignee", "assignee": "Assignee",
"assignedTo": "Assigned to", "assignedTo": "Assigned to",
"createdAt": "Created At",
"unassigned": "Unassigned", "unassigned": "Unassigned",
"noTicketsFound": "No tickets found", "noTicketsFound": "No tickets found",
"noTicketsInStatus": "No tickets with this status", "noTicketsInStatus": "No tickets with this status",
@@ -300,15 +297,8 @@
}, },
"sandboxRestriction": "Platform Support Unavailable in Test Mode", "sandboxRestriction": "Platform Support Unavailable in Test Mode",
"sandboxRestrictionMessage": "You can only contact SmoothSchedule support in live mode. Please switch to live mode to create a support ticket.", "sandboxRestrictionMessage": "You can only contact SmoothSchedule support in live mode. Please switch to live mode to create a support ticket.",
"status": {
"open": "Open",
"in_progress": "In Progress",
"awaiting_response": "Awaiting Response",
"resolved": "Resolved",
"closed": "Closed"
},
"ticketNumber": "Ticket #{{number}}", "ticketNumber": "Ticket #{{number}}",
"createdAt": "Created {{date}}" "createdDate": "Created {{date}}"
}, },
"customerSupport": { "customerSupport": {
"title": "Support", "title": "Support",
@@ -673,46 +663,46 @@
"signup": "Sign Up" "signup": "Sign Up"
}, },
"hero": { "hero": {
"headline": "Scheduling Made Simple", "headline": "Orchestrate Your Business",
"subheadline": "The all-in-one platform for managing appointments, resources, and customers. Start free, scale as you grow.", "subheadline": "The enterprise-grade scheduling platform for service businesses. Multi-tenant, white-label ready, and designed for scale.",
"cta": "Get Started Free", "cta": "Start Your Free Trial",
"secondaryCta": "Watch Demo", "secondaryCta": "View Live Demo",
"trustedBy": "Trusted by 1,000+ businesses worldwide" "trustedBy": "Powering next-generation service platforms"
}, },
"features": { "features": {
"title": "Everything You Need", "title": "Built for Modern Service Businesses",
"subtitle": "Powerful features to run your service business", "subtitle": "A complete platform to manage your schedule, staff, and growth.",
"scheduling": { "scheduling": {
"title": "Smart Scheduling", "title": "Intelligent Scheduling",
"description": "Drag-and-drop calendar with real-time availability, automated reminders, and conflict detection." "description": "Conflict-free booking engine that handles complex resource availability and staff schedules automatically."
}, },
"resources": { "resources": {
"title": "Resource Management", "title": "Resource Orchestration",
"description": "Manage staff, rooms, and equipment. Set availability, skills, and booking rules." "description": "Manage rooms, equipment, and staff as distinct resources with their own availability rules and dependencies."
}, },
"customers": { "customers": {
"title": "Customer Portal", "title": "Client Portal",
"description": "Self-service booking portal for customers. View history, manage appointments, and save payment methods." "description": "Give your clients a premium self-service experience with a dedicated portal to book, pay, and manage appointments."
}, },
"payments": { "payments": {
"title": "Integrated Payments", "title": "Seamless Payments",
"description": "Accept payments online with Stripe. Deposits, full payments, and automatic invoicing." "description": "Secure payment processing powered by Stripe. Accept deposits, full payments, and manage refunds effortlessly."
}, },
"multiTenant": { "multiTenant": {
"title": "Multi-Location Support", "title": "Multi-Location & Franchise Ready",
"description": "Manage multiple locations or brands from a single dashboard with isolated data." "description": "Scale from one location to hundreds. Isolated data, centralized management, and role-based access control."
}, },
"whiteLabel": { "whiteLabel": {
"title": "White-Label Ready", "title": "Your Brand, Front and Center",
"description": "Custom domain, branding, and remove SmoothSchedule branding for a seamless experience." "description": "Fully white-label capable. Use your own domain, logo, and colors. Your customers will never know it's us."
}, },
"analytics": { "analytics": {
"title": "Analytics & Reports", "title": "Business Intelligence",
"description": "Track revenue, appointments, and customer trends with beautiful dashboards." "description": "Real-time dashboards showing revenue, utilization, and growth metrics to help you make data-driven decisions."
}, },
"integrations": { "integrations": {
"title": "Powerful Integrations", "title": "Extensible Platform",
"description": "Connect with Google Calendar, Zoom, Stripe, and more. API access for custom integrations." "description": "API-first design allows deep integration with your existing tools and workflows."
} }
}, },
"howItWorks": { "howItWorks": {
@@ -1147,4 +1137,4 @@
"goToDashboard": "Go to Dashboard" "goToDashboard": "Go to Dashboard"
} }
} }
} }

View File

@@ -59,6 +59,18 @@ const HomePage: React.FC = () => {
descriptionKey: 'marketing.features.whiteLabel.description', descriptionKey: 'marketing.features.whiteLabel.description',
color: 'cyan', color: 'cyan',
}, },
{
icon: BarChart3,
titleKey: 'marketing.features.analytics.title',
descriptionKey: 'marketing.features.analytics.description',
color: 'indigo',
},
{
icon: Plug,
titleKey: 'marketing.features.integrations.title',
descriptionKey: 'marketing.features.integrations.description',
color: 'teal',
},
]; ];
const testimonials = [ const testimonials = [

View File

@@ -37,7 +37,9 @@ http:
- web-secure - web-secure
middlewares: middlewares:
- csrf - csrf
service: django middlewares:
- csrf
service: nginx
tls: tls:
certResolver: letsencrypt certResolver: letsencrypt
@@ -48,7 +50,7 @@ http:
- web-secure - web-secure
middlewares: middlewares:
- csrf - csrf
service: django service: nginx
tls: tls:
certResolver: letsencrypt certResolver: letsencrypt
@@ -101,6 +103,11 @@ http:
servers: servers:
- url: http://flower:5555 - url: http://flower:5555
nginx:
loadBalancer:
servers:
- url: http://nginx:80
providers: providers:
# https://doc.traefik.io/traefik/master/providers/file/ # https://doc.traefik.io/traefik/master/providers/file/
file: file:

View File

@@ -2,10 +2,8 @@ volumes:
production_postgres_data: {} production_postgres_data: {}
production_postgres_data_backups: {} production_postgres_data_backups: {}
production_traefik: {} production_traefik: {}
production_redis_data: {}
production_redis_data: {}
services: services:
django: &django django: &django
@@ -46,13 +44,21 @@ services:
- '0.0.0.0:80:80' - '0.0.0.0:80:80'
- '0.0.0.0:443:443' - '0.0.0.0:443:443'
- '0.0.0.0:5555:5555' - '0.0.0.0:5555:5555'
- '0.0.0.0:5555:5555'
nginx:
build:
context: ../frontend
dockerfile: Dockerfile.prod
depends_on:
- django
ports:
- "8080:80" # Expose internally for Traefik
redis: redis:
image: docker.io/redis:7.2 image: docker.io/redis:7.2
volumes: volumes:
- production_redis_data:/data - production_redis_data:/data
celeryworker: celeryworker:
<<: *django <<: *django