wip: add landing page refactoring

This commit is contained in:
Golek 2022-12-01 17:29:26 +07:00
parent cf1af613a5
commit 70dc4ccbef
57 changed files with 1790 additions and 599 deletions

View File

@ -1,17 +1,46 @@
import 'package:component_library/component_library.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:golek_flutter_new/routes/app_router.gr.dart';
class GolekTruk extends StatelessWidget {
import 'l10n/app_localizations.dart';
class GolekTruk extends StatefulWidget {
const GolekTruk({Key? key}) : super(key: key);
@override
State<GolekTruk> createState() => _GolekTrukState();
}
class _GolekTrukState extends State<GolekTruk> {
final _lightTheme = LightGolekThemeData();
final _darkTheme = DarkGolekThemeData();
final _appRouter = AppRouter();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Scaffold(
body: Text('HomePage GolekTruk'),
return GolekTheme(
darkTheme: _darkTheme,
lightTheme: _lightTheme,
child: MaterialApp.router(
debugShowCheckedModeBanner: false,
title: 'GolekTruk',
darkTheme: _darkTheme.materialThemeData,
theme: _lightTheme.materialThemeData,
themeMode: ThemeMode.light,
localizationsDelegates: const [
GlobalCupertinoLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
AppLocalizations.delegate,
ComponentLibraryLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''),
Locale('id', 'ID'),
],
backButtonDispatcher: RootBackButtonDispatcher(),
routeInformationParser: _appRouter.defaultRouteParser(),
routerDelegate: _appRouter.delegate(),
),
);
}

View File

@ -6,7 +6,7 @@ import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;
import 'app_localizations_en.dart';
import 'app_localizations_pt.dart';
import 'app_localizations_id.dart';
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
@ -90,7 +90,7 @@ abstract class AppLocalizations {
/// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[
Locale('en'),
Locale('pt')
Locale('id')
];
/// No description provided for @quotesBottomNavigationBarItemLabel.
@ -115,7 +115,7 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations>
}
@override
bool isSupported(Locale locale) => <String>['en', 'pt'].contains(locale.languageCode);
bool isSupported(Locale locale) => <String>['en', 'id'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
@ -127,7 +127,7 @@ AppLocalizations lookupAppLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en': return AppLocalizationsEn();
case 'pt': return AppLocalizationsPt();
case 'id': return AppLocalizationsId();
}
throw FlutterError(

View File

@ -1,8 +1,8 @@
import 'app_localizations.dart';
/// The translations for Portuguese (`pt`).
class AppLocalizationsPt extends AppLocalizations {
AppLocalizationsPt([String locale = 'pt']) : super(locale);
/// The translations for Indonesian (`id`).
class AppLocalizationsId extends AppLocalizations {
AppLocalizationsId([String locale = 'id']) : super(locale);
@override
String get quotesBottomNavigationBarItemLabel => 'Frases';

View File

@ -0,0 +1,10 @@
import 'package:auto_route/auto_route.dart';
import 'package:landing_menu/landing_menu.dart';
@MaterialAutoRouter(
replaceInRouteName: 'Page,Route',
routes: <AutoRoute>[
AutoRoute(page: LandingPage, initial: true),
],
)
class $AppRouter {}

View File

@ -0,0 +1,51 @@
// **************************************************************************
// AutoRouteGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// **************************************************************************
// AutoRouteGenerator
// **************************************************************************
//
// ignore_for_file: type=lint
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:auto_route/auto_route.dart' as _i2;
import 'package:flutter/material.dart' as _i3;
import 'package:landing_menu/landing_menu.dart' as _i1;
class AppRouter extends _i2.RootStackRouter {
AppRouter([_i3.GlobalKey<_i3.NavigatorState>? navigatorKey])
: super(navigatorKey);
@override
final Map<String, _i2.PageFactory> pagesMap = {
LandingRoute.name: (routeData) {
return _i2.MaterialPageX<dynamic>(
routeData: routeData,
child: const _i1.LandingPage(),
);
}
};
@override
List<_i2.RouteConfig> get routes => [
_i2.RouteConfig(
LandingRoute.name,
path: '/',
)
];
}
/// generated route for
/// [_i1.LandingPage]
class LandingRoute extends _i2.PageRouteInfo<void> {
const LandingRoute()
: super(
LandingRoute.name,
path: '/',
);
static const String name = 'LandingRoute';
}

View File

@ -1,9 +1,15 @@
PACKAGES := $(wildcard packages/*)
FEATURES := $(wildcard packages/features/*)
BUILD-RUNNER := packages/fav_qs_api packages/key_value_storage
BUILD-RUNNER := packages/golektruk_api
intl:
flutter gen-l10n
cd packages/component_library ; \
flutter gen-l10n ; \
cd ../../ ; \
for feature in $(FEATURES); do \
cd $${feature} ; \
echo "Generate localization on $${feature}" ; \

View File

@ -1 +0,0 @@
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M7.5 6a2.5 2.5 0 0 1 2.495 2.336l.005.206c-.01 3.555-1.24 6.614-3.705 9.223a.75.75 0 1 1-1.09-1.03c1.64-1.737 2.66-3.674 3.077-5.859A2.5 2.5 0 1 1 7.5 6Zm9 0a2.5 2.5 0 0 1 2.495 2.336l.005.206c-.01 3.56-1.237 6.614-3.705 9.223a.75.75 0 0 1-1.09-1.03c1.643-1.738 2.662-3.672 3.078-5.859A2.5 2.5 0 1 1 16.5 6Zm-9 1.5a1 1 0 1 0 .993 1.117l.007-.124a1 1 0 0 0-1-.993Zm9 0a1 1 0 1 0 .993 1.117l.007-.124a1 1 0 0 0-1-.993Z" fill="#212121" fill-rule="nonzero"/></svg>

Before

Width:  |  Height:  |  Size: 532 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24" xml:space="preserve"><path d="M19 8.5c0 1.4-1.1 2.5-2.5 2.5-.3 0-.5 0-.8-.1.4 2.2 1.4 4.1 3.1 5.9.3.3.3.8 0 1.1-.3.3-.8.3-1.1 0-2.5-2.6-3.7-5.7-3.7-9.2v-.2C14.1 7 15.2 6 16.5 6 17.9 6 19 7.1 19 8.5zm-9 0C10 9.9 8.9 11 7.5 11c-.3 0-.5 0-.8-.1.4 2.2 1.4 4.1 3.1 5.9.3.3.3.8 0 1.1s-.8.3-1.1 0C6.2 15.2 5 12.1 5 8.5v-.2C5.1 7 6.2 6 7.5 6 8.9 6 10 7.1 10 8.5zm5.5 0v.1c.1.5.5.9 1 .9.6 0 1-.4 1-1s-.4-1-1-1c-.5 0-1 .4-1 1zm-9 0v.1c.1.5.5.9 1 .9.6 0 1-.4 1-1s-.4-1-1-1c-.5 0-1 .4-1 1z" style="fill:#212121"/></svg>

Before

Width:  |  Height:  |  Size: 607 B

View File

@ -15,7 +15,7 @@ class ComponentStorybook extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = WonderTheme.of(context);
final theme = GolekTheme.of(context);
return Storybook(
theme: lightThemeData,
darkTheme: darkThemeData,

View File

@ -2,7 +2,7 @@ import 'package:component_library/component_library.dart';
import 'package:flutter/material.dart';
import 'package:storybook_flutter/storybook_flutter.dart';
List<Story> getStories(WonderThemeData theme) {
List<Story> getStories(GolekThemeData theme) {
return [
Story.simple(
name: 'Simple Expanded Elevated Button',
@ -111,24 +111,6 @@ List<Story> getStories(WonderThemeData theme) {
),
),
),
Story(
name: 'Upvote Icon Button',
section: 'Count Indicator Buttons',
builder: (_, k) => UpvoteIconButton(
count: k.sliderInt(
label: 'count',
max: 10,
min: 0,
initial: 0,
divisions: 9,
),
onTap: () {},
isUpvoted: k.boolean(
label: 'isUpvoted',
initial: false,
),
),
),
Story(
name: 'Exception Indicator',
section: 'Indicators',
@ -149,80 +131,6 @@ List<Story> getStories(WonderThemeData theme) {
: null,
),
),
Story(
name: 'QuoteCard',
section: 'Quote',
builder: (_, k) => QuoteCard(
isFavorite: k.boolean(
label: 'Is Favorite',
initial: false,
),
statement: k.text(
label: 'Statement',
initial:
'Wherever you go, no matter what the weather, always bring your own sunshine.',
),
author: k.text(
label: 'Author',
initial: 'Author name',
),
),
),
Story(
name: 'Quotes in List',
section: 'Quote',
wrapperBuilder: (context, story, child) => Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.separated(
itemCount: 15,
itemBuilder: (_, __) => child,
separatorBuilder: (_, __) => const Divider(
height: 16.0,
),
),
),
builder: (_, k) => QuoteCard(
isFavorite: k.boolean(
label: 'Is Favorite',
initial: false,
),
statement: k.text(
label: 'Statement',
initial: 'The finest steel has to go through the hottest fire.',
),
author: k.text(
label: 'Author',
initial: 'Author name',
),
),
),
Story(
name: 'Quotes in Grid',
section: 'Quote',
wrapperBuilder: (context, story, child) => Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.count(
crossAxisCount: 2,
crossAxisSpacing: theme.gridSpacing,
mainAxisSpacing: theme.gridSpacing,
children: [for (int i = 0; i < 15; i++) child],
),
),
builder: (_, k) => QuoteCard(
isFavorite: k.boolean(
label: 'Is Favorite',
initial: false,
),
statement: k.text(
label: 'Statement',
initial: 'A quote statement',
),
author: k.text(
label: 'Author',
initial: 'Author name',
),
),
),
Story.simple(
name: 'Centered Circular Progress Indicator',
child: const CenteredCircularProgressIndicator(),
@ -247,7 +155,7 @@ List<Story> getStories(WonderThemeData theme) {
)
? Icon(
Icons.favorite,
color: theme.roundedChoiceChipSelectedAvatarColor,
color: theme.warningMainColor,
)
: null,
onSelected: k.boolean(
@ -330,24 +238,6 @@ List<Story> getStories(WonderThemeData theme) {
name: 'Search Bar',
child: const SearchBar(),
),
Story.simple(
name: 'Row App Bar',
child: const RowAppBar(
children: [
FavoriteIconButton(
isFavorite: true,
),
UpvoteIconButton(
count: 10,
isUpvoted: true,
),
DownvoteIconButton(
count: 5,
isDownvoted: false,
),
],
),
),
Story(
name: 'Shrinkable Text',
builder: (_, k) => SafeArea(
@ -359,20 +249,20 @@ List<Story> getStories(WonderThemeData theme) {
),
style: k.options(
label: 'style',
initial: theme.quoteTextStyle.copyWith(
fontSize: FontSize.xxLarge,
initial: theme.textStyle.copyWith(
fontSize: FontSize.style24,
),
options: [
Option(
'XX large',
theme.quoteTextStyle.copyWith(
fontSize: FontSize.xxLarge,
theme.textStyle.copyWith(
fontSize: FontSize.style24,
),
),
Option(
'Small',
theme.quoteTextStyle.copyWith(
fontSize: FontSize.small,
theme.textStyle.copyWith(
fontSize: FontSize.style12,
),
),
],

View File

@ -5,12 +5,12 @@ import 'package:flutter/material.dart';
class StoryApp extends StatelessWidget {
StoryApp({Key? key}) : super(key: key);
final _lightTheme = LightWonderThemeData();
final _darkTheme = DarkWonderThemeData();
final _lightTheme = LightGolekThemeData();
final _darkTheme = DarkGolekThemeData();
@override
Widget build(BuildContext context) {
return WonderTheme(
return GolekTheme(
lightTheme: _lightTheme,
darkTheme: _darkTheme,
child: ComponentStorybook(

View File

@ -6,7 +6,6 @@ export 'src/expanded_elevated_button.dart';
export 'src/in_progress_text_button.dart';
export 'src/favorite_icon_button.dart';
export 'src/l10n/component_library_localizations.dart';
export 'src/quote_card.dart';
export 'src/centered_circular_progress_indicator.dart';
export 'src/rounded_choice_chip.dart';
export 'src/generic_error_snack_bar.dart';
@ -16,9 +15,7 @@ export 'src/search_bar.dart';
export 'src/share_icon_button.dart';
export 'src/shrinkable_text.dart';
export 'src/styled_status_bar.dart';
export 'src/svg_asset.dart';
export 'src/theme/font_size.dart';
export 'src/theme/spacing.dart';
export 'src/theme/wonder_theme.dart';
export 'src/theme/wonder_theme_data.dart';
export 'src/upvote_icon_button.dart';
export 'src/theme/golek_theme.dart';
export 'src/theme/golek_theme_data.dart';

View File

@ -17,7 +17,7 @@ class ChevronListTile extends StatelessWidget {
title: Text(
label,
style: const TextStyle(
fontSize: FontSize.mediumLarge,
fontSize: FontSize.style18,
),
),
trailing: const Icon(

View File

@ -33,7 +33,7 @@ class CountIndicatorIconButton extends StatelessWidget {
Text(
count.toString(),
style: const TextStyle(
fontSize: FontSize.small,
fontSize: FontSize.style12,
),
),
],

View File

@ -16,13 +16,13 @@ class DownvoteIconButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = ComponentLibraryLocalizations.of(context);
final theme = WonderTheme.of(context);
final theme = GolekTheme.of(context);
return CountIndicatorIconButton(
onTap: onTap,
tooltip: l10n.downvoteIconButtonTooltip,
iconData: Icons.arrow_downward_sharp,
iconColor:
isDownvoted ? theme.votedButtonColor : theme.unvotedButtonColor,
isDownvoted ? theme.warningMainColor : theme.neutral20Color,
count: count,
);
}

View File

@ -36,7 +36,7 @@ class ExceptionIndicator extends StatelessWidget {
title ?? l10n.exceptionIndicatorGenericTitle,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: FontSize.mediumLarge,
fontSize: FontSize.style16,
fontWeight: FontWeight.bold,
),
),

View File

@ -6,16 +6,16 @@ import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;
import 'component_library_localizations_en.dart';
import 'component_library_localizations_pt.dart';
import 'component_library_localizations_id.dart';
/// Callers can lookup localized strings with an instance of ComponentLibraryLocalizations returned
/// by `ComponentLibraryLocalizations.of(context)`.
/// Callers can lookup localized strings with an instance of ComponentLibraryLocalizations
/// returned by `ComponentLibraryLocalizations.of(context)`.
///
/// Applications need to include `ComponentLibraryLocalizations.delegate()` in their app's
/// localizationDelegates list, and the locales they support in the app's
/// supportedLocales list. For example:
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```
/// ```dart
/// import 'l10n/component_library_localizations.dart';
///
/// return MaterialApp(
@ -30,14 +30,14 @@ import 'component_library_localizations_pt.dart';
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```
/// ```yaml
/// dependencies:
/// # Internationalization support.
/// flutter_localizations:
/// sdk: flutter
/// intl: any # Use the pinned version from flutter_localizations
///
/// # rest of dependencies
/// # Rest of dependencies
/// ```
///
/// ## iOS Applications
@ -60,18 +60,15 @@ import 'component_library_localizations_pt.dart';
/// be consistent with the languages listed in the ComponentLibraryLocalizations.supportedLocales
/// property.
abstract class ComponentLibraryLocalizations {
ComponentLibraryLocalizations(String locale)
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
ComponentLibraryLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static ComponentLibraryLocalizations of(BuildContext context) {
return Localizations.of<ComponentLibraryLocalizations>(
context, ComponentLibraryLocalizations)!;
return Localizations.of<ComponentLibraryLocalizations>(context, ComponentLibraryLocalizations)!;
}
static const LocalizationsDelegate<ComponentLibraryLocalizations> delegate =
_ComponentLibraryLocalizationsDelegate();
static const LocalizationsDelegate<ComponentLibraryLocalizations> delegate = _ComponentLibraryLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
@ -83,8 +80,7 @@ abstract class ComponentLibraryLocalizations {
/// Additional delegates can be added by appending to this list in
/// MaterialApp. This list does not have to be used at all if a custom list
/// of delegates is preferred or required.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
<LocalizationsDelegate<dynamic>>[
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = <LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
@ -94,7 +90,7 @@ abstract class ComponentLibraryLocalizations {
/// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[
Locale('en'),
Locale('pt')
Locale('id')
];
/// No description provided for @downvoteIconButtonTooltip.
@ -164,37 +160,34 @@ abstract class ComponentLibraryLocalizations {
String get authenticationRequiredErrorSnackbarMessage;
}
class _ComponentLibraryLocalizationsDelegate
extends LocalizationsDelegate<ComponentLibraryLocalizations> {
class _ComponentLibraryLocalizationsDelegate extends LocalizationsDelegate<ComponentLibraryLocalizations> {
const _ComponentLibraryLocalizationsDelegate();
@override
Future<ComponentLibraryLocalizations> load(Locale locale) {
return SynchronousFuture<ComponentLibraryLocalizations>(
lookupComponentLibraryLocalizations(locale));
return SynchronousFuture<ComponentLibraryLocalizations>(lookupComponentLibraryLocalizations(locale));
}
@override
bool isSupported(Locale locale) =>
<String>['en', 'pt'].contains(locale.languageCode);
bool isSupported(Locale locale) => <String>['en', 'id'].contains(locale.languageCode);
@override
bool shouldReload(_ComponentLibraryLocalizationsDelegate old) => false;
}
ComponentLibraryLocalizations lookupComponentLibraryLocalizations(
Locale locale) {
ComponentLibraryLocalizations lookupComponentLibraryLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en':
return ComponentLibraryLocalizationsEn();
case 'pt':
return ComponentLibraryLocalizationsPt();
case 'en': return ComponentLibraryLocalizationsEn();
case 'id': return ComponentLibraryLocalizationsId();
}
throw FlutterError(
'ComponentLibraryLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.');
'ComponentLibraryLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.'
);
}

View File

@ -29,14 +29,11 @@ class ComponentLibraryLocalizationsEn extends ComponentLibraryLocalizations {
String get exceptionIndicatorTryAgainButton => 'Try Again';
@override
String get exceptionIndicatorGenericMessage =>
'There has been an error.\nPlease, check your internet connection and try again later.';
String get exceptionIndicatorGenericMessage => 'There has been an error.\nPlease, check your internet connection and try again later.';
@override
String get genericErrorSnackbarMessage =>
'There has been an error. Please, check your internet connection.';
String get genericErrorSnackbarMessage => 'There has been an error. Please, check your internet connection.';
@override
String get authenticationRequiredErrorSnackbarMessage =>
'You need to sign in before performing this action.';
String get authenticationRequiredErrorSnackbarMessage => 'You need to sign in before performing this action.';
}

View File

@ -0,0 +1,39 @@
import 'component_library_localizations.dart';
/// The translations for Indonesian (`id`).
class ComponentLibraryLocalizationsId extends ComponentLibraryLocalizations {
ComponentLibraryLocalizationsId([String locale = 'id']) : super(locale);
@override
String get downvoteIconButtonTooltip => 'Downvote';
@override
String get upvoteIconButtonTooltip => 'Upvote';
@override
String get searchBarHintText => 'journey';
@override
String get searchBarLabelText => 'Search';
@override
String get shareIconButtonTooltip => 'Share';
@override
String get favoriteIconButtonTooltip => 'Favorite';
@override
String get exceptionIndicatorGenericTitle => 'Something went wrong';
@override
String get exceptionIndicatorTryAgainButton => 'Try Again';
@override
String get exceptionIndicatorGenericMessage => 'There has been an error.\nPlease, check your internet connection and try again later.';
@override
String get genericErrorSnackbarMessage => 'There has been an error. Please, check your internet connection.';
@override
String get authenticationRequiredErrorSnackbarMessage => 'You need to sign in before performing this action.';
}

View File

@ -1,42 +0,0 @@
import 'component_library_localizations.dart';
/// The translations for Portuguese (`pt`).
class ComponentLibraryLocalizationsPt extends ComponentLibraryLocalizations {
ComponentLibraryLocalizationsPt([String locale = 'pt']) : super(locale);
@override
String get downvoteIconButtonTooltip => 'Negativo';
@override
String get upvoteIconButtonTooltip => 'Positivo';
@override
String get searchBarHintText => 'jornada';
@override
String get searchBarLabelText => 'Pesquisar';
@override
String get shareIconButtonTooltip => 'Compartilhar';
@override
String get favoriteIconButtonTooltip => 'Favoritar';
@override
String get exceptionIndicatorGenericTitle => 'Algo deu errado';
@override
String get exceptionIndicatorTryAgainButton => 'Tentar Novamente';
@override
String get exceptionIndicatorGenericMessage =>
'Ocorreu um erro.\nPor favor, confira sua conexão com a internet e tente novamente mais tarde.';
@override
String get genericErrorSnackbarMessage =>
'Ocorreu um erro. Por favor, confira sua conexão com a internet.';
@override
String get authenticationRequiredErrorSnackbarMessage =>
'Você precisa estar logado para executar essa ação.';
}

View File

@ -0,0 +1,13 @@
{
"downvoteIconButtonTooltip": "Downvote",
"upvoteIconButtonTooltip": "Upvote",
"searchBarHintText": "journey",
"searchBarLabelText": "Search",
"shareIconButtonTooltip": "Share",
"favoriteIconButtonTooltip": "Favorite",
"exceptionIndicatorGenericTitle": "Something went wrong",
"exceptionIndicatorTryAgainButton": "Try Again",
"exceptionIndicatorGenericMessage": "There has been an error.\nPlease, check your internet connection and try again later.",
"genericErrorSnackbarMessage": "There has been an error. Please, check your internet connection.",
"authenticationRequiredErrorSnackbarMessage": "You need to sign in before performing this action."
}

View File

@ -1,13 +0,0 @@
{
"downvoteIconButtonTooltip": "Negativo",
"upvoteIconButtonTooltip": "Positivo",
"searchBarHintText": "jornada",
"searchBarLabelText": "Pesquisar",
"shareIconButtonTooltip": "Compartilhar",
"favoriteIconButtonTooltip": "Favoritar",
"exceptionIndicatorGenericTitle": "Algo deu errado",
"exceptionIndicatorTryAgainButton": "Tentar Novamente",
"exceptionIndicatorGenericMessage": "Ocorreu um erro.\nPor favor, confira sua conexão com a internet e tente novamente mais tarde.",
"genericErrorSnackbarMessage": "Ocorreu um erro. Por favor, confira sua conexão com a internet.",
"authenticationRequiredErrorSnackbarMessage": "Você precisa estar logado para executar essa ação."
}

View File

@ -1,91 +0,0 @@
import 'package:component_library/component_library.dart';
import 'package:flutter/material.dart';
class QuoteCard extends StatelessWidget {
const QuoteCard({
required this.statement,
required this.isFavorite,
this.author,
this.top,
this.bottom,
this.onTap,
this.onFavorite,
Key? key,
}) : super(key: key);
final String statement;
final String? author;
final bool isFavorite;
final Widget? top;
final Widget? bottom;
final VoidCallback? onTap;
final VoidCallback? onFavorite;
@override
Widget build(BuildContext context) {
final top = this.top;
final bottom = this.bottom;
final theme = WonderTheme.of(context);
final author = this.author;
return Card(
margin: const EdgeInsets.all(0),
child: InkWell(
onTap: onTap,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Row(
children: [
if (top != null)
Padding(
padding: const EdgeInsets.only(
left: Spacing.medium,
),
child: top,
),
const Spacer(),
IconButton(
onPressed: onFavorite,
icon: Icon(
isFavorite
? Icons.favorite
: Icons.favorite_border_outlined,
),
)
],
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: Spacing.xLarge,
),
child: Text(
statement,
style: theme.quoteTextStyle.copyWith(
fontSize: FontSize.large,
),
),
),
if (bottom != null)
Padding(
padding: const EdgeInsets.only(
right: Spacing.medium,
),
child: bottom,
),
const SizedBox(
height: Spacing.mediumLarge,
),
if (author != null)
Padding(
padding: const EdgeInsets.only(
bottom: Spacing.medium,
right: Spacing.medium,
),
child: Text(author),
),
],
),
),
);
}
}

View File

@ -25,7 +25,7 @@ class RoundedChoiceChip extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = WonderTheme.of(context);
final theme = GolekTheme.of(context);
return ChoiceChip(
shape: const StadiumBorder(
side: BorderSide(),
@ -35,17 +35,16 @@ class RoundedChoiceChip extends StatelessWidget {
label,
style: TextStyle(
color: isSelected
? (selectedLabelColor ??
theme.roundedChoiceChipSelectedLabelColor)
: (labelColor ?? theme.roundedChoiceChipLabelColor),
? (selectedLabelColor ?? theme.primaryMainColor)
: (labelColor ?? theme.primarySurfaceColor),
),
),
onSelected: onSelected,
selected: isSelected,
backgroundColor:
(backgroundColor ?? theme.roundedChoiceChipBackgroundColor),
(backgroundColor ?? theme.primaryMainColor),
selectedColor: (selectedBackgroundColor ??
theme.roundedChoiceChipSelectedBackgroundColor),
theme.primarySurfaceColor),
);
}
}

View File

@ -1,78 +0,0 @@
import 'package:component_library/src/theme/wonder_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_svg/flutter_svg.dart';
class _SvgAsset extends StatelessWidget {
const _SvgAsset(
this.assetPath, {
this.width,
this.height,
this.color,
Key? key,
}) : super(key: key);
final String assetPath;
final double? width;
final double? height;
final Color? color;
@override
Widget build(BuildContext context) {
return SvgPicture.asset(
'assets/$assetPath',
width: width,
height: height,
color: color,
package: 'component_library',
);
}
}
class OpeningQuoteSvgAsset extends StatelessWidget {
const OpeningQuoteSvgAsset({
this.width,
this.height,
this.color,
Key? key,
}) : super(key: key);
final double? width;
final double? height;
final Color? color;
@override
Widget build(BuildContext context) {
final theme = WonderTheme.of(context);
return _SvgAsset(
'opening-quote.svg',
width: width,
height: height,
color: theme.quoteSvgColor,
);
}
}
class ClosingQuoteSvgAsset extends StatelessWidget {
const ClosingQuoteSvgAsset({
this.width,
this.height,
this.color,
Key? key,
}) : super(key: key);
final double? width;
final double? height;
final Color? color;
@override
Widget build(BuildContext context) {
final theme = WonderTheme.of(context);
return _SvgAsset(
'closing-quote.svg',
width: width,
height: height,
color: theme.quoteSvgColor,
);
}
}

View File

@ -1,8 +1,14 @@
abstract class FontSize {
static const double small = 11;
static const double medium = 14;
static const double mediumLarge = 18;
static const double large = 22;
static const double xLarge = 64;
static const double xxLarge = 192;
static const double style24 = 24;
static const double style20 = 20;
static const double style18 = 18;
static const double style16 = 16;
static const double style15 = 15;
static const double style14 = 14;
static const double style13 = 13;
static const double style12 = 12;
static const double style11 = 11;
static const double style10 = 10;
}

View File

@ -1,8 +1,8 @@
import 'package:component_library/src/theme/wonder_theme_data.dart';
import 'package:component_library/src/theme/golek_theme_data.dart';
import 'package:flutter/material.dart';
class WonderTheme extends InheritedWidget {
const WonderTheme({
class GolekTheme extends InheritedWidget {
const GolekTheme({
required Widget child,
required this.lightTheme,
required this.darkTheme,
@ -12,19 +12,19 @@ class WonderTheme extends InheritedWidget {
child: child,
);
final WonderThemeData lightTheme;
final WonderThemeData darkTheme;
final GolekThemeData lightTheme;
final GolekThemeData darkTheme;
@override
bool updateShouldNotify(
WonderTheme oldWidget,
GolekTheme oldWidget,
) =>
oldWidget.lightTheme != lightTheme || oldWidget.darkTheme != darkTheme;
static WonderThemeData of(BuildContext context) {
final WonderTheme? inheritedTheme =
context.dependOnInheritedWidgetOfExactType<WonderTheme>();
assert(inheritedTheme != null, 'No WonderTheme found in context');
static GolekThemeData of(BuildContext context) {
final GolekTheme? inheritedTheme =
context.dependOnInheritedWidgetOfExactType<GolekTheme>();
assert(inheritedTheme != null, 'No GolekTheme found in context');
final currentBrightness = Theme.of(context).brightness;
return currentBrightness == Brightness.dark
? inheritedTheme!.darkTheme

View File

@ -0,0 +1,466 @@
import 'package:component_library/component_library.dart';
import 'package:component_library/src/theme/spacing.dart';
import 'package:flutter/material.dart';
const _dividerThemeData = DividerThemeData(
space: 0,
);
// If the number of properties get too big, we can start grouping them in
// classes like Flutter does with TextTheme, ButtonTheme, etc, inside ThemeData.
abstract class GolekThemeData {
ThemeData get materialThemeData;
double screenMargin = Spacing.mediumLarge;
double gridSpacing = Spacing.mediumLarge;
Color get primaryMainColor;
Color get primaryOldColor;
Color get primarySurfaceColor;
Color get primaryBorderColor;
Color get primaryHoverColor;
Color get primaryPressedColor;
Color get primaryFocusColor;
Color get secondaryMainColor;
Color get secondarySurfaceColor;
Color get secondaryBorderColor;
Color get secondaryHoverColor;
Color get secondaryPressedColor;
Color get secondaryFocusColor;
Color get tertiaryMainColor;
Color get tertiarySurfaceColor;
Color get tertiaryBorderColor;
Color get tertiaryHoverColor;
Color get tertiaryPressedColor;
Color get tertiaryFocusColor;
Color get disabledColor;
Color get neutral10Color;
Color get neutral20Color;
Color get neutral30Color;
Color get neutral40Color;
Color get neutral50Color;
Color get neutral60Color;
Color get neutral70Color;
Color get neutral80Color;
Color get neutral90Color;
Color get neutral100Color;
Color get dangerMainColor;
Color get dangerSurfaceColor;
Color get dangerBorderColor;
Color get dangerHoverColor;
Color get dangerPressedColor;
Color get successMainColor;
Color get successSurfaceColor;
Color get successBorderColor;
Color get successHoverColor;
Color get successPressedColor;
Color get warningMainColor;
Color get warningSurfaceColor;
Color get warningBorderColor;
Color get warningHoverColor;
Color get warningPressedColor;
TextStyle textStyle = const TextStyle(
fontFamily: 'Montserrat',
package: 'component_library',
);
}
class LightGolekThemeData extends GolekThemeData {
@override
ThemeData get materialThemeData => ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.black.toMaterialColor(),
dividerTheme: _dividerThemeData,
);
@override
Color get dangerBorderColor => const Color(0xffFEC4C4);
@override
Color get dangerHoverColor => const Color(0xffFA2020);
@override
Color get dangerMainColor => const Color(0xffFA2020);
@override
Color get dangerPressedColor => const Color(0xffE11D1D);
@override
Color get dangerSurfaceColor => const Color(0xffFED2D2);
@override
Color get disabledColor => const Color(0xffededed);
@override
Color get neutral10Color => Colors.white;
@override
Color get neutral20Color => const Color(0xffEAF2FF);
@override
Color get neutral30Color => const Color(0xffC6CFDD);
@override
Color get neutral40Color => const Color(0xffB0B8C5);
@override
Color get neutral50Color => const Color(0xff9AA1AC);
@override
Color get neutral60Color => const Color(0xff848A94);
@override
Color get neutral70Color => const Color(0xff6E737B);
@override
Color get neutral80Color => const Color(0xff585C62);
@override
Color get neutral90Color => const Color(0xff585C62);
@override
Color get neutral100Color => const Color(0xff3E3E3E);
@override
Color get primaryBorderColor => const Color(0xff9EF3D4);
@override
Color get primaryFocusColor => const Color(0xff5EEBB7).withOpacity(0.2);
@override
Color get primaryHoverColor => const Color(0xff4BBC92);
@override
Color get primaryMainColor => const Color(0xff4BBC92);
@override
Color get primaryOldColor => const Color(0xff5EEBB7);
@override
Color get primaryPressedColor => const Color(0xff388D6E);
@override
Color get primarySurfaceColor => const Color(0xffEFFDF8);
@override
Color get secondaryBorderColor => const Color(0xffFFECAA);
@override
Color get secondaryFocusColor => const Color.fromRGBO(255, 199, 0, 0.2);
@override
Color get secondaryHoverColor => const Color(0xffE6B300);
@override
Color get secondaryMainColor => const Color(0xff122307);
@override
Color get secondaryPressedColor => const Color(0xffCC9F00);
@override
Color get secondarySurfaceColor => const Color(0xffFFF2C3);
@override
Color get successBorderColor => const Color(0xffD8FFF0);
@override
Color get successHoverColor => const Color(0xff3DFFB5);
@override
Color get successMainColor => const Color(0xff8BFFD3);
@override
Color get successPressedColor => const Color(0xff18D48C);
@override
Color get successSurfaceColor => const Color(0xffECFFF8);
@override
Color get tertiaryBorderColor => const Color(0xffDCE6F6);
@override
Color get tertiaryFocusColor => const Color.fromRGBO(198, 207, 221, 0.2);
@override
Color get tertiaryHoverColor => const Color(0xffB0B8C5);
@override
Color get tertiaryMainColor => const Color(0xff1A82E4);
@override
Color get tertiaryPressedColor => const Color(0xff9AA1AC);
@override
Color get tertiarySurfaceColor =>const Color(0xffF5F5F5);
@override
Color get warningBorderColor => const Color(0xffFFF9CF);
@override
Color get warningHoverColor => const Color(0xffFEE31A);
@override
Color get warningMainColor => const Color(0xffFFEE6E);
@override
Color get warningPressedColor => const Color(0xffCBB511);
@override
Color get warningSurfaceColor => const Color(0xffFFFCE2);
}
class DarkGolekThemeData extends GolekThemeData {
@override
ThemeData get materialThemeData => ThemeData(
brightness: Brightness.dark,
toggleableActiveColor: Colors.white,
primarySwatch: Colors.white.toMaterialColor(),
dividerTheme: _dividerThemeData,
);
@override
// TODO: implement dangerBorderColor
Color get dangerBorderColor => throw UnimplementedError();
@override
// TODO: implement dangerHoverColor
Color get dangerHoverColor => throw UnimplementedError();
@override
// TODO: implement dangerMainColor
Color get dangerMainColor => throw UnimplementedError();
@override
// TODO: implement dangerPressedColor
Color get dangerPressedColor => throw UnimplementedError();
@override
// TODO: implement dangerSurfaceColor
Color get dangerSurfaceColor => throw UnimplementedError();
@override
// TODO: implement disabledColor
Color get disabledColor => throw UnimplementedError();
@override
// TODO: implement neutral100Color
Color get neutral100Color => throw UnimplementedError();
@override
// TODO: implement neutral10Color
Color get neutral10Color => throw UnimplementedError();
@override
// TODO: implement neutral20Color
Color get neutral20Color => throw UnimplementedError();
@override
// TODO: implement neutral30Color
Color get neutral30Color => throw UnimplementedError();
@override
// TODO: implement neutral40Color
Color get neutral40Color => throw UnimplementedError();
@override
// TODO: implement neutral50Color
Color get neutral50Color => throw UnimplementedError();
@override
// TODO: implement neutral60Color
Color get neutral60Color => throw UnimplementedError();
@override
// TODO: implement neutral70Color
Color get neutral70Color => throw UnimplementedError();
@override
// TODO: implement neutral80Color
Color get neutral80Color => throw UnimplementedError();
@override
// TODO: implement neutral90Color
Color get neutral90Color => throw UnimplementedError();
@override
// TODO: implement primaryBorderColor
Color get primaryBorderColor => throw UnimplementedError();
@override
// TODO: implement primaryFocusColor
Color get primaryFocusColor => throw UnimplementedError();
@override
// TODO: implement primaryHoverColor
Color get primaryHoverColor => throw UnimplementedError();
@override
// TODO: implement primaryMainColor
Color get primaryMainColor => throw UnimplementedError();
@override
// TODO: implement primaryOldColor
Color get primaryOldColor => throw UnimplementedError();
@override
// TODO: implement primaryPressedColor
Color get primaryPressedColor => throw UnimplementedError();
@override
// TODO: implement primarySurfaceColor
Color get primarySurfaceColor => throw UnimplementedError();
@override
// TODO: implement secondaryBorderColor
Color get secondaryBorderColor => throw UnimplementedError();
@override
// TODO: implement secondaryFocusColor
Color get secondaryFocusColor => throw UnimplementedError();
@override
// TODO: implement secondaryHoverColor
Color get secondaryHoverColor => throw UnimplementedError();
@override
// TODO: implement secondaryMainColor
Color get secondaryMainColor => throw UnimplementedError();
@override
// TODO: implement secondaryPressedColor
Color get secondaryPressedColor => throw UnimplementedError();
@override
// TODO: implement secondarySurfaceColor
Color get secondarySurfaceColor => throw UnimplementedError();
@override
// TODO: implement successBorderColor
Color get successBorderColor => throw UnimplementedError();
@override
// TODO: implement successHoverColor
Color get successHoverColor => throw UnimplementedError();
@override
// TODO: implement successMainColor
Color get successMainColor => throw UnimplementedError();
@override
// TODO: implement successPressedColor
Color get successPressedColor => throw UnimplementedError();
@override
// TODO: implement successSurfaceColor
Color get successSurfaceColor => throw UnimplementedError();
@override
// TODO: implement tertiaryBorderColor
Color get tertiaryBorderColor => throw UnimplementedError();
@override
// TODO: implement tertiaryFocusColor
Color get tertiaryFocusColor => throw UnimplementedError();
@override
// TODO: implement tertiaryHoverColor
Color get tertiaryHoverColor => throw UnimplementedError();
@override
// TODO: implement tertiaryMainColor
Color get tertiaryMainColor => throw UnimplementedError();
@override
// TODO: implement tertiaryPressedColor
Color get tertiaryPressedColor => throw UnimplementedError();
@override
// TODO: implement tertiarySurfaceColor
Color get tertiarySurfaceColor => throw UnimplementedError();
@override
// TODO: implement warningBorderColor
Color get warningBorderColor => throw UnimplementedError();
@override
// TODO: implement warningHoverColor
Color get warningHoverColor => throw UnimplementedError();
@override
// TODO: implement warningMainColor
Color get warningMainColor => throw UnimplementedError();
@override
// TODO: implement warningPressedColor
Color get warningPressedColor => throw UnimplementedError();
@override
// TODO: implement warningSurfaceColor
Color get warningSurfaceColor => throw UnimplementedError();
}
extension on Color {
Map<int, Color> _toSwatch() => {
50: withOpacity(0.1),
100: withOpacity(0.2),
200: withOpacity(0.3),
300: withOpacity(0.4),
400: withOpacity(0.5),
500: withOpacity(0.6),
600: withOpacity(0.7),
700: withOpacity(0.8),
800: withOpacity(0.9),
900: this,
};
MaterialColor toMaterialColor() => MaterialColor(
value,
_toSwatch(),
);
}

View File

@ -1,133 +0,0 @@
import 'package:component_library/component_library.dart';
import 'package:component_library/src/theme/spacing.dart';
import 'package:flutter/material.dart';
const _dividerThemeData = DividerThemeData(
space: 0,
);
// If the number of properties get too big, we can start grouping them in
// classes like Flutter does with TextTheme, ButtonTheme, etc, inside ThemeData.
abstract class WonderThemeData {
ThemeData get materialThemeData;
double screenMargin = Spacing.mediumLarge;
double gridSpacing = Spacing.mediumLarge;
Color get roundedChoiceChipBackgroundColor;
Color get roundedChoiceChipSelectedBackgroundColor;
Color get roundedChoiceChipLabelColor;
Color get roundedChoiceChipSelectedLabelColor;
Color get roundedChoiceChipAvatarColor;
Color get roundedChoiceChipSelectedAvatarColor;
Color get quoteSvgColor;
Color get unvotedButtonColor;
Color get votedButtonColor;
TextStyle quoteTextStyle = const TextStyle(
fontFamily: 'Fondamento',
package: 'component_library',
);
}
class LightWonderThemeData extends WonderThemeData {
@override
ThemeData get materialThemeData => ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.black.toMaterialColor(),
dividerTheme: _dividerThemeData,
);
@override
Color get roundedChoiceChipBackgroundColor => Colors.white;
@override
Color get roundedChoiceChipLabelColor => Colors.black;
@override
Color get roundedChoiceChipSelectedBackgroundColor => Colors.black;
@override
Color get roundedChoiceChipSelectedLabelColor => Colors.white;
@override
Color get quoteSvgColor => Colors.black;
@override
Color get roundedChoiceChipAvatarColor => Colors.black;
@override
Color get roundedChoiceChipSelectedAvatarColor => Colors.white;
@override
Color get unvotedButtonColor => Colors.black54;
@override
Color get votedButtonColor => Colors.black;
}
class DarkWonderThemeData extends WonderThemeData {
@override
ThemeData get materialThemeData => ThemeData(
brightness: Brightness.dark,
toggleableActiveColor: Colors.white,
primarySwatch: Colors.white.toMaterialColor(),
dividerTheme: _dividerThemeData,
);
@override
Color get roundedChoiceChipBackgroundColor => Colors.black;
@override
Color get roundedChoiceChipLabelColor => Colors.white;
@override
Color get roundedChoiceChipSelectedBackgroundColor => Colors.white;
@override
Color get roundedChoiceChipSelectedLabelColor => Colors.black;
@override
Color get quoteSvgColor => Colors.white;
@override
Color get roundedChoiceChipAvatarColor => Colors.white;
@override
Color get roundedChoiceChipSelectedAvatarColor => Colors.black;
@override
Color get unvotedButtonColor => Colors.white54;
@override
Color get votedButtonColor => Colors.white;
}
extension on Color {
Map<int, Color> _toSwatch() => {
50: withOpacity(0.1),
100: withOpacity(0.2),
200: withOpacity(0.3),
300: withOpacity(0.4),
400: withOpacity(0.5),
500: withOpacity(0.6),
600: withOpacity(0.7),
700: withOpacity(0.8),
800: withOpacity(0.9),
900: this,
};
MaterialColor toMaterialColor() => MaterialColor(
value,
_toSwatch(),
);
}

View File

@ -1,28 +0,0 @@
import 'package:component_library/component_library.dart';
import 'package:flutter/material.dart';
class UpvoteIconButton extends StatelessWidget {
const UpvoteIconButton({
required this.count,
required this.isUpvoted,
this.onTap,
Key? key,
}) : super(key: key);
final int count;
final bool isUpvoted;
final VoidCallback? onTap;
@override
Widget build(BuildContext context) {
final l10n = ComponentLibraryLocalizations.of(context);
final theme = WonderTheme.of(context);
return CountIndicatorIconButton(
onTap: onTap,
tooltip: l10n.upvoteIconButtonTooltip,
iconData: Icons.arrow_upward_sharp,
iconColor: isUpvoted ? theme.votedButtonColor : theme.unvotedButtonColor,
count: count,
);
}
}

View File

@ -25,6 +25,22 @@ flutter:
assets:
- assets/
fonts:
- family: Fondamento
- family: Montserrat
fonts:
- asset: assets/Fondamento-Regular.ttf
- asset: assets/fonts/Montserrat-Regular.ttf
weight: 400
- asset: assets/fonts/Montserrat-Medium.ttf
weight: 500
- asset: assets/fonts/Montserrat-MediumItalic.ttf
weight: 500
style: italic
- asset: assets/fonts/Montserrat-SemiBold.ttf
weight: 600
- asset: assets/fonts/Montserrat-SemiBoldItalic.ttf
weight: 600
style: italic
- asset: assets/fonts/Montserrat-Bold.ttf
weight: 700
- asset: assets/fonts/Montserrat-BoldItalic.ttf
weight: 700
style: italic

View File

@ -0,0 +1 @@
include: package:flutter_lints/flutter.yaml

View File

@ -0,0 +1,6 @@
arb-dir: lib/src/l10n
template-arb-file: messages_id.arb
output-localization-file: landing_menu_localizations.dart
output-class: LandingMenuLocalizations
synthetic-package: false
nullable-getter: false

View File

@ -0,0 +1 @@
export 'src/landing_page.dart';

View File

@ -0,0 +1,175 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;
import 'landing_menu_localizations_en.dart';
import 'landing_menu_localizations_id.dart';
/// Callers can lookup localized strings with an instance of LandingMenuLocalizations
/// returned by `LandingMenuLocalizations.of(context)`.
///
/// Applications need to include `LandingMenuLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'l10n/landing_menu_localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: LandingMenuLocalizations.localizationsDelegates,
/// supportedLocales: LandingMenuLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
/// # Internationalization support.
/// flutter_localizations:
/// sdk: flutter
/// intl: any # Use the pinned version from flutter_localizations
///
/// # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, youll need to edit this
/// file.
///
/// First, open your projects ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// projects Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the LandingMenuLocalizations.supportedLocales
/// property.
abstract class LandingMenuLocalizations {
LandingMenuLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static LandingMenuLocalizations of(BuildContext context) {
return Localizations.of<LandingMenuLocalizations>(context, LandingMenuLocalizations)!;
}
static const LocalizationsDelegate<LandingMenuLocalizations> delegate = _LandingMenuLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
///
/// Returns a list of localizations delegates containing this delegate along with
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
/// and GlobalWidgetsLocalizations.delegate.
///
/// Additional delegates can be added by appending to this list in
/// MaterialApp. This list does not have to be used at all if a custom list
/// of delegates is preferred or required.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = <LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
];
/// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[
Locale('en'),
Locale('id')
];
/// No description provided for @dialogTitle.
///
/// In id, this message translates to:
/// **'Esqueci Minha Senha'**
String get dialogTitle;
/// No description provided for @emailTextFieldLabel.
///
/// In id, this message translates to:
/// **'Email'**
String get emailTextFieldLabel;
/// No description provided for @emailTextFieldEmptyErrorMessage.
///
/// In id, this message translates to:
/// **'Seu email não pode ser vazio.'**
String get emailTextFieldEmptyErrorMessage;
/// No description provided for @emailTextFieldInvalidErrorMessage.
///
/// In id, this message translates to:
/// **'Este email não é válido.'**
String get emailTextFieldInvalidErrorMessage;
/// No description provided for @emailRequestSuccessMessage.
///
/// In id, this message translates to:
/// **'Se este email estiver registrado em nossos servidores, um link será enviado para você com instruções sobre como resetar sua senha.'**
String get emailRequestSuccessMessage;
/// No description provided for @confirmButtonLabel.
///
/// In id, this message translates to:
/// **'Confirmar'**
String get confirmButtonLabel;
/// No description provided for @cancelButtonLabel.
///
/// In id, this message translates to:
/// **'Cancelar'**
String get cancelButtonLabel;
/// No description provided for @errorMessage.
///
/// In id, this message translates to:
/// **'Ocorreu um erro. Por favor, confira sua conexão com a internet.'**
String get errorMessage;
}
class _LandingMenuLocalizationsDelegate extends LocalizationsDelegate<LandingMenuLocalizations> {
const _LandingMenuLocalizationsDelegate();
@override
Future<LandingMenuLocalizations> load(Locale locale) {
return SynchronousFuture<LandingMenuLocalizations>(lookupLandingMenuLocalizations(locale));
}
@override
bool isSupported(Locale locale) => <String>['en', 'id'].contains(locale.languageCode);
@override
bool shouldReload(_LandingMenuLocalizationsDelegate old) => false;
}
LandingMenuLocalizations lookupLandingMenuLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en': return LandingMenuLocalizationsEn();
case 'id': return LandingMenuLocalizationsId();
}
throw FlutterError(
'LandingMenuLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.'
);
}

View File

@ -0,0 +1,30 @@
import 'landing_menu_localizations.dart';
/// The translations for English (`en`).
class LandingMenuLocalizationsEn extends LandingMenuLocalizations {
LandingMenuLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get dialogTitle => 'Forgot My Password';
@override
String get emailTextFieldLabel => 'Email';
@override
String get emailTextFieldEmptyErrorMessage => 'Your email can\'t be empty.';
@override
String get emailTextFieldInvalidErrorMessage => 'This email is not valid.';
@override
String get emailRequestSuccessMessage => 'If this email is registered in our systems, a link will be sent to you with instructions on how to reset your password.';
@override
String get confirmButtonLabel => 'Confirm';
@override
String get cancelButtonLabel => 'Cancel';
@override
String get errorMessage => 'There has been an error. Please, check your internet connection.';
}

View File

@ -0,0 +1,30 @@
import 'landing_menu_localizations.dart';
/// The translations for Indonesian (`id`).
class LandingMenuLocalizationsId extends LandingMenuLocalizations {
LandingMenuLocalizationsId([String locale = 'id']) : super(locale);
@override
String get dialogTitle => 'Esqueci Minha Senha';
@override
String get emailTextFieldLabel => 'Email';
@override
String get emailTextFieldEmptyErrorMessage => 'Seu email não pode ser vazio.';
@override
String get emailTextFieldInvalidErrorMessage => 'Este email não é válido.';
@override
String get emailRequestSuccessMessage => 'Se este email estiver registrado em nossos servidores, um link será enviado para você com instruções sobre como resetar sua senha.';
@override
String get confirmButtonLabel => 'Confirmar';
@override
String get cancelButtonLabel => 'Cancelar';
@override
String get errorMessage => 'Ocorreu um erro. Por favor, confira sua conexão com a internet.';
}

View File

@ -0,0 +1,10 @@
{
"dialogTitle": "Forgot My Password",
"emailTextFieldLabel": "Email",
"emailTextFieldEmptyErrorMessage": "Your email can't be empty.",
"emailTextFieldInvalidErrorMessage": "This email is not valid.",
"emailRequestSuccessMessage": "If this email is registered in our systems, a link will be sent to you with instructions on how to reset your password.",
"confirmButtonLabel": "Confirm",
"cancelButtonLabel": "Cancel",
"errorMessage": "There has been an error. Please, check your internet connection."
}

View File

@ -0,0 +1,10 @@
{
"dialogTitle": "Esqueci Minha Senha",
"emailTextFieldLabel": "Email",
"emailTextFieldEmptyErrorMessage": "Seu email não pode ser vazio.",
"emailTextFieldInvalidErrorMessage": "Este email não é válido.",
"emailRequestSuccessMessage": "Se este email estiver registrado em nossos servidores, um link será enviado para você com instruções sobre como resetar sua senha.",
"confirmButtonLabel": "Confirmar",
"cancelButtonLabel": "Cancelar",
"errorMessage": "Ocorreu um erro. Por favor, confira sua conexão com a internet."
}

View File

@ -0,0 +1,206 @@
import 'package:component_library/component_library.dart';
import 'package:flutter/material.dart';
import 'package:landing_menu/src/widgets/landing_app_bar.dart';
class LandingPage extends StatefulWidget {
const LandingPage({Key? key}) : super(key: key);
@override
State<LandingPage> createState() => _LandingPageState();
}
class _LandingPageState extends State<LandingPage> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
// TODO: check for new version of application
});
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
final theme = GolekTheme.of(context);
return Scaffold(
appBar: LandingAppBar(),
body: SafeArea(
child: Stack(
children: [
Container(
width: double.infinity,
height: 497,
decoration: BoxDecoration(
color: theme.primaryMainColor,
borderRadius: const BorderRadius.vertical(
bottom: Radius.circular(25),
),
),
),
Container(
padding: const EdgeInsets.only(
right: 20,
left: 20,
bottom: 80,
),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Image.asset(
'assets/images/truckershipper.png',
width: 300,
height: 200,
),
const SizedBox(height: 12),
Text(
'Cari, Muat, Jalan.\nPraktis kan ?',
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: theme.textStyle.copyWith(
fontSize: FontSize.style24,
color: theme.neutral10Color,
fontWeight: FontWeight.w600,
letterSpacing: 1,
),
),
const SizedBox(height: 21),
GestureDetector(
onTap: () async {},
child: Text(
'GolekTruk memberikan kebebasan\nberlogistik menggunakan budaya\nperusahaan sendiri.',
textAlign: TextAlign.center,
style: theme.textStyle.copyWith(
fontSize: FontSize.style14,
color: theme.neutral10Color,
fontWeight: FontWeight.w500,
),
),
),
SizedBox(height: 21),
Row(
children: [
CardProduct(
onClickInfo: () => {},
label: 'Cari Truk',
description: 'Pengirim Muatan',
assets: 'assets/images/box_shipper.png',
onTap: () {},
),
const SizedBox(width: 14),
CardProduct(
onClickInfo: () => {},
label: 'Cari Muatan',
description: 'Penyedia Angkutan',
assets: 'assets/images/truk_trucker.png',
onTap: () async {},
),
],
),
],
),
),
],
),
),
);
}
}
class CardProduct extends StatelessWidget {
final String assets;
final String label;
final String description;
final Function() onTap;
final Function() onClickInfo;
const CardProduct({
Key? key,
required this.assets,
required this.label,
required this.description,
required this.onTap,
required this.onClickInfo,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final theme = GolekTheme.of(context);
return Expanded(
child: Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: theme.neutral10Color,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Material(
borderRadius: BorderRadius.circular(10),
child: InkWell(
splashColor: theme.primaryMainColor,
onTap: onTap,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Align(
alignment: Alignment.topRight,
child: GestureDetector(
onTap: onClickInfo,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
Icons.info_outline,
color: theme.neutral70Color,
),
),
),
),
const SizedBox(height: 8),
Image(
image: AssetImage(assets),
width: 131,
height: 100,
fit: BoxFit.contain,
),
const SizedBox(height: 15),
Text(
label,
style: theme.textStyle.copyWith(
fontSize: FontSize.style15,
color: theme.neutral100Color,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 2),
Text(
description,
style: theme.textStyle.copyWith(
fontSize: FontSize.style12,
color: theme.neutral100Color,
),
),
const SizedBox(height: 14),
],
),
),
),
),
);
}
}

View File

@ -0,0 +1,63 @@
import 'package:component_library/component_library.dart';
import 'package:flutter/material.dart';
class LandingAppBar extends StatelessWidget with PreferredSizeWidget {
LandingAppBar({Key? key}) : super(key: key);
final LayerLink _link = LayerLink();
@override
Widget build(BuildContext context) {
final theme = GolekTheme.of(context);
return AppBar(
backgroundColor: theme.primaryMainColor,
actions: [
CompositedTransformTarget(
link: _link,
child: GestureDetector(
onTap: () {},
child: Container(
color: theme.primaryMainColor,
width: 60,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 4,
height: 4,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9999),
color: theme.neutral10Color,
),
),
const SizedBox(height: 4),
Container(
width: 4,
height: 4,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9999),
color: theme.neutral10Color,
),
),
const SizedBox(height: 4),
Container(
width: 4,
height: 4,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9999),
color: theme.neutral10Color,
),
),
],
),
),
),
),
],
);
}
@override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}

View File

@ -0,0 +1,488 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "47.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "4.7.0"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.1"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.9.0"
auto_size_text:
dependency: transitive
description:
name: auto_size_text
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
bloc:
dependency: transitive
description:
name: bloc
url: "https://pub.dartlang.org"
source: hosted
version: "8.1.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.16.0"
component_library:
dependency: "direct main"
description:
path: "../../component_library"
relative: true
source: path
version: "0.0.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
coverage:
dependency: transitive
description:
name: coverage
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.4"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_bloc:
dependency: "direct main"
description:
name: flutter_bloc
url: "https://pub.dartlang.org"
source: hosted
version: "8.1.1"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
flutter_localizations:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
flutter_svg:
dependency: transitive
description:
name: flutter_svg
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
form_fields:
dependency: "direct main"
description:
path: "../../form_fields"
relative: true
source: path
version: "1.0.0"
frontend_server_client:
dependency: transitive
description:
name: frontend_server_client
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.1"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.2"
intl:
dependency: transitive
description:
name: intl
url: "https://pub.dartlang.org"
source: hosted
version: "0.17.0"
io:
dependency: transitive
description:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.5"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.12"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
mime:
dependency: transitive
description:
name: mime
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
mocktail:
dependency: "direct dev"
description:
name: mocktail
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
nested:
dependency: transitive
description:
name: nested
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
node_preamble:
dependency: transitive
description:
name: node_preamble
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.2"
path_drawing:
dependency: transitive
description:
name: path_drawing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
path_parsing:
dependency: transitive
description:
name: path_parsing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.0"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1"
provider:
dependency: transitive
description:
name: provider
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.4"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
shelf_packages_handler:
dependency: transitive
description:
name: shelf_packages_handler
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
shelf_static:
dependency: transitive
description:
name: shelf_static
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_map_stack_trace:
dependency: transitive
description:
name: source_map_stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
source_maps:
dependency: transitive
description:
name: source_maps
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.11"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
test:
dependency: "direct dev"
description:
name: test
url: "https://pub.dartlang.org"
source: hosted
version: "1.21.4"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.12"
test_core:
dependency: transitive
description:
name: test_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.16"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
vm_service:
dependency: transitive
description:
name: vm_service
url: "https://pub.dartlang.org"
source: hosted
version: "9.4.0"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
webkit_inspection_protocol:
dependency: transitive
description:
name: webkit_inspection_protocol
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.0"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
sdks:
dart: ">=2.18.2 <3.0.0"
flutter: ">=2.11.0-0.1.pre"

View File

@ -0,0 +1,24 @@
name: landing_menu
publish_to: none
environment:
sdk: ">=2.14.0 <3.0.0"
dependencies:
component_library:
path: ../../component_library
flutter_bloc: ^8.0.1
flutter:
sdk: flutter
form_fields:
path: ../../form_fields
dev_dependencies:
flutter_test:
sdk: flutter
mocktail: 0.1.4
test: ^1.16.8
flutter_lints: ^1.0.4
flutter:
uses-material-design: true

View File

@ -0,0 +1,14 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Forgot my password', (WidgetTester tester) async {
// Build our app and trigger a frame.
});
}

View File

@ -427,6 +427,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "4.7.0"
landing_menu:
dependency: "direct main"
description:
path: "packages/features/landing_menu"
relative: true
source: path
version: "0.0.0"
lints:
dependency: transitive
description:

View File

@ -24,7 +24,8 @@ dependencies:
path: packages/component_library
subscription_menu:
path: packages/features/subscription_menu
landing_menu:
path: packages/features/landing_menu
dev_dependencies:
flutter_test:
sdk: flutter