이벤트 개발완료
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../../models/event_model.dart';
|
||||
import '../../../utils/url_utils.dart';
|
||||
import '../../../utils/enum_mappings.dart';
|
||||
import '../../../theme/badges.dart';
|
||||
|
||||
class BasicInfoTab extends StatelessWidget {
|
||||
final Event event;
|
||||
final int participantsCount;
|
||||
final VoidCallback onShareEvent;
|
||||
final VoidCallback onSetEventReminders;
|
||||
|
||||
const BasicInfoTab({
|
||||
super.key,
|
||||
required this.event,
|
||||
required this.participantsCount,
|
||||
required this.onShareEvent,
|
||||
required this.onSetEventReminders,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 4,
|
||||
children: [
|
||||
_badge(
|
||||
text: getEventTypeLabel(event.type),
|
||||
color: _getTypeColor(getEventTypeLabel(event.type)),
|
||||
icon: _getTypeIcon(getEventTypeLabel(event.type)),
|
||||
),
|
||||
if (event.status != null)
|
||||
BadgeStyles.eventStatus(
|
||||
getEventStatusLabel(event.status),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.share),
|
||||
onPressed: onShareEvent,
|
||||
tooltip: '이벤트 공유',
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
if (event.description != null && event.description!.isNotEmpty) ...[
|
||||
const Text('설명', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(event.description ?? ''),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
|
||||
const Text('이벤트 정보', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 8),
|
||||
_infoRow(Icons.calendar_today, '시작: ${DateFormat('yyyy-MM-dd HH:mm').format(event.startDate)}'),
|
||||
if (event.endDate != null)
|
||||
_infoRow(Icons.calendar_today, '종료: ${DateFormat('yyyy-MM-dd HH:mm').format(event.endDate!)}'),
|
||||
if (event.location != null && event.location!.isNotEmpty)
|
||||
_infoRow(Icons.location_on, '장소: ${event.location}'),
|
||||
if (event.maxParticipants != null)
|
||||
_infoRow(Icons.people, '최대 참가자: ${event.maxParticipants}명'),
|
||||
if (event.gameCount != null)
|
||||
_infoRow(Icons.sports, '게임 수: ${event.gameCount}게임'),
|
||||
if (event.participantFee != null)
|
||||
_infoRow(
|
||||
Icons.attach_money,
|
||||
event.participantFee == 0
|
||||
? '참가비: 무료'
|
||||
: '참가비: ${NumberFormat.currency(locale: 'ko_KR', symbol: '₩', decimalDigits: 0).format(event.participantFee)}',
|
||||
),
|
||||
if (event.registrationDeadline != null)
|
||||
_infoRow(Icons.timer, '신청마감: ${DateFormat('yyyy-MM-dd HH:mm').format(event.registrationDeadline!)}'),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
const Text('공개 접근', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 8),
|
||||
if (event.publicHash != null && event.publicHash!.isNotEmpty) ...[
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _infoRow(
|
||||
Icons.link,
|
||||
UrlUtils.getEventPublicUrl(event.publicHash!),
|
||||
isSelectable: true,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.copy),
|
||||
onPressed: () {
|
||||
final publicUrl = UrlUtils.getEventPublicUrl(event.publicHash!);
|
||||
UrlUtils.copyUrlToClipboard(context, publicUrl);
|
||||
},
|
||||
tooltip: 'URL 복사',
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
if (event.accessPassword != null && event.accessPassword!.isNotEmpty)
|
||||
_infoRow(Icons.lock, '접근 비밀번호: ${event.accessPassword}'),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
const Text('참가자 정보', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 8),
|
||||
_infoRow(Icons.people, '현재 참가자: $participantsCount명'),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
ElevatedButton.icon(
|
||||
onPressed: onSetEventReminders,
|
||||
icon: const Icon(Icons.notifications_active),
|
||||
label: const Text('알림 설정'),
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white,
|
||||
backgroundColor: Colors.green,
|
||||
minimumSize: const Size(double.infinity, 48),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _infoRow(IconData icon, String text, {bool isSelectable = false}) {
|
||||
final textWidget = isSelectable
|
||||
? SelectableText(
|
||||
text,
|
||||
maxLines: 3,
|
||||
onTap: () {},
|
||||
)
|
||||
: Text(text);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(icon, size: 20, color: Colors.blueGrey),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: textWidget),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _badge({required String text, required Color color, required IconData icon}) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: color.withValues(alpha: 0.15),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: color.withValues(alpha: 0.3)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(icon, size: 16, color: color),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(fontWeight: FontWeight.w600, color: color),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Color _getTypeColor(String type) {
|
||||
switch (type) {
|
||||
case '정기전':
|
||||
return Colors.indigo;
|
||||
case '연습':
|
||||
return Colors.teal;
|
||||
case '대회':
|
||||
return Colors.deepOrange;
|
||||
default:
|
||||
return Colors.blueGrey;
|
||||
}
|
||||
}
|
||||
|
||||
IconData _getTypeIcon(String type) {
|
||||
switch (type) {
|
||||
case '정기전':
|
||||
return Icons.event;
|
||||
case '연습':
|
||||
return Icons.fitness_center;
|
||||
case '대회':
|
||||
return Icons.emoji_events;
|
||||
default:
|
||||
return Icons.info;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user