Skip to content

Commit

Permalink
redesign event code structure
Browse files Browse the repository at this point in the history
  • Loading branch information
Kouhakouu committed Oct 19, 2024
1 parent 1dcf53c commit d2eba52
Show file tree
Hide file tree
Showing 3 changed files with 344 additions and 0 deletions.
72 changes: 72 additions & 0 deletions lib/features/admin/domain/events.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// lib/domain/events.dart

import 'package:intl/intl.dart';

class Event {
final String id; // Document ID in Firestore
final String title;
final String content;
final String organizer;
final String participants;
final String location;
final DateTime date;

Event({
required this.id,
required this.title,
required this.content,
required this.organizer,
required this.participants,
required this.location,
required this.date,
});

/// Factory method để tạo Event từ tài liệu Firestore
factory Event.fromFirestore(Map<String, dynamic> data, String documentId) {
try {
String? timestamp = data['date']?['timestampValue'];
DateTime parsedDate = timestamp != null
? DateTime.parse(timestamp).toLocal() // Chuyển đổi sang múi giờ địa phương
: DateTime.now();

return Event(
id: documentId,
title: data['title']?['stringValue'] ?? '',
content: data['content']?['stringValue'] ?? '',
organizer: data['organizer']?['stringValue'] ?? '',
participants: data['participants']?['stringValue'] ?? '',
location: data['location']?['stringValue'] ?? '',
date: parsedDate,
);
} catch (e) {
return Event(
id: documentId,
title: 'Error',
content: '',
organizer: '',
participants: '',
location: '',
date: DateTime.now(),
);
}
}

/// Chuyển đổi Event thành các trường Firestore
Map<String, dynamic> toFirestore() {
return {
'title': {'stringValue': title},
'content': {'stringValue': content},
'organizer': {'stringValue': organizer},
'participants': {'stringValue': participants},
'location': {'stringValue': location},
'date': {'timestampValue': date.toUtc().toIso8601String()},
};
}
}

class EventWithDate {
final Event event;
final DateTime date;

EventWithDate({required this.event, required this.date});
}
114 changes: 114 additions & 0 deletions lib/features/admin/presentation/widgets/daily_event_box.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// lib/widgets/daily_event_box.dart

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../domain/events.dart';

class DailyEventBox extends StatelessWidget {
final DateTime selectedDay;
final List<Event> events;
final Function(Event) onEdit;
final Function(Event) onDelete;

const DailyEventBox({
Key? key,
required this.selectedDay,
required this.events,
required this.onEdit,
required this.onDelete,
}) : super(key: key);

@override
Widget build(BuildContext context) {
String formattedDate = DateFormat('dd/MM/yyyy').format(selectedDay);

return Container(
decoration: BoxDecoration(
color: Colors.blue[50], // Màu nền xanh dương nhẹ
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 5,
offset: const Offset(0, 3),
),
],
),
padding: const EdgeInsets.all(16.0),
width: double.infinity, // Ensure full width
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Tiêu đề
Text(
'Sự kiện ngày $formattedDate',
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8.0),
// Danh sách sự kiện
events.isEmpty
? const Center(
child: Text('Không có sự kiện nào trong ngày này.'),
)
: ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: events.length,
itemBuilder: (context, index) {
final event = events[index];
return ExpansionTile(
leading: const Icon(Icons.event),
title: Row(
children: [
Expanded(
child: Text(
event.title,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
IconButton(
icon: const Icon(Icons.edit, color: Colors.blue),
onPressed: () {
onEdit(event);
},
),
IconButton(
icon: const Icon(Icons.delete, color: Colors.red),
onPressed: () {
onDelete(event);
},
),
],
),
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Nội dung: ${event.content}'),
const SizedBox(height: 4),
Text('Người tổ chức: ${event.organizer}'),
const SizedBox(height: 4),
Text('Thành phần tham dự: ${event.participants}'),
const SizedBox(height: 4),
Text('Địa điểm: ${event.location}'),
const SizedBox(height: 4),
Text('Thời gian: ${DateFormat('dd/MM/yyyy').format(event.date)}'),
],
),
),
],
);
},
),
],
),
);
}
}
158 changes: 158 additions & 0 deletions lib/features/admin/presentation/widgets/event_box.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// lib/widgets/event_box.dart

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../domain/events.dart';

class EventBox extends StatelessWidget {
final String title;
final int count;
final List<EventWithDate> events;
final String emptyMessage;
final Function(Event) onEventTap;
final Function(Event) onEdit;
final Function(Event) onDelete;
final String screenSize; // 'wide', 'medium', 'small'

const EventBox({
Key? key,
required this.title,
required this.count,
required this.events,
required this.emptyMessage,
required this.onEventTap,
required this.onEdit,
required this.onDelete,
required this.screenSize,
}) : super(key: key);

@override
Widget build(BuildContext context) {
// Determine button layout based on screen size
bool isMediumScreen = screenSize == 'medium';
bool isWideScreen = screenSize == 'wide';
bool isSmallScreen = screenSize == 'small';

return Container(
decoration: BoxDecoration(
color: Colors.white, // Màu nền trắng
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 5,
offset: const Offset(0, 3),
),
],
),
padding: const EdgeInsets.all(16.0),
width: double.infinity, // Ensure full width
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Tiêu đề và thống kê
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4.0),
Text(
count > 0 ? (title == 'Sự kiện sắp tới' ? 'Trong 30 ngày sắp tới: $count sự kiện' : 'Trong 30 ngày đã qua: $count sự kiện') : (title == 'Sự kiện sắp tới' ? 'Trong 30 ngày sắp tới: 0 sự kiện' : 'Trong 30 ngày đã qua: 0 sự kiện'),
style: const TextStyle(
fontSize: 14,
color: Colors.grey,
),
),
],
),
const SizedBox(height: 8.0),
// Danh sách sự kiện
events.isEmpty
? Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(emptyMessage),
)
: ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: events.length,
itemBuilder: (context, index) {
final eventWithDate = events[index];
return ListTile(
leading: const Icon(Icons.event),
title: isMediumScreen || isSmallScreen
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
eventWithDate.event.title,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
const SizedBox(height: 4.0),
Row(
children: [
IconButton(
icon: const Icon(Icons.edit, color: Colors.blue, size: 20),
onPressed: () {
onEdit(eventWithDate.event);
},
),
IconButton(
icon: const Icon(Icons.delete, color: Colors.red, size: 20),
onPressed: () {
onDelete(eventWithDate.event);
},
),
],
),
],
)
: Row(
children: [
Expanded(
child: Text(
eventWithDate.event.title,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
IconButton(
icon: const Icon(Icons.edit, color: Colors.blue),
onPressed: () {
onEdit(eventWithDate.event);
},
),
IconButton(
icon: const Icon(Icons.delete, color: Colors.red),
onPressed: () {
onDelete(eventWithDate.event);
},
),
],
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Thời gian: ${DateFormat('dd/MM/yyyy').format(eventWithDate.date)}'),
Text('Địa điểm: ${eventWithDate.event.location}'),
],
),
onTap: () {
onEventTap(eventWithDate.event);
},
);
},
),
],
),
);
}
}

0 comments on commit d2eba52

Please sign in to comment.