Files
Client/lib/view/pages/timetable/widgets/appointment_tile.dart
T

103 lines
3.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_calendar/calendar.dart';
import 'cross_painter.dart';
class AppointmentTile extends StatelessWidget {
static const _radius = BorderRadius.all(Radius.circular(7));
final Appointment appointment;
final bool crossedOut;
const AppointmentTile({super.key, required this.appointment, this.crossedOut = false});
@override
Widget build(BuildContext context) {
final isPast = appointment.endTime.isBefore(DateTime.now());
final color = appointment.color.withAlpha(isPast ? 160 : 255);
final locationLines = (appointment.location ?? '')
.split('\n')
.where((p) => p.isNotEmpty)
.take(2)
.toList(growable: false);
return Padding(
padding: const EdgeInsets.all(1),
child: Stack(
children: [
Positioned.fill(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
alignment: Alignment.topLeft,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: _radius,
color: color,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
_ScaledLine(
text: appointment.subject,
fontSize: 15,
fontWeight: FontWeight.w500,
),
for (final line in locationLines)
_ScaledLine(text: line, fontSize: 10),
],
),
),
),
if (crossedOut)
Positioned.fill(
child: ClipRRect(
borderRadius: _radius,
child: DecoratedBox(
decoration: BoxDecoration(
border: Border.all(width: 2, color: Colors.red.withAlpha(200)),
borderRadius: _radius,
),
child: CustomPaint(painter: CrossPainter()),
),
),
),
],
),
);
}
}
/// One row of appointment text. The FittedBox scales **only this line** down
/// when the text is wider than the tile, so a long teacher name does not
/// shrink the room number above it.
class _ScaledLine extends StatelessWidget {
final String text;
final double fontSize;
final FontWeight? fontWeight;
const _ScaledLine({
required this.text,
required this.fontSize,
this.fontWeight,
});
@override
Widget build(BuildContext context) => FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: Text(
text,
style: TextStyle(
color: Colors.white,
fontSize: fontSize,
fontWeight: fontWeight,
height: 1.1,
),
maxLines: 1,
softWrap: false,
),
);
}