From 60febfa5c8eb6141d054fd74ecf6141197f916a2 Mon Sep 17 00:00:00 2001 From: sindhu Date: Sat, 15 Feb 2025 13:24:26 +0700 Subject: [PATCH] step 4 : slicing login screen --- images/vektoratas.png | Bin 0 -> 1729 bytes lib/app/constant.dart | 161 ++--------------- lib/app/route.dart | 13 ++ lib/main.dart | 3 +- lib/screen/login_screen.dart | 336 +++++++++++++++++++++++++++++++++++ pubspec.yaml | 1 + 6 files changed, 363 insertions(+), 151 deletions(-) create mode 100644 images/vektoratas.png create mode 100644 lib/screen/login_screen.dart diff --git a/images/vektoratas.png b/images/vektoratas.png new file mode 100644 index 0000000000000000000000000000000000000000..f4260354436083795994429a372ae1038f3827fe GIT binary patch literal 1729 zcmW-id0bOh7RTR9URItONRXg|1lbHAzS0(^qX9xA1Q7y3GROcvD4_5G5!oY@N21Y+ zSXNoY5D?i!py0}mv+JLhx%x!?HucxhHbhk^ct57S04KyOse#4qfa%OS1JEX3z@ zPRE^1UkfnCDPNnNNm+_Z5U(`;KWV9L{f~b>eU+u@S-16gm6iH_=Bczjc~gc0YQJPh zm(5uDy_U7FvmB>IiPZY-8(F~_PMglDz8U)p{};ECE(|vGxGq8SQ6TWE=acIlUVrVZ z7=CasjGDIY)&8F*IQypbc!EQx{fled#i~=D2rwC#>e%}poqiYFb0^o|bv%StQN(R+ zvsSwyz-WyBV_A3|8=V~CaE&A&`EhOWkB*kH{1iEEXR?~oL4*5P;m+6NZ@*$J)<2ai z^!kC=d(G!VRyb|#EBAv0pf`RQ3Lz5*ePPSkeSZ^xKe^B9s%VdVMK=Dv0H>;!YPy8RoiWt>+%Ao3N~8v<|C<>aMGme6|Hm%RtmXD~YbuN62jrv7x$wzVV`DZ6( z-neqyp2!#UBr~RgXh9i&?tU(wvqp}go*JWT+!0>Hc&^ZXO7(zMhee9DPbZ`7KRwmd zY5q&Lyy`}1PevL)_>cNaeYlrbLs9+s-hmUSI51DYQ)UFn@;&6X~@OFbyx*F66$-5(_*1sh? z_ogq?fFU0+M*}sPF$di^gkwrVj5GT)TQM%hg2_L!?C)AA$F4#6QR?!APsYdSsxp+7 zmfwX$?GodNEGGFf8`a~0<}~=|V@9hv2c*+rc!bgF!~qKpV9gVTsz8qQk%>W{5Rw$u ztTU4A+_rP>Dw+o3xg(3{^IM8HK4C$lblU#@yoM{L3@4ZaQuJZtz&U*5)58xL&+_Hi zd5Y}38c(dTW|>ROgsYgJnle~`Uc#JF3o)*g4rh;&uJ8qbEk*W?8gHer#%_>h`r7E0 zHO8UHcohla z34p>Mt(Y1R9H+bb7QnFDI|4f=?~AFX~pgvTA#d9u}v!nn*7yPYd~qN zl{DJ!%Q{MMjf_Op_=3Mr`7buF9@~Y_*}eoCKRjW%zqdP40JaYI3wnp62y6#K;7;0H zip|>&N#&gaTnI%Lc-)de+{+9PFJ>^aQF2)WP>P{sglB9oI6wrOiiTO4(GCjk0 zLyND{|A7Qr5}1J#ItEQLBT5?p)NPz34G?0AE2gl>6O=gm=$K1S5FNt`$|Md9bW)3+ z0PkY9@&$L}b$R~3XHdith generateRoute(RouteSettings settings) { @@ -16,6 +18,17 @@ class AppRoute { ); }); } + + // login screen + if (settings.name == loginRoute) { + return MaterialPageRoute(builder: (context) { + return MediaQuery( + data: MediaQuery.of(context) + .copyWith(textScaler: TextScaler.linear(1.0), padding: EdgeInsets.all(0)), + child: LoginScreen(), + ); + }); + } return MaterialPageRoute(builder: (context) { return MediaQuery( diff --git a/lib/main.dart b/lib/main.dart index e8d7a6d..550ba1b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -31,7 +31,8 @@ class MyApp extends StatelessWidget { }, ), debugShowCheckedModeBanner: false, - initialRoute: splashRoute, + // initialRoute: splashRoute, + initialRoute: loginRoute, onGenerateRoute: AppRoute.generateRoute, ); } diff --git a/lib/screen/login_screen.dart b/lib/screen/login_screen.dart new file mode 100644 index 0000000..1b5fa43 --- /dev/null +++ b/lib/screen/login_screen.dart @@ -0,0 +1,336 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; + +import '../app/constant.dart'; + +class LoginScreen extends HookConsumerWidget { + const LoginScreen({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [ + SystemUiOverlay.bottom, + ]); + + final usernameCtr = useTextEditingController( + text: "", + ); + + final passwordCtr = useTextEditingController( + text: "", + ); + + final hostCtr = useTextEditingController( + text: "", + ); + + return GestureDetector( + onTap: () { + FocusManager.instance.primaryFocus!.unfocus(); + }, + child: Scaffold( + resizeToAvoidBottomInset: true, + backgroundColor: Constant.textWhite, + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // atas + Image.asset( + 'images/vektoratas.png', + width: double.infinity, + fit: BoxFit.cover, + ), + + SizedBox( + height: Constant.getActualYPhone( + context: context, + y: 40, + ), + ), + // konten didalamnya + Padding( + padding: EdgeInsets.only( + left: Constant.getActualXPhone( + context: context, + x: 20, + ), + right: Constant.getActualXPhone( + context: context, + x: 20, + ), + ), + child: Text( + 'Selamat Datang', + style: Constant.title_700(context: context).copyWith( + color: Constant.textBlack, + ), + ), + ), + Padding( + padding: EdgeInsets.only( + left: Constant.getActualXPhone( + context: context, + x: 20, + ), + right: Constant.getActualXPhone( + context: context, + x: 20, + ), + ), + child: Text( + 'Silahkan masuk untuk mengakses akun Anda', + style: Constant.title_400(context: context).copyWith( + color: Constant.textBlack, + ), + ), + ), + + SizedBox( + height: Constant.getActualYPhone( + context: context, + y: 64, + ), + ), + + // inputan + Padding( + padding: EdgeInsets.only( + left: Constant.getActualXPhone( + context: context, + x: 20, + ), + right: Constant.getActualXPhone( + context: context, + x: 20, + ), + ), + child: Text( + 'Username', + style: Constant.title_400(context: context).copyWith( + color: Constant.inputanGrey, + ), + ), + ), + SizedBox( + height: Constant.getActualYPhone( + context: context, + y: 16, + ), + ), + Padding( + padding: EdgeInsets.only( + left: Constant.getActualXPhone( + context: context, + x: 20, + ), + right: Constant.getActualXPhone( + context: context, + x: 20, + ), + ), + child: TextField( + controller: usernameCtr, + onTap: () {}, + decoration: InputDecoration( + hintText: "Masukkan Username", + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide( + color: Colors.grey, + width: 1, + ), + ), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide( + color: Colors.blue, + width: 2, + ), + ), + ), + ), + ), + SizedBox( + height: Constant.getActualYPhone( + context: context, + y: 20, + ), + ), + Padding( + padding: EdgeInsets.only( + left: Constant.getActualXPhone( + context: context, + x: 20, + ), + right: Constant.getActualXPhone( + context: context, + x: 20, + ), + ), + child: Text( + 'Password', + style: Constant.title_400(context: context).copyWith( + color: Constant.inputanGrey, + ), + ), + ), + SizedBox( + height: Constant.getActualYPhone( + context: context, + y: 16, + ), + ), + Padding( + padding: EdgeInsets.only( + left: Constant.getActualXPhone( + context: context, + x: 20, + ), + right: Constant.getActualXPhone( + context: context, + x: 20, + ), + ), + child: TextField( + controller: passwordCtr, + obscureText: true, + onTap: () {}, + decoration: InputDecoration( + hintText: "Masukkan Password", + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide( + color: Colors.grey, + width: 1, + ), + ), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide( + color: Colors.blue, + width: 2, + ), + ), + ), + ), + ), + SizedBox( + height: Constant.getActualYPhone( + context: context, + y: 20, + ), + ), + Padding( + padding: EdgeInsets.only( + left: Constant.getActualXPhone( + context: context, + x: 20, + ), + right: Constant.getActualXPhone( + context: context, + x: 20, + ), + ), + child: Text( + 'Host', + style: Constant.title_400(context: context).copyWith( + color: Constant.inputanGrey, + ), + ), + ), + SizedBox( + height: Constant.getActualYPhone( + context: context, + y: 16, + ), + ), + Padding( + padding: EdgeInsets.only( + left: Constant.getActualXPhone( + context: context, + x: 20, + ), + right: Constant.getActualXPhone( + context: context, + x: 20, + ), + ), + child: TextField( + controller: hostCtr, + onTap: () {}, + decoration: InputDecoration( + hintText: "Masukkan Host", + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide( + color: Colors.grey, + width: 1, + ), + ), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide( + color: Colors.blue, + width: 2, + ), + ), + ), + ), + ), + SizedBox( + height: Constant.getActualYPhone( + context: context, + y: 64, + ), + ), + // inputan + + // button login + Padding( + padding: EdgeInsets.only( + left: Constant.getActualXPhone( + context: context, + x: 20, + ), + right: Constant.getActualXPhone( + context: context, + x: 20, + ), + ), + child: SizedBox( + width: double.infinity, + height: Constant.getActualYPhone( + context: context, + y: 48, + ), + child: ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: Constant.bgButton, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + elevation: 8, + shadowColor: Constant.bgButton.withOpacity(0.24), + ), + child: Text( + 'LOGIN', + style: Constant.titleButton500(context: context).copyWith( + color: Constant.textWhite, + ), + ), + ), + ), + ), + // konten didalamnya + + SizedBox( + height: Constant.getActualYPhone( + context: context, + y: 60, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 740d51f..d2b9a89 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -72,6 +72,7 @@ flutter: - images/splash.png - images/splashatas.png - images/splashbawah.png + - images/vektoratas.png # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images