instruction_app/lib/screens/add_edit_instruction_page.dart

150 lines
5.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../models/instruction.dart';
import '../providers/instruction_provider.dart';
import '../widgets/tag_selection_dialog.dart';
class AddEditInstructionPage extends StatefulWidget {
final Instruction? initialInstruction;
const AddEditInstructionPage({super.key, this.initialInstruction});
@override
State<AddEditInstructionPage> createState() => _AddEditInstructionPageState();
}
class _AddEditInstructionPageState extends State<AddEditInstructionPage> {
final _formKey = GlobalKey<FormState>();
late TextEditingController _titleController;
late TextEditingController _contentController;
late List<String> _selectedTags;
bool get _isEditing => widget.initialInstruction != null;
@override
void initState() {
super.initState();
_titleController = TextEditingController(text: widget.initialInstruction?.title ?? '');
_contentController = TextEditingController(text: widget.initialInstruction?.content ?? '');
_selectedTags = List<String>.from(widget.initialInstruction?.tags ?? []);
}
@override
void dispose() {
_titleController.dispose();
_contentController.dispose();
super.dispose();
}
Future<void> _showTagSelectionDialog() async {
final provider = context.read<InstructionProvider>();
final result = await showDialog<List<String>>(
context: context,
builder: (ctx) => TagSelectionDialog(
allTags: provider.allAvailableTags,
initialSelectedTags: _selectedTags.toSet(),
),
);
if (result != null) {
setState(() {
_selectedTags = result;
});
}
}
Future<void> _saveForm() async {
if (_formKey.currentState!.validate()) {
final provider = context.read<InstructionProvider>();
final title = _titleController.text;
final content = _contentController.text;
showDialog(
context: context,
barrierDismissible: false,
builder: (ctx) => const Center(child: CircularProgressIndicator()));
try {
if (_isEditing) {
final updatedInstruction = widget.initialInstruction!.copyWith(
title: title,
content: content,
tags: _selectedTags,
);
await provider.updateInstruction(updatedInstruction);
} else {
await provider.addInstruction(title, content, _selectedTags);
}
if (mounted) {
Navigator.of(context)..pop()..pop();
}
} catch (e) {
if(mounted) {
Navigator.of(context).pop();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Ошибка сохранения: $e')),
);
}
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_isEditing ? 'Редактировать' : 'Новый инструктаж'),
actions: [IconButton(icon: const Icon(Icons.save), onPressed: _saveForm)],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: ListView(
children: [
TextFormField(
controller: _titleController,
decoration: const InputDecoration(labelText: 'Название', border: OutlineInputBorder()),
validator: (v) => v == null || v.isEmpty ? 'Название не может быть пустым' : null,
),
const SizedBox(height: 16),
TextFormField(
controller: _contentController,
decoration: const InputDecoration(labelText: 'Содержание', border: OutlineInputBorder()),
maxLines: 8,
validator: (v) => v == null || v.isEmpty ? 'Содержание не может быть пустым' : null,
),
const SizedBox(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('Теги:', style: TextStyle(fontSize: 16)),
OutlinedButton.icon(
icon: const Icon(Icons.edit_note),
label: const Text('Изменить теги'),
onPressed: _showTagSelectionDialog,
),
],
),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade400),
borderRadius: BorderRadius.circular(4),
),
child: Wrap(
spacing: 8.0,
runSpacing: 4.0,
children: _selectedTags.isEmpty
? [const Text('Теги не выбраны')]
: _selectedTags.map((tag) => Chip(label: Text(tag))).toList(),
),
),
],
),
),
),
);
}
}