1- change text form field code
2- app bar design 3- working on request gas refill screenmain_design2.0
parent
5ded8e4386
commit
3bdae42769
@ -0,0 +1,5 @@
|
||||
class Base {
|
||||
final String name, identifier;
|
||||
|
||||
const Base({this.name, this.identifier});
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:test_sa/extensions/context_extension.dart';
|
||||
import 'package:test_sa/extensions/int_extensions.dart';
|
||||
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
|
||||
|
||||
import '../app_style/app_color.dart';
|
||||
|
||||
class AppLoadingManager extends StatefulWidget {
|
||||
final bool isLoading;
|
||||
final bool isFailedLoading;
|
||||
final bool isNotPage;
|
||||
final int progress;
|
||||
final bool askOnBack;
|
||||
final int stateCode;
|
||||
final Future<void> Function() onRefresh;
|
||||
final Widget child;
|
||||
|
||||
const AppLoadingManager({
|
||||
Key key,
|
||||
@required this.isLoading,
|
||||
@required this.isFailedLoading,
|
||||
@required this.stateCode,
|
||||
@required this.onRefresh,
|
||||
@required this.child,
|
||||
this.progress,
|
||||
this.isNotPage = false,
|
||||
this.askOnBack = false,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<AppLoadingManager> createState() => _AppLoadingManagerState();
|
||||
}
|
||||
|
||||
class _AppLoadingManagerState extends State<AppLoadingManager> {
|
||||
@override
|
||||
void initState() {
|
||||
if (widget.onRefresh != null && widget.stateCode == null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
widget.onRefresh();
|
||||
});
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget placeHolder;
|
||||
// to load data if load not start
|
||||
if (widget.isLoading != true && widget.stateCode == null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
widget.onRefresh();
|
||||
});
|
||||
}
|
||||
|
||||
// if loading of still not start in loading (true or null)
|
||||
// return loading widget
|
||||
if (widget.isLoading != false || widget.stateCode == null) {
|
||||
placeHolder = Container(
|
||||
height: 60.toScreenHeight,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: context.isDark ? AppColor.neutral50 : Colors.white,
|
||||
),
|
||||
child: const AppLazyLoading(),
|
||||
);
|
||||
} else if (widget.isFailedLoading && !widget.isNotPage) {
|
||||
// if failed return failed widget
|
||||
placeHolder = Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text("Error Request Failed", style: Theme.of(context).textTheme.titleMedium),
|
||||
16.height,
|
||||
OutlinedButton(
|
||||
onPressed: widget.onRefresh,
|
||||
child: const Text("try again"),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// if load end successfully return loaded widget
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
await widget.onRefresh();
|
||||
},
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 400),
|
||||
child: placeHolder ?? widget.child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,139 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:test_sa/extensions/context_extension.dart';
|
||||
import 'package:test_sa/extensions/int_extensions.dart';
|
||||
import 'package:test_sa/models/enums/translation_keys.dart';
|
||||
import 'package:test_sa/new_views/common_widgets/app_loading_manager.dart';
|
||||
import 'package:test_sa/providers/loading_list_notifier.dart';
|
||||
|
||||
import '../../models/base.dart';
|
||||
import '../app_style/app_color.dart';
|
||||
|
||||
class SingleItemDropDownMenu<T extends Base, X extends LoadingListNotifier> extends StatefulWidget {
|
||||
final BuildContext context;
|
||||
final Function(T) onSelect;
|
||||
final T initialValue;
|
||||
final bool enabled;
|
||||
final TranslationKeys title;
|
||||
const SingleItemDropDownMenu({Key key, @required this.context, @required this.title, this.onSelect, this.initialValue, this.enabled = true}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<SingleItemDropDownMenu<T, X>> createState() => _SingleItemDropDownMenuState<T, X>();
|
||||
}
|
||||
|
||||
class _SingleItemDropDownMenuState<T extends Base, X extends LoadingListNotifier> extends State<SingleItemDropDownMenu<T, X>> {
|
||||
T _selectedItem;
|
||||
X provider;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
provider = Provider.of<X>(widget.context);
|
||||
if (widget.initialValue != null) {
|
||||
final result = provider.items?.where((element) {
|
||||
return element == widget.initialValue;
|
||||
});
|
||||
if (result.isNotEmpty) _selectedItem = result.first;
|
||||
if (widget.initialValue?.identifier ?? "" != _selectedItem?.identifier ?? "") {
|
||||
widget.onSelect(_selectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void setState(VoidCallback fn) {
|
||||
if (mounted) super.setState(fn);
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant SingleItemDropDownMenu<T, X> oldWidget) {
|
||||
if (widget.initialValue != null) {
|
||||
final result = provider.items?.where((element) {
|
||||
return element == widget.initialValue;
|
||||
});
|
||||
if (result.isNotEmpty) {
|
||||
_selectedItem = result.first;
|
||||
} else {
|
||||
_selectedItem = null;
|
||||
}
|
||||
if (widget.initialValue?.identifier ?? "" != _selectedItem?.identifier ?? "") {
|
||||
widget.onSelect(_selectedItem);
|
||||
}
|
||||
} else {
|
||||
_selectedItem = null;
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppLoadingManager(
|
||||
isLoading: provider.loading,
|
||||
isFailedLoading: provider.items == null,
|
||||
stateCode: provider.stateCode,
|
||||
onRefresh: () async {
|
||||
provider.reset();
|
||||
await provider.getDate();
|
||||
},
|
||||
child: Container(
|
||||
height: 60.toScreenHeight,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth),
|
||||
decoration: BoxDecoration(
|
||||
color: context.isDark ? AppColor.neutral50 : Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
|
||||
),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
const PositionedDirectional(end: 0, child: Icon(Icons.keyboard_arrow_down_rounded)),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
context.translate(widget.title),
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500),
|
||||
),
|
||||
DropdownButton<T>(
|
||||
value: _selectedItem,
|
||||
iconSize: 24,
|
||||
isDense: true,
|
||||
icon: const SizedBox.shrink(),
|
||||
elevation: 0,
|
||||
isExpanded: true,
|
||||
hint: Text(
|
||||
context.translate(TranslationKeys.select),
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
style: TextStyle(color: Theme.of(context).primaryColor),
|
||||
underline: const SizedBox.shrink(),
|
||||
onChanged: widget.enabled == false
|
||||
? null
|
||||
: (T newValue) {
|
||||
setState(() {
|
||||
_selectedItem = newValue;
|
||||
});
|
||||
widget.onSelect(newValue);
|
||||
},
|
||||
items: provider.items?.map<DropdownMenuItem<T>>((value) {
|
||||
return DropdownMenuItem<T>(
|
||||
value: value,
|
||||
child: Text(
|
||||
value?.name ?? "",
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
);
|
||||
})?.toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../../controllers/api_routes/api_manager.dart';
|
||||
import '../../controllers/api_routes/urls.dart';
|
||||
import '../../models/lookup.dart';
|
||||
import '../loading_list_notifier.dart';
|
||||
|
||||
class CylinderSizeProvider extends LoadingListNotifier<Lookup> {
|
||||
@override
|
||||
Future getDate() async {
|
||||
if (loading ?? false) return -2;
|
||||
loading = true;
|
||||
notifyListeners();
|
||||
try {
|
||||
Response response = await ApiManager.instance.get(URLs.getGasTypes);
|
||||
stateCode = response.statusCode;
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
// client's request was successfully received
|
||||
List categoriesListJson = json.decode(response.body)["data"];
|
||||
items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
|
||||
}
|
||||
loading = false;
|
||||
notifyListeners();
|
||||
return response.statusCode;
|
||||
} catch (error) {
|
||||
loading = false;
|
||||
stateCode = -1;
|
||||
notifyListeners();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../../controllers/api_routes/api_manager.dart';
|
||||
import '../../controllers/api_routes/urls.dart';
|
||||
import '../../models/lookup.dart';
|
||||
import '../loading_list_notifier.dart';
|
||||
|
||||
class CylinderTypesProvider extends LoadingListNotifier<Lookup> {
|
||||
@override
|
||||
Future getDate() async {
|
||||
if (loading ?? false) return -2;
|
||||
loading = true;
|
||||
notifyListeners();
|
||||
try {
|
||||
Response response = await ApiManager.instance.get(URLs.getGasTypes);
|
||||
stateCode = response.statusCode;
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
// client's request was successfully received
|
||||
List categoriesListJson = json.decode(response.body)["data"];
|
||||
items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
|
||||
}
|
||||
loading = false;
|
||||
notifyListeners();
|
||||
return response.statusCode;
|
||||
} catch (error) {
|
||||
loading = false;
|
||||
stateCode = -1;
|
||||
notifyListeners();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart';
|
||||
import 'package:test_sa/models/lookup.dart';
|
||||
import 'package:test_sa/providers/loading_list_notifier.dart';
|
||||
|
||||
import '../../controllers/api_routes/api_manager.dart';
|
||||
import '../../controllers/api_routes/urls.dart';
|
||||
|
||||
class GasTypesProvider extends LoadingListNotifier<Lookup> {
|
||||
@override
|
||||
Future getDate() async {
|
||||
if (loading ?? false) return -2;
|
||||
loading = true;
|
||||
notifyListeners();
|
||||
try {
|
||||
Response response = await ApiManager.instance.get(URLs.getGasTypes);
|
||||
stateCode = response.statusCode;
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
// client's request was successfully received
|
||||
List categoriesListJson = json.decode(response.body)["data"];
|
||||
items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
|
||||
}
|
||||
loading = false;
|
||||
notifyListeners();
|
||||
return response.statusCode;
|
||||
} catch (error) {
|
||||
loading = false;
|
||||
stateCode = -1;
|
||||
notifyListeners();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:test_sa/models/base.dart';
|
||||
|
||||
abstract class LoadingListNotifier<T extends Base> extends ChangeNotifier {
|
||||
int stateCode;
|
||||
|
||||
List<T> items = [];
|
||||
|
||||
bool _loading = false;
|
||||
|
||||
bool get loading => _loading;
|
||||
|
||||
set loading(bool value) {
|
||||
_loading = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
items = null;
|
||||
_loading = null;
|
||||
stateCode = null;
|
||||
}
|
||||
|
||||
Future getDate();
|
||||
}
|
||||
Loading…
Reference in New Issue