- Add TimeBlock and Holiday models with recurrence support (one-time, weekly, monthly, yearly, holiday) - Implement business-level and resource-level blocking with hard/soft block types - Add multi-select holiday picker for bulk holiday blocking - Add calendar overlay visualization with distinct colors: - Business blocks: Red (hard) / Yellow (soft) - Resource blocks: Purple (hard) / Cyan (soft) - Add month view resource indicators showing 1/n width per resource - Add yearly calendar view for block overview - Add My Availability page for staff self-service - Add contracts module with templates, signing flow, and PDF generation - Update scheduler with click-to-day navigation in week view 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
99 lines
3.3 KiB
TypeScript
99 lines
3.3 KiB
TypeScript
/**
|
|
* FloatingHelpButton Component
|
|
*
|
|
* A floating help button fixed in the top-right corner of the screen.
|
|
* Automatically determines the help path based on the current route.
|
|
*/
|
|
|
|
import React from 'react';
|
|
import { Link, useLocation } from 'react-router-dom';
|
|
import { HelpCircle } from 'lucide-react';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
// Map routes to their help paths
|
|
const routeToHelpPath: Record<string, string> = {
|
|
'/': '/help/dashboard',
|
|
'/dashboard': '/help/dashboard',
|
|
'/scheduler': '/help/scheduler',
|
|
'/tasks': '/help/tasks',
|
|
'/customers': '/help/customers',
|
|
'/services': '/help/services',
|
|
'/resources': '/help/resources',
|
|
'/staff': '/help/staff',
|
|
'/time-blocks': '/help/time-blocks',
|
|
'/my-availability': '/help/time-blocks',
|
|
'/messages': '/help/messages',
|
|
'/tickets': '/help/ticketing',
|
|
'/payments': '/help/payments',
|
|
'/contracts': '/help/contracts',
|
|
'/contracts/templates': '/help/contracts',
|
|
'/plugins': '/help/plugins',
|
|
'/plugins/marketplace': '/help/plugins',
|
|
'/plugins/my-plugins': '/help/plugins',
|
|
'/plugins/create': '/help/plugins/create',
|
|
'/settings': '/help/settings/general',
|
|
'/settings/general': '/help/settings/general',
|
|
'/settings/resource-types': '/help/settings/resource-types',
|
|
'/settings/booking': '/help/settings/booking',
|
|
'/settings/appearance': '/help/settings/appearance',
|
|
'/settings/email': '/help/settings/email',
|
|
'/settings/domains': '/help/settings/domains',
|
|
'/settings/api': '/help/settings/api',
|
|
'/settings/auth': '/help/settings/auth',
|
|
'/settings/billing': '/help/settings/billing',
|
|
'/settings/quota': '/help/settings/quota',
|
|
// Platform routes
|
|
'/platform/dashboard': '/help/dashboard',
|
|
'/platform/businesses': '/help/dashboard',
|
|
'/platform/users': '/help/staff',
|
|
'/platform/tickets': '/help/ticketing',
|
|
};
|
|
|
|
const FloatingHelpButton: React.FC = () => {
|
|
const { t } = useTranslation();
|
|
const location = useLocation();
|
|
|
|
// Get the help path for the current route
|
|
const getHelpPath = (): string => {
|
|
// Exact match first
|
|
if (routeToHelpPath[location.pathname]) {
|
|
return routeToHelpPath[location.pathname];
|
|
}
|
|
|
|
// Try matching with a prefix (for dynamic routes like /customers/:id)
|
|
const pathSegments = location.pathname.split('/').filter(Boolean);
|
|
if (pathSegments.length > 0) {
|
|
// Try progressively shorter paths
|
|
for (let i = pathSegments.length; i > 0; i--) {
|
|
const testPath = '/' + pathSegments.slice(0, i).join('/');
|
|
if (routeToHelpPath[testPath]) {
|
|
return routeToHelpPath[testPath];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Default to the main help guide
|
|
return '/help';
|
|
};
|
|
|
|
const helpPath = getHelpPath();
|
|
|
|
// Don't show on help pages themselves
|
|
if (location.pathname.startsWith('/help')) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Link
|
|
to={helpPath}
|
|
className="fixed top-20 right-4 z-50 inline-flex items-center justify-center w-10 h-10 bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:text-brand-600 dark:hover:text-brand-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full shadow-lg border border-gray-200 dark:border-gray-700 transition-all duration-200 hover:scale-110"
|
|
title={t('common.help', 'Help')}
|
|
aria-label={t('common.help', 'Help')}
|
|
>
|
|
<HelpCircle size={20} />
|
|
</Link>
|
|
);
|
|
};
|
|
|
|
export default FloatingHelpButton;
|