공개페이지 완료

This commit is contained in:
2025-11-10 14:14:08 +09:00
parent 2ce0b81483
commit ac43ddb55e
67 changed files with 3220 additions and 224696 deletions
@@ -315,7 +315,7 @@ class _ClubSettingsScreenState extends State<ClubSettingsScreen> {
labelText: '평균 산정 기준',
border: OutlineInputBorder(),
),
value: _selectedAverageCalculationPeriod,
initialValue: _selectedAverageCalculationPeriod,
isExpanded: true,
items: averageCalculationPeriodOptions.entries
.map(
@@ -383,7 +383,7 @@ class _EventDetailsScreenState extends State<EventDetailsScreen>
Expanded(
child: DropdownButtonFormField<String>(
key: const Key('event_details_guest_gender_dropdown'),
value: gender,
initialValue: gender,
decoration: const InputDecoration(
labelText: '성별',
border: OutlineInputBorder(),
@@ -469,7 +469,7 @@ class _EventDetailsScreenState extends State<EventDetailsScreen>
key: const Key(
'event_details_participant_status_dropdown',
),
value:
initialValue:
(participantStatusOptions.keys.contains(
participantStatus,
))
@@ -500,7 +500,7 @@ class _EventDetailsScreenState extends State<EventDetailsScreen>
Expanded(
child: DropdownButtonFormField<String>(
key: const Key('event_details_payment_status_dropdown'),
value:
initialValue:
(paymentStatusOptions.keys.contains(paymentStatus))
? paymentStatus
: null,
@@ -1421,7 +1421,7 @@ ${widget.event.accessPassword != null && widget.event.accessPassword!.isNotEmpty
else
DropdownButtonFormField<String>(
key: const Key('quick_add_member_dropdown'),
value: selectedMemberId,
initialValue: selectedMemberId,
isExpanded: true,
decoration: const InputDecoration(
labelText: '회원 선택',
@@ -1447,7 +1447,7 @@ ${widget.event.accessPassword != null && widget.event.accessPassword!.isNotEmpty
Expanded(
child: DropdownButtonFormField<String>(
key: const Key('quick_add_status_dropdown'),
value: status,
initialValue: status,
isExpanded: true,
decoration: const InputDecoration(
labelText: '상태',
@@ -1468,7 +1468,7 @@ ${widget.event.accessPassword != null && widget.event.accessPassword!.isNotEmpty
Expanded(
child: DropdownButtonFormField<String>(
key: const Key('quick_add_payment_dropdown'),
value: paymentStatus,
initialValue: paymentStatus,
isExpanded: true,
decoration: const InputDecoration(
labelText: '결제',
@@ -1578,7 +1578,7 @@ ${widget.event.accessPassword != null && widget.event.accessPassword!.isNotEmpty
mainAxisSize: MainAxisSize.min,
children: [
DropdownButtonFormField<String>(
value: status,
initialValue: status,
isExpanded: true,
decoration: const InputDecoration(labelText: '상태'),
items: participantStatusOptions.entries
@@ -1593,7 +1593,7 @@ ${widget.event.accessPassword != null && widget.event.accessPassword!.isNotEmpty
),
const SizedBox(height: 8),
DropdownButtonFormField<String>(
value: paymentStatus,
initialValue: paymentStatus,
isExpanded: true,
decoration: const InputDecoration(labelText: '결제'),
items: paymentStatusOptions.entries
@@ -480,7 +480,7 @@ class _EventFormScreenState extends State<EventFormScreen> {
// 이벤트 유형
DropdownButtonFormField<String>(
key: const Key('event_form_type_dropdown'),
value: _type,
initialValue: _type,
decoration: InputDecoration(
labelText: '이벤트 유형 *',
labelStyle: TextStyle(
@@ -560,7 +560,7 @@ class _EventFormScreenState extends State<EventFormScreen> {
// 상태
DropdownButtonFormField<String>(
key: const Key('event_form_status_dropdown'),
value: _status,
initialValue: _status,
decoration: InputDecoration(
labelText: '상태 *',
labelStyle: TextStyle(
@@ -1172,10 +1172,10 @@ class _EventFormScreenState extends State<EventFormScreen> {
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: 0.1),
color: Colors.blue.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: Colors.blue.withValues(alpha: 0.3),
color: Colors.blue.withOpacity(0.3),
),
),
child: Column(
@@ -549,8 +549,9 @@ class _EventImportWizardState extends State<EventImportWizard> {
final totalWarnings = _participants
.map(_rowWarnings)
.fold<int>(0, (a, b) => a + b.length);
if (totalWarnings == 0)
if (totalWarnings == 0) {
return const SizedBox.shrink();
}
return Padding(
padding: const EdgeInsets.only(
top: 4.0,
@@ -565,7 +566,7 @@ class _EventImportWizardState extends State<EventImportWizard> {
),
const SizedBox(width: 6),
Text(
'경고 ${totalWarnings}: 이름 누락 또는 점수 개수 불일치',
'경고 $totalWarnings건: 이름 누락 또는 점수 개수 불일치',
),
],
),
@@ -877,7 +878,7 @@ class _EventImportWizardState extends State<EventImportWizard> {
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('이벤트: ${_titleCtrl.text} (${_gameCount}게임)'),
Text('이벤트: ${_titleCtrl.text} ($_gameCount게임)'),
if (_startDate != null)
Text('시작일: ${dateFmt.format(_startDate!)}'),
if (_endDate != null) Text('종료일: ${dateFmt.format(_endDate!)}'),
+4 -3
View File
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:intl/intl.dart';
@@ -45,11 +44,13 @@ class _EventsScreenState extends State<EventsScreen> {
s == 'draft' ||
s == 'scheduled' ||
s == 'waiting' ||
s == '대기')
s == '대기') {
return '대기';
}
if (s == 'canceled' || s == 'cancelled' || s == '취소') return '취소';
if (s == 'completed' || s == 'done' || s == 'finished' || s == '완료')
if (s == 'completed' || s == 'done' || s == 'finished' || s == '완료') {
return '완료';
}
return status; //
}
+6 -6
View File
@@ -411,7 +411,7 @@ class _MembersScreenState extends State<MembersScreen> {
const SizedBox(height: 16),
DropdownButtonFormField<String>(
key: const Key('members_add_gender_dropdown'),
value: selectedGender,
initialValue: selectedGender,
decoration: const InputDecoration(
labelText: '성별',
border: OutlineInputBorder(),
@@ -432,7 +432,7 @@ class _MembersScreenState extends State<MembersScreen> {
const SizedBox(height: 16),
DropdownButtonFormField<String>(
key: const Key('members_add_member_type_dropdown'),
value: selectedMemberType,
initialValue: selectedMemberType,
decoration: const InputDecoration(
labelText: '회원 유형',
border: OutlineInputBorder(),
@@ -454,7 +454,7 @@ class _MembersScreenState extends State<MembersScreen> {
const SizedBox(height: 16),
DropdownButtonFormField<String>(
key: const Key('members_add_status_dropdown'),
value: selectedStatus,
initialValue: selectedStatus,
decoration: const InputDecoration(
labelText: '상태',
border: OutlineInputBorder(),
@@ -727,7 +727,7 @@ class _MembersScreenState extends State<MembersScreen> {
buildFormField('성별', isEditing ?
DropdownButtonFormField<String>(
key: const Key('members_edit_gender_dropdown'),
value: selectedGender,
initialValue: selectedGender,
decoration: const InputDecoration(
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
@@ -756,7 +756,7 @@ class _MembersScreenState extends State<MembersScreen> {
if (isEditing)
buildFormField('회원 유형', DropdownButtonFormField<String>(
key: const Key('members_edit_member_type_dropdown'),
value: selectedMemberType,
initialValue: selectedMemberType,
decoration: const InputDecoration(
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
@@ -830,7 +830,7 @@ class _MembersScreenState extends State<MembersScreen> {
if (isEditing)
buildFormField('상태', DropdownButtonFormField<String>(
key: const Key('members_edit_status_dropdown'),
value: selectedStatus,
initialValue: selectedStatus,
decoration: const InputDecoration(
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
@@ -214,7 +214,7 @@ class _ScoreFormScreenState extends State<ScoreFormScreen> {
//
DropdownButtonFormField<String>(
key: const Key('score_form_participant_dropdown'),
value: _selectedParticipantId,
initialValue: _selectedParticipantId,
decoration: const InputDecoration(labelText: '참가자 *'),
isExpanded: true,
items: widget.participants.map((participant) {
@@ -164,9 +164,9 @@ class BasicInfoTab extends StatelessWidget {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: color.withValues(alpha: 0.15),
color: color.withOpacity(0.15),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: color.withValues(alpha: 0.3)),
border: Border.all(color: color.withOpacity(0.3)),
),
child: Row(
mainAxisSize: MainAxisSize.min,
@@ -34,10 +34,12 @@ class _ParticipantsTabState extends State<ParticipantsTab> {
String _buildFilterSummary() {
final parts = <String>[];
if (_filterStatus != null && _filterStatus!.isNotEmpty)
if (_filterStatus != null && _filterStatus!.isNotEmpty) {
parts.add('상태: ${_filterStatus!}');
if (_filterMemberType != null && _filterMemberType!.isNotEmpty)
}
if (_filterMemberType != null && _filterMemberType!.isNotEmpty) {
parts.add('유형: ${_filterMemberType!}');
}
if (_filterPaid != null) parts.add('결제: ${_filterPaid! ? '완료' : '미결제'}');
final q = _searchController.text.trim();
if (q.isNotEmpty) parts.add("검색: '$q'");
@@ -237,7 +239,7 @@ class _ParticipantsTabState extends State<ParticipantsTab> {
final icon = isFemale ? Icons.female : Icons.male;
final color = isFemale ? Colors.pink : Colors.blue;
return CircleAvatar(
backgroundColor: color.withValues(alpha: 0.1),
backgroundColor: color.withOpacity(0.1),
child: Icon(icon, size: 18, color: color),
);
},
@@ -266,10 +268,10 @@ class _ParticipantsTabState extends State<ParticipantsTab> {
vertical: 2,
),
decoration: BoxDecoration(
color: Colors.deepPurple.withValues(alpha: 0.10),
color: Colors.deepPurple.withOpacity(0.10),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.deepPurple.withValues(alpha: 0.25),
color: Colors.deepPurple.withOpacity(0.25),
),
),
child: Text(
@@ -290,10 +292,10 @@ class _ParticipantsTabState extends State<ParticipantsTab> {
vertical: 2,
),
decoration: BoxDecoration(
color: Colors.indigo.withValues(alpha: 0.10),
color: Colors.indigo.withOpacity(0.10),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.indigo.withValues(alpha: 0.25),
color: Colors.indigo.withOpacity(0.25),
),
),
child: Text(
+34 -34
View File
@@ -93,8 +93,9 @@ class TeamsTab extends StatelessWidget {
value: 1,
groupValue: teamGenerationMethod,
onChanged: (value) {
if (value != null)
if (value != null) {
onChangeTeamGenerationMethod(value);
}
},
),
const Text('팀 인원수로 나누기'),
@@ -131,8 +132,9 @@ class TeamsTab extends StatelessWidget {
value: 2,
groupValue: teamGenerationMethod,
onChanged: (value) {
if (value != null)
if (value != null) {
onChangeTeamGenerationMethod(value);
}
},
),
const Text('팀 개수로 나누기'),
@@ -463,11 +465,12 @@ class TeamsTab extends StatelessWidget {
final memberCount = team.memberIds.length;
return DragTarget<Map<String, dynamic>>(
onWillAccept: (data) =>
data != null && data['participant'] is Participant,
onAccept: (data) {
final Participant p = data['participant'] as Participant;
final Team from = data['fromTeam'] as Team;
onWillAcceptWithDetails: (details) =>
details.data['participant'] is Participant,
onAcceptWithDetails: (details) {
final Participant p =
details.data['participant'] as Participant;
final Team from = details.data['fromTeam'] as Team;
if (onMoveParticipant != null) {
onMoveParticipant!(p, from, team, team.memberIds.length);
}
@@ -520,12 +523,12 @@ class TeamsTab extends StatelessWidget {
children: [
// : ( 0)
DragTarget<Map<String, dynamic>>(
onWillAccept: (data) =>
data != null && data['participant'] is Participant,
onAccept: (data) {
onWillAcceptWithDetails: (details) =>
details.data['participant'] is Participant,
onAcceptWithDetails: (details) {
final Participant dp =
data['participant'] as Participant;
final Team from = data['fromTeam'] as Team;
details.data['participant'] as Participant;
final Team from = details.data['fromTeam'] as Team;
if (onMoveParticipant != null) {
onMoveParticipant!(dp, from, team, 0);
}
@@ -558,13 +561,12 @@ class TeamsTab extends StatelessWidget {
// ( )
return DragTarget<Map<String, dynamic>>(
onWillAccept: (data) =>
data != null &&
data['participant'] is Participant,
onAccept: (data) {
onWillAcceptWithDetails: (details) =>
details.data['participant'] is Participant,
onAcceptWithDetails: (details) {
final Participant dp =
data['participant'] as Participant;
final Team from = data['fromTeam'] as Team;
details.data['participant'] as Participant;
final Team from = details.data['fromTeam'] as Team;
if (onMoveParticipant != null) {
onMoveParticipant!(dp, from, team, memberIndex);
}
@@ -624,9 +626,7 @@ class TeamsTab extends StatelessWidget {
? Colors.pink
: Colors.blue;
return CircleAvatar(
backgroundColor: color.withValues(
alpha: 0.1,
),
backgroundColor: color.withOpacity(0.1),
child: Icon(
icon,
size: 18,
@@ -687,12 +687,12 @@ class TeamsTab extends StatelessWidget {
),
decoration: BoxDecoration(
color: Colors.deepPurple
.withValues(alpha: 0.10),
.withOpacity(0.10),
borderRadius:
BorderRadius.circular(12),
border: Border.all(
color: Colors.deepPurple
.withValues(alpha: 0.25),
.withOpacity(0.25),
),
),
child: Text(
@@ -780,7 +780,7 @@ class TeamsTab extends StatelessWidget {
: Colors.blue;
return CircleAvatar(
backgroundColor: color
.withValues(alpha: 0.1),
.withOpacity(0.1),
child: Icon(
icon,
size: 18,
@@ -1054,12 +1054,12 @@ class TeamsTab extends StatelessWidget {
}),
// : ( length)
DragTarget<Map<String, dynamic>>(
onWillAccept: (data) =>
data != null && data['participant'] is Participant,
onAccept: (data) {
onWillAcceptWithDetails: (details) =>
details.data['participant'] is Participant,
onAcceptWithDetails: (details) {
final Participant dp =
data['participant'] as Participant;
final Team from = data['fromTeam'] as Team;
details.data['participant'] as Participant;
final Team from = details.data['fromTeam'] as Team;
if (onMoveParticipant != null) {
onMoveParticipant!(
dp,
@@ -1130,7 +1130,7 @@ class _UnassignedChip extends StatelessWidget {
return Chip(
avatar: CircleAvatar(
backgroundColor: color.withValues(alpha: 0.1),
backgroundColor: color.withOpacity(0.1),
child: Icon(icon, size: 16, color: color),
),
label: Row(
@@ -1158,10 +1158,10 @@ class _UnassignedChip extends StatelessWidget {
vertical: 2,
),
decoration: BoxDecoration(
color: Colors.deepPurple.withValues(alpha: 0.10),
color: Colors.deepPurple.withOpacity(0.10),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.deepPurple.withValues(alpha: 0.25),
color: Colors.deepPurple.withOpacity(0.25),
),
),
child: Text(
@@ -1182,10 +1182,10 @@ class _UnassignedChip extends StatelessWidget {
vertical: 2,
),
decoration: BoxDecoration(
color: Colors.indigo.withValues(alpha: 0.10),
color: Colors.indigo.withOpacity(0.10),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.indigo.withValues(alpha: 0.25),
color: Colors.indigo.withOpacity(0.25),
),
),
child: Text(