93 lines
2.9 KiB
Dart
93 lines
2.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:lanebow/services/public_event_service.dart';
|
|
|
|
class JoinDialog extends StatefulWidget {
|
|
final String publicHash;
|
|
final PublicEventService service;
|
|
const JoinDialog({super.key, required this.publicHash, required this.service});
|
|
|
|
@override
|
|
State<JoinDialog> createState() => _JoinDialogState();
|
|
}
|
|
|
|
class _JoinDialogState extends State<JoinDialog> {
|
|
final _formKey = GlobalKey<FormState>();
|
|
final _nameCtrl = TextEditingController();
|
|
final _phoneCtrl = TextEditingController();
|
|
final _avgCtrl = TextEditingController();
|
|
bool _saving = false;
|
|
|
|
@override
|
|
void dispose() {
|
|
_nameCtrl.dispose();
|
|
_phoneCtrl.dispose();
|
|
_avgCtrl.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> _save() async {
|
|
if (!_formKey.currentState!.validate()) return;
|
|
setState(() => _saving = true);
|
|
try {
|
|
final avg = int.tryParse(_avgCtrl.text);
|
|
await widget.service.addGuest(
|
|
widget.publicHash,
|
|
name: _nameCtrl.text.trim(),
|
|
phone: _phoneCtrl.text.trim().isEmpty ? null : _phoneCtrl.text.trim(),
|
|
gender: null,
|
|
average: avg,
|
|
);
|
|
if (!mounted) return;
|
|
Navigator.of(context).pop(true);
|
|
} catch (e) {
|
|
if (!mounted) return;
|
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('신청 실패: ' + e.toString())));
|
|
} finally {
|
|
if (mounted) setState(() => _saving = false);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AlertDialog(
|
|
title: const Text('참가 신청(게스트)'),
|
|
content: Form(
|
|
key: _formKey,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
TextFormField(
|
|
key: const Key('join_name_input'),
|
|
controller: _nameCtrl,
|
|
decoration: const InputDecoration(labelText: '이름*'),
|
|
validator: (v) => (v == null || v.trim().isEmpty) ? '이름을 입력하세요' : null,
|
|
),
|
|
TextFormField(
|
|
key: const Key('join_phone_input'),
|
|
controller: _phoneCtrl,
|
|
decoration: const InputDecoration(labelText: '연락처(선택)'),
|
|
),
|
|
TextFormField(
|
|
key: const Key('join_avg_input'),
|
|
controller: _avgCtrl,
|
|
keyboardType: TextInputType.number,
|
|
decoration: const InputDecoration(labelText: '에버리지(선택)')
|
|
),
|
|
],
|
|
),
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: _saving ? null : () => Navigator.of(context).pop(false),
|
|
child: const Text('취소'),
|
|
),
|
|
ElevatedButton(
|
|
key: const Key('join_save_button'),
|
|
onPressed: _saving ? null : _save,
|
|
child: _saving ? const SizedBox(width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2)) : const Text('신청'),
|
|
)
|
|
],
|
|
);
|
|
}
|
|
}
|