Initial commit: SmoothSchedule multi-tenant scheduling platform

This commit includes:
- Django backend with multi-tenancy (django-tenants)
- React + TypeScript frontend with Vite
- Platform administration API with role-based access control
- Authentication system with token-based auth
- Quick login dev tools for testing different user roles
- CORS and CSRF configuration for local development
- Docker development environment setup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
poduck
2025-11-27 01:43:20 -05:00
commit 2e111364a2
567 changed files with 96410 additions and 0 deletions

210
frontend/src/types.ts Normal file
View File

@@ -0,0 +1,210 @@
// Domain models based on the Game Plan
// FIX: Added PageComponent types and updated Business interface for website editor feature.
export type PageComponentType = 'HEADING' | 'TEXT' | 'IMAGE' | 'BUTTON' | 'SERVICE' | 'COLUMNS';
export interface PageComponent {
id: string;
type: PageComponentType;
content?: {
text?: string;
level?: 1 | 2 | 3;
src?: string;
alt?: string;
buttonText?: string;
href?: string;
serviceId?: string;
};
children?: PageComponent[][];
}
export interface CustomDomain {
id: number;
domain: string;
is_verified: boolean;
ssl_provisioned: boolean;
is_primary: boolean;
verification_token: string;
dns_txt_record: string;
dns_txt_record_name: string;
created_at: string;
verified_at?: string;
}
export interface Business {
id: string;
name: string;
subdomain: string;
primaryColor: string;
secondaryColor: string;
logoUrl?: string;
whitelabelEnabled: boolean;
plan?: 'Free' | 'Professional' | 'Business' | 'Enterprise';
status?: 'Active' | 'Suspended' | 'Trial';
joinedAt?: Date;
resourcesCanReschedule?: boolean;
paymentsEnabled: boolean;
requirePaymentMethodToBook: boolean;
cancellationWindowHours: number;
lateCancellationFeePercent: number;
initialSetupComplete?: boolean;
customDomain?: string;
customDomainVerified?: boolean;
stripeConnectAccountId?: string;
websitePages?: Record<string, { name: string; content: PageComponent[] }>;
customerDashboardContent?: PageComponent[];
trialStart?: string;
trialEnd?: string;
isTrialActive?: boolean;
isTrialExpired?: boolean;
daysLeftInTrial?: number;
}
export type UserRole = 'superuser' | 'platform_manager' | 'platform_support' | 'owner' | 'manager' | 'staff' | 'resource' | 'customer';
export interface NotificationPreferences {
email: boolean;
sms: boolean;
in_app: boolean;
appointment_reminders: boolean;
marketing: boolean;
}
export interface User {
id: string | number;
username?: string;
name: string;
email: string;
role: UserRole;
avatarUrl?: string;
phone?: string;
email_verified?: boolean;
two_factor_enabled?: boolean;
timezone?: string;
locale?: string;
notification_preferences?: NotificationPreferences;
}
export type ResourceType = 'STAFF' | 'ROOM' | 'EQUIPMENT';
export interface Resource {
id: string;
name: string;
type: ResourceType;
userId?: string;
}
export type AppointmentStatus = 'PENDING' | 'CONFIRMED' | 'COMPLETED' | 'CANCELLED' | 'NO_SHOW';
export interface Appointment {
id: string;
resourceId: string | null; // null if unassigned
customerId?: string; // optional for walk-in appointments
customerName: string;
serviceId: string;
startTime: Date; // For MVP, we will assume a specific date
durationMinutes: number;
status: AppointmentStatus;
notes?: string;
}
export interface Blocker {
id: string;
resourceId: string;
startTime: Date;
durationMinutes: number;
title: string;
}
export interface PaymentMethod {
id: string;
brand: 'Visa' | 'Mastercard' | 'Amex';
last4: string;
isDefault: boolean;
}
export interface Customer {
id: string;
name: string;
email: string;
phone: string;
city?: string;
state?: string;
zip?: string;
totalSpend: number;
lastVisit: Date | null;
status: 'Active' | 'Inactive' | 'Blocked';
avatarUrl?: string;
tags?: string[];
userId?: string;
paymentMethods: PaymentMethod[];
}
export interface Service {
id: string;
name: string;
durationMinutes: number;
price: number;
description: string;
}
export interface Metric {
label: string;
value: string;
change: string;
trend: 'up' | 'down' | 'neutral';
}
// --- Platform Types ---
export interface Ticket {
id: string;
subject: string;
businessName: string;
priority: 'Low' | 'Medium' | 'High' | 'Critical';
status: 'Open' | 'In Progress' | 'Resolved';
createdAt: Date;
}
export interface PlatformMetric {
label: string;
value: string;
change: string;
trend: 'up' | 'down' | 'neutral';
color: 'blue' | 'green' | 'purple' | 'orange';
}
// --- OAuth Settings Types ---
export interface BusinessOAuthSettings {
enabledProviders: string[];
allowRegistration: boolean;
autoLinkByEmail: boolean;
}
export interface BusinessOAuthSettingsResponse {
businessSettings: BusinessOAuthSettings;
availableProviders: string[];
}
// --- OAuth Credentials Types ---
export interface OAuthProviderCredentials {
client_id: string;
client_secret: string;
team_id?: string; // Apple only
key_id?: string; // Apple only
tenant_id?: string; // Microsoft only
}
export interface BusinessOAuthCredentials {
use_custom_credentials: boolean;
google?: OAuthProviderCredentials;
apple?: OAuthProviderCredentials;
facebook?: OAuthProviderCredentials;
linkedin?: OAuthProviderCredentials;
microsoft?: OAuthProviderCredentials;
twitter?: OAuthProviderCredentials;
twitch?: OAuthProviderCredentials;
}