feat: login view

This commit is contained in:
Prajna Prayoga 2024-02-07 14:44:40 +07:00
parent 0a347f5e6d
commit 9475767021
10 changed files with 318 additions and 7 deletions

View File

@ -1,17 +1,22 @@
import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/utils/size_config.dart'; import 'package:cims_apps/core/utils/size_config.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class ButtonBack extends StatelessWidget { class ButtonBack extends StatelessWidget {
const ButtonBack({super.key}); final EdgeInsets? margin;
const ButtonBack({super.key, this.margin});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return Container(
margin: margin ?? EdgeInsets.all(0),
width: SizeConfig.width * 0.1, width: SizeConfig.width * 0.1,
child: IconButton( child: IconButton(
style: IconButton.styleFrom( style: IconButton.styleFrom(
backgroundColor: Colors.white, backgroundColor: Colors.white,
shape: const CircleBorder() shape: const CircleBorder(
side: BorderSide(color: ColorPalette.slate200)
)
), ),
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);

View File

@ -95,6 +95,8 @@ class TextFormView extends StatelessWidget {
name, name,
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600,
color: ColorPalette.slate800
// color: ColorPalette.greyLight, // color: ColorPalette.greyLight,
), ),
), ),
@ -112,6 +114,8 @@ class TextFormView extends StatelessWidget {
name, name,
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600,
color: ColorPalette.slate800
), ),
) )
: const SizedBox(), : const SizedBox(),

View File

@ -73,7 +73,6 @@ class ColorPalette {
static const Color chathamsBlue = Color(0xFF285BB9); static const Color chathamsBlue = Color(0xFF285BB9);
static const Color background = Color(0xFFDADADA); static const Color background = Color(0xFFDADADA);
static const Color backgroundBlueLight = Color(0xFFEBF3FD); static const Color backgroundBlueLight = Color(0xFFEBF3FD);
static const Color slate500 = Color(0xFF64748B);
static const Color blue50 = Color(0xFFEFF6FF); static const Color blue50 = Color(0xFFEFF6FF);
static const Color blue200 = Color(0xFFBFDBFE); static const Color blue200 = Color(0xFFBFDBFE);
static const Color slate50 = Color(0xFFF8FAFC); static const Color slate50 = Color(0xFFF8FAFC);

View File

@ -0,0 +1,94 @@
import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/button/button_back.dart';
import 'package:cims_apps/application/component/button/button_view.dart';
import 'package:cims_apps/application/component/image/image_view.dart';
import 'package:cims_apps/application/component/text_form/text_form_view.dart';
import 'package:cims_apps/application/component/text_title/text_title.dart';
import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/auth/login/view/password_view.dart';
import 'package:cims_apps/features/auth/login/view/phone_number_view.dart';
import 'package:cims_apps/features/auth/login/view_model/login_view_model.dart';
import 'package:cims_apps/features/bottom_navigation_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
class LoginView extends StatefulWidget {
const LoginView({super.key});
@override
State<LoginView> createState() => _LoginViewState();
}
class _LoginViewState extends State<LoginView> {
int currentPage = 0;
PageController pageController = PageController(initialPage: 0);
TextEditingController phoneNumberController = TextEditingController();
TextEditingController passwordController = TextEditingController();
@override
void dispose() {
// TODO: implement dispose
pageController.dispose();
phoneNumberController.dispose();
passwordController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => LoginViewModel(),
child: WillPopScope(
onWillPop: () async {
if(currentPage == 1){
currentPage--;
pageController.jumpToPage(0);
return false;
}
return true;
},
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
toolbarHeight: 70,
backgroundColor: Colors.white,
surfaceTintColor: Colors.white,
automaticallyImplyLeading: false,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ButtonBack(),
const Text('Sign Up'),
SizedBox(
width: SizeConfig.width * 0.1,
)
],
),
shape: const RoundedRectangleBorder(
side: BorderSide(color: ColorPalette.slate200)
),
),
body: PageView(
controller: pageController,
children: [
PhoneNumberView(nextStep: nextStep, controller: phoneNumberController),
PasswordView(nextStep: nextStep, controller: passwordController)
],
),
),
),
);
}
void nextStep() {
if(pageController.page == 0){
currentPage++;
pageController.jumpToPage(1);
}else{
routePush(context, page: BottomNavigationView(), routeType: RouteType.pushRemove);
}
}
}

View File

@ -0,0 +1,80 @@
import 'package:cims_apps/application/component/button/button_view.dart';
import 'package:cims_apps/application/component/text_form/text_form_view.dart';
import 'package:cims_apps/application/component/text_title/text_title.dart';
import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/auth/login/view_model/login_view_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class PasswordView extends StatelessWidget {
final void Function() nextStep;
final TextEditingController controller;
const PasswordView({super.key, required this.nextStep, required this.controller});
@override
Widget build(BuildContext context) {
return Consumer<LoginViewModel>(
builder: (context, provider, child) {
return Container(
width: SizeConfig.width,
height: SizeConfig.height,
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const TextTitle(title: 'Enter your phone number', fontSize: 24),
SizedBox(
height: 24,
),
TextFormView(
name: 'Password',
ctrl: controller,
obscureText: !provider.showPassword,
prefix: SizedBox(
width: 16,
),
suffixIcon: GestureDetector(
onTap: () {
provider.changeShowPassword();
},
child: Icon(
provider.showPassword
? Icons.visibility_outlined
: Icons.visibility_off_outlined,
color: ColorPalette.greyDarker,
),
),
),
TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.all(0)
),
onPressed: () {
},
child: Text(
'Forget the password?',
style: TextStyle(
color: ColorPalette.primary,
),
)
),
SizedBox(
height: 16,
),
ButtonView(
name: 'Confirm',
heightWrapContent: true,
width: SizeConfig.width,
marginVertical: 0,
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
onPressed: nextStep,
)
],
),
);
}
);
}
}

