kz_educa/lib/screens/settings_screen.dart

343 lines
10 KiB
Dart
Executable File

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:provider/provider.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:share_plus/share_plus.dart';
import 'package:kzeduca_app/services/i18n_service.dart';
import 'package:kzeduca_app/screens/privacy_policy_screen.dart'; // Importa a nova tela
// KzEduca Palette
const _kGradientStart = Color(0xFF512DA8); // Roxo vibrante
const _kGradientEnd = Color(0xFF000000); // Preto profundo
const _kAccent = Color(0xFF00BFA5); // Verde água
const _kAction = Color(0xFFFFD600); // Amarelo/dourado
const _kCardColor = Color(0xFF1E1E1E); // Cinza escuro para cards
class SettingsScreen extends StatefulWidget {
final Function(Locale)? onLocaleChanged;
final Function(String) onCurrencyChanged;
const SettingsScreen({
super.key,
this.onLocaleChanged,
required this.onCurrencyChanged,
});
@override
State<SettingsScreen> createState() => _SettingsScreenState();
}
class _SettingsScreenState extends State<SettingsScreen> {
String _selectedLanguage = 'pt';
String _selectedCurrency = 'KZ';
@override
void initState() {
super.initState();
_loadSettings();
}
Future<void> _loadSettings() async {
final prefs = await SharedPreferences.getInstance();
final i18n = Provider.of<I18nService>(context, listen: false);
setState(() {
_selectedLanguage =
prefs.getString('languageCode') ?? i18n.locale.languageCode;
_selectedCurrency = prefs.getString('currencySymbol') ?? 'KZ';
});
}
Future<void> _saveLanguage(String languageCode) async {
final i18n = Provider.of<I18nService>(context, listen: false);
await i18n.setLocale(Locale(languageCode));
setState(() {
_selectedLanguage = languageCode;
});
}
Future<void> _saveCurrency(String currencySymbol) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('currencySymbol', currencySymbol);
setState(() {
_selectedCurrency = currencySymbol;
});
widget.onCurrencyChanged(currencySymbol);
}
Future<void> _launchUrl(Uri url) async {
if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
throw 'Não foi possível abrir o link: $url';
}
}
void _rateApp() {
final i18n = Provider.of<I18nService>(context, listen: false);
final isAndroid = Theme.of(context).platform == TargetPlatform.android;
final url = isAndroid
? 'market://details?id=com.kzeduca.app'
: 'https://apps.apple.com/app/idYOUR_APPLE_ID';
try {
_launchUrl(Uri.parse(url));
} catch (e) {
_showErrorDialog(i18n.t('rate_app_error'), 'Erro: $e');
}
}
void _sendFeedback() {
final i18n = Provider.of<I18nService>(context, listen: false);
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: 'kzeducaapp@gmail.com', // E-mail de suporte da sua aplicação
query: encodeQueryParameters(<String, String>{
'subject': i18n.t('feedback_email_subject'),
'body': i18n.t('feedback_email_body'),
}),
);
try {
_launchUrl(emailLaunchUri);
} catch (e) {
_showErrorDialog(i18n.t('send_feedback_error'), 'Erro: $e');
}
}
void _shareApp() {
final i18n = Provider.of<I18nService>(context, listen: false);
final String message = i18n.t('share_message');
Share.share(message);
}
void _showPrivacyPolicy() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const PrivacyPolicyScreen()),
);
}
void _showErrorDialog(String title, String message) {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text(title),
content: Text(message),
actions: [
TextButton(
onPressed: () => Navigator.of(ctx).pop(),
child: const Text('OK'),
),
],
),
);
}
String? encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((e) => '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
@override
Widget build(BuildContext context) {
final i18n = Provider.of<I18nService>(context);
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back_rounded, color: Colors.white, size: 28),
onPressed: () {
Navigator.of(context).pop();
},
),
),
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [_kGradientStart, _kGradientEnd],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 24),
// Título da Tela
Text(
i18n.t('settings_title'),
style: GoogleFonts.montserrat(
color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 32),
// Seção de Configurações Gerais
_SectionHeader(title: i18n.t('general_settings')),
_SettingCard(
icon: Icons.language_rounded,
title: i18n.t('language'),
trailing: _buildLanguageDropdown(i18n),
),
_SettingCard(
icon: Icons.currency_exchange_rounded,
title: i18n.t('currency'),
trailing: _buildCurrencyDropdown(),
),
const SizedBox(height: 32),
// Seção de Políticas e Feedback
_SectionHeader(title: i18n.t('policies_and_feedback')),
_SettingCard(
icon: Icons.star_rounded,
title: i18n.t('rate_app'),
onTap: _rateApp,
),
_SettingCard(
icon: Icons.feedback_rounded,
title: i18n.t('send_feedback'),
onTap: _sendFeedback,
),
_SettingCard(
icon: Icons.share_rounded,
title: i18n.t('share_with_friends'),
onTap: _shareApp,
),
_SettingCard(
icon: Icons.policy_rounded,
title: i18n.t('privacy_policy'),
onTap: _showPrivacyPolicy,
),
const SizedBox(height: 40),
],
),
),
),
),
);
}
Widget _buildLanguageDropdown(I18nService i18n) {
return DropdownButton<String>(
value: _selectedLanguage,
icon: const Icon(Icons.arrow_drop_down_rounded, color: Colors.white54),
dropdownColor: _kCardColor,
underline: const SizedBox(),
style: GoogleFonts.montserrat(color: _kAccent, fontWeight: FontWeight.w500),
onChanged: (String? newValue) {
if (newValue != null) {
_saveLanguage(newValue);
}
},
items: <DropdownMenuItem<String>>[
DropdownMenuItem<String>(
value: 'pt',
child: Text(i18n.t('portuguese_brazil')),
),
DropdownMenuItem<String>(
value: 'en',
child: Text(i18n.t('english')),
),
],
);
}
Widget _buildCurrencyDropdown() {
return DropdownButton<String>(
value: _selectedCurrency,
icon: const Icon(Icons.arrow_drop_down_rounded, color: Colors.white54),
dropdownColor: _kCardColor,
underline: const SizedBox(),
style: GoogleFonts.montserrat(color: _kAccent, fontWeight: FontWeight.w500),
onChanged: (String? newValue) {
if (newValue != null) {
_saveCurrency(newValue);
}
},
items: const <DropdownMenuItem<String>>[
DropdownMenuItem<String>(value: 'USD', child: Text('USD')),
DropdownMenuItem<String>(value: 'EUR', child: Text('EUR')),
DropdownMenuItem<String>(value: 'KZ', child: Text('KZ')),
],
);
}
}
class _SectionHeader extends StatelessWidget {
final String title;
const _SectionHeader({required this.title});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
title,
style: GoogleFonts.montserrat(
color: Colors.white70,
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
);
}
}
class _SettingCard extends StatelessWidget {
final IconData icon;
final String title;
final Widget? trailing;
final VoidCallback? onTap;
const _SettingCard({
required this.icon,
required this.title,
this.trailing,
this.onTap,
});
@override
Widget build(BuildContext context) {
return Card(
color: _kCardColor,
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
margin: const EdgeInsets.symmetric(vertical: 8.0),
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(16),
splashColor: _kAccent.withOpacity(0.2),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
Icon(icon, color: _kAccent, size: 28),
const SizedBox(width: 16),
Expanded(
child: Text(
title,
style: GoogleFonts.montserrat(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
),
if (trailing != null) trailing!,
],
),
),
),
);
}
}