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

@@ -29,6 +29,8 @@ import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';
import api from '../api/client';
import { PluginTemplate, PluginCategory } from '../types';
import { usePlanFeatures } from '../hooks/usePlanFeatures';
import { LockedSection } from '../components/UpgradePrompt';
// Category icon mapping
const categoryIcons: Record<PluginCategory, React.ReactNode> = {
@@ -91,6 +93,11 @@ const PluginMarketplace: React.FC = () => {
const [showWhatsNextModal, setShowWhatsNextModal] = useState(false);
const [installedPluginId, setInstalledPluginId] = useState<string | null>(null);
// Check plan permissions
const { canUse, isLoading: permissionsLoading } = usePlanFeatures();
const hasPluginsFeature = canUse('plugins');
const isLocked = !hasPluginsFeature;
// Fetch marketplace plugins
const { data: plugins = [], isLoading, error } = useQuery<PluginTemplate[]>({
queryKey: ['plugin-templates', 'marketplace'],
@@ -206,7 +213,7 @@ const PluginMarketplace: React.FC = () => {
}
};
if (isLoading) {
if (isLoading || permissionsLoading) {
return (
<div className="p-8">
<div className="flex items-center justify-center h-64">
@@ -229,6 +236,7 @@ const PluginMarketplace: React.FC = () => {
}
return (
<LockedSection feature="plugins" isLocked={isLocked} variant="overlay">
<div className="p-8 space-y-6 max-w-7xl mx-auto">
{/* Header */}
<div className="flex items-center justify-between">
@@ -702,6 +710,7 @@ const PluginMarketplace: React.FC = () => {
</div>
)}
</div>
</LockedSection>
);
};