diff --git a/packages/uni_ui/assets/images/profile_placeholder.png b/packages/uni_ui/assets/images/profile_placeholder.png new file mode 100644 index 000000000..75a1560f0 Binary files /dev/null and b/packages/uni_ui/assets/images/profile_placeholder.png differ diff --git a/packages/uni_ui/lib/cards/generic_card.dart b/packages/uni_ui/lib/cards/generic_card.dart index c2fb96d8b..f23cc7c89 100644 --- a/packages/uni_ui/lib/cards/generic_card.dart +++ b/packages/uni_ui/lib/cards/generic_card.dart @@ -2,16 +2,16 @@ import 'package:figma_squircle/figma_squircle.dart'; import 'package:flutter/material.dart'; class GenericCard extends StatelessWidget { - const GenericCard({ - super.key, - this.margin, - this.padding, - this.color, - this.shadowColor, - this.borderRadius, - this.onClick, - this.child, - }); + const GenericCard( + {super.key, + this.margin, + this.padding, + this.color, + this.shadowColor, + this.borderRadius, + this.onClick, + this.child, + this.gradient}); final EdgeInsetsGeometry? margin; final EdgeInsetsGeometry? padding; @@ -20,6 +20,7 @@ class GenericCard extends StatelessWidget { final double? borderRadius; final Function? onClick; final Widget? child; + final Gradient? gradient; @override Widget build(BuildContext context) { @@ -40,6 +41,7 @@ class GenericCard extends StatelessWidget { color: color ?? cardTheme.color ?? theme.colorScheme.surfaceContainer, + gradient: gradient, boxShadow: [ BoxShadow( color: shadowColor ?? @@ -50,7 +52,9 @@ class GenericCard extends StatelessWidget { ], ), child: Padding( - padding: padding ?? const EdgeInsets.all(10), child: child), + padding: padding ?? + const EdgeInsets.symmetric(vertical: 15, horizontal: 25), + child: child), ), ), ), diff --git a/packages/uni_ui/lib/cards/schedule_card.dart b/packages/uni_ui/lib/cards/schedule_card.dart new file mode 100644 index 000000000..3718a6dc0 --- /dev/null +++ b/packages/uni_ui/lib/cards/schedule_card.dart @@ -0,0 +1,133 @@ +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 ScheduleCard extends StatelessWidget { + const ScheduleCard( + {super.key, + required this.name, + required this.acronym, + required this.room, + required this.type, + // required this.badgeColor, + this.isActive = false, + this.teacherName, + this.teacherPhoto}); + + final String name; + final String acronym; + final String room; + final String type; + // final BadgeColors badgeColor; + final bool isActive; + final String? teacherName; + final String? teacherPhoto; + + @override + Widget build(BuildContext context) { + return GenericCard( + gradient: isActive + ? RadialGradient( + colors: [ + Color(0xFF280709), + Color(0xFF511515), + ], + center: Alignment.topLeft, + radius: 1.5, + stops: [0, 1]) + : null, + key: key, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + if (isActive) ...[ + PhosphorIcon( + PhosphorIcons.clock(PhosphorIconsStyle.duotone), + color: Theme.of(context).colorScheme.secondary, + size: 20, + ), + SizedBox(width: 5), + ], + Text( + acronym, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: Theme.of(context) + .textTheme + .headlineMedium! + .fontSize, + fontWeight: Theme.of(context) + .textTheme + .headlineMedium! + .fontWeight, + color: isActive + ? Theme.of(context).colorScheme.secondary + : Theme.of(context).colorScheme.primary), + ), + const SizedBox(width: 8), //TODO: Create a custom Gap()? + Badge( + label: Text(type), + backgroundColor: BadgeColors.tp, + textColor: Theme.of(context).colorScheme.surface, + ), + ], + ), + Text( + name, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: + Theme.of(context).textTheme.titleLarge!.fontSize, + fontWeight: + Theme.of(context).textTheme.titleLarge!.fontWeight, + color: isActive + ? Theme.of(context).colorScheme.secondary + : Theme.of(context).colorScheme.primary), + ), + SizedBox(height: 5), + if (isActive) + Row(children: [ + CircleAvatar( + radius: 15, + backgroundImage: const AssetImage( + 'assets/images/profile_placeholder.png', // to change + )), + const SizedBox(width: 8), //TODO: create gap()? + Text(teacherName!, + style: TextStyle( + color: isActive + ? Theme.of(context).colorScheme.secondary + : Theme.of(context).colorScheme.primary)), + ]) + ], + ), + ), + Column( + children: [ + PhosphorIcon( + PhosphorIcons.mapPin(PhosphorIconsStyle.duotone), + color: isActive + ? Theme.of(context).colorScheme.secondary + : Theme.of(context).iconTheme.color, + size: 35, + ), + Text(room, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: isActive + ? Theme.of(context).colorScheme.secondary + : Theme.of(context).colorScheme.primary)), + ], + ) + ], + ), + ); + } +} diff --git a/packages/uni_ui/lib/main.dart b/packages/uni_ui/lib/main.dart index fc1d906a2..d60cea8c9 100644 --- a/packages/uni_ui/lib/main.dart +++ b/packages/uni_ui/lib/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:uni_ui/timeline/timeline.dart'; +import 'package:uni_ui/cards/schedule_card.dart'; +import 'package:uni_ui/theme.dart'; void main() { runApp(MyApp()); @@ -9,321 +10,28 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - theme: ThemeData.light(), + theme: lightTheme, home: Scaffold( - appBar: AppBar( - title: Text('Timeline Example'), - ), - body: Timeline( - content: [ - Container( - color: Colors.red[100], - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Content for Tab 1', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), - SizedBox(height: 8), - Text( - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' - 'Suspendisse eget tincidunt sapien. Phasellus sed ligula id ' - 'turpis vulputate efficitur. Donec ut arcu vel leo blandit ' - 'dictum. Cras ut massa nisi. Nulla facilisi. Quisque porta ' - 'lobortis diam, at interdum orci.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ' - 'accusantium doloremque laudantium, totam rem aperiam, eaque ' - 'ipsa quae ab illo inventore veritatis et quasi architecto ' - 'beatae vitae dicta sunt explicabo.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'At vero eos et accusamus et iusto odio dignissimos ducimus ' - 'qui blanditiis praesentium voluptatum deleniti atque corrupti ' - 'quos dolores et quas molestias excepturi sint occaecati ' - 'cupiditate non provident.', - style: TextStyle(fontSize: 16), - ), - ], + body: Column( + children: [ + Row( + children: [ + SizedBox( + width: 70, ), - ), - Container( - color: Colors.green[100], - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Content for Tab 2', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), - SizedBox(height: 8), - Text( - 'Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut ' - 'odit aut fugit, sed quia consequuntur magni dolores eos qui ' - 'ratione voluptatem sequi nesciunt.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, ' - 'consectetur, adipisci velit, sed quia non numquam eius modi ' - 'tempora incidunt ut labore et dolore magnam aliquam quaerat ' - 'voluptatem.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'Ut enim ad minima veniam, quis nostrum exercitationem ullam ' - 'corporis suscipit laboriosam, nisi ut aliquid ex ea commodi ' - 'consequatur?', - style: TextStyle(fontSize: 16), - ), - ], - ), - ), - Container( - color: Colors.blue[100], - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Content for Tab 3', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), - SizedBox(height: 8), - Text( - 'Quis autem vel eum iure reprehenderit qui in ea voluptate ' - 'velit esse quam nihil molestiae consequatur, vel illum qui ' - 'dolorem eum fugiat quo voluptas nulla pariatur?', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'But I must explain to you how all this mistaken idea of ' - 'denouncing pleasure and praising pain was born and I will ' - 'give you a complete account of the system, and expound the ' - 'actual teachings of the great explorer of the truth.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'Nor again is there anyone who loves or pursues or desires to ' - 'obtain pain of itself, because it is pain, but because ' - 'occasionally circumstances occur in which toil and pain can ' - 'procure him some great pleasure.', - style: TextStyle(fontSize: 16), - ), - ], - ), - ), - Container( - color: Colors.red[100], - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Content for Tab 4', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), - SizedBox(height: 8), - Text( - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' - 'Suspendisse eget tincidunt sapien. Phasellus sed ligula id ' - 'turpis vulputate efficitur. Donec ut arcu vel leo blandit ' - 'dictum. Cras ut massa nisi. Nulla facilisi. Quisque porta ' - 'lobortis diam, at interdum orci.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ' - 'accusantium doloremque laudantium, totam rem aperiam, eaque ' - 'ipsa quae ab illo inventore veritatis et quasi architecto ' - 'beatae vitae dicta sunt explicabo.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'At vero eos et accusamus et iusto odio dignissimos ducimus ' - 'qui blanditiis praesentium voluptatum deleniti atque corrupti ' - 'quos dolores et quas molestias excepturi sint occaecati ' - 'cupiditate non provident.', - style: TextStyle(fontSize: 16), - ), - ], - ), - ), - Container( - color: Colors.red[100], - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Content for Tab 5', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), - SizedBox(height: 8), - Text( - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' - 'Suspendisse eget tincidunt sapien. Phasellus sed ligula id ' - 'turpis vulputate efficitur. Donec ut arcu vel leo blandit ' - 'dictum. Cras ut massa nisi. Nulla facilisi. Quisque porta ' - 'lobortis diam, at interdum orci.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ' - 'accusantium doloremque laudantium, totam rem aperiam, eaque ' - 'ipsa quae ab illo inventore veritatis et quasi architecto ' - 'beatae vitae dicta sunt explicabo.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'At vero eos et accusamus et iusto odio dignissimos ducimus ' - 'qui blanditiis praesentium voluptatum deleniti atque corrupti ' - 'quos dolores et quas molestias excepturi sint occaecati ' - 'cupiditate non provident.', - style: TextStyle(fontSize: 16), - ), - ], - ), - ), - Container( - color: Colors.red[100], - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Content for Tab 6', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), - SizedBox(height: 8), - Text( - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' - 'Suspendisse eget tincidunt sapien. Phasellus sed ligula id ' - 'turpis vulputate efficitur. Donec ut arcu vel leo blandit ' - 'dictum. Cras ut massa nisi. Nulla facilisi. Quisque porta ' - 'lobortis diam, at interdum orci.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ' - 'accusantium doloremque laudantium, totam rem aperiam, eaque ' - 'ipsa quae ab illo inventore veritatis et quasi architecto ' - 'beatae vitae dicta sunt explicabo.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'At vero eos et accusamus et iusto odio dignissimos ducimus ' - 'qui blanditiis praesentium voluptatum deleniti atque corrupti ' - 'quos dolores et quas molestias excepturi sint occaecati ' - 'cupiditate non provident.', - style: TextStyle(fontSize: 16), - ), - ], - ), - ), - Container( - color: Colors.red[100], - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Content for Tab 7', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), - SizedBox(height: 8), - Text( - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' - 'Suspendisse eget tincidunt sapien. Phasellus sed ligula id ' - 'turpis vulputate efficitur. Donec ut arcu vel leo blandit ' - 'dictum. Cras ut massa nisi. Nulla facilisi. Quisque porta ' - 'lobortis diam, at interdum orci.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ' - 'accusantium doloremque laudantium, totam rem aperiam, eaque ' - 'ipsa quae ab illo inventore veritatis et quasi architecto ' - 'beatae vitae dicta sunt explicabo.', - style: TextStyle(fontSize: 16), - ), - SizedBox(height: 16), - Text( - 'At vero eos et accusamus et iusto odio dignissimos ducimus ' - 'qui blanditiis praesentium voluptatum deleniti atque corrupti ' - 'quos dolores et quas molestias excepturi sint occaecati ' - 'cupiditate non provident.', - style: TextStyle(fontSize: 16), - ), - ], - ), - ), - ], - tabs: [ - Column( - children: [ - Text('Mon'), - Text('1'), - ], - ), - Column( - children: [ - Text('Tue'), - Text('2'), - ], - ), - Column( - children: [ - Text('Wed'), - Text('3'), - ], - ), - Column( - children: [ - Text('Thu'), - Text('4'), - ], - ), - Column( - children: [ - Text('Fri'), - Text('5'), - ], - ), - Column( - children: [ - Text('Sat'), - Text('6'), - ], - ), - Column( - children: [ - Text('Sun'), - Text('7'), - ], - ), - ], - ), - ), + Flexible( + child: ScheduleCard( + name: "Computer Laboratory", + acronym: "LCOM", + room: "B315", + type: "TP", + isActive: false, + teacherName: 'Pedro Souto'), + ) + ], + ) + ], + )), ); } } diff --git a/packages/uni_ui/lib/theme.dart b/packages/uni_ui/lib/theme.dart index 431d4d1e8..096f619b9 100644 --- a/packages/uni_ui/lib/theme.dart +++ b/packages/uni_ui/lib/theme.dart @@ -13,12 +13,12 @@ const Color salmon = Color.fromARGB(255, 227, 145, 145); 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), + displaySmall: TextStyle(fontSize: 28, fontWeight: FontWeight.w500), + headlineMedium: TextStyle(fontSize: 24, fontWeight: FontWeight.w600), headlineSmall: TextStyle(fontSize: 20, fontWeight: FontWeight.w400), - titleLarge: TextStyle(fontSize: 18, fontWeight: FontWeight.w300), - titleMedium: TextStyle(fontSize: 17, fontWeight: FontWeight.w300), + headlineLarge: TextStyle(fontSize: 28, fontWeight: FontWeight.w400), + titleLarge: TextStyle(fontSize: 18, fontWeight: FontWeight.w400), + titleMedium: TextStyle(fontSize: 18, fontWeight: FontWeight.w500), titleSmall: TextStyle(fontSize: 16, fontWeight: FontWeight.w300), bodyLarge: TextStyle(fontSize: 16, fontWeight: FontWeight.w400), bodyMedium: TextStyle(fontSize: 14, fontWeight: FontWeight.w400), @@ -57,15 +57,24 @@ ThemeData lightTheme = ThemeData( cardTheme: CardTheme( margin: EdgeInsets.all(4), color: mildWhite, + shadowColor: Colors.black.withOpacity(0.25), ), dividerColor: lightGray, hintColor: lightGray, indicatorColor: darkRed, secondaryHeaderColor: normalGray, iconTheme: const IconThemeData(color: darkRed), + scaffoldBackgroundColor: pureWhite, ); class BadgeColors { + static const te = Color(0xFFfbc11f); + static const tp = Color(0xFFd3944c); + static const p = Color(0xFFab4d39); + static const pl = Color(0xFF769c87); + static const ot = Color(0xFF7ca5b8); + static const tc = Color(0xFFcdbeb1); + static const s = Color(0xFF917c9b); static const mt = Color(0xFF7ca5b8); static const en = Color(0xFF769c87); static const er = Color(0xFFab4d39); diff --git a/packages/uni_ui/pubspec.yaml b/packages/uni_ui/pubspec.yaml index dbfd71135..0b66282e9 100644 --- a/packages/uni_ui/pubspec.yaml +++ b/packages/uni_ui/pubspec.yaml @@ -22,4 +22,6 @@ dev_dependencies: test: any flutter: + assets: + - assets/images/ uses-material-design: true