View File

@ -0,0 +1,111 @@
import 'package:cims_apps/application/assets/path_assets.dart';
import 'package:cims_apps/application/component/button/button_view.dart';
import 'package:cims_apps/application/component/image/image_view.dart';
import 'package:cims_apps/application/component/text_form/text_form_view.dart';
import 'package:cims_apps/application/component/text_title/text_title.dart';
import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/utils/size_config.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class PhoneNumberView extends StatelessWidget {
final void Function() nextStep;
final TextEditingController controller;
const PhoneNumberView({super.key, required this.nextStep, required this.controller});
@override
Widget build(BuildContext context) {
return Container(
width: SizeConfig.width,
height: SizeConfig.height,
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const TextTitle(title: 'Enter your phone number', fontSize: 24),
SizedBox(
height: 24,
),
TextFormView(
name: 'Phone Number',
keyboardType: TextInputType.number,
ctrl: controller,
inputFormatters: [
FilteringTextInputFormatter.deny(RegExp(r'^0'))
],
prefixIcon: Container(
width: SizeConfig.width * .23,
padding:
const EdgeInsets.symmetric(horizontal: 16.0),
margin: const EdgeInsets.only(right: 16),
decoration: const BoxDecoration(
color: ColorPalette.grey,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8),
bottomLeft: Radius.circular(8),
)),
child: const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ImageView(
image: PathAssets.iconFlag,
fit: BoxFit.contain,
width: 24,
height: 24,
),
Text(
'+62',
style: TextStyle(
fontWeight: FontWeight.w600,
color: ColorPalette.slate800,
),
)
],
)),
validator: (value) {
if (value!.isEmpty) {
return 'Phone number must be filled';
} else {
return null;
}
},
),
SizedBox(
height: 32,
),
ButtonView(
name: 'Next',
heightWrapContent: true,
width: SizeConfig.width,
marginVertical: 0,
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
onPressed: nextStep,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Don't have an account yet?",
style: TextStyle(
color: ColorPalette.slate500,
),
),
TextButton(
onPressed: () {
},
child: Text(
'Sign Up',
style: TextStyle(
fontWeight: FontWeight.w600,
color: ColorPalette.primary
),
)
)
],
)
],
),
);
}
}

View File

@ -0,0 +1,10 @@
import 'package:flutter/foundation.dart';
class LoginViewModel extends ChangeNotifier {
bool showPassword = false;
void changeShowPassword() {
showPassword = !showPassword;
notifyListeners();
}
}

View File

@ -515,9 +515,15 @@ class _HomeViewState extends State<HomeView> {
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30), borderRadius: BorderRadius.circular(30),
color: ColorPalette.colorSwitchButtonActive color: ColorPalette.green100
),
child: Text(
article.type,
style: TextStyle(
fontWeight: FontWeight.w600,
color: ColorPalette.green500
),
), ),
child: Text(article.type),
), ),
], ],
) )

View File

@ -4,6 +4,7 @@ import 'package:cims_apps/application/component/image/image_view.dart';
import 'package:cims_apps/application/theme/color_palette.dart'; import 'package:cims_apps/application/theme/color_palette.dart';
import 'package:cims_apps/core/route/route.dart'; import 'package:cims_apps/core/route/route.dart';
import 'package:cims_apps/core/utils/size_config.dart'; import 'package:cims_apps/core/utils/size_config.dart';
import 'package:cims_apps/features/auth/login/view/login_view.dart';
import 'package:cims_apps/features/auth/registration/view/registration_view.dart'; import 'package:cims_apps/features/auth/registration/view/registration_view.dart';
import 'package:cims_apps/features/bottom_navigation_view.dart'; import 'package:cims_apps/features/bottom_navigation_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -70,7 +71,7 @@ class DashboardPublicView extends StatelessWidget {
width: SizeConfig.width * .43, width: SizeConfig.width * .43,
height: SizeConfig.height * .06, height: SizeConfig.height * .06,
onPressed: () { onPressed: () {
routePush(context, page: const BottomNavigationView()); routePush(context, page: const LoginView());
}, },
), ),
ButtonView( ButtonView(

View File

@ -28,6 +28,7 @@ class MyApp extends StatelessWidget {
titleTextStyle: TextStyle( titleTextStyle: TextStyle(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
fontFamily: 'Manrope',
color: ColorPalette.slate800, color: ColorPalette.slate800,
)), )),
fontFamily: 'Manrope', fontFamily: 'Manrope',