Add scheduler improvements, API endpoints, and month calendar view

Backend:
- Add /api/customers/ endpoint (CustomerViewSet, CustomerSerializer)
- Add /api/services/ endpoint with Service model and migrations
- Add Resource.type field (STAFF, ROOM, EQUIPMENT) with migration
- Fix EventSerializer to return resource_id, customer_id, service_id
- Add date range filtering to EventViewSet (start_date, end_date params)
- Add create_demo_appointments management command
- Set default brand colors in business API

Frontend:
- Add calendar grid view for month mode in OwnerScheduler
- Fix sidebar navigation active link contrast (bg-white/10)
- Add default primaryColor/secondaryColor fallbacks in useBusiness
- Disable WebSocket (backend not implemented) to stop reconnect loop
- Fix Resource.type.toLowerCase() error by adding type to backend

🤖 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 20:09:04 -05:00
parent 38c43d3f27
commit 373257469b
38 changed files with 977 additions and 2111 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

View File

@@ -1,343 +0,0 @@
# Page snapshot
```yaml
- generic [ref=e2]:
- generic [ref=e3]:
- navigation [ref=e4]:
- generic [ref=e6]:
- link "Smooth Schedule" [ref=e7] [cursor=pointer]:
- /url: "#/"
- img [ref=e8]
- generic [ref=e14]: Smooth Schedule
- generic [ref=e15]:
- link "Features" [ref=e16] [cursor=pointer]:
- /url: "#/features"
- link "Pricing" [ref=e17] [cursor=pointer]:
- /url: "#/pricing"
- link "About" [ref=e18] [cursor=pointer]:
- /url: "#/about"
- link "Contact" [ref=e19] [cursor=pointer]:
- /url: "#/contact"
- generic [ref=e20]:
- button "🇺🇸 English" [ref=e23]:
- img [ref=e24]
- generic [ref=e27]: 🇺🇸
- generic [ref=e28]: English
- img [ref=e29]
- button "Switch to dark mode" [ref=e31]:
- img [ref=e32]
- link "Login" [ref=e34] [cursor=pointer]:
- /url: "#/login"
- link "Get Started" [ref=e35] [cursor=pointer]:
- /url: "#/signup"
- main [ref=e36]:
- generic [ref=e37]:
- generic [ref=e42]:
- generic [ref=e43]:
- generic [ref=e44]:
- generic [ref=e47]: Get started today
- heading "Scheduling Made Simple" [level=1] [ref=e48]
- paragraph [ref=e49]: The all-in-one platform for managing appointments, resources, and customers. Start free, scale as you grow.
- generic [ref=e50]:
- link "Get Started Free" [ref=e51] [cursor=pointer]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e52]
- button "Watch Demo" [ref=e54]:
- img [ref=e55]
- text: Watch Demo
- generic [ref=e57]:
- generic [ref=e58]:
- img [ref=e59]
- generic [ref=e62]: No credit card required
- generic [ref=e64]:
- img [ref=e65]
- generic [ref=e68]: Get started today
- generic [ref=e69]:
- generic [ref=e71]:
- generic [ref=e78]: dashboard.smoothschedule.com
- generic [ref=e79]:
- generic [ref=e80]:
- generic [ref=e81]:
- generic [ref=e82]: Today
- generic [ref=e83]: "12"
- generic [ref=e84]:
- generic [ref=e85]: This Week
- generic [ref=e86]: "48"
- generic [ref=e87]:
- generic [ref=e88]: Revenue
- generic [ref=e89]: $2.4k
- generic [ref=e90]:
- generic [ref=e91]: Today's Schedule
- generic [ref=e92]:
- generic [ref=e95]:
- generic [ref=e96]: 9:00 AM
- generic [ref=e97]: Sarah J. - Haircut
- generic [ref=e100]:
- generic [ref=e101]: 10:30 AM
- generic [ref=e102]: Mike T. - Consultation
- generic [ref=e105]:
- generic [ref=e106]: 2:00 PM
- generic [ref=e107]: Emma W. - Color
- generic [ref=e109]:
- img [ref=e111]
- generic [ref=e114]:
- generic [ref=e115]: New Booking!
- generic [ref=e116]: Just now
- generic [ref=e117]:
- paragraph [ref=e118]: Trusted by 1,000+ businesses worldwide
- generic [ref=e119]:
- generic [ref=e120]: TechCorp
- generic [ref=e121]: Innovate
- generic [ref=e122]: StartupX
- generic [ref=e123]: GrowthCo
- generic [ref=e124]: ScaleUp
- generic [ref=e126]:
- generic [ref=e127]:
- heading "Everything You Need" [level=2] [ref=e128]
- paragraph [ref=e129]: Powerful features to run your service business
- generic [ref=e130]:
- generic [ref=e131]:
- img [ref=e133]
- heading "Smart Scheduling" [level=3] [ref=e135]
- paragraph [ref=e136]: Drag-and-drop calendar with real-time availability, automated reminders, and conflict detection.
- generic [ref=e137]:
- img [ref=e139]
- heading "Resource Management" [level=3] [ref=e144]
- paragraph [ref=e145]: Manage staff, rooms, and equipment. Set availability, skills, and booking rules.
- generic [ref=e146]:
- img [ref=e148]
- heading "Customer Portal" [level=3] [ref=e152]
- paragraph [ref=e153]: Self-service booking portal for customers. View history, manage appointments, and save payment methods.
- generic [ref=e154]:
- img [ref=e156]
- heading "Integrated Payments" [level=3] [ref=e158]
- paragraph [ref=e159]: Accept payments online with Stripe. Deposits, full payments, and automatic invoicing.
- generic [ref=e160]:
- img [ref=e162]
- heading "Multi-Location Support" [level=3] [ref=e166]
- paragraph [ref=e167]: Manage multiple locations or brands from a single dashboard with isolated data.
- generic [ref=e168]:
- img [ref=e170]
- heading "White-Label Ready" [level=3] [ref=e176]
- paragraph [ref=e177]: Custom domain, branding, and remove SmoothSchedule branding for a seamless experience.
- link "View All features" [ref=e179] [cursor=pointer]:
- /url: "#/features"
- text: View All features
- img [ref=e180]
- generic [ref=e183]:
- generic [ref=e184]:
- heading "Get Started in Minutes" [level=2] [ref=e185]
- paragraph [ref=e186]: Three simple steps to transform your scheduling
- generic [ref=e187]:
- generic [ref=e190]:
- generic [ref=e191]: "01"
- img [ref=e193]
- heading "Create Your Account" [level=3] [ref=e196]
- paragraph [ref=e197]: Sign up for free and set up your business profile in minutes.
- generic [ref=e200]:
- generic [ref=e201]: "02"
- img [ref=e203]
- heading "Add Your Services" [level=3] [ref=e206]
- paragraph [ref=e207]: Configure your services, pricing, and available resources.
- generic [ref=e209]:
- generic [ref=e210]: "03"
- img [ref=e212]
- heading "Start Booking" [level=3] [ref=e217]
- paragraph [ref=e218]: Share your booking link and let customers schedule instantly.
- generic [ref=e221]:
- generic [ref=e222]:
- img [ref=e224]
- generic [ref=e226]: 1M+
- generic [ref=e227]: Appointments Scheduled
- generic [ref=e228]:
- img [ref=e230]
- generic [ref=e234]: 5,000+
- generic [ref=e235]: Businesses
- generic [ref=e236]:
- img [ref=e238]
- generic [ref=e241]: 50+
- generic [ref=e242]: Countries
- generic [ref=e243]:
- img [ref=e245]
- generic [ref=e248]: 99.9%
- generic [ref=e249]: Uptime
- generic [ref=e251]:
- generic [ref=e252]:
- heading "Loved by Businesses Everywhere" [level=2] [ref=e253]
- paragraph [ref=e254]: See what our customers have to say
- generic [ref=e255]:
- generic [ref=e256]:
- generic [ref=e257]:
- img [ref=e258]
- img [ref=e260]
- img [ref=e262]
- img [ref=e264]
- img [ref=e266]
- blockquote [ref=e268]: "\"SmoothSchedule transformed how we manage appointments. Our no-show rate dropped by 40% with automated reminders.\""
- generic [ref=e269]:
- generic [ref=e271]: S
- generic [ref=e272]:
- generic [ref=e273]: Sarah Johnson
- generic [ref=e274]: Owner at Luxe Salon
- generic [ref=e275]:
- generic [ref=e276]:
- img [ref=e277]
- img [ref=e279]
- img [ref=e281]
- img [ref=e283]
- img [ref=e285]
- blockquote [ref=e287]: "\"The white-label feature is perfect for our multi-location business. Each location has its own branded booking experience.\""
- generic [ref=e288]:
- generic [ref=e290]: M
- generic [ref=e291]:
- generic [ref=e292]: Michael Chen
- generic [ref=e293]: CEO at FitLife Studios
- generic [ref=e294]:
- generic [ref=e295]:
- img [ref=e296]
- img [ref=e298]
- img [ref=e300]
- img [ref=e302]
- img [ref=e304]
- blockquote [ref=e306]: "\"Setup was incredibly easy. We were up and running in under an hour, and our clients love the self-service booking.\""
- generic [ref=e307]:
- generic [ref=e309]: E
- generic [ref=e310]:
- generic [ref=e311]: Emily Rodriguez
- generic [ref=e312]: Manager at Peak Performance Therapy
- generic [ref=e314]:
- generic [ref=e315]:
- heading "Simple, Transparent Pricing" [level=2] [ref=e316]
- paragraph [ref=e317]: Start free, upgrade as you grow. No hidden fees.
- generic [ref=e318]:
- generic [ref=e319]:
- heading "Free" [level=3] [ref=e320]
- paragraph [ref=e321]: Perfect for getting started
- generic [ref=e322]: $0/month
- link "Get Started" [ref=e323] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e324]:
- generic [ref=e325]: Most Popular
- heading "Professional" [level=3] [ref=e326]
- paragraph [ref=e327]: For growing businesses
- generic [ref=e328]: $29/month
- link "Get Started" [ref=e329] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e330]:
- heading "Business" [level=3] [ref=e331]
- paragraph [ref=e332]: For established teams
- generic [ref=e333]: $79/month
- link "Get Started" [ref=e334] [cursor=pointer]:
- /url: "#/signup"
- link "View full pricing details" [ref=e336] [cursor=pointer]:
- /url: "#/pricing"
- text: View full pricing details
- img [ref=e337]
- generic [ref=e343]:
- heading "Ready to get started?" [level=2] [ref=e344]
- paragraph [ref=e345]: Join thousands of businesses already using SmoothSchedule.
- generic [ref=e346]:
- link "Get Started Free" [ref=e347] [cursor=pointer]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e348]
- link "Talk to Sales" [ref=e350] [cursor=pointer]:
- /url: "#/contact"
- paragraph [ref=e351]: No credit card required
- contentinfo [ref=e352]:
- generic [ref=e353]:
- generic [ref=e354]:
- generic [ref=e355]:
- link "Smooth Schedule" [ref=e356] [cursor=pointer]:
- /url: "#/"
- img [ref=e357]
- generic [ref=e363]: Smooth Schedule
- paragraph [ref=e364]: The all-in-one scheduling platform for businesses of all sizes. Manage resources, staff, and bookings effortlessly.
- generic [ref=e365]:
- link "Twitter" [ref=e366] [cursor=pointer]:
- /url: https://twitter.com/smoothschedule
- img [ref=e367]
- link "LinkedIn" [ref=e369] [cursor=pointer]:
- /url: https://linkedin.com/company/smoothschedule
- img [ref=e370]
- link "GitHub" [ref=e374] [cursor=pointer]:
- /url: https://github.com/smoothschedule
- img [ref=e375]
- link "YouTube" [ref=e378] [cursor=pointer]:
- /url: https://youtube.com/@smoothschedule
- img [ref=e379]
- generic [ref=e382]:
- heading "Product" [level=3] [ref=e383]
- list [ref=e384]:
- listitem [ref=e385]:
- link "Features" [ref=e386] [cursor=pointer]:
- /url: "#/features"
- listitem [ref=e387]:
- link "Pricing" [ref=e388] [cursor=pointer]:
- /url: "#/pricing"
- listitem [ref=e389]:
- link "Get Started" [ref=e390] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e391]:
- heading "Company" [level=3] [ref=e392]
- list [ref=e393]:
- listitem [ref=e394]:
- link "About" [ref=e395] [cursor=pointer]:
- /url: "#/about"
- listitem [ref=e396]:
- link "Contact" [ref=e397] [cursor=pointer]:
- /url: "#/contact"
- generic [ref=e398]:
- heading "Legal" [level=3] [ref=e399]
- list [ref=e400]:
- listitem [ref=e401]:
- link "Privacy Policy" [ref=e402] [cursor=pointer]:
- /url: "#/privacy"
- listitem [ref=e403]:
- link "Terms of Service" [ref=e404] [cursor=pointer]:
- /url: "#/terms"
- paragraph [ref=e406]: © 2025 Smooth Schedule Inc. All rights reserved.
- generic [ref=e407]:
- generic [ref=e408]:
- heading "🔓 Quick Login (Dev Only)" [level=3] [ref=e409]:
- generic [ref=e410]: 🔓
- generic [ref=e411]: Quick Login (Dev Only)
- button "×" [ref=e412]
- generic [ref=e413]:
- button "Logging in..." [disabled] [ref=e414]:
- generic [ref=e415]:
- img [ref=e416]
- text: Logging in...
- button "Platform Manager PLATFORM_MANAGER" [disabled] [ref=e419]:
- generic [ref=e420]:
- generic [ref=e421]: Platform Manager
- generic [ref=e422]: PLATFORM_MANAGER
- button "Platform Sales PLATFORM_SALES" [disabled] [ref=e423]:
- generic [ref=e424]:
- generic [ref=e425]: Platform Sales
- generic [ref=e426]: PLATFORM_SALES
- button "Platform Support PLATFORM_SUPPORT" [disabled] [ref=e427]:
- generic [ref=e428]:
- generic [ref=e429]: Platform Support
- generic [ref=e430]: PLATFORM_SUPPORT
- button "Business Owner TENANT_OWNER" [disabled] [ref=e431]:
- generic [ref=e432]:
- generic [ref=e433]: Business Owner
- generic [ref=e434]: TENANT_OWNER
- button "Business Manager TENANT_MANAGER" [disabled] [ref=e435]:
- generic [ref=e436]:
- generic [ref=e437]: Business Manager
- generic [ref=e438]: TENANT_MANAGER
- button "Staff Member TENANT_STAFF" [disabled] [ref=e439]:
- generic [ref=e440]:
- generic [ref=e441]: Staff Member
- generic [ref=e442]: TENANT_STAFF
- button "Customer CUSTOMER" [disabled] [ref=e443]:
- generic [ref=e444]:
- generic [ref=e445]: Customer
- generic [ref=e446]: CUSTOMER
- generic [ref=e447]:
- text: "Password for all:"
- code [ref=e448]: test123
```

