Skip to content

Instantly share code, notes, and snippets.

@plotsklapps
Last active September 23, 2023 14:57
Show Gist options
  • Select an option

  • Save plotsklapps/2a4366f027a4193fd9893fc1de372220 to your computer and use it in GitHub Desktop.

Select an option

Save plotsklapps/2a4366f027a4193fd9893fc1de372220 to your computer and use it in GitHub Desktop.
Flutter Fullstack #2

Flutter Fullstack #2

Created with <3 with dartpad.dev.

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
void main() {
runApp(const FlutterBankApp());
}
class FlutterBankApp extends StatelessWidget {
const FlutterBankApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
textTheme: GoogleFonts.poppinsTextTheme(
Theme.of(context).textTheme,
),
),
home: const FlutterBankSplash(),
);
}
}
class FlutterBankSplash extends StatelessWidget {
const FlutterBankSplash({super.key});
@override
Widget build(BuildContext context) {
// Future.delayed takes two parameters: a Duration object with is seconds
// property set to 2, and a callback. When the 2 seconds have ellapsed, it will call the callback. The callback has inside a trigger to perform a navigation
Future.delayed(const Duration(seconds: 2), () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const FlutterBankLogin();
}),
);
});
return const Scaffold(
backgroundColor: Utils.mainThemeColor,
body: Stack(
children: [
Center(
child: Icon(
Icons.savings,
size: 60.0,
color: Colors.white,
),
),
Center(
child: SizedBox(
height: 100.0,
width: 100.0,
child: CircularProgressIndicator(
strokeWidth: 8.0,
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
)),
],
),
);
}
}
class FlutterBankLogin extends StatefulWidget {
const FlutterBankLogin({super.key});
@override
State<FlutterBankLogin> createState() {
return _FlutterBankLoginState();
}
}
class _FlutterBankLoginState extends State<FlutterBankLogin> {
// At the top of the FlutterBankLoginState class, add two TextEditingController instances, one for each of our fields. The TextEditingController allows us to controller the actions on a TextField widget, get notifications on text field updates, set initial values, get its provided input, etc.
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
padding: const EdgeInsets.all(30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 80.0,
height: 80.0,
decoration: BoxDecoration(
border: Border.all(
color: Utils.mainThemeColor,
width: 7.0,
),
borderRadius: BorderRadius.circular(100.0),
),
child: const Icon(
Icons.savings,
size: 45.0,
color: Utils.mainThemeColor,
),
),
const SizedBox(height: 30.0),
const Text(
'Welcome to',
style: TextStyle(
color: Colors.grey,
fontSize: 15.0,
),
),
const Text(
'Flutter\nSavings Bank',
style: TextStyle(
color: Utils.mainThemeColor,
fontSize: 30.0,
),
),
Expanded(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
'Sign Into Your Bank Account',
style: TextStyle(
color: Colors.grey,
fontSize: 12.0,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 12.0),
Container(
padding: const EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.2),
borderRadius: BorderRadius.circular(50.0),
),
child: TextField(
onChanged: (text) {
setState(() {
// We use setState to update the state of the widget. In this case, we are updating the state of the emailController
emailController.text = text;
});
},
controller: emailController,
decoration: const InputDecoration(
prefixIcon: Icon(
Icons.email,
color: Utils.mainThemeColor,
),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.fromLTRB(15.0, 11.0, 15.0, 11.0),
hintText: 'Email Address',
),
style: const TextStyle(
fontSize: 16.0,
),
),
),
const SizedBox(height: 16.0),
Container(
padding: const EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.2),
borderRadius: BorderRadius.circular(50.0),
),
child: TextField(
onChanged: (text) {
setState(() {
// We use setState to update the state of the widget. In this case, we are updating the state of the passwordController
passwordController.text = text;
});
},
controller: passwordController,
obscureText: true,
decoration: const InputDecoration(
prefixIcon: Icon(
Icons.lock,
color: Utils.mainThemeColor,
),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding:
EdgeInsets.fromLTRB(20.0, 11.0, 15.0, 11.0),
hintText: 'Password',
),
style: const TextStyle(
fontSize: 16.0,
),
),
),
],
),
),
),
FlutterBankMainButton(
label: 'Sign In',
enabled: true,
onTap: () {},
),
const SizedBox(height: 16.0),
FlutterBankMainButton(
label: 'Register',
icon: Icons.account_circle,
enabled: true,
onTap: () {},
backgroundColor: Utils.mainThemeColor.withOpacity(0.1),
iconColor: Utils.mainThemeColor,
labelColor: Utils.mainThemeColor,
),
],
),
),
),
);
}
}
// Widgets
class FlutterBankMainButton extends StatelessWidget {
final Function? onTap;
final String? label;
final bool? enabled;
final IconData? icon;
final Color? backgroundColor;
final Color? iconColor;
final Color? labelColor;
const FlutterBankMainButton({
super.key,
this.onTap,
this.label,
this.enabled = true,
this.icon,
this.backgroundColor = Utils.mainThemeColor,
this.iconColor = Colors.white,
this.labelColor = Colors.white,
});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(50.0),
child: Material(
color:
enabled! ? backgroundColor : backgroundColor!.withOpacity(0.5),
child: InkWell(
// Assign a callback that wraps the trigger this widget's onTap event only if the enabled property is true, null otherwise.
onTap: enabled!
? () {
onTap!();
}
: null,
highlightColor: Colors.white.withOpacity(0.2),
splashColor: Colors.white.withOpacity(0.1),
child: Container(
padding: const EdgeInsets.all(15.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Visibility(
visible: icon != null,
child: Container(
margin: const EdgeInsets.only(right: 20.0),
child: Icon(
icon,
color: iconColor,
size: 20.0,
),
)),
Text(
label!,
textAlign: TextAlign.center,
style: TextStyle(
color: labelColor,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
),
),
],
);
}
}
class Utils {
static const Color mainThemeColor = Color(0xFF8700C3);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment