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

@@ -21,6 +21,8 @@ import {
import toast from 'react-hot-toast';
import CreateTaskModal from '../components/CreateTaskModal';
import EditTaskModal from '../components/EditTaskModal';
import { usePlanFeatures } from '../hooks/usePlanFeatures';
import { LockedSection } from '../components/UpgradePrompt';
// Types
interface ScheduledTask {
@@ -95,6 +97,12 @@ const Tasks: React.FC = () => {
const [editingTask, setEditingTask] = useState<ScheduledTask | null>(null);
const [editingEventAutomation, setEditingEventAutomation] = useState<GlobalEventPlugin | null>(null);
// Check plan permissions - tasks requires both plugins AND tasks features
const { canUse, isLoading: permissionsLoading } = usePlanFeatures();
const hasPluginsFeature = canUse('plugins');
const hasTasksFeature = canUse('tasks');
const isLocked = !hasPluginsFeature || !hasTasksFeature;
// Fetch scheduled tasks
const { data: scheduledTasks = [], isLoading: tasksLoading } = useQuery<ScheduledTask[]>({
queryKey: ['scheduled-tasks'],
@@ -246,7 +254,7 @@ const Tasks: React.FC = () => {
return AlertCircle;
};
if (isLoading) {
if (isLoading || permissionsLoading) {
return (
<div className="flex items-center justify-center h-96">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
@@ -255,6 +263,7 @@ const Tasks: React.FC = () => {
}
return (
<LockedSection feature="tasks" isLocked={isLocked} variant="overlay">
<div className="p-6 max-w-7xl mx-auto">
{/* Header */}
<div className="flex items-center justify-between mb-6">
@@ -588,6 +597,7 @@ const Tasks: React.FC = () => {
/>
)}
</div>
</LockedSection>
);
};