View File

@@ -1,343 +0,0 @@
# Page snapshot
```yaml
- generic [ref=e2]:
- generic [ref=e3]:
- navigation [ref=e4]:
- generic [ref=e6]:
- link "Smooth Schedule" [ref=e7]:
- /url: "#/"
- img [ref=e8]
- generic [ref=e14]: Smooth Schedule
- generic [ref=e15]:
- link "Features" [ref=e16]:
- /url: "#/features"
- link "Pricing" [ref=e17]:
- /url: "#/pricing"
- link "About" [ref=e18]:
- /url: "#/about"
- link "Contact" [ref=e19]:
- /url: "#/contact"
- generic [ref=e20]:
- button "🇺🇸 English" [ref=e23]:
- img [ref=e24]
- generic [ref=e27]: 🇺🇸
- generic [ref=e28]: English
- img [ref=e29]
- button "Switch to dark mode" [ref=e31]:
- img [ref=e32]
- link "Login" [ref=e34]:
- /url: "#/login"
- link "Get Started" [ref=e35]:
- /url: "#/signup"
- main [ref=e36]:
- generic [ref=e37]:
- generic [ref=e42]:
- generic [ref=e43]:
- generic [ref=e44]:
- generic [ref=e47]: Get started today
- heading "Scheduling Made Simple" [level=1] [ref=e48]
- paragraph [ref=e49]: The all-in-one platform for managing appointments, resources, and customers. Start free, scale as you grow.
- generic [ref=e50]:
- link "Get Started Free" [ref=e51]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e52]
- button "Watch Demo" [ref=e54]:
- img [ref=e55]
- text: Watch Demo
- generic [ref=e57]:
- generic [ref=e58]:
- img [ref=e59]
- generic [ref=e62]: No credit card required
- generic [ref=e64]:
- img [ref=e65]
- generic [ref=e68]: Get started today
- generic [ref=e69]:
- generic [ref=e71]:
- generic [ref=e78]: dashboard.smoothschedule.com
- generic [ref=e79]:
- generic [ref=e80]:
- generic [ref=e81]:
- generic [ref=e82]: Today
- generic [ref=e83]: "12"
- generic [ref=e84]:
- generic [ref=e85]: This Week
- generic [ref=e86]: "48"
- generic [ref=e87]:
- generic [ref=e88]: Revenue
- generic [ref=e89]: $2.4k
- generic [ref=e90]:
- generic [ref=e91]: Today's Schedule
- generic [ref=e92]:
- generic [ref=e95]:
- generic [ref=e96]: 9:00 AM
- generic [ref=e97]: Sarah J. - Haircut
- generic [ref=e100]:
- generic [ref=e101]: 10:30 AM
- generic [ref=e102]: Mike T. - Consultation
- generic [ref=e105]:
- generic [ref=e106]: 2:00 PM
- generic [ref=e107]: Emma W. - Color
- generic [ref=e109]:
- img [ref=e111]
- generic [ref=e114]:
- generic [ref=e115]: New Booking!
- generic [ref=e116]: Just now
- generic [ref=e117]:
- paragraph [ref=e118]: Trusted by 1,000+ businesses worldwide
- generic [ref=e119]:
- generic [ref=e120]: TechCorp
- generic [ref=e121]: Innovate
- generic [ref=e122]: StartupX
- generic [ref=e123]: GrowthCo
- generic [ref=e124]: ScaleUp
- generic [ref=e126]:
- generic [ref=e127]:
- heading "Everything You Need" [level=2] [ref=e128]
- paragraph [ref=e129]: Powerful features to run your service business
- generic [ref=e130]:
- generic [ref=e131]:
- img [ref=e133]
- heading "Smart Scheduling" [level=3] [ref=e135]
- paragraph [ref=e136]: Drag-and-drop calendar with real-time availability, automated reminders, and conflict detection.
- generic [ref=e137]:
- img [ref=e139]
- heading "Resource Management" [level=3] [ref=e144]
- paragraph [ref=e145]: Manage staff, rooms, and equipment. Set availability, skills, and booking rules.
- generic [ref=e146]:
- img [ref=e148]
- heading "Customer Portal" [level=3] [ref=e152]
- paragraph [ref=e153]: Self-service booking portal for customers. View history, manage appointments, and save payment methods.
- generic [ref=e154]:
- img [ref=e156]
- heading "Integrated Payments" [level=3] [ref=e158]
- paragraph [ref=e159]: Accept payments online with Stripe. Deposits, full payments, and automatic invoicing.
- generic [ref=e160]:
- img [ref=e162]
- heading "Multi-Location Support" [level=3] [ref=e166]
- paragraph [ref=e167]: Manage multiple locations or brands from a single dashboard with isolated data.
- generic [ref=e168]:
- img [ref=e170]
- heading "White-Label Ready" [level=3] [ref=e176]
- paragraph [ref=e177]: Custom domain, branding, and remove SmoothSchedule branding for a seamless experience.
- link "View All features" [ref=e179]:
- /url: "#/features"
- text: View All features
- img [ref=e180]
- generic [ref=e183]:
- generic [ref=e184]:
- heading "Get Started in Minutes" [level=2] [ref=e185]
- paragraph [ref=e186]: Three simple steps to transform your scheduling
- generic [ref=e187]:
- generic [ref=e190]:
- generic [ref=e191]: "01"
- img [ref=e193]
- heading "Create Your Account" [level=3] [ref=e196]
- paragraph [ref=e197]: Sign up for free and set up your business profile in minutes.
- generic [ref=e200]:
- generic [ref=e201]: "02"
- img [ref=e203]
- heading "Add Your Services" [level=3] [ref=e206]
- paragraph [ref=e207]: Configure your services, pricing, and available resources.
- generic [ref=e209]:
- generic [ref=e210]: "03"
- img [ref=e212]
- heading "Start Booking" [level=3] [ref=e217]
- paragraph [ref=e218]: Share your booking link and let customers schedule instantly.
- generic [ref=e221]:
- generic [ref=e222]:
- img [ref=e224]
- generic [ref=e226]: 1M+
- generic [ref=e227]: Appointments Scheduled
- generic [ref=e228]:
- img [ref=e230]
- generic [ref=e234]: 5,000+
- generic [ref=e235]: Businesses
- generic [ref=e236]:
- img [ref=e238]
- generic [ref=e241]: 50+
- generic [ref=e242]: Countries
- generic [ref=e243]:
- img [ref=e245]
- generic [ref=e248]: 99.9%
- generic [ref=e249]: Uptime
- generic [ref=e251]:
- generic [ref=e252]:
- heading "Loved by Businesses Everywhere" [level=2] [ref=e253]
- paragraph [ref=e254]: See what our customers have to say
- generic [ref=e255]:
- generic [ref=e256]:
- generic [ref=e257]:
- img [ref=e258]
- img [ref=e260]
- img [ref=e262]
- img [ref=e264]
- img [ref=e266]
- blockquote [ref=e268]: "\"SmoothSchedule transformed how we manage appointments. Our no-show rate dropped by 40% with automated reminders.\""
- generic [ref=e269]:
- generic [ref=e271]: S
- generic [ref=e272]:
- generic [ref=e273]: Sarah Johnson
- generic [ref=e274]: Owner at Luxe Salon
- generic [ref=e275]:
- generic [ref=e276]:
- img [ref=e277]
- img [ref=e279]
- img [ref=e281]
- img [ref=e283]
- img [ref=e285]
- blockquote [ref=e287]: "\"The white-label feature is perfect for our multi-location business. Each location has its own branded booking experience.\""
- generic [ref=e288]:
- generic [ref=e290]: M
- generic [ref=e291]:
- generic [ref=e292]: Michael Chen
- generic [ref=e293]: CEO at FitLife Studios
- generic [ref=e294]:
- generic [ref=e295]:
- img [ref=e296]
- img [ref=e298]
- img [ref=e300]
- img [ref=e302]
- img [ref=e304]
- blockquote [ref=e306]: "\"Setup was incredibly easy. We were up and running in under an hour, and our clients love the self-service booking.\""
- generic [ref=e307]:
- generic [ref=e309]: E
- generic [ref=e310]:
- generic [ref=e311]: Emily Rodriguez
- generic [ref=e312]: Manager at Peak Performance Therapy
- generic [ref=e314]:
- generic [ref=e315]:
- heading "Simple, Transparent Pricing" [level=2] [ref=e316]
- paragraph [ref=e317]: Start free, upgrade as you grow. No hidden fees.
- generic [ref=e318]:
- generic [ref=e319]:
- heading "Free" [level=3] [ref=e320]
- paragraph [ref=e321]: Perfect for getting started
- generic [ref=e322]: $0/month
- link "Get Started" [ref=e323]:
- /url: "#/signup"
- generic [ref=e324]:
- generic [ref=e325]: Most Popular
- heading "Professional" [level=3] [ref=e326]
- paragraph [ref=e327]: For growing businesses
- generic [ref=e328]: $29/month
- link "Get Started" [ref=e329]:
- /url: "#/signup"
- generic [ref=e330]:
- heading "Business" [level=3] [ref=e331]
- paragraph [ref=e332]: For established teams
- generic [ref=e333]: $79/month
- link "Get Started" [ref=e334]:
- /url: "#/signup"
- link "View full pricing details" [ref=e336]:
- /url: "#/pricing"
- text: View full pricing details
- img [ref=e337]
- generic [ref=e343]:
- heading "Ready to get started?" [level=2] [ref=e344]
- paragraph [ref=e345]: Join thousands of businesses already using SmoothSchedule.
- generic [ref=e346]:
- link "Get Started Free" [ref=e347]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e348]
- link "Talk to Sales" [ref=e350]:
- /url: "#/contact"
- paragraph [ref=e351]: No credit card required
- contentinfo [ref=e352]:
- generic [ref=e353]:
- generic [ref=e354]:
- generic [ref=e355]:
- link "Smooth Schedule" [ref=e356]:
- /url: "#/"
- img [ref=e357]
- generic [ref=e363]: Smooth Schedule
- paragraph [ref=e364]: The all-in-one scheduling platform for businesses of all sizes. Manage resources, staff, and bookings effortlessly.
- generic [ref=e365]:
- link "Twitter" [ref=e366]:
- /url: https://twitter.com/smoothschedule
- img [ref=e367]
- link "LinkedIn" [ref=e369]:
- /url: https://linkedin.com/company/smoothschedule
- img [ref=e370]
- link "GitHub" [ref=e374]:
- /url: https://github.com/smoothschedule
- img [ref=e375]
- link "YouTube" [ref=e378]:
- /url: https://youtube.com/@smoothschedule
- img [ref=e379]
- generic [ref=e382]:
- heading "Product" [level=3] [ref=e383]
- list [ref=e384]:
- listitem [ref=e385]:
- link "Features" [ref=e386]:
- /url: "#/features"
- listitem [ref=e387]:
- link "Pricing" [ref=e388]:
- /url: "#/pricing"
- listitem [ref=e389]:
- link "Get Started" [ref=e390]:
- /url: "#/signup"
- generic [ref=e391]:
- heading "Company" [level=3] [ref=e392]
- list [ref=e393]:
- listitem [ref=e394]:
- link "About" [ref=e395]:
- /url: "#/about"
- listitem [ref=e396]:
- link "Contact" [ref=e397]:
- /url: "#/contact"
- generic [ref=e398]:
- heading "Legal" [level=3] [ref=e399]
- list [ref=e400]:
- listitem [ref=e401]:
- link "Privacy Policy" [ref=e402]:
- /url: "#/privacy"
- listitem [ref=e403]:
- link "Terms of Service" [ref=e404]:
- /url: "#/terms"
- paragraph [ref=e406]: © 2025 Smooth Schedule Inc. All rights reserved.
- generic [ref=e407]:
- generic [ref=e408]:
- heading "🔓 Quick Login (Dev Only)" [level=3] [ref=e409]:
- generic [ref=e410]: 🔓
- generic [ref=e411]: Quick Login (Dev Only)
- button "×" [ref=e412]
- generic [ref=e413]:
- button "Logging in..." [disabled] [ref=e414]:
- generic [ref=e415]:
- img [ref=e416]
- text: Logging in...
- button "Platform Manager PLATFORM_MANAGER" [disabled] [ref=e419]:
- generic [ref=e420]:
- generic [ref=e421]: Platform Manager
- generic [ref=e422]: PLATFORM_MANAGER
- button "Platform Sales PLATFORM_SALES" [disabled] [ref=e423]:
- generic [ref=e424]:
- generic [ref=e425]: Platform Sales
- generic [ref=e426]: PLATFORM_SALES
- button "Platform Support PLATFORM_SUPPORT" [disabled] [ref=e427]:
- generic [ref=e428]:
- generic [ref=e429]: Platform Support
- generic [ref=e430]: PLATFORM_SUPPORT
- button "Business Owner TENANT_OWNER" [disabled] [ref=e431]:
- generic [ref=e432]:
- generic [ref=e433]: Business Owner
- generic [ref=e434]: TENANT_OWNER
- button "Business Manager TENANT_MANAGER" [disabled] [ref=e435]:
- generic [ref=e436]:
- generic [ref=e437]: Business Manager
- generic [ref=e438]: TENANT_MANAGER
- button "Staff Member TENANT_STAFF" [disabled] [ref=e439]:
- generic [ref=e440]:
- generic [ref=e441]: Staff Member
- generic [ref=e442]: TENANT_STAFF
- button "Customer CUSTOMER" [disabled] [ref=e443]:
- generic [ref=e444]:
- generic [ref=e445]: Customer
- generic [ref=e446]: CUSTOMER
- generic [ref=e447]:
- text: "Password for all:"
- code [ref=e448]: test123
```

