diff --git a/packages/uni_ui/lib/course_grade_card.dart b/packages/uni_ui/lib/cards/course_grade_card.dart similarity index 79% rename from packages/uni_ui/lib/course_grade_card.dart rename to packages/uni_ui/lib/cards/course_grade_card.dart index e004c5ee6..845d61715 100644 --- a/packages/uni_ui/lib/course_grade_card.dart +++ b/packages/uni_ui/lib/cards/course_grade_card.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:uni_ui/generic_card.dart'; +import 'package:uni_ui/cards/generic_card.dart'; class CourseGradeCard extends StatelessWidget { const CourseGradeCard( @@ -32,12 +32,8 @@ class CourseGradeCard extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - "${ects} ECTS", - style: theme.textTheme.bodyLarge - ), - Text("${grade.toInt()}", - style: theme.textTheme.bodyLarge) + Text("${ects} ECTS", style: theme.textTheme.bodyLarge), + Text("${grade.toInt()}", style: theme.textTheme.bodyLarge) ], ) ], diff --git a/packages/uni_ui/lib/cards/exam_card.dart b/packages/uni_ui/lib/cards/exam_card.dart new file mode 100644 index 000000000..a6f291c1a --- /dev/null +++ b/packages/uni_ui/lib/cards/exam_card.dart @@ -0,0 +1,123 @@ +import 'package:flutter/material.dart'; +import 'package:phosphor_flutter/phosphor_flutter.dart'; +import 'package:uni_ui/cards/generic_card.dart'; +import 'package:uni_ui/theme.dart'; + +class ExamCard extends StatelessWidget { + const ExamCard({ + super.key, + required this.name, + required this.acronym, + required this.rooms, + required this.type, + this.startTime, + this.isInvisible = false, + this.showIcon = true, + this.iconAction, + }); + + final String name; + final String acronym; + final List rooms; + final String type; + final String? startTime; + final bool isInvisible; + final bool showIcon; + final Function()? iconAction; + + @override + Widget build(BuildContext context) { + return Opacity( + opacity: isInvisible ? 0.6 : 1.0, + child: GenericCard( + key: key, + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + acronym, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.headlineMedium!, + ), + const SizedBox(width: 8), + Badge( + label: Text(type), + backgroundColor: BadgeColors.er, + textColor: Theme.of(context).colorScheme.surface, + ), + ], + ), + Text( + name, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.titleLarge!, + ), + const SizedBox(height: 5), + Row( + children: [ + PhosphorIcon( + PhosphorIcons.clock(PhosphorIconsStyle.duotone), + color: Theme.of(context).iconTheme.color, + size: 20, + ), + const SizedBox(width: 4), + Text( + startTime ?? "--:--", + style: Theme.of(context).textTheme.bodyMedium!, + ), + const SizedBox(width: 8), + if (!rooms.isEmpty) + PhosphorIcon( + PhosphorIcons.mapPin(PhosphorIconsStyle.duotone), + color: Theme.of(context).iconTheme.color, + size: 20, + ), + const SizedBox(width: 4), + Expanded( + child: ShaderMask( + shaderCallback: (Rect bounds) { + return const LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [Colors.black, Colors.transparent], + stops: [0.8, 1.0], + ).createShader(bounds); + }, + blendMode: BlendMode.dstIn, + child: SingleChildScrollView( + physics: const NeverScrollableScrollPhysics(), + scrollDirection: Axis.horizontal, + child: Text( + rooms.join(" "), + style: Theme.of(context).textTheme.bodyMedium, + ), + ), + ), + ), + ], + ) + ], + ), + ), + if (showIcon) + IconButton( + onPressed: iconAction ?? () {}, + icon: PhosphorIcon( + isInvisible + ? PhosphorIcons.eye(PhosphorIconsStyle.duotone) + : PhosphorIcons.eyeSlash(PhosphorIconsStyle.duotone), + color: Theme.of(context).iconTheme.color, + size: 35, + ), + ), + ], + ), + ), + ); + } +} diff --git a/packages/uni_ui/lib/generic_card.dart b/packages/uni_ui/lib/cards/generic_card.dart similarity index 100% rename from packages/uni_ui/lib/generic_card.dart rename to packages/uni_ui/lib/cards/generic_card.dart diff --git a/packages/uni_ui/lib/service_card.dart b/packages/uni_ui/lib/cards/service_card.dart similarity index 96% rename from packages/uni_ui/lib/service_card.dart rename to packages/uni_ui/lib/cards/service_card.dart index 2628c7f1e..c002a7a86 100644 --- a/packages/uni_ui/lib/service_card.dart +++ b/packages/uni_ui/lib/cards/service_card.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; -import 'package:uni_ui/generic_card.dart'; +import 'package:uni_ui/cards/generic_card.dart'; class ServiceCard extends StatelessWidget { const ServiceCard({ diff --git a/packages/uni_ui/lib/theme.dart b/packages/uni_ui/lib/theme.dart index 2c2fd7686..431d4d1e8 100644 --- a/packages/uni_ui/lib/theme.dart +++ b/packages/uni_ui/lib/theme.dart @@ -14,6 +14,7 @@ const _textTheme = TextTheme( displayLarge: TextStyle(fontSize: 40, fontWeight: FontWeight.w400), displayMedium: TextStyle(fontSize: 32, fontWeight: FontWeight.w400), displaySmall: TextStyle(fontSize: 28, fontWeight: FontWeight.w400), + headlineLarge: TextStyle(fontSize: 28, fontWeight: FontWeight.w300), headlineMedium: TextStyle(fontSize: 24, fontWeight: FontWeight.w300), headlineSmall: TextStyle(fontSize: 20, fontWeight: FontWeight.w400), titleLarge: TextStyle(fontSize: 18, fontWeight: FontWeight.w300), @@ -24,9 +25,24 @@ const _textTheme = TextTheme( bodySmall: TextStyle(fontSize: 13, fontWeight: FontWeight.w400), ); +var _lightTextTheme = TextTheme( + displayLarge: _textTheme.displayLarge!, + displayMedium: _textTheme.displayMedium!, + displaySmall: _textTheme.displaySmall!, + headlineLarge: _textTheme.headlineLarge!, + headlineMedium: _textTheme.headlineMedium!.copyWith(color: darkRed), + headlineSmall: _textTheme.headlineSmall!, + titleLarge: _textTheme.titleLarge!.copyWith(color: darkRed), + titleMedium: _textTheme.titleMedium!, + titleSmall: _textTheme.titleSmall!, + bodyLarge: _textTheme.bodyLarge!, + bodyMedium: _textTheme.bodyMedium!, + bodySmall: _textTheme.bodySmall!, +); + ThemeData lightTheme = ThemeData( useMaterial3: true, - textTheme: _textTheme, + textTheme: _lightTextTheme, colorScheme: ColorScheme.fromSeed( seedColor: darkRed, surface: mildWhite, @@ -48,3 +64,10 @@ ThemeData lightTheme = ThemeData( secondaryHeaderColor: normalGray, iconTheme: const IconThemeData(color: darkRed), ); + +class BadgeColors { + static const mt = Color(0xFF7ca5b8); + static const en = Color(0xFF769c87); + static const er = Color(0xFFab4d39); + static const ee = Color(0xFFfbc11f); +}