Options.tsx 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import { useState, useEffect } from 'react';
  2. import '@src/Options.css';
  3. import { Button } from '@extension/ui';
  4. import { withErrorBoundary, withSuspense } from '@extension/shared';
  5. import { GeneralSettings } from './components/GeneralSettings';
  6. import { ModelSettings } from './components/ModelSettings';
  7. type TabTypes = 'general' | 'models';
  8. const TABS: { id: TabTypes; icon: string; label: string }[] = [
  9. { id: 'general', icon: '⚙️', label: 'General' },
  10. { id: 'models', icon: '📊', label: 'Models' },
  11. ];
  12. const Options = () => {
  13. const [activeTab, setActiveTab] = useState<TabTypes>('models');
  14. const [isDarkMode, setIsDarkMode] = useState(false);
  15. // Check for dark mode preference
  16. useEffect(() => {
  17. const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
  18. setIsDarkMode(darkModeMediaQuery.matches);
  19. const handleChange = (e: MediaQueryListEvent) => {
  20. setIsDarkMode(e.matches);
  21. };
  22. darkModeMediaQuery.addEventListener('change', handleChange);
  23. return () => darkModeMediaQuery.removeEventListener('change', handleChange);
  24. }, []);
  25. const renderTabContent = () => {
  26. switch (activeTab) {
  27. case 'general':
  28. return <GeneralSettings isDarkMode={isDarkMode} />;
  29. case 'models':
  30. return <ModelSettings isDarkMode={isDarkMode} />;
  31. default:
  32. return null;
  33. }
  34. };
  35. return (
  36. <div
  37. className={`flex min-h-screen min-w-[768px] ${isDarkMode ? 'bg-slate-900' : "bg-[url('/bg.jpg')] bg-cover bg-center"} ${isDarkMode ? 'text-gray-200' : 'text-gray-900'}`}>
  38. {/* Vertical Navigation Bar */}
  39. <nav
  40. className={`w-48 border-r ${isDarkMode ? 'border-slate-700 bg-slate-800/80' : 'border-white/20 bg-[#0EA5E9]/10'} backdrop-blur-sm`}>
  41. <div className="p-4">
  42. <h1 className={`mb-6 text-xl font-bold ${isDarkMode ? 'text-gray-200' : 'text-gray-800'}`}>Settings</h1>
  43. <ul className="space-y-2">
  44. {TABS.map(item => (
  45. <li key={item.id}>
  46. <Button
  47. onClick={() => setActiveTab(item.id)}
  48. className={`flex w-full items-center space-x-2 rounded-lg px-4 py-2 text-left text-base
  49. ${
  50. activeTab !== item.id
  51. ? `${isDarkMode ? 'bg-slate-700/70 text-gray-300 hover:text-white' : 'bg-[#0EA5E9]/15 font-medium text-gray-700 hover:text-white'} backdrop-blur-sm`
  52. : `${isDarkMode ? 'bg-sky-800/50' : ''} text-white backdrop-blur-sm`
  53. }`}>
  54. <span>{item.icon}</span>
  55. <span>{item.label}</span>
  56. </Button>
  57. </li>
  58. ))}
  59. </ul>
  60. </div>
  61. </nav>
  62. {/* Main Content Area */}
  63. <main className={`flex-1 ${isDarkMode ? 'bg-slate-800/50' : 'bg-white/10'} p-8 backdrop-blur-sm`}>
  64. <div className="mx-auto min-w-[512px] max-w-screen-lg">{renderTabContent()}</div>
  65. </main>
  66. </div>
  67. );
  68. };
  69. export default withErrorBoundary(withSuspense(Options, <div>Loading...</div>), <div>Error Occurred</div>);