172 lines
5.7 KiB
Dart
172 lines
5.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:intl/intl.dart';
|
|
import '../../models/task_log_model.dart';
|
|
import '../../models/project_model.dart';
|
|
import '../../models/user_model.dart';
|
|
import '../../services/task_log_service.dart';
|
|
import '../../services/auth_service.dart';
|
|
import '../../services/project_service.dart';
|
|
import '../../widgets/log_card.dart';
|
|
|
|
class AllLogsTab extends StatefulWidget {
|
|
const AllLogsTab({super.key});
|
|
|
|
@override
|
|
State<AllLogsTab> createState() => _AllLogsTabState();
|
|
}
|
|
|
|
class _AllLogsTabState extends State<AllLogsTab> {
|
|
DateTime? _startDate;
|
|
DateTime? _endDate;
|
|
String? _selectedProjectId;
|
|
String? _selectedUserId;
|
|
|
|
List<ProjectModel> _projects = [];
|
|
List<UserModel> _users = [];
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
// Default range: this week
|
|
final now = DateTime.now();
|
|
_startDate = DateTime(now.year, now.month, now.day).subtract(const Duration(days: 7));
|
|
_endDate = DateTime(now.year, now.month, now.day, 23, 59, 59);
|
|
_loadFilters();
|
|
}
|
|
|
|
void _loadFilters() async {
|
|
final projects = await context.read<ProjectService>().getProjects().first;
|
|
final users = await context.read<AuthService>().getUsers().first;
|
|
if (mounted) {
|
|
setState(() {
|
|
_projects = projects;
|
|
_users = users;
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final service = context.read<TaskLogService>();
|
|
|
|
return Scaffold(
|
|
appBar: PreferredSize(
|
|
preferredSize: const Size.fromHeight(100),
|
|
child: Container(
|
|
color: Colors.indigo.shade50,
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
child: SingleChildScrollView(
|
|
scrollDirection: Axis.horizontal,
|
|
child: Row(
|
|
children: [
|
|
_filterChip("Date Range", Icons.calendar_today, _pickDateRange),
|
|
const SizedBox(width: 8),
|
|
_projectFilterDropdown(),
|
|
const SizedBox(width: 8),
|
|
_userFilterDropdown(),
|
|
if (_selectedProjectId != null || _selectedUserId != null) ...[
|
|
const SizedBox(width: 8),
|
|
IconButton(
|
|
onPressed: () => setState(() {
|
|
_selectedProjectId = null;
|
|
_selectedUserId = null;
|
|
}),
|
|
icon: const Icon(Icons.clear, color: Colors.red),
|
|
tooltip: "Clear Filters",
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
body: StreamBuilder<List<TaskLogModel>>(
|
|
stream: service.getTaskLogs(
|
|
from: _startDate,
|
|
to: _endDate,
|
|
projectId: _selectedProjectId,
|
|
userId: _selectedUserId,
|
|
),
|
|
builder: (context, snapshot) {
|
|
if (snapshot.connectionState == ConnectionState.waiting) return const Center(child: CircularProgressIndicator());
|
|
final logs = snapshot.data ?? [];
|
|
|
|
if (logs.isEmpty) {
|
|
return const Center(child: Text("No logs found for selected filters."));
|
|
}
|
|
|
|
return ListView.builder(
|
|
padding: const EdgeInsets.all(12),
|
|
itemCount: logs.length,
|
|
itemBuilder: (context, index) {
|
|
return LogCard(log: logs[index], canEdit: false);
|
|
},
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _filterChip(String label, IconData icon, VoidCallback onTap) {
|
|
final DateFormat formatter = DateFormat('dd/MM');
|
|
String range = "${formatter.format(_startDate!)} - ${formatter.format(_endDate!)}";
|
|
|
|
return ActionChip(
|
|
avatar: Icon(icon, size: 16, color: Colors.indigo),
|
|
label: Text(range, style: const TextStyle(fontSize: 12)),
|
|
onPressed: onTap,
|
|
backgroundColor: Colors.white,
|
|
);
|
|
}
|
|
|
|
Widget _projectFilterDropdown() {
|
|
return Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20)),
|
|
child: DropdownButton<String>(
|
|
value: _selectedProjectId,
|
|
hint: const Text("Project", style: TextStyle(fontSize: 12)),
|
|
underline: const SizedBox(),
|
|
items: [
|
|
const DropdownMenuItem(value: null, child: Text("All Projects", style: TextStyle(fontSize: 12))),
|
|
..._projects.map((p) => DropdownMenuItem(value: p.id, child: Text(p.name, style: const TextStyle(fontSize: 12))))
|
|
],
|
|
onChanged: (v) => setState(() => _selectedProjectId = v),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _userFilterDropdown() {
|
|
return Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20)),
|
|
child: DropdownButton<String>(
|
|
value: _selectedUserId,
|
|
hint: const Text("Member", style: TextStyle(fontSize: 12)),
|
|
underline: const SizedBox(),
|
|
items: [
|
|
const DropdownMenuItem(value: null, child: Text("All Members", style: TextStyle(fontSize: 12))),
|
|
..._users.map((u) => DropdownMenuItem(value: u.uid, child: Text(u.name, style: const TextStyle(fontSize: 12))))
|
|
],
|
|
onChanged: (v) => setState(() => _selectedUserId = v),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _pickDateRange() async {
|
|
final range = await showDateRangePicker(
|
|
context: context,
|
|
firstDate: DateTime(2024),
|
|
lastDate: DateTime.now(),
|
|
initialDateRange: DateTimeRange(start: _startDate!, end: _endDate!),
|
|
);
|
|
if (range != null) {
|
|
setState(() {
|
|
_startDate = range.start;
|
|
_endDate = DateTime(range.end.year, range.end.month, range.end.day, 23, 59, 59);
|
|
});
|
|
}
|
|
}
|
|
}
|