Files
2026-05-25 05:10:43 -04:00

187 lines
6.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../providers/dashboard_providers.dart';
import '../../../widgets/error_view.dart';
class SettingsScreen extends ConsumerWidget {
const SettingsScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final async = ref.watch(brandSettingsProvider);
return Scaffold(
appBar: AppBar(title: const Text('Brand Settings')),
body: async.when(
loading: () => const Center(child: CircularProgressIndicator()),
error: (e, _) => ErrorView(
message: 'Failed to load settings',
onRetry: () => ref.invalidate(brandSettingsProvider),
),
data: (settings) => _SettingsForm(settings: settings),
),
);
}
}
class _SettingsForm extends ConsumerStatefulWidget {
final dynamic settings;
const _SettingsForm({required this.settings});
@override
ConsumerState<_SettingsForm> createState() => _SettingsFormState();
}
class _SettingsFormState extends ConsumerState<_SettingsForm> {
final _formKey = GlobalKey<FormState>();
bool _loading = false;
late final _displayName =
TextEditingController(text: widget.settings.displayName as String);
late final _tagline =
TextEditingController(text: widget.settings.tagline as String?);
late final _email =
TextEditingController(text: widget.settings.publicEmail as String?);
late final _phone =
TextEditingController(text: widget.settings.publicPhone as String?);
late final _city =
TextEditingController(text: widget.settings.publicCity as String?);
late final _country =
TextEditingController(text: widget.settings.publicCountry as String?);
late final _website =
TextEditingController(text: widget.settings.websiteUrl as String?);
late final _whatsapp =
TextEditingController(text: widget.settings.whatsappNumber as String?);
late bool _listed = widget.settings.isListedOnMarketplace as bool;
@override
void dispose() {
for (final c in [
_displayName, _tagline, _email, _phone, _city, _country, _website, _whatsapp
]) {
c.dispose();
}
super.dispose();
}
Future<void> _submit() async {
if (!_formKey.currentState!.validate()) return;
setState(() => _loading = true);
try {
await ref.read(settingsServiceProvider).updateBrand({
'displayName': _displayName.text.trim(),
if (_tagline.text.isNotEmpty) 'tagline': _tagline.text.trim(),
if (_email.text.isNotEmpty) 'publicEmail': _email.text.trim(),
if (_phone.text.isNotEmpty) 'publicPhone': _phone.text.trim(),
if (_city.text.isNotEmpty) 'publicCity': _city.text.trim(),
if (_country.text.isNotEmpty) 'publicCountry': _country.text.trim(),
if (_website.text.isNotEmpty) 'websiteUrl': _website.text.trim(),
if (_whatsapp.text.isNotEmpty) 'whatsappNumber': _whatsapp.text.trim(),
'isListedOnMarketplace': _listed,
});
ref.invalidate(brandSettingsProvider);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Settings saved')));
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Error: $e')));
}
} finally {
if (mounted) setState(() => _loading = false);
}
}
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: ListView(
padding: const EdgeInsets.all(16),
children: [
_section('Brand', [
_field('Display Name', _displayName, required: true),
_field('Tagline', _tagline),
]),
const SizedBox(height: 16),
_section('Contact', [
_field('Public Email', _email,
inputType: TextInputType.emailAddress),
_field('Public Phone', _phone, inputType: TextInputType.phone),
_field('WhatsApp Number', _whatsapp,
inputType: TextInputType.phone),
_field('Website URL', _website, inputType: TextInputType.url),
]),
const SizedBox(height: 16),
_section('Location', [
_field('City', _city),
_field('Country', _country),
]),
const SizedBox(height: 16),
Card(
child: SwitchListTile(
title: const Text('Listed on Marketplace'),
subtitle: const Text(
'Show your fleet on the public marketplace',
),
value: _listed,
onChanged: (v) => setState(() => _listed = v),
),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: _loading ? null : _submit,
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(48),
),
child: _loading
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2))
: const Text('Save Settings'),
),
],
),
);
}
Widget _section(String title, List<Widget> children) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title,
style: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w600,
color: Color(0xFF6B7280))),
const SizedBox(height: 10),
Card(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Column(children: children),
),
),
],
);
}
Widget _field(String label, TextEditingController ctrl,
{bool required = false, TextInputType? inputType}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: TextFormField(
controller: ctrl,
keyboardType: inputType,
decoration: InputDecoration(labelText: label),
validator: required
? (v) => v == null || v.isEmpty ? 'Required' : null
: null,
),
);
}
}