120 lines
3.7 KiB
Dart
120 lines
3.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../../../domain/models/floor.dart';
|
|
import '../../../providers.dart';
|
|
|
|
class RoomEditSheet extends ConsumerStatefulWidget {
|
|
const RoomEditSheet({super.key, required this.room, required this.floorId});
|
|
|
|
final Room room;
|
|
final int floorId;
|
|
|
|
@override
|
|
ConsumerState<RoomEditSheet> createState() => _RoomEditSheetState();
|
|
}
|
|
|
|
class _RoomEditSheetState extends ConsumerState<RoomEditSheet> {
|
|
late final TextEditingController _nameCtrl;
|
|
late final TextEditingController _widthCtrl;
|
|
late final TextEditingController _heightCtrl;
|
|
bool _saving = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_nameCtrl = TextEditingController(text: widget.room.name);
|
|
_widthCtrl = TextEditingController(text: widget.room.width.toString());
|
|
_heightCtrl = TextEditingController(text: widget.room.height.toString());
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_nameCtrl.dispose();
|
|
_widthCtrl.dispose();
|
|
_heightCtrl.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> _save() async {
|
|
final name = _nameCtrl.text.trim();
|
|
final width = double.tryParse(_widthCtrl.text);
|
|
final height = double.tryParse(_heightCtrl.text);
|
|
if (name.isEmpty || width == null || height == null) return;
|
|
|
|
setState(() => _saving = true);
|
|
try {
|
|
await ref.read(floorRepositoryProvider).updateRoom(
|
|
widget.floorId,
|
|
widget.room.id,
|
|
name: name,
|
|
width: width,
|
|
height: height,
|
|
);
|
|
if (mounted) Navigator.of(context).pop();
|
|
} finally {
|
|
if (mounted) setState(() => _saving = false);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final insets = MediaQuery.viewInsetsOf(context);
|
|
return Padding(
|
|
padding: EdgeInsets.fromLTRB(24, 24, 24, 24 + insets.bottom),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
Text('Edit room', style: Theme.of(context).textTheme.titleMedium),
|
|
const SizedBox(height: 16),
|
|
TextField(
|
|
controller: _nameCtrl,
|
|
decoration: const InputDecoration(labelText: 'Name'),
|
|
autofocus: true,
|
|
textInputAction: TextInputAction.next,
|
|
),
|
|
const SizedBox(height: 12),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: TextField(
|
|
controller: _widthCtrl,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Width', suffixText: 'm'),
|
|
keyboardType:
|
|
const TextInputType.numberWithOptions(decimal: true),
|
|
textInputAction: TextInputAction.next,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: TextField(
|
|
controller: _heightCtrl,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Height', suffixText: 'm'),
|
|
keyboardType:
|
|
const TextInputType.numberWithOptions(decimal: true),
|
|
textInputAction: TextInputAction.done,
|
|
onSubmitted: (_) => _save(),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 24),
|
|
FilledButton(
|
|
onPressed: _saving ? null : _save,
|
|
child: _saving
|
|
? const SizedBox(
|
|
height: 20,
|
|
width: 20,
|
|
child: CircularProgressIndicator(strokeWidth: 2),
|
|
)
|
|
: const Text('Save'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|