import "package:provider/provider.dart"; import "package:shadcn_flutter/shadcn_flutter.dart"; import "../providers/settings_provider.dart"; import "model_picker.dart"; class SettingsSheet extends StatelessWidget { const SettingsSheet(); @override Widget build(BuildContext context) { return Consumer( builder: (context, settingsProvider, _) { return Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( "Settings", style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600), ), const SizedBox(height: 16), // model picker const Text( "Model", style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500), ), const SizedBox(height: 8), const ModelPicker(), const SizedBox(height: 16), // API key setting const Text( "OpenRouter API Key", style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500), ), const SizedBox(height: 8), _ApiKeyInput(settingsProvider: settingsProvider), const SizedBox(height: 16), // theme setting const Text( "Theme", style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500), ), const SizedBox(height: 8), _SimpleDropdown( value: settingsProvider.settings.theme, items: const ["dark", "light"], onChanged: (newTheme) { settingsProvider.updateTheme(newTheme); }, ), const SizedBox(height: 16), // effort level setting const Text( "Effort Level", style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500), ), const SizedBox(height: 8), _SimpleDropdown( value: settingsProvider.settings.effortLevel ?? "medium", items: const ["low", "medium", "high", "max"], onChanged: (newLevel) { settingsProvider.updateEffortLevel(newLevel); }, ), const SizedBox(height: 24), // reset button Button.ghost( onPressed: () { settingsProvider.resetToDefaults(); Navigator.pop(context); }, child: const Text("Reset to Defaults"), ), ], ), ); }, ); } } class _ApiKeyInput extends StatefulWidget { final SettingsProvider settingsProvider; const _ApiKeyInput({required this.settingsProvider}); @override State<_ApiKeyInput> createState() => _ApiKeyInputState(); } class _ApiKeyInputState extends State<_ApiKeyInput> { late TextEditingController _controller; bool _obscureText = true; @override void initState() { super.initState(); _controller = TextEditingController( text: widget.settingsProvider.settings.openRouterApiKey ?? "", ); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Row( children: [ Expanded( child: TextField( controller: _controller, obscureText: _obscureText, onChanged: (value) { widget.settingsProvider.updateApiKey(value); }, placeholder: const Text("sk-or-v1-..."), ), ), const SizedBox(width: 8), GestureDetector( onTap: () { setState(() { _obscureText = !_obscureText; }); }, child: Text( _obscureText ? "Show" : "Hide", style: const TextStyle(fontSize: 12, color: Color(0xFF999999)), ), ), ], ); } } class _SimpleDropdown extends StatelessWidget { final T value; final List items; final Function(T) onChanged; const _SimpleDropdown({ required this.value, required this.items, required this.onChanged, }); @override Widget build(BuildContext context) { return GestureDetector( onTap: () => _showMenu(context), child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( border: Border.all(color: const Color(0xFFE2E8F0)), borderRadius: BorderRadius.circular(6), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(value.toString()), const Text("▼", style: TextStyle(fontSize: 12)), ], ), ), ); } void _showMenu(BuildContext context) { showDialog( context: context, builder: (ctx) => AlertDialog( content: Column( mainAxisSize: MainAxisSize.min, children: items .map((item) { final isSelected = item == value; return Container( color: isSelected ? const Color(0xFFF1F5F9) : Colors.transparent, child: GestureDetector( onTap: () { onChanged(item); Navigator.pop(ctx); }, child: Padding( padding: const EdgeInsets.all(12), child: Row( mainAxisSize: MainAxisSize.min, children: [ if (isSelected) const Padding( padding: EdgeInsets.only(right: 8), child: Text("✓", style: TextStyle(fontWeight: FontWeight.bold)), ), Text(item.toString()), ], ), ), ), ); }) .toList(), ), ), ); } }