343 lines
10 KiB
Dart
Executable File
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!,
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |