amoriai/lib/screens/settings/api_key_settings_screen.dart

283 lines
9.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../services/gemini_service.dart';
import '../../core/theme/app_theme.dart';
import '../../services/dialog_service.dart';
class ApiKeySettingsScreen extends ConsumerStatefulWidget {
const ApiKeySettingsScreen({super.key});
@override
ConsumerState<ApiKeySettingsScreen> createState() =>
_ApiKeySettingsScreenState();
}
class _ApiKeySettingsScreenState extends ConsumerState<ApiKeySettingsScreen> {
final _formKey = GlobalKey<FormState>();
final _apiKeyController = TextEditingController();
bool _isLoading = false;
bool _obscureText = true;
@override
void initState() {
super.initState();
_loadCurrentApiKeyInfo();
}
void _loadCurrentApiKeyInfo() {
// Display current API key info
setState(() {});
}
Future<void> _updateApiKey() async {
if (!_formKey.currentState!.validate()) return;
setState(() {
_isLoading = true;
});
try {
await GeminiService().updateApiKey(_apiKeyController.text.trim());
if (mounted) {
DialogService().showSuccess('API key berhasil diperbarui!');
Navigator.of(context).pop();
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: $e'), backgroundColor: Colors.red),
);
}
} finally {
if (mounted) {
setState(() {
_isLoading = false;
});
}
}
}
Future<void> _resetToDefault() async {
setState(() {
_isLoading = true;
});
try {
await GeminiService().resetToDefaultApiKey();
if (mounted) {
DialogService().showInfo('Kembali menggunakan API key default');
Navigator.of(context).pop();
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: $e'), backgroundColor: Colors.red),
);
}
} finally {
if (mounted) {
setState(() {
_isLoading = false;
});
}
}
}
@override
void dispose() {
_apiKeyController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pengaturan API Key'),
backgroundColor: AppTheme.primaryBrown,
foregroundColor: Colors.white,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Current API Key Info
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Status API Key Saat Ini',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
GeminiService().currentApiKeyInfo,
style: const TextStyle(fontSize: 14),
),
],
),
),
),
const SizedBox(height: 24),
// Information Card
Card(
color: Colors.blue.shade50,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.info, color: Colors.blue.shade700),
const SizedBox(width: 8),
const Text(
'Informasi',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 8),
const Text(
'Anda dapat menggunakan API key Gemini pribadi untuk:\n'
'• Menghindari pembatasan quota\n'
'• Kontrol penggunaan sendiri\n'
'• Performa yang lebih stabil\n\n'
'Dapatkan API key gratis di: https://makersuite.google.com/app/apikey',
style: TextStyle(fontSize: 14),
),
],
),
),
),
const SizedBox(height: 24),
// API Key Input
const Text(
'Masukkan API Key Gemini Anda',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Builder(
builder: (context) {
return TextFormField(
controller: _apiKeyController,
obscureText: _obscureText,
onTap: () {
Future.delayed(const Duration(milliseconds: 300), () {
if (context.mounted) {
Scrollable.ensureVisible(
context,
alignment: 0.5,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
});
},
decoration: InputDecoration(
hintText: 'AIzaSy...',
border: const OutlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(
_obscureText
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_obscureText = !_obscureText;
});
},
),
),
validator: (value) {
if (value == null || value.trim().isEmpty) {
return 'API key tidak boleh kosong';
}
if (!value.trim().startsWith('AIzaSy')) {
return 'Format API key tidak valid';
}
return null;
},
);
},
),
const SizedBox(height: 24),
// Action Buttons
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: _isLoading ? null : _updateApiKey,
style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.primaryBrown,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 12),
),
child: _isLoading
? const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(
Colors.white,
),
),
)
: const Text('Gunakan API Key Ini'),
),
),
const SizedBox(width: 12),
Expanded(
child: OutlinedButton(
onPressed: _isLoading ? null : _resetToDefault,
style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12),
),
child: const Text('Gunakan Default'),
),
),
],
),
const SizedBox(height: 16),
// Help Text
Text(
'Catatan: API key Anda disimpan secara lokal dan tidak dikirim ke server kami.',
style: TextStyle(
fontSize: 12,
color: Colors.grey.shade600,
fontStyle: FontStyle.italic,
),
textAlign: TextAlign.center,
),
],
),
),
),
);
}
}