diff --git a/mdc_100_series/android/build.gradle b/mdc_100_series/android/build.gradle index 83ae22004..3cdaac958 100644 --- a/mdc_100_series/android/build.gradle +++ b/mdc_100_series/android/build.gradle @@ -26,6 +26,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/mdc_100_series/lib/app.dart b/mdc_100_series/lib/app.dart index 524d51924..4e0c81dd1 100644 --- a/mdc_100_series/lib/app.dart +++ b/mdc_100_series/lib/app.dart @@ -13,6 +13,8 @@ // limitations under the License. import 'package:flutter/material.dart'; +import 'supplemental/cut_corners_border.dart'; +import 'colors.dart'; import 'home.dart'; import 'login.dart'; @@ -35,10 +37,99 @@ class ShrineApp extends StatelessWidget { // TODO: Change backLayer field value to CategoryMenuPage (104) }, // TODO: Customize the theme (103) - theme: ThemeData.light(useMaterial3: true), + theme: _kShrineTheme, ); } } // TODO: Build a Shrine Theme (103) +final ThemeData _kShrineTheme = _buildShrineTheme(); + +ThemeData _buildShrineTheme() { + final ThemeData base = ThemeData.light(useMaterial3: true); + return base.copyWith( + colorScheme: base.colorScheme.copyWith( + primary: kShrinePurple, + secondary: kShrinePurple, + error: kShrineErrorRed, + ), + scaffoldBackgroundColor: kShrineSurfaceWhite, + // textTheme: _buildShrineTextTheme(base.textTheme), + textSelectionTheme: const TextSelectionThemeData( + selectionColor: kShrinePurple, + ), + appBarTheme: const AppBarTheme( + foregroundColor: kShrineBrown900, + backgroundColor: kShrinePink100, + ), + // TODO: Decorate the inputs (103) + inputDecorationTheme: const InputDecorationTheme( + border: OutlineInputBorder(), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 2, + color: kShrinePurple, + ), + ), + floatingLabelStyle: TextStyle( + color: kShrinePurple, + ), + ), + elevatedButtonTheme: _buildShrineElevatedButtonTheme(), + textButtonTheme: _buildShrineTextButtonTheme(), + ); +} + // TODO: Build a Shrine Text Theme (103) +TextTheme _buildShrineTextTheme(TextTheme base) { + return base + .copyWith( + headlineSmall: base.headlineSmall!.copyWith( + fontWeight: FontWeight.w500, + ), + titleLarge: base.titleLarge!.copyWith( + fontSize: 18.0, + ), + bodySmall: base.bodySmall!.copyWith( + fontWeight: FontWeight.w400, + fontSize: 14.0, + ), + bodyLarge: base.bodyLarge!.copyWith( + fontWeight: FontWeight.w500, + fontSize: 16.0, + ), + ) + .apply( + fontFamily: 'Rubik', + displayColor: kShrineBrown900, + bodyColor: kShrineBrown900, + ); +} + +ElevatedButtonThemeData _buildShrineElevatedButtonTheme() { + return ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + foregroundColor: kShrineBrown900, + backgroundColor: kShrinePink100, + elevation: 8.0, + shape: const BeveledRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(7.0), + ), + ), + ), + ); +} + +TextButtonThemeData _buildShrineTextButtonTheme() { + return TextButtonThemeData( + style: TextButton.styleFrom( + foregroundColor: kShrineBrown900, + shape: const BeveledRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(7.0), + ), + ), + ), + ); +} diff --git a/mdc_100_series/lib/colors.dart b/mdc_100_series/lib/colors.dart new file mode 100644 index 000000000..1c2a958cb --- /dev/null +++ b/mdc_100_series/lib/colors.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; + +const kShrinePink50 = Color(0xFFFEEAE6); +const kShrinePink100 = Color(0xFFFEDBD0); +const kShrinePink300 = Color(0xFFFBB8AC); +const kShrinePink400 = Color(0xFFEAA4A4); + +const kShrineBrown900 = Color(0xFF442B2D); + +const kShrineErrorRed = Color(0xFFC5032B); + +const kShrineSurfaceWhite = Color(0xFFFFFBFA); +const kShrineBackgroundWhite = Colors.white; +const kShrinePurple = Color(0xFF5D1049); diff --git a/mdc_100_series/lib/home.dart b/mdc_100_series/lib/home.dart index 949922670..f28d934d2 100644 --- a/mdc_100_series/lib/home.dart +++ b/mdc_100_series/lib/home.dart @@ -13,21 +13,116 @@ // limitations under the License. import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'supplemental/asymmetric_view.dart'; + +import 'model/product.dart'; +import 'model/products_repository.dart'; class HomePage extends StatelessWidget { const HomePage({Key? key}) : super(key: key); // TODO: Make a collection of cards (102) + // List _buildGridCards(BuildContext context) { + // List products = ProductsRepository.loadProducts(Category.all); + + // if (products.isEmpty) { + // return const []; + // } + + // final ThemeData theme = Theme.of(context); + // final NumberFormat formatter = NumberFormat.simpleCurrency( + // locale: Localizations.localeOf(context).toString()); + + // return products.map((product) { + // return Card( + // clipBehavior: Clip.antiAlias, + // elevation: 0.0, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // AspectRatio( + // aspectRatio: 18.0 / 11.0, + // child: Image.asset( + // product.assetName, + // package: product.assetPackage, + // fit: BoxFit.fitWidth, + // ), + // ), + // Expanded( + // child: Padding( + // padding: const EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0), + // child: Column( + // // TODO: Align labels to the bottom and center (103) + // mainAxisAlignment: MainAxisAlignment.end, + // crossAxisAlignment: CrossAxisAlignment.center, + // // TODO: Change innermost Column (103) + // children: [ + // // TODO: Handle overflowing labels (103) + // Text( + // product.name, + // style: theme.textTheme.labelLarge, + // softWrap: false, + // overflow: TextOverflow.ellipsis, + // maxLines: 1, + // ), + // const SizedBox(height: 4.0), + // Text( + // formatter.format(product.price), + // style: theme.textTheme.titleSmall, + // ), + // //End new code + // ], + // ), + // ), + // ), + // ], + // ), + // ); + // }).toList(); + // } + // TODO: Add a variable for Category (104) @override Widget build(BuildContext context) { // TODO: Return an AsymmetricView (104) // TODO: Pass Category variable to AsymmetricView (104) - return const Scaffold( - // TODO: Add app bar (102) + return Scaffold( + appBar: AppBar( + title: const Text('SHRINE'), + leading: IconButton( + icon: const Icon( + Icons.menu, + semanticLabel: 'menu', + ), + onPressed: () { + const Text('Icon menu'); + }, + ), + actions: [ + IconButton( + onPressed: () { + debugPrint('Search Button'); + }, + icon: const Icon( + Icons.search, + semanticLabel: 'search', + ), + ), + IconButton( + icon: const Icon( + Icons.filter, + semanticLabel: 'filter', + ), + onPressed: () { + debugPrint('Filter Button'); + }, + ) + ], + ), // TODO: Add a grid view (102) - body: Center( - child: Text('You did it!'), + body: AsymmetricView( + products: ProductsRepository.loadProducts(Category.all), ), resizeToAvoidBottomInset: false, ); diff --git a/mdc_100_series/lib/login.dart b/mdc_100_series/lib/login.dart index 7223aad8f..9f3a30840 100644 --- a/mdc_100_series/lib/login.dart +++ b/mdc_100_series/lib/login.dart @@ -12,7 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +import 'dart:js'; + import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'colors.dart'; class LoginPage extends StatefulWidget { const LoginPage({Key? key}) : super(key: key); @@ -37,7 +41,10 @@ class _LoginPageState extends State { children: [ Image.asset('assets/diamond.png'), const SizedBox(height: 16.0), - const Text('SHRINE'), + Text( + 'SHRINE', + style: Theme.of(context).textTheme.headlineSmall, + ), ], ), const SizedBox(height: 120.0), @@ -45,7 +52,7 @@ class _LoginPageState extends State { TextField( controller: _usernameController, decoration: const InputDecoration( - filled: true, + // filled: true, labelText: 'Username', ), ), @@ -53,7 +60,7 @@ class _LoginPageState extends State { TextField( controller: _passwordController, decoration: const InputDecoration( - filled: true, + // filled: true, labelText: 'Password', ), obscureText: true, @@ -69,6 +76,7 @@ class _LoginPageState extends State { _usernameController.clear(); _passwordController.clear(); }, + style: Theme.of(context).textButtonTheme.style, ), // TODO: Add an elevation to NEXT (103) // TODO: Add a beveled rectangular border to NEXT (103) @@ -77,6 +85,7 @@ class _LoginPageState extends State { onPressed: () { Navigator.pop(context); }, + style: Theme.of(context).elevatedButtonTheme.style, ), ], ), diff --git a/mdc_100_series/pubspec.yaml b/mdc_100_series/pubspec.yaml index 9cb5cc292..36a61a147 100644 --- a/mdc_100_series/pubspec.yaml +++ b/mdc_100_series/pubspec.yaml @@ -19,6 +19,13 @@ dev_dependencies: flutter: # TODO: Insert Fonts (103) + fonts: + - family: Rubik + fonts: + - asset: fonts/Rubik-Regular.ttf + - asset: fonts/Rubik-Medium.ttf + weight: 500 + uses-material-design: true assets: - assets/diamond.png