feat: initial commit — HermesMessages SaaS platform

Backend (FastAPI + Python 3.12):
- Multi-tenant auth with JWT: login, register, refresh, Meta OAuth
- Business & BusinessConfig management
- WhatsApp webhook with HMAC signature verification
- Bot engine powered by Claude AI
- Calendar availability with Redis caching
- Reservations CRUD with status management
- Dashboard analytics (stats, agenda, peak hours)
- Billing & plan management
- Admin panel with platform-wide stats
- Async bcrypt via asyncio.to_thread
- IntegrityError handling for concurrent registration race conditions

Frontend (React 18 + Vite + Tailwind CSS):
- Multi-step guided registration form with helper text on every field
- Login page with show/hide password toggle
- Protected routes with AuthContext
- Dashboard with stats cards, bar chart, and daily agenda
- Reservations list with search, filters, and inline status actions
- Calendar with weekly view, slot availability, and date blocking
- Config page: business info, schedules, bot personality
- Billing page with plan comparison and usage bar

Design system:
- Bricolage Grotesque + DM Sans typography
- Emerald primary palette with semantic color tokens
- scale(0.97) button press feedback, ease-out animations
- Skeleton loaders, stagger animations, prefers-reduced-motion support
- Accessible: aria-labels, visible focus rings, 4.5:1 contrast

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-28 09:49:41 -05:00
commit 798bd14312
95 changed files with 5836 additions and 0 deletions

View File

@ -0,0 +1,93 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html', './src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {
fontFamily: {
display: ['"Bricolage Grotesque"', 'sans-serif'],
body: ['"DM Sans"', 'sans-serif'],
},
colors: {
bg: '#f7f8fc',
surface: '#ffffff',
border: '#e1e7ef',
primary: {
DEFAULT: '#059669',
50: '#ecfdf5',
100: '#d1fae5',
200: '#a7f3d0',
500: '#10b981',
600: '#059669',
700: '#047857',
900: '#064e3b',
},
slate: {
50: '#f8fafc',
100: '#f1f5f9',
200: '#e2e8f0',
300: '#cbd5e1',
400: '#94a3b8',
500: '#64748b',
600: '#475569',
700: '#334155',
800: '#1e293b',
900: '#0f172a',
},
danger: {
DEFAULT: '#dc2626',
50: '#fef2f2',
100: '#fee2e2',
500: '#ef4444',
600: '#dc2626',
},
warning: {
DEFAULT: '#d97706',
50: '#fffbeb',
100: '#fef3c7',
500: '#f59e0b',
600: '#d97706',
},
},
boxShadow: {
card: '0 1px 3px 0 rgb(0 0 0 / 0.06), 0 1px 2px -1px rgb(0 0 0 / 0.04)',
'card-hover': '0 4px 12px 0 rgb(0 0 0 / 0.08), 0 2px 4px -1px rgb(0 0 0 / 0.04)',
dialog: '0 20px 60px -10px rgb(0 0 0 / 0.15)',
},
borderRadius: {
DEFAULT: '0.5rem',
lg: '0.75rem',
xl: '1rem',
'2xl': '1.25rem',
},
animation: {
'fade-in': 'fadeIn 0.2s ease-out',
'slide-up': 'slideUp 0.25s cubic-bezier(0.23, 1, 0.32, 1)',
'stagger-1': 'fadeSlideUp 0.3s cubic-bezier(0.23, 1, 0.32, 1) 0ms both',
'stagger-2': 'fadeSlideUp 0.3s cubic-bezier(0.23, 1, 0.32, 1) 50ms both',
'stagger-3': 'fadeSlideUp 0.3s cubic-bezier(0.23, 1, 0.32, 1) 100ms both',
'stagger-4': 'fadeSlideUp 0.3s cubic-bezier(0.23, 1, 0.32, 1) 150ms both',
'stagger-5': 'fadeSlideUp 0.3s cubic-bezier(0.23, 1, 0.32, 1) 200ms both',
'skeleton': 'skeleton 1.5s ease-in-out infinite',
},
keyframes: {
fadeIn: {
from: { opacity: '0' },
to: { opacity: '1' },
},
slideUp: {
from: { opacity: '0', transform: 'translateY(8px)' },
to: { opacity: '1', transform: 'translateY(0)' },
},
fadeSlideUp: {
from: { opacity: '0', transform: 'translateY(6px)' },
to: { opacity: '1', transform: 'translateY(0)' },
},
skeleton: {
'0%, 100%': { opacity: '1' },
'50%': { opacity: '0.4' },
},
},
},
},
plugins: [],
}