225 lines
7.5 KiB
Dart
225 lines
7.5 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:intl/intl.dart';
|
||
import 'dart:io';
|
||
|
||
class ActivitySubmitPage extends StatefulWidget {
|
||
const ActivitySubmitPage({super.key});
|
||
|
||
@override
|
||
State<ActivitySubmitPage> createState() => _ActivitySubmitPageState();
|
||
}
|
||
|
||
class _ActivitySubmitPageState extends State<ActivitySubmitPage> {
|
||
final _formKey = GlobalKey<FormState>();
|
||
final _titleController = TextEditingController();
|
||
final _locationController = TextEditingController();
|
||
final _descriptionController = TextEditingController();
|
||
DateTime? _startDate;
|
||
DateTime? _endDate;
|
||
String _needRegister = '否';
|
||
String _repeatOption = 'none';
|
||
int _repeatCount = 1;
|
||
File? _poster;
|
||
|
||
Future<void> _selectDateTime(bool isStart) async {
|
||
final now = DateTime.now();
|
||
final date = await showDatePicker(
|
||
context: context,
|
||
initialDate: now,
|
||
firstDate: now,
|
||
lastDate: DateTime(now.year + 2),
|
||
);
|
||
if (date == null) return;
|
||
|
||
final time = await showTimePicker(
|
||
context: context,
|
||
initialTime: TimeOfDay.fromDateTime(now),
|
||
);
|
||
if (time == null) return;
|
||
|
||
final selected = DateTime(
|
||
date.year,
|
||
date.month,
|
||
date.day,
|
||
time.hour,
|
||
time.minute,
|
||
);
|
||
setState(() {
|
||
if (isStart) {
|
||
_startDate = selected;
|
||
} else {
|
||
_endDate = selected;
|
||
}
|
||
});
|
||
}
|
||
|
||
void _submitForm() {
|
||
if (!_formKey.currentState!.validate()) return;
|
||
|
||
if (_startDate == null || _endDate == null) {
|
||
_showAlert('請選擇開始與結束時間');
|
||
return;
|
||
}
|
||
|
||
if (_endDate!.isBefore(_startDate!)) {
|
||
_showAlert('結束時間必須晚於開始時間!');
|
||
return;
|
||
}
|
||
|
||
final formatter = DateFormat('yyyy-MM-dd HH:mm');
|
||
final message =
|
||
StringBuffer()
|
||
..writeln('活動申請已送出')
|
||
..writeln('名稱:${_titleController.text}')
|
||
..writeln('開始時間:${formatter.format(_startDate!)}')
|
||
..writeln('結束時間:${formatter.format(_endDate!)}')
|
||
..writeln('地點:${_locationController.text}')
|
||
..writeln('描述:${_descriptionController.text}')
|
||
..writeln('需報名統計:$_needRegister');
|
||
|
||
if (_repeatOption != 'none') {
|
||
final map = {'weekly': '每週', 'biweekly': '每兩週', 'monthly': '每月'};
|
||
message.writeln('重複設定:${map[_repeatOption]},共重複 $_repeatCount 次');
|
||
}
|
||
|
||
if (_poster != null) {
|
||
message.writeln('檔案名稱:${_poster!.path.split('/').last}');
|
||
}
|
||
|
||
_showAlert(message.toString());
|
||
}
|
||
|
||
void _showAlert(String text) {
|
||
// print('Submit button pressed'); // ← Debug 用
|
||
showDialog(
|
||
context: context,
|
||
builder:
|
||
(_) => AlertDialog(
|
||
title: const Text('訊息'),
|
||
content: Text(text),
|
||
actions: [
|
||
TextButton(
|
||
onPressed: () => Navigator.pop(context),
|
||
child: const Text('確定'),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Scaffold(
|
||
appBar: AppBar(
|
||
title: const Text('提交活動申請'),
|
||
backgroundColor: const Color(0xFF9eaf9f),
|
||
foregroundColor: Colors.white,
|
||
),
|
||
body: SingleChildScrollView(
|
||
padding: const EdgeInsets.all(16),
|
||
child: Form(
|
||
key: _formKey,
|
||
child: Column(
|
||
children: [
|
||
TextFormField(
|
||
controller: _titleController,
|
||
decoration: const InputDecoration(labelText: '活動名稱'),
|
||
validator: (value) => value!.isEmpty ? '必填' : null,
|
||
),
|
||
const SizedBox(height: 12),
|
||
_buildDateField('開始時間', _startDate, () => _selectDateTime(true)),
|
||
const SizedBox(height: 12),
|
||
_buildDateField('結束時間', _endDate, () => _selectDateTime(false)),
|
||
const SizedBox(height: 12),
|
||
TextFormField(
|
||
controller: _locationController,
|
||
decoration: const InputDecoration(labelText: '地點'),
|
||
validator: (value) => value!.isEmpty ? '必填' : null,
|
||
),
|
||
const SizedBox(height: 12),
|
||
TextFormField(
|
||
controller: _descriptionController,
|
||
decoration: const InputDecoration(labelText: '活動描述'),
|
||
maxLines: 4,
|
||
validator: (value) => value!.isEmpty ? '必填' : null,
|
||
),
|
||
const SizedBox(height: 12),
|
||
DropdownButtonFormField<String>(
|
||
value: _needRegister,
|
||
decoration: const InputDecoration(labelText: '是否需統計報名人數?'),
|
||
items:
|
||
['否', '是']
|
||
.map((v) => DropdownMenuItem(value: v, child: Text(v)))
|
||
.toList(),
|
||
onChanged: (v) => setState(() => _needRegister = v!),
|
||
),
|
||
const SizedBox(height: 12),
|
||
DropdownButtonFormField<String>(
|
||
value: _repeatOption,
|
||
decoration: const InputDecoration(labelText: '是否重複舉辦'),
|
||
items: const [
|
||
DropdownMenuItem(value: 'none', child: Text('否')),
|
||
DropdownMenuItem(value: 'weekly', child: Text('每週一次')),
|
||
DropdownMenuItem(value: 'biweekly', child: Text('每兩週一次')),
|
||
DropdownMenuItem(value: 'monthly', child: Text('每月一次')),
|
||
],
|
||
onChanged: (v) => setState(() => _repeatOption = v!),
|
||
),
|
||
if (_repeatOption != 'none') ...[
|
||
const SizedBox(height: 12),
|
||
TextFormField(
|
||
decoration: const InputDecoration(labelText: '重複次數(不含首次)'),
|
||
keyboardType: TextInputType.number,
|
||
initialValue: '1',
|
||
onChanged:
|
||
(v) =>
|
||
_repeatCount =
|
||
int.tryParse(v) != null ? int.parse(v) : 1,
|
||
),
|
||
],
|
||
const SizedBox(height: 24),
|
||
ElevatedButton.icon(
|
||
onPressed: () {
|
||
// 檔案選取功能:日後可整合 `file_picker` 套件
|
||
_showAlert('尚未實作檔案選擇功能,請整合 file_picker 或 image_picker');
|
||
},
|
||
icon: const Icon(Icons.upload_file),
|
||
label: const Text('上傳活動海報'),
|
||
),
|
||
const SizedBox(height: 24),
|
||
ElevatedButton(
|
||
onPressed: _submitForm,
|
||
style: ElevatedButton.styleFrom(
|
||
backgroundColor: Colors.green,
|
||
padding: const EdgeInsets.symmetric(
|
||
vertical: 12,
|
||
horizontal: 32,
|
||
),
|
||
),
|
||
child: const Text(
|
||
'送出申請',
|
||
style: TextStyle(color: Colors.white),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildDateField(String label, DateTime? value, VoidCallback onTap) {
|
||
final formatter = DateFormat('yyyy-MM-dd HH:mm');
|
||
return Row(
|
||
children: [
|
||
Expanded(
|
||
child: Text(
|
||
'$label:${value != null ? formatter.format(value) : '未選擇'}',
|
||
),
|
||
),
|
||
TextButton(onPressed: onTap, child: const Text('選擇')),
|
||
],
|
||
);
|
||
}
|
||
}
|