View File

@@ -1,343 +0,0 @@
# Page snapshot
```yaml
- generic [ref=e2]:
- generic [ref=e3]:
- navigation [ref=e4]:
- generic [ref=e6]:
- link "Smooth Schedule" [ref=e7] [cursor=pointer]:
- /url: "#/"
- img [ref=e8]
- generic [ref=e14]: Smooth Schedule
- generic [ref=e15]:
- link "Features" [ref=e16] [cursor=pointer]:
- /url: "#/features"
- link "Pricing" [ref=e17] [cursor=pointer]:
- /url: "#/pricing"
- link "About" [ref=e18] [cursor=pointer]:
- /url: "#/about"
- link "Contact" [ref=e19] [cursor=pointer]:
- /url: "#/contact"
- generic [ref=e20]:
- button "🇺🇸 English" [ref=e23]:
- img [ref=e24]
- generic [ref=e28]: 🇺🇸
- generic [ref=e29]: English
- img [ref=e30]
- button "Switch to dark mode" [ref=e32]:
- img [ref=e33]
- link "Login" [ref=e35] [cursor=pointer]:
- /url: "#/login"
- link "Get Started" [ref=e36] [cursor=pointer]:
- /url: "#/signup"
- main [ref=e37]:
- generic [ref=e38]:
- generic [ref=e43]:
- generic [ref=e44]:
- generic [ref=e45]:
- generic [ref=e48]: Get started today
- heading "Scheduling Made Simple" [level=1] [ref=e49]
- paragraph [ref=e50]: The all-in-one platform for managing appointments, resources, and customers. Start free, scale as you grow.
- generic [ref=e51]:
- link "Get Started Free" [ref=e52] [cursor=pointer]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e53]
- button "Watch Demo" [ref=e56]:
- img [ref=e57]
- text: Watch Demo
- generic [ref=e59]:
- generic [ref=e60]:
- img [ref=e61]
- generic [ref=e64]: No credit card required
- generic [ref=e66]:
- img [ref=e67]
- generic [ref=e70]: Get started today
- generic [ref=e71]:
- generic [ref=e73]:
- generic [ref=e80]: dashboard.smoothschedule.com
- generic [ref=e81]:
- generic [ref=e82]:
- generic [ref=e83]:
- generic [ref=e84]: Today
- generic [ref=e85]: "12"
- generic [ref=e86]:
- generic [ref=e87]: This Week
- generic [ref=e88]: "48"
- generic [ref=e89]:
- generic [ref=e90]: Revenue
- generic [ref=e91]: $2.4k
- generic [ref=e92]:
- generic [ref=e93]: Today's Schedule
- generic [ref=e94]:
- generic [ref=e97]:
- generic [ref=e98]: 9:00 AM
- generic [ref=e99]: Sarah J. - Haircut
- generic [ref=e102]:
- generic [ref=e103]: 10:30 AM
- generic [ref=e104]: Mike T. - Consultation
- generic [ref=e107]:
- generic [ref=e108]: 2:00 PM
- generic [ref=e109]: Emma W. - Color
- generic [ref=e111]:
- img [ref=e113]
- generic [ref=e116]:
- generic [ref=e117]: New Booking!
- generic [ref=e118]: Just now
- generic [ref=e119]:
- paragraph [ref=e120]: Trusted by 1,000+ businesses worldwide
- generic [ref=e121]:
- generic [ref=e122]: TechCorp
- generic [ref=e123]: Innovate
- generic [ref=e124]: StartupX
- generic [ref=e125]: GrowthCo
- generic [ref=e126]: ScaleUp
- generic [ref=e128]:
- generic [ref=e129]:
- heading "Everything You Need" [level=2] [ref=e130]
- paragraph [ref=e131]: Powerful features to run your service business
- generic [ref=e132]:
- generic [ref=e133]:
- img [ref=e135]
- heading "Smart Scheduling" [level=3] [ref=e140]
- paragraph [ref=e141]: Drag-and-drop calendar with real-time availability, automated reminders, and conflict detection.
- generic [ref=e142]:
- img [ref=e144]
- heading "Resource Management" [level=3] [ref=e149]
- paragraph [ref=e150]: Manage staff, rooms, and equipment. Set availability, skills, and booking rules.
- generic [ref=e151]:
- img [ref=e153]
- heading "Customer Portal" [level=3] [ref=e157]
- paragraph [ref=e158]: Self-service booking portal for customers. View history, manage appointments, and save payment methods.
- generic [ref=e159]:
- img [ref=e161]
- heading "Integrated Payments" [level=3] [ref=e164]
- paragraph [ref=e165]: Accept payments online with Stripe. Deposits, full payments, and automatic invoicing.
- generic [ref=e166]:
- img [ref=e168]
- heading "Multi-Location Support" [level=3] [ref=e174]
- paragraph [ref=e175]: Manage multiple locations or brands from a single dashboard with isolated data.
- generic [ref=e176]:
- img [ref=e178]
- heading "White-Label Ready" [level=3] [ref=e184]
- paragraph [ref=e185]: Custom domain, branding, and remove SmoothSchedule branding for a seamless experience.
- link "View All features" [ref=e187] [cursor=pointer]:
- /url: "#/features"
- text: View All features
- img [ref=e188]
- generic [ref=e192]:
- generic [ref=e193]:
- heading "Get Started in Minutes" [level=2] [ref=e194]
- paragraph [ref=e195]: Three simple steps to transform your scheduling
- generic [ref=e196]:
- generic [ref=e199]:
- generic [ref=e200]: "01"
- img [ref=e202]
- heading "Create Your Account" [level=3] [ref=e207]
- paragraph [ref=e208]: Sign up for free and set up your business profile in minutes.
- generic [ref=e211]:
- generic [ref=e212]: "02"
- img [ref=e214]
- heading "Add Your Services" [level=3] [ref=e217]
- paragraph [ref=e218]: Configure your services, pricing, and available resources.
- generic [ref=e220]:
- generic [ref=e221]: "03"
- img [ref=e223]
- heading "Start Booking" [level=3] [ref=e228]
- paragraph [ref=e229]: Share your booking link and let customers schedule instantly.
- generic [ref=e232]:
- generic [ref=e233]:
- img [ref=e235]
- generic [ref=e240]: 1M+
- generic [ref=e241]: Appointments Scheduled
- generic [ref=e242]:
- img [ref=e244]
- generic [ref=e250]: 5,000+
- generic [ref=e251]: Businesses
- generic [ref=e252]:
- img [ref=e254]
- generic [ref=e258]: 50+
- generic [ref=e259]: Countries
- generic [ref=e260]:
- img [ref=e262]
- generic [ref=e265]: 99.9%
- generic [ref=e266]: Uptime
- generic [ref=e268]:
- generic [ref=e269]:
- heading "Loved by Businesses Everywhere" [level=2] [ref=e270]
- paragraph [ref=e271]: See what our customers have to say
- generic [ref=e272]:
- generic [ref=e273]:
- generic [ref=e274]:
- img [ref=e275]
- img [ref=e277]
- img [ref=e279]
- img [ref=e281]
- img [ref=e283]
- blockquote [ref=e285]: "\"SmoothSchedule transformed how we manage appointments. Our no-show rate dropped by 40% with automated reminders.\""
- generic [ref=e286]:
- generic [ref=e288]: S
- generic [ref=e289]:
- generic [ref=e290]: Sarah Johnson
- generic [ref=e291]: Owner at Luxe Salon
- generic [ref=e292]:
- generic [ref=e293]:
- img [ref=e294]
- img [ref=e296]
- img [ref=e298]
- img [ref=e300]
- img [ref=e302]
- blockquote [ref=e304]: "\"The white-label feature is perfect for our multi-location business. Each location has its own branded booking experience.\""
- generic [ref=e305]:
- generic [ref=e307]: M
- generic [ref=e308]:
- generic [ref=e309]: Michael Chen
- generic [ref=e310]: CEO at FitLife Studios
- generic [ref=e311]:
- generic [ref=e312]:
- img [ref=e313]
- img [ref=e315]
- img [ref=e317]
- img [ref=e319]
- img [ref=e321]
- blockquote [ref=e323]: "\"Setup was incredibly easy. We were up and running in under an hour, and our clients love the self-service booking.\""
- generic [ref=e324]:
- generic [ref=e326]: E
- generic [ref=e327]:
- generic [ref=e328]: Emily Rodriguez
- generic [ref=e329]: Manager at Peak Performance Therapy
- generic [ref=e331]:
- generic [ref=e332]:
- heading "Simple, Transparent Pricing" [level=2] [ref=e333]
- paragraph [ref=e334]: Start free, upgrade as you grow. No hidden fees.
- generic [ref=e335]:
- generic [ref=e336]:
- heading "Free" [level=3] [ref=e337]
- paragraph [ref=e338]: Perfect for getting started
- generic [ref=e339]: $0/month
- link "Get Started" [ref=e340] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e341]:
- generic [ref=e342]: Most Popular
- heading "Professional" [level=3] [ref=e343]
- paragraph [ref=e344]: For growing businesses
- generic [ref=e345]: $29/month
- link "Get Started" [ref=e346] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e347]:
- heading "Business" [level=3] [ref=e348]
- paragraph [ref=e349]: For established teams
- generic [ref=e350]: $79/month
- link "Get Started" [ref=e351] [cursor=pointer]:
- /url: "#/signup"
- link "View full pricing details" [ref=e353] [cursor=pointer]:
- /url: "#/pricing"
- text: View full pricing details
- img [ref=e354]
- generic [ref=e361]:
- heading "Ready to get started?" [level=2] [ref=e362]
- paragraph [ref=e363]: Join thousands of businesses already using SmoothSchedule.
- generic [ref=e364]:
- link "Get Started Free" [ref=e365] [cursor=pointer]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e366]
- link "Talk to Sales" [ref=e369] [cursor=pointer]:
- /url: "#/contact"
- paragraph [ref=e370]: No credit card required
- contentinfo [ref=e371]:
- generic [ref=e372]:
- generic [ref=e373]:
- generic [ref=e374]:
- link "Smooth Schedule" [ref=e375] [cursor=pointer]:
- /url: "#/"
- img [ref=e376]
- generic [ref=e382]: Smooth Schedule
- paragraph [ref=e383]: The all-in-one scheduling platform for businesses of all sizes. Manage resources, staff, and bookings effortlessly.
- generic [ref=e384]:
- link "Twitter" [ref=e385] [cursor=pointer]:
- /url: https://twitter.com/smoothschedule
- img [ref=e386]
- link "LinkedIn" [ref=e388] [cursor=pointer]:
- /url: https://linkedin.com/company/smoothschedule
- img [ref=e389]
- link "GitHub" [ref=e393] [cursor=pointer]:
- /url: https://github.com/smoothschedule
- img [ref=e394]
- link "YouTube" [ref=e397] [cursor=pointer]:
- /url: https://youtube.com/@smoothschedule
- img [ref=e398]
- generic [ref=e401]:
- heading "Product" [level=3] [ref=e402]
- list [ref=e403]:
- listitem [ref=e404]:
- link "Features" [ref=e405] [cursor=pointer]:
- /url: "#/features"
- listitem [ref=e406]:
- link "Pricing" [ref=e407] [cursor=pointer]:
- /url: "#/pricing"
- listitem [ref=e408]:
- link "Get Started" [ref=e409] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e410]:
- heading "Company" [level=3] [ref=e411]
- list [ref=e412]:
- listitem [ref=e413]:
- link "About" [ref=e414] [cursor=pointer]:
- /url: "#/about"
- listitem [ref=e415]:
- link "Contact" [ref=e416] [cursor=pointer]:
- /url: "#/contact"
- generic [ref=e417]:
- heading "Legal" [level=3] [ref=e418]
- list [ref=e419]:
- listitem [ref=e420]:
- link "Privacy Policy" [ref=e421] [cursor=pointer]:
- /url: "#/privacy"
- listitem [ref=e422]:
- link "Terms of Service" [ref=e423] [cursor=pointer]:
- /url: "#/terms"
- paragraph [ref=e425]: © 2025 Smooth Schedule Inc. All rights reserved.
- generic [ref=e426]:
- generic [ref=e427]:
- heading "🔓 Quick Login (Dev Only)" [level=3] [ref=e428]:
- generic [ref=e429]: 🔓
- generic [ref=e430]: Quick Login (Dev Only)
- button "×" [ref=e431]
- generic [ref=e432]:
- button "Logging in..." [disabled] [ref=e433]:
- generic [ref=e434]:
- img [ref=e435]
- text: Logging in...
- button "Platform Manager PLATFORM_MANAGER" [disabled] [ref=e438]:
- generic [ref=e439]:
- generic [ref=e440]: Platform Manager
- generic [ref=e441]: PLATFORM_MANAGER
- button "Platform Sales PLATFORM_SALES" [disabled] [ref=e442]:
- generic [ref=e443]:
- generic [ref=e444]: Platform Sales
- generic [ref=e445]: PLATFORM_SALES
- button "Platform Support PLATFORM_SUPPORT" [disabled] [ref=e446]:
- generic [ref=e447]:
- generic [ref=e448]: Platform Support
- generic [ref=e449]: PLATFORM_SUPPORT
- button "Business Owner TENANT_OWNER" [disabled] [ref=e450]:
- generic [ref=e451]:
- generic [ref=e452]: Business Owner
- generic [ref=e453]: TENANT_OWNER
- button "Business Manager TENANT_MANAGER" [disabled] [ref=e454]:
- generic [ref=e455]:
- generic [ref=e456]: Business Manager
- generic [ref=e457]: TENANT_MANAGER
- button "Staff Member TENANT_STAFF" [disabled] [ref=e458]:
- generic [ref=e459]:
- generic [ref=e460]: Staff Member
- generic [ref=e461]: TENANT_STAFF
- button "Customer CUSTOMER" [disabled] [ref=e462]:
- generic [ref=e463]:
- generic [ref=e464]: Customer
- generic [ref=e465]: CUSTOMER
- generic [ref=e466]:
- text: "Password for all:"
- code [ref=e467]: test123
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB

File diff suppressed because one or more lines are too long

View File

@@ -96,11 +96,36 @@ export function DevQuickLogin({ embedded = false }: DevQuickLoginProps) {
// Store token in cookie (use 'access_token' to match what client.ts expects)
setCookie('access_token', response.data.token, 7);
// Invalidate queries to refetch user data
await queryClient.invalidateQueries({ queryKey: ['currentUser'] });
await queryClient.invalidateQueries({ queryKey: ['currentBusiness'] });
// Fetch user data to determine redirect
const userResponse = await apiClient.get('/api/auth/me/');
const userData = userResponse.data;
// Reload page to trigger auth flow
// Determine the correct subdomain based on user role
const currentHostname = window.location.hostname;
const currentPort = window.location.port;
let targetSubdomain: string | null = null;
// Platform users (superuser, platform_manager, platform_support)
if (['superuser', 'platform_manager', 'platform_support'].includes(userData.role)) {
targetSubdomain = 'platform';
}
// Business users - redirect to their business subdomain
else if (userData.business_subdomain) {
targetSubdomain = userData.business_subdomain;
}
// Check if we need to redirect to a different subdomain
const isOnTargetSubdomain = currentHostname === `${targetSubdomain}.lvh.me`;
const needsRedirect = targetSubdomain && !isOnTargetSubdomain;
if (needsRedirect) {
// Redirect to the correct subdomain
const portStr = currentPort ? `:${currentPort}` : '';
window.location.href = `http://${targetSubdomain}.lvh.me${portStr}/`;
return;
}
// Already on correct subdomain - just reload to update auth state
window.location.reload();
} catch (error: any) {
console.error('Quick login failed:', error);

View File

@@ -36,7 +36,7 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
const baseClasses = `flex items-center gap-3 py-3 text-sm font-medium rounded-lg transition-colors`;
const collapsedClasses = isCollapsed ? 'px-3 justify-center' : 'px-4';
const activeClasses = 'bg-opacity-10 text-white bg-white';
const activeClasses = 'bg-white/10 text-white';
const inactiveClasses = 'text-white/70 hover:text-white hover:bg-white/5';
const disabledClasses = 'text-white/30 cursor-not-allowed';

View File

@@ -35,6 +35,9 @@ interface UseAppointmentWebSocketOptions {
onError?: (error: Event) => void;
}
// WebSocket is not yet implemented in the backend - disable for now
const WEBSOCKET_ENABLED = false;
/**
* Transform backend appointment format to frontend format
*/
@@ -60,6 +63,9 @@ function transformAppointment(data: WebSocketMessage['appointment']): Appointmen
*/
export function useAppointmentWebSocket(options: UseAppointmentWebSocketOptions = {}) {
const { enabled = true, onConnected, onDisconnected, onError } = options;
// Early return if WebSocket is globally disabled
const effectivelyEnabled = enabled && WEBSOCKET_ENABLED;
const queryClient = useQueryClient();
const wsRef = useRef<WebSocket | null>(null);
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
@@ -138,7 +144,7 @@ export function useAppointmentWebSocket(options: UseAppointmentWebSocketOptions
// Main effect to manage WebSocket connection
// Only depends on `enabled` - other values are read from refs or called as functions
useEffect(() => {
if (!enabled) {
if (!effectivelyEnabled) {
return;
}
@@ -285,7 +291,7 @@ export function useAppointmentWebSocket(options: UseAppointmentWebSocketOptions
setIsConnected(false);
};
}, [enabled]); // Only re-run when enabled changes
}, [effectivelyEnabled]); // Only re-run when enabled changes
const reconnect = useCallback(() => {
isCleaningUpRef.current = false;

View File

@@ -30,8 +30,8 @@ export const useCurrentBusiness = () => {
id: String(data.id),
name: data.name,
subdomain: data.subdomain,
primaryColor: data.primary_color,
secondaryColor: data.secondary_color,
primaryColor: data.primary_color || '#3B82F6', // Blue-500 default
secondaryColor: data.secondary_color || '#1E40AF', // Blue-800 default
logoUrl: data.logo_url,
whitelabelEnabled: data.whitelabel_enabled,
plan: data.tier, // Map tier to plan

View File

@@ -43,6 +43,7 @@ export const useCustomers = (filters?: CustomerFilters) => {
user_data: c.user_data, // Include user_data for masquerading
}));
},
retry: false, // Don't retry on 404 - endpoint may not exist yet
});
};

