190 lines
6.0 KiB
Dart
190 lines
6.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
import '../models/models.dart';
|
|
import '../services/auth_controller.dart';
|
|
import '../ui/feedback.dart';
|
|
|
|
class EventFormScreen extends StatefulWidget {
|
|
const EventFormScreen({super.key});
|
|
|
|
@override
|
|
State<EventFormScreen> createState() => _EventFormScreenState();
|
|
}
|
|
|
|
class _EventFormScreenState extends State<EventFormScreen> {
|
|
final _title = TextEditingController();
|
|
final _description = TextEditingController();
|
|
final _expense = TextEditingController();
|
|
final _urls = TextEditingController();
|
|
String _planType = 'general';
|
|
int _month = DateTime.now().month;
|
|
int _year = DateTime.now().year;
|
|
String? _dealerId;
|
|
List<Dealer> _dealers = [];
|
|
bool _loading = true;
|
|
bool _saving = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_prepare();
|
|
}
|
|
|
|
Future<void> _prepare() async {
|
|
final user = context.read<AuthController>().user;
|
|
if (user?.role == 'dealer') {
|
|
setState(() {
|
|
_dealerId = user?.dealerId;
|
|
_loading = false;
|
|
});
|
|
return;
|
|
}
|
|
try {
|
|
final dealers = await context.read<AuthController>().api.dealers();
|
|
if (!mounted) return;
|
|
setState(() {
|
|
_dealers = dealers;
|
|
if (dealers.length == 1) _dealerId = dealers.first.id;
|
|
_loading = false;
|
|
});
|
|
} catch (error) {
|
|
if (!mounted) return;
|
|
setState(() => _loading = false);
|
|
showError(context, error);
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_title.dispose();
|
|
_description.dispose();
|
|
_expense.dispose();
|
|
_urls.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> _save() async {
|
|
final expense = double.tryParse(_expense.text.trim());
|
|
if (_dealerId == null || expense == null) {
|
|
showError(context, 'Dealer and a numeric expense are required');
|
|
return;
|
|
}
|
|
final urls = _urls.text
|
|
.split('\n')
|
|
.map((line) => line.trim())
|
|
.where((line) => line.isNotEmpty)
|
|
.toList();
|
|
setState(() => _saving = true);
|
|
try {
|
|
await context.read<AuthController>().api.createEvent({
|
|
'dealerId': _dealerId,
|
|
'planType': _planType,
|
|
'title': _title.text.trim(),
|
|
'description': _description.text.trim(),
|
|
'expense': expense,
|
|
'imageUrls': urls,
|
|
if (_planType == 'monthlySpecial') 'month': _month,
|
|
if (_planType == 'monthlySpecial') 'year': _year,
|
|
});
|
|
if (mounted) Navigator.pop(context, true);
|
|
} catch (error) {
|
|
if (mounted) showError(context, error);
|
|
} finally {
|
|
if (mounted) setState(() => _saving = false);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (_loading) {
|
|
return const Scaffold(body: Center(child: CircularProgressIndicator()));
|
|
}
|
|
final isDealer = context.watch<AuthController>().user?.role == 'dealer';
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('New plan')),
|
|
body: ListView(
|
|
padding: const EdgeInsets.all(16),
|
|
children: [
|
|
SegmentedButton<String>(
|
|
segments: const [
|
|
ButtonSegment(value: 'general', label: Text('General')),
|
|
ButtonSegment(value: 'monthlySpecial', label: Text('Monthly')),
|
|
],
|
|
selected: {_planType},
|
|
onSelectionChanged: (value) => setState(() => _planType = value.first),
|
|
),
|
|
const SizedBox(height: 12),
|
|
TextField(controller: _title, decoration: const InputDecoration(labelText: 'Title')),
|
|
const SizedBox(height: 12),
|
|
TextField(
|
|
controller: _description,
|
|
minLines: 3,
|
|
maxLines: 5,
|
|
decoration: const InputDecoration(labelText: 'Description'),
|
|
),
|
|
const SizedBox(height: 12),
|
|
TextField(
|
|
controller: _expense,
|
|
keyboardType: TextInputType.number,
|
|
decoration: const InputDecoration(labelText: 'Expense'),
|
|
),
|
|
const SizedBox(height: 12),
|
|
TextField(
|
|
controller: _urls,
|
|
minLines: 2,
|
|
maxLines: 4,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Image URLs',
|
|
hintText: 'One URL per line',
|
|
),
|
|
),
|
|
if (!isDealer) ...[
|
|
const SizedBox(height: 12),
|
|
DropdownButtonFormField<String>(
|
|
initialValue: _dealerId,
|
|
decoration: const InputDecoration(labelText: 'Dealer'),
|
|
items: [
|
|
for (final dealer in _dealers)
|
|
DropdownMenuItem(value: dealer.id, child: Text('${dealer.name} (${dealer.code})')),
|
|
],
|
|
onChanged: (value) => setState(() => _dealerId = value),
|
|
),
|
|
],
|
|
if (_planType == 'monthlySpecial') ...[
|
|
const SizedBox(height: 12),
|
|
DropdownButtonFormField<int>(
|
|
initialValue: _month,
|
|
decoration: const InputDecoration(labelText: 'Month'),
|
|
items: [
|
|
for (var month = 1; month <= 12; month++)
|
|
DropdownMenuItem(value: month, child: Text('$month')),
|
|
],
|
|
onChanged: (value) {
|
|
if (value != null) setState(() => _month = value);
|
|
},
|
|
),
|
|
const SizedBox(height: 12),
|
|
DropdownButtonFormField<int>(
|
|
initialValue: _year,
|
|
decoration: const InputDecoration(labelText: 'Year'),
|
|
items: [
|
|
for (var year = DateTime.now().year - 1; year <= DateTime.now().year + 2; year++)
|
|
DropdownMenuItem(value: year, child: Text('$year')),
|
|
],
|
|
onChanged: (value) {
|
|
if (value != null) setState(() => _year = value);
|
|
},
|
|
),
|
|
],
|
|
const SizedBox(height: 16),
|
|
FilledButton(
|
|
onPressed: _saving ? null : _save,
|
|
child: Text(_saving ? 'Saving' : 'Save plan'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|