claude refactor
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncfusion_flutter_calendar/calendar.dart';
|
||||
|
||||
import 'cross_painter.dart';
|
||||
|
||||
class AppointmentTile extends StatelessWidget {
|
||||
final CalendarAppointmentDetails details;
|
||||
final bool crossedOut;
|
||||
|
||||
const AppointmentTile({super.key, required this.details, this.crossedOut = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Appointment meeting = details.appointments.first;
|
||||
final isPast = meeting.endTime.isBefore(DateTime.now());
|
||||
final color = meeting.color.withAlpha(isPast ? 100 : 255);
|
||||
|
||||
return Stack(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(3),
|
||||
height: details.bounds.height,
|
||||
alignment: Alignment.topLeft,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(5)),
|
||||
color: color,
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
FittedBox(
|
||||
fit: BoxFit.fitWidth,
|
||||
child: Text(
|
||||
meeting.subject,
|
||||
style: const TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500),
|
||||
maxLines: 1,
|
||||
softWrap: false,
|
||||
),
|
||||
),
|
||||
FittedBox(
|
||||
fit: BoxFit.fitWidth,
|
||||
child: Text(
|
||||
meeting.location?.isNotEmpty == true ? meeting.location! : ' ',
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(color: Colors.white, fontSize: 10),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (crossedOut)
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(width: 2, color: Colors.red.withAlpha(200)),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(5)),
|
||||
),
|
||||
child: CustomPaint(painter: CrossPainter()),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CrossPainter extends CustomPainter {
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint = Paint()
|
||||
..color = Colors.red.withAlpha(200)
|
||||
..strokeWidth = 2.0;
|
||||
|
||||
canvas.drawLine(const Offset(0, 0), Offset(size.width, size.height), paint);
|
||||
canvas.drawLine(Offset(size.width, 0), Offset(0, size.height), paint);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(CrossPainter oldDelegate) => false;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import 'package:syncfusion_flutter_calendar/calendar.dart';
|
||||
|
||||
class LessonAppointmentSource extends CalendarDataSource {
|
||||
LessonAppointmentSource(List<Appointment> source) {
|
||||
appointments = source;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncfusion_flutter_calendar/calendar.dart';
|
||||
|
||||
import '../../../../api/webuntis/queries/getHolidays/getHolidaysResponse.dart';
|
||||
import '../../../../extensions/dateTime.dart';
|
||||
import '../data/webuntis_time.dart';
|
||||
import 'time_region_tile.dart';
|
||||
|
||||
class SpecialRegionsBuilder {
|
||||
final GetHolidaysResponse holidays;
|
||||
final ColorScheme colorScheme;
|
||||
final Color disabledColor;
|
||||
|
||||
SpecialRegionsBuilder({
|
||||
required this.holidays,
|
||||
required this.colorScheme,
|
||||
required this.disabledColor,
|
||||
});
|
||||
|
||||
List<TimeRegion> build() {
|
||||
final lastMonday = DateTime.now().subtract(const Duration(days: 14)).nextWeekday(DateTime.monday);
|
||||
final firstBreak = lastMonday.copyWith(hour: 10, minute: 15);
|
||||
final secondBreak = lastMonday.copyWith(hour: 13, minute: 50);
|
||||
|
||||
final holidayRegions = _buildHolidayRegions().toList();
|
||||
bool isInHoliday(DateTime time) => holidayRegions.any((region) => region.startTime.isSameDay(time));
|
||||
|
||||
return [
|
||||
...holidayRegions,
|
||||
if (!isInHoliday(firstBreak)) _breakRegion(firstBreak, const Duration(minutes: 20)),
|
||||
if (!isInHoliday(secondBreak)) _breakRegion(secondBreak, const Duration(minutes: 15)),
|
||||
];
|
||||
}
|
||||
|
||||
Iterable<TimeRegion> _buildHolidayRegions() => holidays.result.expand((holiday) {
|
||||
final startDay = WebuntisTime.parse(holiday.startDate, 0);
|
||||
final dayCount = WebuntisTime.parse(holiday.endDate, 0).difference(startDay).inDays;
|
||||
final days = List<DateTime>.generate(dayCount, (i) => startDay.add(Duration(days: i)));
|
||||
return days.map((day) => TimeRegion(
|
||||
startTime: day.copyWith(hour: 7, minute: 55),
|
||||
endTime: day.copyWith(hour: 16, minute: 30),
|
||||
text: '$kTimeRegionHolidayPrefix${holiday.name}',
|
||||
color: disabledColor.withAlpha(50),
|
||||
iconData: Icons.holiday_village_outlined,
|
||||
));
|
||||
});
|
||||
|
||||
TimeRegion _breakRegion(DateTime start, Duration duration) => TimeRegion(
|
||||
startTime: start,
|
||||
endTime: start.add(duration),
|
||||
recurrenceRule: 'FREQ=DAILY;INTERVAL=1',
|
||||
text: kTimeRegionCenterIcon,
|
||||
color: colorScheme.primary.withAlpha(50),
|
||||
iconData: Icons.restaurant,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncfusion_flutter_calendar/calendar.dart';
|
||||
|
||||
const String kTimeRegionCenterIcon = 'centerIcon';
|
||||
const String kTimeRegionHolidayPrefix = 'holiday:';
|
||||
|
||||
class TimeRegionTile extends StatelessWidget {
|
||||
final TimeRegionDetails details;
|
||||
|
||||
const TimeRegionTile({super.key, required this.details});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final text = details.region.text ?? '';
|
||||
final color = details.region.color;
|
||||
|
||||
if (text == kTimeRegionCenterIcon) {
|
||||
return Container(
|
||||
color: color,
|
||||
alignment: Alignment.center,
|
||||
child: Icon(details.region.iconData, size: 17, color: Theme.of(context).primaryColor),
|
||||
);
|
||||
}
|
||||
|
||||
if (text.startsWith(kTimeRegionHolidayPrefix)) {
|
||||
return Container(
|
||||
color: color,
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 15),
|
||||
const Icon(Icons.cake),
|
||||
const Text('FREI'),
|
||||
const SizedBox(height: 10),
|
||||
RotatedBox(
|
||||
quarterTurns: 1,
|
||||
child: Text(
|
||||
text.substring(kTimeRegionHolidayPrefix.length),
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15,
|
||||
decorationStyle: TextDecorationStyle.dashed,
|
||||
letterSpacing: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user