SettingsDrawer.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import React from 'react';
  2. import { createPortal } from 'react-dom';
  3. import ConfigPanel from './ConfigPanel';
  4. import { AppSettings, ModelConfig } from '../types';
  5. import { X } from 'lucide-react';
  6. import { useLanguage } from '../contexts/LanguageContext';
  7. interface SettingsDrawerProps {
  8. isOpen: boolean;
  9. onClose: () => void;
  10. settings: AppSettings;
  11. models: ModelConfig[];
  12. onSettingsChange: (newSettings: AppSettings) => void;
  13. onOpenSettings: () => void; // Keeps the "Full Settings" link working if needed, or we might redirect
  14. mode?: 'chat' | 'kb' | 'all';
  15. isAdmin?: boolean;
  16. }
  17. export const SettingsDrawer: React.FC<SettingsDrawerProps> = ({
  18. isOpen,
  19. onClose,
  20. settings,
  21. models,
  22. onSettingsChange,
  23. onOpenSettings,
  24. mode = 'all',
  25. isAdmin = false
  26. }) => {
  27. const { t } = useLanguage();
  28. const [localSettings, setLocalSettings] = React.useState<AppSettings>(settings);
  29. // Initial sync
  30. React.useEffect(() => {
  31. if (isOpen) {
  32. setLocalSettings(settings);
  33. }
  34. }, [isOpen, settings]);
  35. if (!isOpen) return null;
  36. const handleLocalChange = (newSettings: AppSettings) => {
  37. setLocalSettings(newSettings);
  38. };
  39. const handleConfirm = () => {
  40. onSettingsChange(localSettings);
  41. onClose();
  42. };
  43. return createPortal(
  44. <div className="fixed inset-0 z-50 overflow-hidden">
  45. <div className="absolute inset-0 bg-black/40 backdrop-blur-sm transition-opacity" onClick={onClose} />
  46. <div className="absolute inset-y-0 right-0 max-w-md w-full flex">
  47. <div className="flex-1 flex flex-col bg-white shadow-xl animate-in slide-in-from-right duration-300">
  48. <div className="flex items-center justify-between px-4 py-3 border-b border-gray-200">
  49. <h2 className="text-lg font-medium text-gray-900">{t('systemConfiguration')}</h2>
  50. <button
  51. onClick={onClose}
  52. className="text-gray-400 hover:text-gray-500 focus:outline-none"
  53. >
  54. <X size={24} />
  55. </button>
  56. </div>
  57. <div className="flex-1 overflow-y-auto">
  58. <ConfigPanel
  59. settings={localSettings}
  60. models={models}
  61. onSettingsChange={handleLocalChange}
  62. onOpenSettings={onOpenSettings}
  63. mode={mode}
  64. isAdmin={isAdmin}
  65. />
  66. </div>
  67. <div className="p-4 border-t border-gray-200 bg-gray-50">
  68. <button
  69. onClick={handleConfirm}
  70. className="w-full py-2.5 bg-blue-600 text-white font-medium rounded-xl hover:bg-blue-700 transition-colors shadow-sm"
  71. >
  72. {t('confirm')}
  73. </button>
  74. </div>
  75. </div>
  76. </div>
  77. </div>,
  78. document.body
  79. );
  80. };