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:
@@ -52,7 +52,7 @@ const BusinessLayoutContent: React.FC<BusinessLayoutProps> = ({ business, user,
|
||||
const [searchParams] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useScrollToTop();
|
||||
useScrollToTop(mainContentRef);
|
||||
|
||||
// Fetch ticket data when modal is opened from notification
|
||||
const { data: ticketFromNotification } = useTicket(ticketModalId || undefined);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { Outlet, Link, useNavigate } from 'react-router-dom';
|
||||
import { User, Business } from '../types';
|
||||
import { LayoutDashboard, CalendarPlus, CreditCard, HelpCircle, Sun, Moon } from 'lucide-react';
|
||||
@@ -18,7 +18,8 @@ interface CustomerLayoutProps {
|
||||
|
||||
const CustomerLayout: React.FC<CustomerLayoutProps> = ({ business, user, darkMode, toggleTheme }) => {
|
||||
const navigate = useNavigate();
|
||||
useScrollToTop();
|
||||
const mainContentRef = useRef<HTMLElement>(null);
|
||||
useScrollToTop(mainContentRef);
|
||||
|
||||
// Masquerade logic
|
||||
const [masqueradeStack, setMasqueradeStack] = useState<MasqueradeStackEntry[]>([]);
|
||||
@@ -116,7 +117,7 @@ const CustomerLayout: React.FC<CustomerLayoutProps> = ({ business, user, darkMod
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main className="flex-1 overflow-y-auto">
|
||||
<main ref={mainContentRef} className="flex-1 overflow-y-auto">
|
||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<Outlet context={{ business, user }} />
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useRef } from 'react';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
import { Moon, Sun, Bell, Globe, Menu } from 'lucide-react';
|
||||
import { User } from '../types';
|
||||
@@ -16,8 +16,9 @@ interface ManagerLayoutProps {
|
||||
const ManagerLayout: React.FC<ManagerLayoutProps> = ({ user, darkMode, toggleTheme, onSignOut }) => {
|
||||
const [isCollapsed, setIsCollapsed] = useState(false);
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
const mainContentRef = useRef<HTMLElement>(null);
|
||||
|
||||
useScrollToTop();
|
||||
useScrollToTop(mainContentRef);
|
||||
|
||||
return (
|
||||
<div className="flex h-full bg-gray-100 dark:bg-gray-900">
|
||||
@@ -63,7 +64,7 @@ const ManagerLayout: React.FC<ManagerLayoutProps> = ({ user, darkMode, toggleThe
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="flex-1 overflow-auto bg-gray-50 dark:bg-gray-900 p-8">
|
||||
<main ref={mainContentRef} className="flex-1 overflow-auto bg-gray-50 dark:bg-gray-900 p-8">
|
||||
<Outlet />
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useRef } from 'react';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
import { Moon, Sun, Globe, Menu } from 'lucide-react';
|
||||
import { User } from '../types';
|
||||
@@ -21,8 +21,9 @@ const PlatformLayout: React.FC<PlatformLayoutProps> = ({ user, darkMode, toggleT
|
||||
const [isCollapsed, setIsCollapsed] = useState(false);
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
const [ticketModalId, setTicketModalId] = useState<string | null>(null);
|
||||
const mainContentRef = useRef<HTMLElement>(null);
|
||||
|
||||
useScrollToTop();
|
||||
useScrollToTop(mainContentRef);
|
||||
|
||||
// Fetch ticket data when modal is opened from notification
|
||||
const { data: ticketFromNotification } = useTicket(ticketModalId && ticketModalId !== 'undefined' ? ticketModalId : undefined);
|
||||
@@ -83,7 +84,7 @@ const PlatformLayout: React.FC<PlatformLayoutProps> = ({ user, darkMode, toggleT
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="flex-1 overflow-auto bg-gray-50 dark:bg-gray-900 p-8">
|
||||
<main ref={mainContentRef} className="flex-1 overflow-auto bg-gray-50 dark:bg-gray-900 p-8">
|
||||
<Outlet />
|
||||
</main>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user