View File

@@ -24,6 +24,7 @@ export const useServices = () => {
description: s.description || '',
}));
},
retry: false, // Don't retry on 404 - endpoint may not exist yet
});
};
@@ -45,6 +46,7 @@ export const useService = (id: string) => {
};
},
enabled: !!id,
retry: false,
});
};

View File

@@ -224,6 +224,56 @@ const OwnerScheduler: React.FC<OwnerSchedulerProps> = ({ user, business }) => {
return new Date(date.getFullYear(), date.getMonth() + 1, 0);
};
// Generate calendar grid data for month view
const getMonthCalendarData = () => {
const firstDay = getStartOfMonth(viewDate);
const lastDay = getEndOfMonth(viewDate);
const startDayOfWeek = firstDay.getDay(); // 0 = Sunday
const daysInMonth = lastDay.getDate();
// Create array of week rows
const weeks: (Date | null)[][] = [];
let currentWeek: (Date | null)[] = [];
// Add empty cells for days before the first of the month
for (let i = 0; i < startDayOfWeek; i++) {
currentWeek.push(null);
}
// Add all days of the month
for (let day = 1; day <= daysInMonth; day++) {
currentWeek.push(new Date(viewDate.getFullYear(), viewDate.getMonth(), day));
if (currentWeek.length === 7) {
weeks.push(currentWeek);
currentWeek = [];
}
}
// Add empty cells for remaining days after the last of the month
if (currentWeek.length > 0) {
while (currentWeek.length < 7) {
currentWeek.push(null);
}
weeks.push(currentWeek);
}
return weeks;
};
// Get appointments for a specific day (for month view)
const getAppointmentsForDay = (date: Date) => {
const dayStart = new Date(date);
dayStart.setHours(0, 0, 0, 0);
const dayEnd = new Date(date);
dayEnd.setHours(23, 59, 59, 999);
return filteredAppointments.filter(apt => {
if (!apt.resourceId) return false; // Exclude pending
const aptDate = new Date(apt.startTime);
return aptDate >= dayStart && aptDate <= dayEnd;
}).sort((a, b) => new Date(a.startTime).getTime() - new Date(b.startTime).getTime());
};
const navigateDate = (direction: 'prev' | 'next') => {
const newDate = new Date(viewDate);
@@ -685,11 +735,13 @@ const OwnerScheduler: React.FC<OwnerSchedulerProps> = ({ user, business }) => {
Month
</button>
</div>
<div className="flex items-center gap-2">
<button className="p-1.5 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors" onClick={() => setZoomLevel(Math.max(0.5, zoomLevel - 0.25))}>-</button>
<span className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">Zoom</span>
<button className="p-1.5 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors" onClick={() => setZoomLevel(Math.min(2, zoomLevel + 0.25))}>+</button>
</div>
{viewMode !== 'month' && (
<div className="flex items-center gap-2">
<button className="p-1.5 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors" onClick={() => setZoomLevel(Math.max(0.5, zoomLevel - 0.25))}>-</button>
<span className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">Zoom</span>
<button className="p-1.5 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors" onClick={() => setZoomLevel(Math.min(2, zoomLevel + 0.25))}>+</button>
</div>
)}
<div className="flex items-center gap-1 border-l border-gray-300 dark:border-gray-600 pl-4">
<button
onClick={undo}
@@ -727,6 +779,108 @@ const OwnerScheduler: React.FC<OwnerSchedulerProps> = ({ user, business }) => {
</div>
</div>
{/* Month View - Calendar Grid */}
{viewMode === 'month' && (
<div className="flex flex-1 overflow-hidden">
{/* Pending Sidebar for Month View */}
<div className="flex flex-col bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 shrink-0 shadow-lg z-20 transition-colors duration-200" style={{ width: SIDEBAR_WIDTH }}>
<div className={`flex-1 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800 p-4 flex flex-col transition-colors duration-200 ${draggedAppointmentId ? 'bg-blue-50/50 dark:bg-blue-900/20' : ''}`}>
<h3 className="text-xs font-bold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-3 flex items-center gap-2 shrink-0"><Clock size={12} /> Pending Requests ({pendingAppointments.length})</h3>
<div className="space-y-2 overflow-y-auto flex-1 mb-2">
{pendingAppointments.length === 0 && (<div className="text-xs text-gray-400 italic text-center py-4">No pending requests</div>)}
{pendingAppointments.map(apt => {
const service = services.find(s => s.id === apt.serviceId);
return (
<div
key={apt.id}
className="p-3 bg-white dark:bg-gray-700 border border-l-4 border-gray-200 dark:border-gray-600 border-l-orange-400 dark:border-l-orange-500 rounded shadow-sm cursor-pointer hover:shadow-md transition-all"
onClick={() => handleAppointmentClick(apt)}
>
<p className="font-semibold text-sm text-gray-900 dark:text-white">{apt.customerName}</p>
<p className="text-xs text-gray-500 dark:text-gray-400">{service?.name}</p>
<div className="mt-2 flex items-center gap-1 text-xs text-gray-400 dark:text-gray-500">
<Clock size={10} /> {formatDuration(apt.durationMinutes)}
</div>
</div>
);
})}
</div>
</div>
</div>
{/* Calendar Grid */}
<div className="flex-1 flex flex-col overflow-hidden bg-white dark:bg-gray-900 transition-colors duration-200">
<div className="flex-1 overflow-auto p-4">
{/* Day headers */}
<div className="grid grid-cols-7 gap-px bg-gray-200 dark:bg-gray-700 rounded-t-lg overflow-hidden">
{['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map(day => (
<div key={day} className="bg-gray-50 dark:bg-gray-800 px-2 py-3 text-center text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">
{day}
</div>
))}
</div>
{/* Calendar weeks */}
<div className="grid grid-cols-7 gap-px bg-gray-200 dark:bg-gray-700 rounded-b-lg overflow-hidden">
{getMonthCalendarData().flat().map((date, index) => {
const isToday = date && new Date().toDateString() === date.toDateString();
const dayAppointments = date ? getAppointmentsForDay(date) : [];
const displayedAppointments = dayAppointments.slice(0, 3);
const remainingCount = dayAppointments.length - 3;
return (
<div
key={index}
className={`bg-white dark:bg-gray-900 min-h-[120px] p-2 transition-colors ${
date ? 'hover:bg-gray-50 dark:hover:bg-gray-800 cursor-pointer' : 'bg-gray-50 dark:bg-gray-800/50'
}`}
onClick={() => { if (date) { setViewDate(date); setViewMode('day'); } }}
>
{date && (
<>
<div className={`text-sm font-medium mb-1 ${
isToday
? 'w-7 h-7 flex items-center justify-center rounded-full bg-brand-500 text-white'
: 'text-gray-700 dark:text-gray-300'
}`}>
{date.getDate()}
</div>
<div className="space-y-1">
{displayedAppointments.map(apt => {
const service = services.find(s => s.id === apt.serviceId);
const resource = resources.find(r => r.id === apt.resourceId);
const startTime = new Date(apt.startTime);
return (
<div
key={apt.id}
className="text-xs p-1.5 rounded bg-blue-100 dark:bg-blue-900/50 text-blue-800 dark:text-blue-200 truncate cursor-pointer hover:bg-blue-200 dark:hover:bg-blue-800/50 transition-colors"
onClick={(e) => { e.stopPropagation(); handleAppointmentClick(apt); }}
title={`${apt.customerName} - ${service?.name} with ${resource?.name}`}
>
<span className="font-medium">{startTime.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' })}</span>
{' '}{apt.customerName}
</div>
);
})}
{remainingCount > 0 && (
<div className="text-xs text-gray-500 dark:text-gray-400 font-medium pl-1">
+{remainingCount} more
</div>
)}
</div>
</>
)}
</div>
);
})}
</div>
</div>
</div>
</div>
)}
{/* Day/Week View - Timeline */}
{viewMode !== 'month' && (
<div className="flex flex-1 overflow-hidden">
<div className="flex flex-col bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 shrink-0 shadow-lg z-20 transition-colors duration-200" style={{ width: SIDEBAR_WIDTH }}>
<div className="border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 flex items-center px-4 font-semibold text-gray-500 dark:text-gray-400 text-xs uppercase tracking-wider shrink-0 transition-colors duration-200" style={{ height: HEADER_HEIGHT }}>Resources</div>
@@ -849,6 +1003,7 @@ const OwnerScheduler: React.FC<OwnerSchedulerProps> = ({ user, business }) => {
</div>
</div>
</div>
)}
{/* Appointment Detail/Edit Modal */}
{selectedAppointment && (

View File

@@ -24,20 +24,20 @@ const VerifyEmail: React.FC = () => {
setStatus('loading');
try {
const response = await apiClient.get(`/api/auth/emails/verify/${token}/`);
const response = await apiClient.post('/api/auth/email/verify/', { token });
// Immediately clear auth cookies to log out
deleteCookie('access_token');
deleteCookie('refresh_token');
if (response.data.message === 'Email is already verified') {
if (response.data.detail === 'Email already verified.') {
setStatus('already_verified');
} else {
setStatus('success');
}
} catch (err: any) {
setStatus('error');
setErrorMessage(err.response?.data?.detail || 'Failed to verify email');
setErrorMessage(err.response?.data?.error || 'Failed to verify email');
}
};

View File

@@ -1,8 +1,6 @@
{
"status": "failed",
"failedTests": [
"5f1889fdd7b10a4db9e9-2b1e81c51a733cc89956",
"5f1889fdd7b10a4db9e9-66724cc37c12aaf9dc66",
"5f1889fdd7b10a4db9e9-b93c630b7987c0eb4adc"
"7662eeffef95b745c0c7-05f7d22eaed6ca80a04d"
]
}

View File

@@ -1,343 +0,0 @@
# Page snapshot
```yaml
- generic [ref=e2]:
- generic [ref=e3]:
- navigation [ref=e4]:
- generic [ref=e6]:
- link "Smooth Schedule" [ref=e7] [cursor=pointer]:
- /url: "#/"
- img [ref=e8]
- generic [ref=e14]: Smooth Schedule
- generic [ref=e15]:
- link "Features" [ref=e16] [cursor=pointer]:
- /url: "#/features"
- link "Pricing" [ref=e17] [cursor=pointer]:
- /url: "#/pricing"
- link "About" [ref=e18] [cursor=pointer]:
- /url: "#/about"
- link "Contact" [ref=e19] [cursor=pointer]:
- /url: "#/contact"
- generic [ref=e20]:
- button "🇺🇸 English" [ref=e23]:
- img [ref=e24]
- generic [ref=e27]: 🇺🇸
- generic [ref=e28]: English
- img [ref=e29]
- button "Switch to dark mode" [ref=e31]:
- img [ref=e32]
- link "Login" [ref=e34] [cursor=pointer]:
- /url: "#/login"
- link "Get Started" [ref=e35] [cursor=pointer]:
- /url: "#/signup"
- main [ref=e36]:
- generic [ref=e37]:
- generic [ref=e42]:
- generic [ref=e43]:
- generic [ref=e44]:
- generic [ref=e47]: Get started today
- heading "Scheduling Made Simple" [level=1] [ref=e48]
- paragraph [ref=e49]: The all-in-one platform for managing appointments, resources, and customers. Start free, scale as you grow.
- generic [ref=e50]:
- link "Get Started Free" [ref=e51] [cursor=pointer]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e52]
- button "Watch Demo" [ref=e54]:
- img [ref=e55]
- text: Watch Demo
- generic [ref=e57]:
- generic [ref=e58]:
- img [ref=e59]
- generic [ref=e62]: No credit card required
- generic [ref=e64]:
- img [ref=e65]
- generic [ref=e68]: Get started today
- generic [ref=e69]:
- generic [ref=e71]:
- generic [ref=e78]: dashboard.smoothschedule.com
- generic [ref=e79]:
- generic [ref=e80]:
- generic [ref=e81]:
- generic [ref=e82]: Today
- generic [ref=e83]: "12"
- generic [ref=e84]:
- generic [ref=e85]: This Week
- generic [ref=e86]: "48"
- generic [ref=e87]:
- generic [ref=e88]: Revenue
- generic [ref=e89]: $2.4k
- generic [ref=e90]:
- generic [ref=e91]: Today's Schedule
- generic [ref=e92]:
- generic [ref=e95]:
- generic [ref=e96]: 9:00 AM
- generic [ref=e97]: Sarah J. - Haircut
- generic [ref=e100]:
- generic [ref=e101]: 10:30 AM
- generic [ref=e102]: Mike T. - Consultation
- generic [ref=e105]:
- generic [ref=e106]: 2:00 PM
- generic [ref=e107]: Emma W. - Color
- generic [ref=e109]:
- img [ref=e111]
- generic [ref=e114]:
- generic [ref=e115]: New Booking!
- generic [ref=e116]: Just now
- generic [ref=e117]:
- paragraph [ref=e118]: Trusted by 1,000+ businesses worldwide
- generic [ref=e119]:
- generic [ref=e120]: TechCorp
- generic [ref=e121]: Innovate
- generic [ref=e122]: StartupX
- generic [ref=e123]: GrowthCo
- generic [ref=e124]: ScaleUp
- generic [ref=e126]:
- generic [ref=e127]:
- heading "Everything You Need" [level=2] [ref=e128]
- paragraph [ref=e129]: Powerful features to run your service business
- generic [ref=e130]:
- generic [ref=e131]:
- img [ref=e133]
- heading "Smart Scheduling" [level=3] [ref=e135]
- paragraph [ref=e136]: Drag-and-drop calendar with real-time availability, automated reminders, and conflict detection.
- generic [ref=e137]:
- img [ref=e139]
- heading "Resource Management" [level=3] [ref=e144]
- paragraph [ref=e145]: Manage staff, rooms, and equipment. Set availability, skills, and booking rules.
- generic [ref=e146]:
- img [ref=e148]
- heading "Customer Portal" [level=3] [ref=e152]
- paragraph [ref=e153]: Self-service booking portal for customers. View history, manage appointments, and save payment methods.
- generic [ref=e154]:
- img [ref=e156]
- heading "Integrated Payments" [level=3] [ref=e158]
- paragraph [ref=e159]: Accept payments online with Stripe. Deposits, full payments, and automatic invoicing.
- generic [ref=e160]:
- img [ref=e162]
- heading "Multi-Location Support" [level=3] [ref=e166]
- paragraph [ref=e167]: Manage multiple locations or brands from a single dashboard with isolated data.
- generic [ref=e168]:
- img [ref=e170]
- heading "White-Label Ready" [level=3] [ref=e176]
- paragraph [ref=e177]: Custom domain, branding, and remove SmoothSchedule branding for a seamless experience.
- link "View All features" [ref=e179] [cursor=pointer]:
- /url: "#/features"
- text: View All features
- img [ref=e180]
- generic [ref=e183]:
- generic [ref=e184]:
- heading "Get Started in Minutes" [level=2] [ref=e185]
- paragraph [ref=e186]: Three simple steps to transform your scheduling
- generic [ref=e187]:
- generic [ref=e190]:
- generic [ref=e191]: "01"
- img [ref=e193]
- heading "Create Your Account" [level=3] [ref=e196]
- paragraph [ref=e197]: Sign up for free and set up your business profile in minutes.
- generic [ref=e200]:
- generic [ref=e201]: "02"
- img [ref=e203]
- heading "Add Your Services" [level=3] [ref=e206]
- paragraph [ref=e207]: Configure your services, pricing, and available resources.
- generic [ref=e209]:
- generic [ref=e210]: "03"
- img [ref=e212]
- heading "Start Booking" [level=3] [ref=e217]
- paragraph [ref=e218]: Share your booking link and let customers schedule instantly.
- generic [ref=e221]:
- generic [ref=e222]:
- img [ref=e224]
- generic [ref=e226]: 1M+
- generic [ref=e227]: Appointments Scheduled
- generic [ref=e228]:
- img [ref=e230]
- generic [ref=e234]: 5,000+
- generic [ref=e235]: Businesses
- generic [ref=e236]:
- img [ref=e238]
- generic [ref=e241]: 50+
- generic [ref=e242]: Countries
- generic [ref=e243]:
- img [ref=e245]
- generic [ref=e248]: 99.9%
- generic [ref=e249]: Uptime
- generic [ref=e251]:
- generic [ref=e252]:
- heading "Loved by Businesses Everywhere" [level=2] [ref=e253]
- paragraph [ref=e254]: See what our customers have to say
- generic [ref=e255]:
- generic [ref=e256]:
- generic [ref=e257]:
- img [ref=e258]
- img [ref=e260]
- img [ref=e262]
- img [ref=e264]
- img [ref=e266]
- blockquote [ref=e268]: "\"SmoothSchedule transformed how we manage appointments. Our no-show rate dropped by 40% with automated reminders.\""
- generic [ref=e269]:
- generic [ref=e271]: S
- generic [ref=e272]:
- generic [ref=e273]: Sarah Johnson
- generic [ref=e274]: Owner at Luxe Salon
- generic [ref=e275]:
- generic [ref=e276]:
- img [ref=e277]
- img [ref=e279]
- img [ref=e281]
- img [ref=e283]
- img [ref=e285]
- blockquote [ref=e287]: "\"The white-label feature is perfect for our multi-location business. Each location has its own branded booking experience.\""
- generic [ref=e288]:
- generic [ref=e290]: M
- generic [ref=e291]:
- generic [ref=e292]: Michael Chen
- generic [ref=e293]: CEO at FitLife Studios
- generic [ref=e294]:
- generic [ref=e295]:
- img [ref=e296]
- img [ref=e298]
- img [ref=e300]
- img [ref=e302]
- img [ref=e304]
- blockquote [ref=e306]: "\"Setup was incredibly easy. We were up and running in under an hour, and our clients love the self-service booking.\""
- generic [ref=e307]:
- generic [ref=e309]: E
- generic [ref=e310]:
- generic [ref=e311]: Emily Rodriguez
- generic [ref=e312]: Manager at Peak Performance Therapy
- generic [ref=e314]:
- generic [ref=e315]:
- heading "Simple, Transparent Pricing" [level=2] [ref=e316]
- paragraph [ref=e317]: Start free, upgrade as you grow. No hidden fees.
- generic [ref=e318]:
- generic [ref=e319]:
- heading "Free" [level=3] [ref=e320]
- paragraph [ref=e321]: Perfect for getting started
- generic [ref=e322]: $0/month
- link "Get Started" [ref=e323] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e324]:
- generic [ref=e325]: Most Popular
- heading "Professional" [level=3] [ref=e326]
- paragraph [ref=e327]: For growing businesses
- generic [ref=e328]: $29/month
- link "Get Started" [ref=e329] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e330]:
- heading "Business" [level=3] [ref=e331]
- paragraph [ref=e332]: For established teams
- generic [ref=e333]: $79/month
- link "Get Started" [ref=e334] [cursor=pointer]:
- /url: "#/signup"
- link "View full pricing details" [ref=e336] [cursor=pointer]:
- /url: "#/pricing"
- text: View full pricing details
- img [ref=e337]
- generic [ref=e343]:
- heading "Ready to get started?" [level=2] [ref=e344]
- paragraph [ref=e345]: Join thousands of businesses already using SmoothSchedule.
- generic [ref=e346]:
- link "Get Started Free" [ref=e347] [cursor=pointer]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e348]
- link "Talk to Sales" [ref=e350] [cursor=pointer]:
- /url: "#/contact"
- paragraph [ref=e351]: No credit card required
- contentinfo [ref=e352]:
- generic [ref=e353]:
- generic [ref=e354]:
- generic [ref=e355]:
- link "Smooth Schedule" [ref=e356] [cursor=pointer]:
- /url: "#/"
- img [ref=e357]
- generic [ref=e363]: Smooth Schedule
- paragraph [ref=e364]: The all-in-one scheduling platform for businesses of all sizes. Manage resources, staff, and bookings effortlessly.
- generic [ref=e365]:
- link "Twitter" [ref=e366] [cursor=pointer]:
- /url: https://twitter.com/smoothschedule
- img [ref=e367]
- link "LinkedIn" [ref=e369] [cursor=pointer]:
- /url: https://linkedin.com/company/smoothschedule
- img [ref=e370]
- link "GitHub" [ref=e374] [cursor=pointer]:
- /url: https://github.com/smoothschedule
- img [ref=e375]
- link "YouTube" [ref=e378] [cursor=pointer]:
- /url: https://youtube.com/@smoothschedule
- img [ref=e379]
- generic [ref=e382]:
- heading "Product" [level=3] [ref=e383]
- list [ref=e384]:
- listitem [ref=e385]:
- link "Features" [ref=e386] [cursor=pointer]:
- /url: "#/features"
- listitem [ref=e387]:
- link "Pricing" [ref=e388] [cursor=pointer]:
- /url: "#/pricing"
- listitem [ref=e389]:
- link "Get Started" [ref=e390] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e391]:
- heading "Company" [level=3] [ref=e392]
- list [ref=e393]:
- listitem [ref=e394]:
- link "About" [ref=e395] [cursor=pointer]:
- /url: "#/about"
- listitem [ref=e396]:
- link "Contact" [ref=e397] [cursor=pointer]:
- /url: "#/contact"
- generic [ref=e398]:
- heading "Legal" [level=3] [ref=e399]
- list [ref=e400]:
- listitem [ref=e401]:
- link "Privacy Policy" [ref=e402] [cursor=pointer]:
- /url: "#/privacy"
- listitem [ref=e403]:
- link "Terms of Service" [ref=e404] [cursor=pointer]:
- /url: "#/terms"
- paragraph [ref=e406]: © 2025 Smooth Schedule Inc. All rights reserved.
- generic [ref=e407]:
- generic [ref=e408]:
- heading "🔓 Quick Login (Dev Only)" [level=3] [ref=e409]:
- generic [ref=e410]: 🔓
- generic [ref=e411]: Quick Login (Dev Only)
- button "×" [ref=e412]
- generic [ref=e413]:
- button "Logging in..." [disabled] [ref=e414]:
- generic [ref=e415]:
- img [ref=e416]
- text: Logging in...
- button "Platform Manager PLATFORM_MANAGER" [disabled] [ref=e419]:
- generic [ref=e420]:
- generic [ref=e421]: Platform Manager
- generic [ref=e422]: PLATFORM_MANAGER
- button "Platform Sales PLATFORM_SALES" [disabled] [ref=e423]:
- generic [ref=e424]:
- generic [ref=e425]: Platform Sales
- generic [ref=e426]: PLATFORM_SALES
- button "Platform Support PLATFORM_SUPPORT" [disabled] [ref=e427]:
- generic [ref=e428]:
- generic [ref=e429]: Platform Support
- generic [ref=e430]: PLATFORM_SUPPORT
- button "Business Owner TENANT_OWNER" [disabled] [ref=e431]:
- generic [ref=e432]:
- generic [ref=e433]: Business Owner
- generic [ref=e434]: TENANT_OWNER
- button "Business Manager TENANT_MANAGER" [disabled] [ref=e435]:
- generic [ref=e436]:
- generic [ref=e437]: Business Manager
- generic [ref=e438]: TENANT_MANAGER
- button "Staff Member TENANT_STAFF" [disabled] [ref=e439]:
- generic [ref=e440]:
- generic [ref=e441]: Staff Member
- generic [ref=e442]: TENANT_STAFF
- button "Customer CUSTOMER" [disabled] [ref=e443]:
- generic [ref=e444]:
- generic [ref=e445]: Customer
- generic [ref=e446]: CUSTOMER
- generic [ref=e447]:
- text: "Password for all:"
- code [ref=e448]: test123
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

View File

@@ -1,343 +0,0 @@
# Page snapshot
```yaml
- generic [ref=e2]:
- generic [ref=e3]:
- navigation [ref=e4]:
- generic [ref=e6]:
- link "Smooth Schedule" [ref=e7] [cursor=pointer]:
- /url: "#/"
- img [ref=e8]
- generic [ref=e14]: Smooth Schedule
- generic [ref=e15]:
- link "Features" [ref=e16] [cursor=pointer]:
- /url: "#/features"
- link "Pricing" [ref=e17] [cursor=pointer]:
- /url: "#/pricing"
- link "About" [ref=e18] [cursor=pointer]:
- /url: "#/about"
- link "Contact" [ref=e19] [cursor=pointer]:
- /url: "#/contact"
- generic [ref=e20]:
- button "🇺🇸 English" [ref=e23]:
- img [ref=e24]
- generic [ref=e28]: 🇺🇸
- generic [ref=e29]: English
- img [ref=e30]
- button "Switch to dark mode" [ref=e32]:
- img [ref=e33]
- link "Login" [ref=e35] [cursor=pointer]:
- /url: "#/login"
- link "Get Started" [ref=e36] [cursor=pointer]:
- /url: "#/signup"
- main [ref=e37]:
- generic [ref=e38]:
- generic [ref=e43]:
- generic [ref=e44]:
- generic [ref=e45]:
- generic [ref=e48]: Get started today
- heading "Scheduling Made Simple" [level=1] [ref=e49]
- paragraph [ref=e50]: The all-in-one platform for managing appointments, resources, and customers. Start free, scale as you grow.
- generic [ref=e51]:
- link "Get Started Free" [ref=e52] [cursor=pointer]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e53]
- button "Watch Demo" [ref=e56]:
- img [ref=e57]
- text: Watch Demo
- generic [ref=e59]:
- generic [ref=e60]:
- img [ref=e61]
- generic [ref=e64]: No credit card required
- generic [ref=e66]:
- img [ref=e67]
- generic [ref=e70]: Get started today
- generic [ref=e71]:
- generic [ref=e73]:
- generic [ref=e80]: dashboard.smoothschedule.com
- generic [ref=e81]:
- generic [ref=e82]:
- generic [ref=e83]:
- generic [ref=e84]: Today
- generic [ref=e85]: "12"
- generic [ref=e86]:
- generic [ref=e87]: This Week
- generic [ref=e88]: "48"
- generic [ref=e89]:
- generic [ref=e90]: Revenue
- generic [ref=e91]: $2.4k
- generic [ref=e92]:
- generic [ref=e93]: Today's Schedule
- generic [ref=e94]:
- generic [ref=e97]:
- generic [ref=e98]: 9:00 AM
- generic [ref=e99]: Sarah J. - Haircut
- generic [ref=e102]:
- generic [ref=e103]: 10:30 AM
- generic [ref=e104]: Mike T. - Consultation
- generic [ref=e107]:
- generic [ref=e108]: 2:00 PM
- generic [ref=e109]: Emma W. - Color
- generic [ref=e111]:
- img [ref=e113]
- generic [ref=e116]:
- generic [ref=e117]: New Booking!
- generic [ref=e118]: Just now
- generic [ref=e119]:
- paragraph [ref=e120]: Trusted by 1,000+ businesses worldwide
- generic [ref=e121]:
- generic [ref=e122]: TechCorp
- generic [ref=e123]: Innovate
- generic [ref=e124]: StartupX
- generic [ref=e125]: GrowthCo
- generic [ref=e126]: ScaleUp
- generic [ref=e128]:
- generic [ref=e129]:
- heading "Everything You Need" [level=2] [ref=e130]
- paragraph [ref=e131]: Powerful features to run your service business
- generic [ref=e132]:
- generic [ref=e133]:
- img [ref=e135]
- heading "Smart Scheduling" [level=3] [ref=e140]
- paragraph [ref=e141]: Drag-and-drop calendar with real-time availability, automated reminders, and conflict detection.
- generic [ref=e142]:
- img [ref=e144]
- heading "Resource Management" [level=3] [ref=e149]
- paragraph [ref=e150]: Manage staff, rooms, and equipment. Set availability, skills, and booking rules.
- generic [ref=e151]:
- img [ref=e153]
- heading "Customer Portal" [level=3] [ref=e157]
- paragraph [ref=e158]: Self-service booking portal for customers. View history, manage appointments, and save payment methods.
- generic [ref=e159]:
- img [ref=e161]
- heading "Integrated Payments" [level=3] [ref=e164]
- paragraph [ref=e165]: Accept payments online with Stripe. Deposits, full payments, and automatic invoicing.
- generic [ref=e166]:
- img [ref=e168]
- heading "Multi-Location Support" [level=3] [ref=e174]
- paragraph [ref=e175]: Manage multiple locations or brands from a single dashboard with isolated data.
- generic [ref=e176]:
- img [ref=e178]
- heading "White-Label Ready" [level=3] [ref=e184]
- paragraph [ref=e185]: Custom domain, branding, and remove SmoothSchedule branding for a seamless experience.
- link "View All features" [ref=e187] [cursor=pointer]:
- /url: "#/features"
- text: View All features
- img [ref=e188]
- generic [ref=e192]:
- generic [ref=e193]:
- heading "Get Started in Minutes" [level=2] [ref=e194]
- paragraph [ref=e195]: Three simple steps to transform your scheduling
- generic [ref=e196]:
- generic [ref=e199]:
- generic [ref=e200]: "01"
- img [ref=e202]
- heading "Create Your Account" [level=3] [ref=e207]
- paragraph [ref=e208]: Sign up for free and set up your business profile in minutes.
- generic [ref=e211]:
- generic [ref=e212]: "02"
- img [ref=e214]
- heading "Add Your Services" [level=3] [ref=e217]
- paragraph [ref=e218]: Configure your services, pricing, and available resources.
- generic [ref=e220]:
- generic [ref=e221]: "03"
- img [ref=e223]
- heading "Start Booking" [level=3] [ref=e228]
- paragraph [ref=e229]: Share your booking link and let customers schedule instantly.
- generic [ref=e232]:
- generic [ref=e233]:
- img [ref=e235]
- generic [ref=e240]: 1M+
- generic [ref=e241]: Appointments Scheduled
- generic [ref=e242]:
- img [ref=e244]
- generic [ref=e250]: 5,000+
- generic [ref=e251]: Businesses
- generic [ref=e252]:
- img [ref=e254]
- generic [ref=e258]: 50+
- generic [ref=e259]: Countries
- generic [ref=e260]:
- img [ref=e262]
- generic [ref=e265]: 99.9%
- generic [ref=e266]: Uptime
- generic [ref=e268]:
- generic [ref=e269]:
- heading "Loved by Businesses Everywhere" [level=2] [ref=e270]
- paragraph [ref=e271]: See what our customers have to say
- generic [ref=e272]:
- generic [ref=e273]:
- generic [ref=e274]:
- img [ref=e275]
- img [ref=e277]
- img [ref=e279]
- img [ref=e281]
- img [ref=e283]
- blockquote [ref=e285]: "\"SmoothSchedule transformed how we manage appointments. Our no-show rate dropped by 40% with automated reminders.\""
- generic [ref=e286]:
- generic [ref=e288]: S
- generic [ref=e289]:
- generic [ref=e290]: Sarah Johnson
- generic [ref=e291]: Owner at Luxe Salon
- generic [ref=e292]:
- generic [ref=e293]:
- img [ref=e294]
- img [ref=e296]
- img [ref=e298]
- img [ref=e300]
- img [ref=e302]
- blockquote [ref=e304]: "\"The white-label feature is perfect for our multi-location business. Each location has its own branded booking experience.\""
- generic [ref=e305]:
- generic [ref=e307]: M
- generic [ref=e308]:
- generic [ref=e309]: Michael Chen
- generic [ref=e310]: CEO at FitLife Studios
- generic [ref=e311]:
- generic [ref=e312]:
- img [ref=e313]
- img [ref=e315]
- img [ref=e317]
- img [ref=e319]
- img [ref=e321]
- blockquote [ref=e323]: "\"Setup was incredibly easy. We were up and running in under an hour, and our clients love the self-service booking.\""
- generic [ref=e324]:
- generic [ref=e326]: E
- generic [ref=e327]:
- generic [ref=e328]: Emily Rodriguez
- generic [ref=e329]: Manager at Peak Performance Therapy
- generic [ref=e331]:
- generic [ref=e332]:
- heading "Simple, Transparent Pricing" [level=2] [ref=e333]
- paragraph [ref=e334]: Start free, upgrade as you grow. No hidden fees.
- generic [ref=e335]:
- generic [ref=e336]:
- heading "Free" [level=3] [ref=e337]
- paragraph [ref=e338]: Perfect for getting started
- generic [ref=e339]: $0/month
- link "Get Started" [ref=e340] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e341]:
- generic [ref=e342]: Most Popular
- heading "Professional" [level=3] [ref=e343]
- paragraph [ref=e344]: For growing businesses
- generic [ref=e345]: $29/month
- link "Get Started" [ref=e346] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e347]:
- heading "Business" [level=3] [ref=e348]
- paragraph [ref=e349]: For established teams
- generic [ref=e350]: $79/month
- link "Get Started" [ref=e351] [cursor=pointer]:
- /url: "#/signup"
- link "View full pricing details" [ref=e353] [cursor=pointer]:
- /url: "#/pricing"
- text: View full pricing details
- img [ref=e354]
- generic [ref=e361]:
- heading "Ready to get started?" [level=2] [ref=e362]
- paragraph [ref=e363]: Join thousands of businesses already using SmoothSchedule.
- generic [ref=e364]:
- link "Get Started Free" [ref=e365] [cursor=pointer]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e366]
- link "Talk to Sales" [ref=e369] [cursor=pointer]:
- /url: "#/contact"
- paragraph [ref=e370]: No credit card required
- contentinfo [ref=e371]:
- generic [ref=e372]:
- generic [ref=e373]:
- generic [ref=e374]:
- link "Smooth Schedule" [ref=e375] [cursor=pointer]:
- /url: "#/"
- img [ref=e376]
- generic [ref=e382]: Smooth Schedule
- paragraph [ref=e383]: The all-in-one scheduling platform for businesses of all sizes. Manage resources, staff, and bookings effortlessly.
- generic [ref=e384]:
- link "Twitter" [ref=e385] [cursor=pointer]:
- /url: https://twitter.com/smoothschedule
- img [ref=e386]
- link "LinkedIn" [ref=e388] [cursor=pointer]:
- /url: https://linkedin.com/company/smoothschedule
- img [ref=e389]
- link "GitHub" [ref=e393] [cursor=pointer]:
- /url: https://github.com/smoothschedule
- img [ref=e394]
- link "YouTube" [ref=e397] [cursor=pointer]:
- /url: https://youtube.com/@smoothschedule
- img [ref=e398]
- generic [ref=e401]:
- heading "Product" [level=3] [ref=e402]
- list [ref=e403]:
- listitem [ref=e404]:
- link "Features" [ref=e405] [cursor=pointer]:
- /url: "#/features"
- listitem [ref=e406]:
- link "Pricing" [ref=e407] [cursor=pointer]:
- /url: "#/pricing"
- listitem [ref=e408]:
- link "Get Started" [ref=e409] [cursor=pointer]:
- /url: "#/signup"
- generic [ref=e410]:
- heading "Company" [level=3] [ref=e411]
- list [ref=e412]:
- listitem [ref=e413]:
- link "About" [ref=e414] [cursor=pointer]:
- /url: "#/about"
- listitem [ref=e415]:
- link "Contact" [ref=e416] [cursor=pointer]:
- /url: "#/contact"
- generic [ref=e417]:
- heading "Legal" [level=3] [ref=e418]
- list [ref=e419]:
- listitem [ref=e420]:
- link "Privacy Policy" [ref=e421] [cursor=pointer]:
- /url: "#/privacy"
- listitem [ref=e422]:
- link "Terms of Service" [ref=e423] [cursor=pointer]:
- /url: "#/terms"
- paragraph [ref=e425]: © 2025 Smooth Schedule Inc. All rights reserved.
- generic [ref=e426]:
- generic [ref=e427]:
- heading "🔓 Quick Login (Dev Only)" [level=3] [ref=e428]:
- generic [ref=e429]: 🔓
- generic [ref=e430]: Quick Login (Dev Only)
- button "×" [ref=e431]
- generic [ref=e432]:
- button "Logging in..." [disabled] [ref=e433]:
- generic [ref=e434]:
- img [ref=e435]
- text: Logging in...
- button "Platform Manager PLATFORM_MANAGER" [disabled] [ref=e438]:
- generic [ref=e439]:
- generic [ref=e440]: Platform Manager
- generic [ref=e441]: PLATFORM_MANAGER
- button "Platform Sales PLATFORM_SALES" [disabled] [ref=e442]:
- generic [ref=e443]:
- generic [ref=e444]: Platform Sales
- generic [ref=e445]: PLATFORM_SALES
- button "Platform Support PLATFORM_SUPPORT" [disabled] [ref=e446]:
- generic [ref=e447]:
- generic [ref=e448]: Platform Support
- generic [ref=e449]: PLATFORM_SUPPORT
- button "Business Owner TENANT_OWNER" [disabled] [ref=e450]:
- generic [ref=e451]:
- generic [ref=e452]: Business Owner
- generic [ref=e453]: TENANT_OWNER
- button "Business Manager TENANT_MANAGER" [disabled] [ref=e454]:
- generic [ref=e455]:
- generic [ref=e456]: Business Manager
- generic [ref=e457]: TENANT_MANAGER
- button "Staff Member TENANT_STAFF" [disabled] [ref=e458]:
- generic [ref=e459]:
- generic [ref=e460]: Staff Member
- generic [ref=e461]: TENANT_STAFF
- button "Customer CUSTOMER" [disabled] [ref=e462]:
- generic [ref=e463]:
- generic [ref=e464]: Customer
- generic [ref=e465]: CUSTOMER
- generic [ref=e466]:
- text: "Password for all:"
- code [ref=e467]: test123
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

View File

@@ -1,343 +0,0 @@
# Page snapshot
```yaml
- generic [ref=e2]:
- generic [ref=e3]:
- navigation [ref=e4]:
- generic [ref=e6]:
- link "Smooth Schedule" [ref=e7]:
- /url: "#/"
- img [ref=e8]
- generic [ref=e14]: Smooth Schedule
- generic [ref=e15]:
- link "Features" [ref=e16]:
- /url: "#/features"
- link "Pricing" [ref=e17]:
- /url: "#/pricing"
- link "About" [ref=e18]:
- /url: "#/about"
- link "Contact" [ref=e19]:
- /url: "#/contact"
- generic [ref=e20]:
- button "🇺🇸 English" [ref=e23]:
- img [ref=e24]
- generic [ref=e27]: 🇺🇸
- generic [ref=e28]: English
- img [ref=e29]
- button "Switch to dark mode" [ref=e31]:
- img [ref=e32]
- link "Login" [ref=e34]:
- /url: "#/login"
- link "Get Started" [ref=e35]:
- /url: "#/signup"
- main [ref=e36]:
- generic [ref=e37]:
- generic [ref=e42]:
- generic [ref=e43]:
- generic [ref=e44]:
- generic [ref=e47]: Get started today
- heading "Scheduling Made Simple" [level=1] [ref=e48]
- paragraph [ref=e49]: The all-in-one platform for managing appointments, resources, and customers. Start free, scale as you grow.
- generic [ref=e50]:
- link "Get Started Free" [ref=e51]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e52]
- button "Watch Demo" [ref=e54]:
- img [ref=e55]
- text: Watch Demo
- generic [ref=e57]:
- generic [ref=e58]:
- img [ref=e59]
- generic [ref=e62]: No credit card required
- generic [ref=e64]:
- img [ref=e65]
- generic [ref=e68]: Get started today
- generic [ref=e69]:
- generic [ref=e71]:
- generic [ref=e78]: dashboard.smoothschedule.com
- generic [ref=e79]:
- generic [ref=e80]:
- generic [ref=e81]:
- generic [ref=e82]: Today
- generic [ref=e83]: "12"
- generic [ref=e84]:
- generic [ref=e85]: This Week
- generic [ref=e86]: "48"
- generic [ref=e87]:
- generic [ref=e88]: Revenue
- generic [ref=e89]: $2.4k
- generic [ref=e90]:
- generic [ref=e91]: Today's Schedule
- generic [ref=e92]:
- generic [ref=e95]:
- generic [ref=e96]: 9:00 AM
- generic [ref=e97]: Sarah J. - Haircut
- generic [ref=e100]:
- generic [ref=e101]: 10:30 AM
- generic [ref=e102]: Mike T. - Consultation
- generic [ref=e105]:
- generic [ref=e106]: 2:00 PM
- generic [ref=e107]: Emma W. - Color
- generic [ref=e109]:
- img [ref=e111]
- generic [ref=e114]:
- generic [ref=e115]: New Booking!
- generic [ref=e116]: Just now
- generic [ref=e117]:
- paragraph [ref=e118]: Trusted by 1,000+ businesses worldwide
- generic [ref=e119]:
- generic [ref=e120]: TechCorp
- generic [ref=e121]: Innovate
- generic [ref=e122]: StartupX
- generic [ref=e123]: GrowthCo
- generic [ref=e124]: ScaleUp
- generic [ref=e126]:
- generic [ref=e127]:
- heading "Everything You Need" [level=2] [ref=e128]
- paragraph [ref=e129]: Powerful features to run your service business
- generic [ref=e130]:
- generic [ref=e131]:
- img [ref=e133]
- heading "Smart Scheduling" [level=3] [ref=e135]
- paragraph [ref=e136]: Drag-and-drop calendar with real-time availability, automated reminders, and conflict detection.
- generic [ref=e137]:
- img [ref=e139]
- heading "Resource Management" [level=3] [ref=e144]
- paragraph [ref=e145]: Manage staff, rooms, and equipment. Set availability, skills, and booking rules.
- generic [ref=e146]:
- img [ref=e148]
- heading "Customer Portal" [level=3] [ref=e152]
- paragraph [ref=e153]: Self-service booking portal for customers. View history, manage appointments, and save payment methods.
- generic [ref=e154]:
- img [ref=e156]
- heading "Integrated Payments" [level=3] [ref=e158]
- paragraph [ref=e159]: Accept payments online with Stripe. Deposits, full payments, and automatic invoicing.
- generic [ref=e160]:
- img [ref=e162]
- heading "Multi-Location Support" [level=3] [ref=e166]
- paragraph [ref=e167]: Manage multiple locations or brands from a single dashboard with isolated data.
- generic [ref=e168]:
- img [ref=e170]
- heading "White-Label Ready" [level=3] [ref=e176]
- paragraph [ref=e177]: Custom domain, branding, and remove SmoothSchedule branding for a seamless experience.
- link "View All features" [ref=e179]:
- /url: "#/features"
- text: View All features
- img [ref=e180]
- generic [ref=e183]:
- generic [ref=e184]:
- heading "Get Started in Minutes" [level=2] [ref=e185]
- paragraph [ref=e186]: Three simple steps to transform your scheduling
- generic [ref=e187]:
- generic [ref=e190]:
- generic [ref=e191]: "01"
- img [ref=e193]
- heading "Create Your Account" [level=3] [ref=e196]
- paragraph [ref=e197]: Sign up for free and set up your business profile in minutes.
- generic [ref=e200]:
- generic [ref=e201]: "02"
- img [ref=e203]
- heading "Add Your Services" [level=3] [ref=e206]
- paragraph [ref=e207]: Configure your services, pricing, and available resources.
- generic [ref=e209]:
- generic [ref=e210]: "03"
- img [ref=e212]
- heading "Start Booking" [level=3] [ref=e217]
- paragraph [ref=e218]: Share your booking link and let customers schedule instantly.
- generic [ref=e221]:
- generic [ref=e222]:
- img [ref=e224]
- generic [ref=e226]: 1M+
- generic [ref=e227]: Appointments Scheduled
- generic [ref=e228]:
- img [ref=e230]
- generic [ref=e234]: 5,000+
- generic [ref=e235]: Businesses
- generic [ref=e236]:
- img [ref=e238]
- generic [ref=e241]: 50+
- generic [ref=e242]: Countries
- generic [ref=e243]:
- img [ref=e245]
- generic [ref=e248]: 99.9%
- generic [ref=e249]: Uptime
- generic [ref=e251]:
- generic [ref=e252]:
- heading "Loved by Businesses Everywhere" [level=2] [ref=e253]
- paragraph [ref=e254]: See what our customers have to say
- generic [ref=e255]:
- generic [ref=e256]:
- generic [ref=e257]:
- img [ref=e258]
- img [ref=e260]
- img [ref=e262]
- img [ref=e264]
- img [ref=e266]
- blockquote [ref=e268]: "\"SmoothSchedule transformed how we manage appointments. Our no-show rate dropped by 40% with automated reminders.\""
- generic [ref=e269]:
- generic [ref=e271]: S
- generic [ref=e272]:
- generic [ref=e273]: Sarah Johnson
- generic [ref=e274]: Owner at Luxe Salon
- generic [ref=e275]:
- generic [ref=e276]:
- img [ref=e277]
- img [ref=e279]
- img [ref=e281]
- img [ref=e283]
- img [ref=e285]
- blockquote [ref=e287]: "\"The white-label feature is perfect for our multi-location business. Each location has its own branded booking experience.\""
- generic [ref=e288]:
- generic [ref=e290]: M
- generic [ref=e291]:
- generic [ref=e292]: Michael Chen
- generic [ref=e293]: CEO at FitLife Studios
- generic [ref=e294]:
- generic [ref=e295]:
- img [ref=e296]
- img [ref=e298]
- img [ref=e300]
- img [ref=e302]
- img [ref=e304]
- blockquote [ref=e306]: "\"Setup was incredibly easy. We were up and running in under an hour, and our clients love the self-service booking.\""
- generic [ref=e307]:
- generic [ref=e309]: E
- generic [ref=e310]:
- generic [ref=e311]: Emily Rodriguez
- generic [ref=e312]: Manager at Peak Performance Therapy
- generic [ref=e314]:
- generic [ref=e315]:
- heading "Simple, Transparent Pricing" [level=2] [ref=e316]
- paragraph [ref=e317]: Start free, upgrade as you grow. No hidden fees.
- generic [ref=e318]:
- generic [ref=e319]:
- heading "Free" [level=3] [ref=e320]
- paragraph [ref=e321]: Perfect for getting started
- generic [ref=e322]: $0/month
- link "Get Started" [ref=e323]:
- /url: "#/signup"
- generic [ref=e324]:
- generic [ref=e325]: Most Popular
- heading "Professional" [level=3] [ref=e326]
- paragraph [ref=e327]: For growing businesses
- generic [ref=e328]: $29/month
- link "Get Started" [ref=e329]:
- /url: "#/signup"
- generic [ref=e330]:
- heading "Business" [level=3] [ref=e331]
- paragraph [ref=e332]: For established teams
- generic [ref=e333]: $79/month
- link "Get Started" [ref=e334]:
- /url: "#/signup"
- link "View full pricing details" [ref=e336]:
- /url: "#/pricing"
- text: View full pricing details
- img [ref=e337]
- generic [ref=e343]:
- heading "Ready to get started?" [level=2] [ref=e344]
- paragraph [ref=e345]: Join thousands of businesses already using SmoothSchedule.
- generic [ref=e346]:
- link "Get Started Free" [ref=e347]:
- /url: "#/signup"
- text: Get Started Free
- img [ref=e348]
- link "Talk to Sales" [ref=e350]:
- /url: "#/contact"
- paragraph [ref=e351]: No credit card required
- contentinfo [ref=e352]:
- generic [ref=e353]:
- generic [ref=e354]:
- generic [ref=e355]:
- link "Smooth Schedule" [ref=e356]:
- /url: "#/"
- img [ref=e357]
- generic [ref=e363]: Smooth Schedule
- paragraph [ref=e364]: The all-in-one scheduling platform for businesses of all sizes. Manage resources, staff, and bookings effortlessly.
- generic [ref=e365]:
- link "Twitter" [ref=e366]:
- /url: https://twitter.com/smoothschedule
- img [ref=e367]
- link "LinkedIn" [ref=e369]:
- /url: https://linkedin.com/company/smoothschedule
- img [ref=e370]
- link "GitHub" [ref=e374]:
- /url: https://github.com/smoothschedule
- img [ref=e375]
- link "YouTube" [ref=e378]:
- /url: https://youtube.com/@smoothschedule
- img [ref=e379]
- generic [ref=e382]:
- heading "Product" [level=3] [ref=e383]
- list [ref=e384]:
- listitem [ref=e385]:
- link "Features" [ref=e386]:
- /url: "#/features"
- listitem [ref=e387]:
- link "Pricing" [ref=e388]:
- /url: "#/pricing"
- listitem [ref=e389]:
- link "Get Started" [ref=e390]:
- /url: "#/signup"
- generic [ref=e391]:
- heading "Company" [level=3] [ref=e392]
- list [ref=e393]:
- listitem [ref=e394]:
- link "About" [ref=e395]:
- /url: "#/about"
- listitem [ref=e396]:
- link "Contact" [ref=e397]:
- /url: "#/contact"
- generic [ref=e398]:
- heading "Legal" [level=3] [ref=e399]
- list [ref=e400]:
- listitem [ref=e401]:
- link "Privacy Policy" [ref=e402]:
- /url: "#/privacy"
- listitem [ref=e403]:
- link "Terms of Service" [ref=e404]:
- /url: "#/terms"
- paragraph [ref=e406]: © 2025 Smooth Schedule Inc. All rights reserved.
- generic [ref=e407]:
- generic [ref=e408]:
- heading "🔓 Quick Login (Dev Only)" [level=3] [ref=e409]:
- generic [ref=e410]: 🔓
- generic [ref=e411]: Quick Login (Dev Only)
- button "×" [ref=e412]
- generic [ref=e413]:
- button "Logging in..." [disabled] [ref=e414]:
- generic [ref=e415]:
- img [ref=e416]
- text: Logging in...
- button "Platform Manager PLATFORM_MANAGER" [disabled] [ref=e419]:
- generic [ref=e420]:
- generic [ref=e421]: Platform Manager
- generic [ref=e422]: PLATFORM_MANAGER
- button "Platform Sales PLATFORM_SALES" [disabled] [ref=e423]:
- generic [ref=e424]:
- generic [ref=e425]: Platform Sales
- generic [ref=e426]: PLATFORM_SALES
- button "Platform Support PLATFORM_SUPPORT" [disabled] [ref=e427]:
- generic [ref=e428]:
- generic [ref=e429]: Platform Support
- generic [ref=e430]: PLATFORM_SUPPORT
- button "Business Owner TENANT_OWNER" [disabled] [ref=e431]:
- generic [ref=e432]:
- generic [ref=e433]: Business Owner
- generic [ref=e434]: TENANT_OWNER
- button "Business Manager TENANT_MANAGER" [disabled] [ref=e435]:
- generic [ref=e436]:
- generic [ref=e437]: Business Manager
- generic [ref=e438]: TENANT_MANAGER
- button "Staff Member TENANT_STAFF" [disabled] [ref=e439]:
- generic [ref=e440]:
- generic [ref=e441]: Staff Member
- generic [ref=e442]: TENANT_STAFF
- button "Customer CUSTOMER" [disabled] [ref=e443]:
- generic [ref=e444]:
- generic [ref=e445]: Customer
- generic [ref=e446]: CUSTOMER
- generic [ref=e447]:
- text: "Password for all:"
- code [ref=e448]: test123
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB

View File

@@ -0,0 +1,97 @@
import { test, expect } from '@playwright/test';
test('business owner login flow', async ({ page }) => {
// Enable console logging
page.on('console', msg => {
const type = msg.type();
const text = msg.text();
// Only log errors, warnings, and our custom debug logs
if (type === 'error' || type === 'warning' || text.includes('Failed to')) {
console.log(`BROWSER ${type.toUpperCase()}:`, text);
}
});
// Enable error logging
page.on('pageerror', error => {
console.error('PAGE ERROR:', error.message);
console.error('STACK:', error.stack);
});
// Track network errors
page.on('requestfailed', request => {
console.error('REQUEST FAILED:', request.url(), request.failure()?.errorText);
});
// Go to the login page
console.log('Navigating to login page...');
await page.goto('http://lvh.me:5173/#/login');
// Wait for the page to load
await page.waitForLoadState('networkidle');
// Take screenshot of initial state
await page.screenshot({ path: 'test-results/01-initial-page.png', fullPage: true });
// Check if DevQuickLogin component loaded
const quickLoginVisible = await page.locator('text=Quick Login (Dev Only)').isVisible().catch(() => false);
console.log('Quick Login visible:', quickLoginVisible);
if (quickLoginVisible) {
// Click the Business Owner button
console.log('Clicking Business Owner button...');
await page.click('button:has-text("Business Owner")');
// Wait for navigation or changes
await page.waitForTimeout(2000);
// Take screenshot after clicking
await page.screenshot({ path: 'test-results/02-after-click.png', fullPage: true });
// Check the current URL
const currentUrl = page.url();
console.log('Current URL:', currentUrl);
// Check if #root has content
const rootContent = await page.locator('#root').innerHTML();
console.log('Root content length:', rootContent.length);
console.log('Root content:', rootContent.substring(0, 500));
// Check full page HTML if root is empty
if (rootContent.length === 0) {
const bodyContent = await page.locator('body').innerHTML();
console.log('\nFull body HTML (first 1000 chars):');
console.log(bodyContent.substring(0, 1000));
// Check for script tags
const scripts = await page.locator('script').count();
console.log('\nNumber of script tags:', scripts);
// Evaluate JavaScript in the page context to check for errors
const jsErrors = await page.evaluate(() => {
// Check if React root exists
const root = document.getElementById('root');
return {
rootExists: !!root,
rootHasChildren: root ? root.childNodes.length : 0,
documentReady: document.readyState,
};
});
console.log('\nJS Context:', JSON.stringify(jsErrors, null, 2));
}
// Check for React errors
const hasReactError = await page.locator('text=/error|failed/i').count();
console.log('\nError count on page:', hasReactError);
} else {
console.log('Quick Login component not found. Page content:');
const bodyText = await page.locator('body').textContent();
console.log(bodyText?.substring(0, 1000));
}
// Wait a bit more to see what happens
await page.waitForTimeout(3000);
// Final screenshot
await page.screenshot({ path: 'test-results/03-final-state.png', fullPage: true });
});