feat: Dashboard redesign, plan permissions, and help docs improvements

Major updates including:
- Customizable dashboard with drag-and-drop widget grid layout
- Plan-based feature locking for plugins and tasks
- Comprehensive help documentation updates across all pages
- Plugin seeding in deployment process for all tenants
- Permission synchronization system for subscription plans
- QuotaOverageModal component and enhanced UX flows

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-03 13:02:44 -05:00
parent 9444e26924
commit dcb14503a2
66 changed files with 7099 additions and 1467 deletions

View File

@@ -84,6 +84,7 @@ export const FEATURE_NAMES: Record<FeatureKey, string> = {
white_label: 'White Label',
custom_oauth: 'Custom OAuth',
plugins: 'Custom Plugins',
tasks: 'Scheduled Tasks',
export_data: 'Data Export',
video_conferencing: 'Video Conferencing',
two_factor_auth: 'Two-Factor Authentication',
@@ -103,6 +104,7 @@ export const FEATURE_DESCRIPTIONS: Record<FeatureKey, string> = {
white_label: 'Remove SmoothSchedule branding and use your own',
custom_oauth: 'Configure your own OAuth credentials for social login',
plugins: 'Create custom plugins to extend functionality',
tasks: 'Create scheduled tasks to automate plugin execution',
export_data: 'Export your data to CSV or other formats',
video_conferencing: 'Add video conferencing links to appointments',
two_factor_auth: 'Require two-factor authentication for enhanced security',

View File

@@ -243,3 +243,15 @@ export const useSyncPlansWithStripe = () => {
},
});
};
/**
* Hook to sync a plan's permissions to all tenants on that plan
*/
export const useSyncPlanToTenants = () => {
return useMutation({
mutationFn: async (planId: number) => {
const { data } = await apiClient.post(`/platform/subscription-plans/${planId}/sync_tenants/`);
return data as { message: string; tenant_count: number };
},
});
};

View File

@@ -1,15 +1,22 @@
import { useEffect } from 'react';
import { useEffect, RefObject } from 'react';
import { useLocation } from 'react-router-dom';
/**
* Hook to scroll to top on route changes
* Should be used in layout components to ensure scroll restoration
* works consistently across all routes
*
* @param containerRef - Optional ref to a scrollable container element.
* If provided, scrolls that element instead of window.
*/
export function useScrollToTop() {
export function useScrollToTop(containerRef?: RefObject<HTMLElement | null>) {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
if (containerRef?.current) {
containerRef.current.scrollTo(0, 0);
} else {
window.scrollTo(0, 0);
}
}, [pathname, containerRef]);
}