feat: set pin page
This commit is contained in:
parent
5cb76fca7f
commit
afc2bd3cc9
BIN
assets/icons/icon-lock.png
Normal file
BIN
assets/icons/icon-lock.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
|
@ -39,6 +39,7 @@ class PathAssets {
|
||||||
static const String iconCreatePlan = 'assets/icons/icon-create-plan.png';
|
static const String iconCreatePlan = 'assets/icons/icon-create-plan.png';
|
||||||
static const String iconChecklistOutlined =
|
static const String iconChecklistOutlined =
|
||||||
'assets/icons/icon-ceklis-outline.png';
|
'assets/icons/icon-ceklis-outline.png';
|
||||||
|
static const String iconLock = 'assets/icons/icon-lock.png';
|
||||||
|
|
||||||
/// IMAGE
|
/// IMAGE
|
||||||
static const String imgSplashLogo = 'assets/images/splash-logo.png';
|
static const String imgSplashLogo = 'assets/images/splash-logo.png';
|
||||||
|
|
135
lib/application/component/set_pin_view/set_pin_view.dart
Normal file
135
lib/application/component/set_pin_view/set_pin_view.dart
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
import 'package:cims_apps/application/assets/path_assets.dart';
|
||||||
|
import 'package:cims_apps/application/component/custom_app_bar/custom_app_bar.dart';
|
||||||
|
import 'package:cims_apps/application/component/image/image_view.dart';
|
||||||
|
import 'package:cims_apps/application/component/set_pin_view/set_pin_viewmodel.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/registration/view/registration_success_view.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:pinput/pinput.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class SetPinView extends StatelessWidget {
|
||||||
|
final String currentPin;
|
||||||
|
final void Function(BuildContext context, String pin) submitPin;
|
||||||
|
|
||||||
|
const SetPinView({
|
||||||
|
Key? key,
|
||||||
|
required this.currentPin,
|
||||||
|
required this.submitPin,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
Widget _stepItem({bool isCurrentStep = false, bool isDone = false}) {
|
||||||
|
return Container(
|
||||||
|
margin:
|
||||||
|
const EdgeInsets.only(right: 4.0, left: 4.0, top: 16.0, bottom: 40.0),
|
||||||
|
height: 6,
|
||||||
|
width: SizeConfig.width * .08,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isCurrentStep || isDone
|
||||||
|
? ColorPalette.primary
|
||||||
|
: ColorPalette.greyBorderNeutrals,
|
||||||
|
borderRadius: BorderRadius.circular(50),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
final pinInputController = TextEditingController();
|
||||||
|
const pinInputLength = 6;
|
||||||
|
const defaultPinTheme = PinTheme(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 4.0, vertical: 16.0),
|
||||||
|
textStyle: TextStyle(
|
||||||
|
fontSize: 22,
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(),
|
||||||
|
);
|
||||||
|
|
||||||
|
final pInputFocusNode = FocusNode();
|
||||||
|
|
||||||
|
final focusedPinTheme = defaultPinTheme.copyWith(
|
||||||
|
decoration: defaultPinTheme.decoration?.copyWith(),
|
||||||
|
);
|
||||||
|
|
||||||
|
final submittedPinTheme = defaultPinTheme.copyWith(
|
||||||
|
decoration: defaultPinTheme.decoration?.copyWith(),
|
||||||
|
);
|
||||||
|
final followingPinTheme = defaultPinTheme.copyWith(
|
||||||
|
width: 13,
|
||||||
|
height: 13,
|
||||||
|
textStyle: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: Color.fromRGBO(30, 60, 87, 1),
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
decoration: defaultPinTheme.decoration?.copyWith(
|
||||||
|
color: ColorPalette.white,
|
||||||
|
border: Border.all(color: ColorPalette.slate300),
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return ChangeNotifierProvider(
|
||||||
|
create: (context) => SetPinViewModel(),
|
||||||
|
builder: (context, child) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: CustomAppBar(
|
||||||
|
height: SizeConfig.height * .1, title: 'Registration'),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: Consumer<SetPinViewModel>(
|
||||||
|
builder: (context, provider, child) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: List.generate(
|
||||||
|
9,
|
||||||
|
(index) => _stepItem(isCurrentStep: true, isDone: true),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ImageView(
|
||||||
|
image: PathAssets.iconLock,
|
||||||
|
width: SizeConfig.width * .15,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
!provider.isPinCompleted
|
||||||
|
? 'Set your PIN'
|
||||||
|
: 'Confirm your PIN',
|
||||||
|
style: textTheme.headlineLarge,
|
||||||
|
),
|
||||||
|
Pinput(
|
||||||
|
onCompleted: (pin) {
|
||||||
|
if (!provider.isPinCompleted) {
|
||||||
|
provider.changePin();
|
||||||
|
pinInputController.clear();
|
||||||
|
} else {
|
||||||
|
routePush(context,
|
||||||
|
routeType: RouteType.pushReplace,
|
||||||
|
page: const RegistrationSuccessView());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
obscureText: true,
|
||||||
|
autofocus: true,
|
||||||
|
isCursorAnimationEnabled: false,
|
||||||
|
length: pinInputLength,
|
||||||
|
controller: pinInputController,
|
||||||
|
defaultPinTheme: defaultPinTheme,
|
||||||
|
focusNode: pInputFocusNode,
|
||||||
|
focusedPinTheme: focusedPinTheme,
|
||||||
|
submittedPinTheme: submittedPinTheme,
|
||||||
|
followingPinTheme: followingPinTheme,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SetPinViewModel extends ChangeNotifier {
|
||||||
|
bool isPinCompleted = false;
|
||||||
|
void changePin() {
|
||||||
|
isPinCompleted = !isPinCompleted;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:cims_apps/application/component/custom_app_bar/custom_app_bar.dart';
|
import 'package:cims_apps/application/component/custom_app_bar/custom_app_bar.dart';
|
||||||
import 'package:cims_apps/application/component/button/button_view.dart';
|
import 'package:cims_apps/application/component/button/button_view.dart';
|
||||||
|
import 'package:cims_apps/application/component/set_pin_view/set_pin_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/features/auth/registration/view/submission_data/submission_parent.dart';
|
|
||||||
import 'package:cims_apps/features/auth/registration/viewmodel/submission_data_viewmodel.dart';
|
import 'package:cims_apps/features/auth/registration/viewmodel/submission_data_viewmodel.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -90,7 +90,10 @@ class TermsAndConditionView extends StatelessWidget {
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
provider.nextSubmission(context);
|
provider.nextSubmission(context);
|
||||||
routePush(context,
|
routePush(context,
|
||||||
page: const SubmissionParent());
|
page: SetPinView(
|
||||||
|
currentPin: '',
|
||||||
|
submitPin: (context, pin) {},
|
||||||
|
));
|
||||||
},
|
},
|
||||||
marginVertical: 16))
|
marginVertical: 16))
|
||||||
],
|
],
|
||||||
|
|
|
@ -33,6 +33,38 @@ class MyApp extends StatelessWidget {
|
||||||
)),
|
)),
|
||||||
fontFamily: 'Manrope',
|
fontFamily: 'Manrope',
|
||||||
scaffoldBackgroundColor: Colors.white,
|
scaffoldBackgroundColor: Colors.white,
|
||||||
|
textTheme: const TextTheme(
|
||||||
|
headlineSmall: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: ColorPalette.slate800,
|
||||||
|
),
|
||||||
|
headlineLarge: TextStyle(
|
||||||
|
fontSize: 28,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: ColorPalette.slate800,
|
||||||
|
),
|
||||||
|
displayMedium: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: ColorPalette.slate800,
|
||||||
|
),
|
||||||
|
displayLarge: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: ColorPalette.slate800,
|
||||||
|
),
|
||||||
|
bodyMedium: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: ColorPalette.slate500,
|
||||||
|
),
|
||||||
|
bodyLarge: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: ColorPalette.slate500,
|
||||||
|
),
|
||||||
|
),
|
||||||
colorScheme: const ColorScheme.light().copyWith(
|
colorScheme: const ColorScheme.light().copyWith(
|
||||||
primary: const Color(0xff2563EB),
|
primary: const Color(0xff2563EB),
|
||||||
onPrimary: const Color(0xFFFF9130),
|
onPrimary: const Color(0xFFFF9130),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user