git pull origin dev
This commit is contained in:
70
lib/application/component/list_tile/list_tile_view.dart
Normal file
70
lib/application/component/list_tile/list_tile_view.dart
Normal file
@@ -0,0 +1,70 @@
|
||||
import 'package:cims_apps/application/assets/path_assets.dart';
|
||||
import 'package:cims_apps/application/component/image/image_view.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
import 'package:cims_apps/core/utils/size_config.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ListTileView extends StatelessWidget {
|
||||
final String title;
|
||||
final VoidCallback? onPressed;
|
||||
final Widget? prefixIcon, suffixIcon;
|
||||
final Color? colorTitle;
|
||||
const ListTileView(
|
||||
{Key? key,
|
||||
required this.title,
|
||||
this.onPressed,
|
||||
this.prefixIcon,
|
||||
this.suffixIcon,
|
||||
this.colorTitle})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: SizeConfig.width,
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 8.0),
|
||||
margin: const EdgeInsets.symmetric(vertical: 16.0),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorPalette.blue50,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(
|
||||
color: ColorPalette.greyLights,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
prefixIcon ??
|
||||
const ImageView(
|
||||
image: PathAssets.iconChecklistOutlined,
|
||||
width: 38,
|
||||
height: 38,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 16,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorTitle ?? ColorPalette.slate500,
|
||||
),
|
||||
),
|
||||
),
|
||||
suffixIcon != null
|
||||
? IconButton(
|
||||
onPressed: onPressed,
|
||||
icon: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorPalette.primary,
|
||||
size: 20,
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cims_apps/application/component/custom_app_bar/custom_app_bar.dart';
|
||||
import 'package:cims_apps/application/component/otp/otp_viewmodel.dart';
|
||||
import 'package:cims_apps/application/component/text_caption/text_caption.dart';
|
||||
import 'package:cims_apps/application/theme/color_palette.dart';
|
||||
@@ -112,10 +113,8 @@ class OtpView extends StatelessWidget {
|
||||
create: (context) => OtpViewModel(),
|
||||
builder: (context, child) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(title),
|
||||
),
|
||||
body: Container(
|
||||
appBar: CustomAppBar(height: SizeConfig.height * .1, title: title),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child:
|
||||
Consumer<OtpViewModel>(builder: (context, provider, child) {
|
||||
|
||||
@@ -9,7 +9,7 @@ class ItemSelectForm {
|
||||
final String text;
|
||||
final String? description;
|
||||
final bool isOther;
|
||||
final String image;
|
||||
String image;
|
||||
|
||||
ItemSelectForm(
|
||||
this.key,
|
||||
@@ -25,7 +25,6 @@ class SelectFormView extends StatelessWidget {
|
||||
final String? hintText;
|
||||
final TextStyle? hintTextStyle;
|
||||
final TextEditingController? ctrl;
|
||||
final Widget? bottomSheetTitle;
|
||||
final List<ItemSelectForm> listItem;
|
||||
final ValueChanged<String> onSelect;
|
||||
final FormFieldValidator<String>? validator;
|
||||
@@ -37,7 +36,6 @@ class SelectFormView extends StatelessWidget {
|
||||
this.hintText,
|
||||
this.hintTextStyle,
|
||||
this.ctrl,
|
||||
this.bottomSheetTitle,
|
||||
required this.listItem,
|
||||
required this.onSelect,
|
||||
this.validator,
|
||||
@@ -56,48 +54,71 @@ class SelectFormView extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
builder: (BuildContext context) {
|
||||
ItemSelectForm? selectedForm;
|
||||
String? selectedKey;
|
||||
if (listItem.isNotEmpty) {
|
||||
var res = listItem.where((element) => element.key == selectedKey);
|
||||
if (res.isNotEmpty) {
|
||||
selectedForm = res.first;
|
||||
}
|
||||
}
|
||||
return StatefulBuilder(builder: (
|
||||
BuildContext context,
|
||||
StateSetter stateSetter,
|
||||
) {
|
||||
return Container(
|
||||
height: SizeConfig.height * .45,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(20),
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
bottomSheetTitle ?? Container(),
|
||||
// const SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
name,
|
||||
style: const TextStyle(
|
||||
color: ColorPalette.slate800,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
icon: const Icon(
|
||||
Icons.clear,
|
||||
size: 26,
|
||||
color: ColorPalette.greyBase,
|
||||
)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
children: [
|
||||
...listItem.map(
|
||||
(e) => Card(
|
||||
...listItem.map((e) {
|
||||
bool selected = e.text == ctrl?.text;
|
||||
return Card(
|
||||
elevation: 0,
|
||||
color: Colors.transparent,
|
||||
shape: const RoundedRectangleBorder(
|
||||
color: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
color: ColorPalette.greyBorder,
|
||||
color: selected
|
||||
? ColorPalette.primary
|
||||
: ColorPalette.greyBorder,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(12)),
|
||||
const BorderRadius.all(Radius.circular(12)),
|
||||
),
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
e.text,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: selected
|
||||
? ColorPalette.primary
|
||||
: ColorPalette.slate500),
|
||||
),
|
||||
subtitle: e.description != null
|
||||
? Text(
|
||||
@@ -106,37 +127,19 @@ class SelectFormView extends StatelessWidget {
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)
|
||||
: null,
|
||||
// trailing: const Icon(
|
||||
// Icons.check_circle,
|
||||
// color: ColorPalette.primary,
|
||||
// ),
|
||||
trailing: Radio(
|
||||
focusColor: ColorPalette.primary,
|
||||
activeColor: ColorPalette.primary,
|
||||
visualDensity: const VisualDensity(
|
||||
horizontal: VisualDensity.minimumDensity,
|
||||
vertical: VisualDensity.minimumDensity,
|
||||
),
|
||||
materialTapTargetSize:
|
||||
MaterialTapTargetSize.shrinkWrap,
|
||||
value: e.key,
|
||||
groupValue: selectedKey,
|
||||
onChanged: (value) {
|
||||
// selectedForm =
|
||||
// ItemSelectForm(e.key, e.text);
|
||||
// stateSetter(() {
|
||||
// selectedKey = selectedForm!.key;
|
||||
// });
|
||||
},
|
||||
),
|
||||
trailing: selected
|
||||
? const Icon(Icons.check_circle_rounded,
|
||||
color: ColorPalette.primary)
|
||||
: null,
|
||||
onTap: () {
|
||||
ctrl?.text = e.text;
|
||||
onSelect(e.key);
|
||||
Navigator.of(context).pop();
|
||||
stateSetter(() {
|
||||
ctrl?.text = e.text;
|
||||
onSelect(e.key);
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -145,7 +148,7 @@ class SelectFormView extends StatelessWidget {
|
||||
name: 'Select',
|
||||
marginVertical: 4.0,
|
||||
onPressed: () {
|
||||
// print('object $')
|
||||
Navigator.pop(context);
|
||||
},
|
||||
)
|
||||
],
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -11,13 +11,34 @@ import 'package:cims_apps/features/auth/registration/view/submission_data/submis
|
||||
import 'package:cims_apps/features/auth/registration/viewmodel/submission_data_viewmodel.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class DisplayPictureScreen extends StatelessWidget {
|
||||
class DisplayPictureScreen extends StatefulWidget {
|
||||
final String imagePath, content;
|
||||
|
||||
const DisplayPictureScreen(
|
||||
{super.key, required this.imagePath, required this.content});
|
||||
|
||||
@override
|
||||
State<DisplayPictureScreen> createState() => _DisplayPictureScreenState();
|
||||
}
|
||||
|
||||
class _DisplayPictureScreenState extends State<DisplayPictureScreen> {
|
||||
Future<void> saveData() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
if (widget.content == 'ktp') {
|
||||
prefs.setString('imagePath', widget.imagePath);
|
||||
} else {
|
||||
prefs.setString('imagePathSelfie', widget.imagePath);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
saveData();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List listIcons = [
|
||||
@@ -85,7 +106,7 @@ class DisplayPictureScreen extends StatelessWidget {
|
||||
SizedBox(
|
||||
width: SizeConfig.width,
|
||||
height: SizeConfig.height * .4,
|
||||
child: Image.file(File(imagePath))),
|
||||
child: Image.file(File(widget.imagePath))),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: Text(
|
||||
@@ -103,7 +124,8 @@ class DisplayPictureScreen extends StatelessWidget {
|
||||
runSpacing: 8,
|
||||
children: List.generate(4, (index) {
|
||||
List filteredList = listIcons
|
||||
.where((element) => element['key'] == content)
|
||||
.where(
|
||||
(element) => element['key'] == widget.content)
|
||||
.toList();
|
||||
final urlImg = filteredList[index]['urlImg'];
|
||||
final tag = filteredList[index]['tag'];
|
||||
@@ -162,10 +184,10 @@ class DisplayPictureScreen extends StatelessWidget {
|
||||
provider.initCamera().then((cameras) {
|
||||
routePush(context,
|
||||
page: TakePictureScreen(
|
||||
camera: content == 'ktp'
|
||||
camera: widget.content == 'ktp'
|
||||
? cameras[0]
|
||||
: cameras[1],
|
||||
takeContent: content,
|
||||
takeContent: widget.content,
|
||||
));
|
||||
});
|
||||
},
|
||||
|
||||
@@ -139,9 +139,9 @@ class TextFormView extends StatelessWidget {
|
||||
onTap: onTap,
|
||||
onEditingComplete: onSubmit,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
color: fontColorDisabled ?? Colors.black,
|
||||
color: fontColorDisabled ?? ColorPalette.slate500,
|
||||
),
|
||||
readOnly: readOnly,
|
||||
validator: validator,
|
||||
|
||||
Reference in New Issue
Block a user