Files
smoothschedule/frontend/CLAUDE.md
poduck b10426fbdb feat: Add photo galleries to services, resource types management, and UI improvements
Major features:
- Add drag-and-drop photo gallery to Service create/edit modals
- Add Resource Types management section to Settings (CRUD for custom types)
- Add edit icon consistency to Resources table (pencil icon in actions)
- Improve Services page with drag-to-reorder and customer preview mockup

Backend changes:
- Add photos JSONField to Service model with migration
- Add ResourceType model with category (STAFF/OTHER), description fields
- Add ResourceTypeViewSet with CRUD operations
- Add service reorder endpoint for display order

Frontend changes:
- Services page: two-column layout, drag-reorder, photo upload
- Settings page: Resource Types tab with full CRUD modal
- Resources page: Edit icon in actions column instead of row click
- Sidebar: Payments link visibility based on role and paymentsEnabled
- Update types.ts with Service.photos and ResourceTypeDefinition

Note: Removed photos from ResourceType (kept only for Service)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 01:11:53 -05:00

191 lines
6.1 KiB
Markdown

# SmoothSchedule Frontend Development Guide
## Project Overview
This is the React frontend for SmoothSchedule, a multi-tenant scheduling platform.
**See also:** `/home/poduck/Desktop/smoothschedule2/smoothschedule/CLAUDE.md` for backend documentation.
## Key Paths
```
/home/poduck/Desktop/smoothschedule2/
├── frontend/ # This React frontend
│ ├── src/
│ │ ├── api/client.ts # Axios API client
│ │ ├── components/ # Reusable components
│ │ ├── hooks/ # React Query hooks (useResources, useAuth, etc.)
│ │ ├── pages/ # Page components
│ │ ├── types.ts # TypeScript interfaces
│ │ ├── i18n/locales/en.json # English translations
│ │ └── utils/cookies.ts # Cookie utilities
│ ├── .env.development # Frontend env vars
│ └── vite.config.ts # Vite configuration
└── smoothschedule/ # Django backend (runs in Docker!)
├── docker-compose.local.yml # Docker config
├── .envs/.local/ # Backend env vars
├── config/settings/ # Django settings
└── smoothschedule/
├── schedule/ # Core scheduling app
└── users/ # User management
```
## Local Development Domain Setup
### Why lvh.me instead of localhost?
This project uses **lvh.me** for local development instead of `localhost` due to cookie domain restrictions in RFC 6265.
**The Problem with localhost:**
- Browsers reject cookies with `domain=.localhost` for security reasons
- `localhost` is treated as a special-use domain where domain cookies don't work
- Cannot share cookies across subdomains like `platform.localhost` and `business.localhost`
**The Solution - lvh.me:**
- `lvh.me` is a public DNS service that resolves all `*.lvh.me` domains to `127.0.0.1`
- Browsers allow setting cookies with `domain=.lvh.me`
- Cookies are accessible across all subdomains (platform.lvh.me, business1.lvh.me, etc.)
- No /etc/hosts configuration needed - it just works!
### Development URLs
Use these URLs for local development:
- **Base domain:** `http://lvh.me:5173`
- **Platform dashboard:** `http://platform.lvh.me:5173`
- **Business subdomains:** `http://{subdomain}.lvh.me:5173`
### Multi-Tenant Architecture
The application uses subdomain-based multi-tenancy:
1. **Platform Users** (superuser, platform_manager, platform_support)
- Access the app at `http://platform.lvh.me:5173`
- See platform dashboard and administrative features
2. **Business Users** (owner, manager, staff, resource)
- Access the app at `http://{business_subdomain}.lvh.me:5173`
- See business-specific dashboard and features
### Cookie-Based Authentication
Tokens are stored in cookies with `domain=.lvh.me` to enable cross-subdomain access:
```typescript
// Set cookie accessible across all *.lvh.me subdomains
setCookie('access_token', token, 7); // domain=.lvh.me
// Cookie is accessible on:
// - platform.lvh.me:5173
// - business1.lvh.me:5173
// - business2.lvh.me:5173
// etc.
```
**Key Files:**
- `/src/utils/cookies.ts` - Cookie utilities with cross-subdomain support
- `/src/hooks/useAuth.ts` - Authentication hooks using cookies
- `/src/api/client.ts` - API client with cookie-based auth
### Login Flow
1. User navigates to `http://platform.lvh.me:5173`
2. If not authenticated, shows login page
3. User enters credentials and submits
4. Backend validates and returns JWT tokens + user data
5. Tokens stored in cookies with `domain=.lvh.me`
6. User data stored in React Query cache
7. App checks user role:
- Platform users: Stay on platform.lvh.me
- Business users: Redirect to {business_subdomain}.lvh.me
8. Cookies accessible on target subdomain - user sees dashboard
### Testing with Playwright
Tests use lvh.me for proper subdomain testing:
```typescript
// Start on platform subdomain
await page.goto('http://platform.lvh.me:5173');
// Login sets cookies with domain=.lvh.me
await page.getByPlaceholder(/username/i).fill('poduck');
await page.getByPlaceholder(/password/i).fill('starry12');
await page.getByRole('button', { name: /sign in/i }).click();
// Cookies accessible, dashboard loads
await expect(page.getByRole('heading', { name: /platform dashboard/i })).toBeVisible();
```
### Running the Development Server
```bash
# Install dependencies
npm install
# Start dev server
npm run dev
# Access at http://platform.lvh.me:5173
```
### Running Tests
```bash
# Run all tests
npm test
# Run E2E tests
npx playwright test
# Run specific test file
npx playwright test login-flow.spec.ts
# Run with UI
npx playwright test --ui
```
## Production Deployment
In production, replace `lvh.me` with your actual domain:
1. Update `src/utils/cookies.ts`:
```typescript
const domain = window.location.hostname.includes('yourdomain.com')
? '.yourdomain.com'
: window.location.hostname;
```
2. Configure DNS:
- `platform.yourdomain.com` → Your server IP
- `*.yourdomain.com` → Your server IP (wildcard for business subdomains)
3. SSL certificates:
- Get wildcard certificate for `*.yourdomain.com`
- Or use Let's Encrypt with wildcard support
## Troubleshooting
### Cookies not working?
- Make sure you're using `lvh.me`, not `localhost`
- Check browser DevTools → Application → Cookies
- Verify `domain=.lvh.me` is set on cookies
- Clear cookies and try again
### Redirect issues?
- Check `/src/pages/LoginPage.tsx` redirect logic
- Verify user role and business_subdomain in response
- Check browser console for navigation errors
### Can't access lvh.me?
- Verify internet connection (lvh.me requires DNS lookup)
- Try `ping lvh.me` - should resolve to `127.0.0.1`
- Alternative: Use `127.0.0.1.nip.io` (similar service)
## References
- [RFC 6265 - HTTP State Management Mechanism](https://datatracker.ietf.org/doc/html/rfc6265)
- [lvh.me DNS service](http://lvh.me)
- [Cookie Domain Attribute Rules](https://stackoverflow.com/questions/1062963/how-do-browser-cookie-domains-work)