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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user