first commit

This commit is contained in:
2026-02-07 15:57:09 +07:00
commit 157096f164
1153 changed files with 415766 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
class UserRoleListModelNew {
final num? id;
final int? businessId;
final int? activeBranchId;
final int? branchId;
final String? email;
final String? name;
final String? role;
final String? phone;
final String? image;
final String? lang;
final num? isVerified;
final Map<String, Map<String, String>> visibility;
final Branch? branch;
UserRoleListModelNew({
this.id,
this.businessId,
this.activeBranchId,
this.branchId,
this.email,
this.name,
this.role,
this.phone,
this.image,
this.lang,
this.isVerified,
required this.visibility,
this.branch,
});
factory UserRoleListModelNew.fromJson(Map<String, dynamic> json) {
final rawVisibility = json['visibility'];
Map<String, Map<String, String>> parsedVisibility = {};
if (rawVisibility is Map<String, dynamic>) {
parsedVisibility = rawVisibility.map((moduleKey, perms) {
if (perms is Map<String, dynamic>) {
return MapEntry(
moduleKey,
perms.map((permKey, value) => MapEntry(permKey, value.toString())),
);
}
return MapEntry(moduleKey, <String, String>{});
});
}
return UserRoleListModelNew(
id: json['id'],
businessId: json['business_id'],
activeBranchId: json['active_branch_id'],
branchId: json['branch_id'],
email: json['email'],
name: json['name'],
role: json['role'],
phone: json['phone'],
image: json['image'],
lang: json['lang'],
isVerified: json['is_verified'],
visibility: parsedVisibility,
branch: json['branch'] != null ? Branch.fromJson(json['branch']) : null,
);
}
List<String> getAllPermissions() {
final List<String> permissions = [];
visibility.forEach((module, perms) {
perms.forEach((action, value) {
if (value == "1") {
permissions.add('$module.$action');
}
// permissions.add('$module.$action');
});
});
return permissions;
}
}
class Branch {
Branch({
this.id,
this.name,
});
Branch.fromJson(dynamic json) {
id = json['id'];
name = json['name'];
}
num? id;
String? name;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['name'] = name;
return map;
}
}

View File

@@ -0,0 +1,7 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../Model/user_role_model_new.dart';
import '../Repo/user_role_repo.dart';
UserRoleRepo repo = UserRoleRepo();
final userRoleProvider = FutureProvider<List<UserRoleListModelNew>>((ref) => repo.fetchAllUsers());

View File

@@ -0,0 +1,185 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http;
import 'package:nb_utils/nb_utils.dart';
import '../../../Const/api_config.dart';
import '../../../Repository/constant_functions.dart';
import '../../../core/constant_variables/local_data_saving_keys.dart';
import '../../../http_client/custome_http_client.dart';
import '../../../http_client/customer_http_client_get.dart';
import '../Model/user_role_model_new.dart';
class UserRoleRepo {
Future<List<UserRoleListModelNew>> fetchAllUsers() async {
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
final uri = Uri.parse('${APIConfig.url}/users');
final response = await clientGet.get(url: uri);
if (response.statusCode == 200) {
final Map<String, dynamic> parsedData = jsonDecode(response.body);
final List<dynamic> userList = parsedData['data'] ?? [];
return userList.map((user) => UserRoleListModelNew.fromJson(user)).toList();
} else {
throw Exception('Failed to fetch users: ${response.statusCode}');
}
}
Future<void> addUser({
required WidgetRef ref,
required BuildContext context,
required String name,
required String email,
required String password,
String? branchId,
required Map<String, Map<String, String>> visibility,
}) async {
final uri = Uri.parse('${APIConfig.url}/users');
CustomHttpClient customHttpClient = CustomHttpClient(client: http.Client(), ref: ref, context: context);
var request = http.MultipartRequest('POST', uri)
..headers['Accept'] = 'application/json'
..headers['Authorization'] = await getAuthToken();
request.fields.addAll({
"name": name,
"email": email,
"password": password,
});
if (branchId != null) {
request.fields['branch_id'] = branchId;
}
visibility.forEach((key, perm) {
perm.forEach((action, value) {
if (value != null) {
request.fields['visibility[$key][$action]'] = value;
}
});
});
final response = await customHttpClient.uploadFile(
url: uri,
fields: request.fields,
);
final responseData = await response.stream.bytesToString();
final parsedData = jsonDecode(responseData);
print(response.statusCode);
print(parsedData);
EasyLoading.dismiss();
if (response.statusCode == 200) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Added successful!')));
} else {
EasyLoading.dismiss();
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('User creation failed: ${parsedData['message']}')));
}
}
Future<void> updateUser({
required WidgetRef ref,
required BuildContext context,
required String name,
required String email,
String? password,
String? branchId,
required String userId,
required Map<String, Map<String, String>> visibility,
}) async {
final uri = Uri.parse('${APIConfig.url}/users/$userId');
CustomHttpClient customHttpClient = CustomHttpClient(
client: http.Client(),
ref: ref,
context: context,
);
var request = http.MultipartRequest('POST', uri)
..headers['Accept'] = 'application/json'
..headers['Authorization'] = await getAuthToken();
request.fields.addAll({
"name": name,
"email": email,
"_method": 'put',
});
if (branchId != null) {
request.fields['branch_id'] = branchId;
}
if (password != null) {
request.fields['password'] = password;
}
// Add visibility fields
visibility.forEach((key, perm) {
perm.forEach((action, value) {
if (value != null) {
request.fields['visibility[$key][$action]'] = value;
}
});
});
final response = await customHttpClient.uploadFile(
url: uri,
fields: request.fields,
);
final responseData = await response.stream.bytesToString();
final parsedData = jsonDecode(responseData);
EasyLoading.dismiss();
if (response.statusCode == 200) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Update successful!')),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('User update failed: ${parsedData['message']}')),
);
}
}
Future<bool> deleteUser({
required String id,
required BuildContext context,
required WidgetRef ref,
}) async {
EasyLoading.show(status: 'Processing');
final prefs = await SharedPreferences.getInstance();
String token = prefs.getString(LocalDataBaseSavingKey.tokenKey) ?? '';
final url = Uri.parse('${APIConfig.url}/users/$id');
final headers = {
'Accept': 'application/json',
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
};
try {
CustomHttpClient customHttpClient = CustomHttpClient(ref: ref, context: context, client: http.Client());
var response = await customHttpClient.delete(
url: url,
headers: headers,
);
EasyLoading.dismiss();
print(response.statusCode);
if (response.statusCode == 200) {
return true;
} else {
var data = jsonDecode(response.body);
EasyLoading.showError(data['message'] ?? 'Failed to delete');
print(data['message']);
return false;
}
} catch (e) {
EasyLoading.dismiss();
EasyLoading.showError('Error: ${e.toString()}');
print(e.toString());
return false;
}
}
}

View File

@@ -0,0 +1,719 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mobile_pos/constant.dart';
import 'package:mobile_pos/generated/l10n.dart' as l;
import '../../Provider/profile_provider.dart';
import '../branch/model/branch_list_model.dart';
import '../branch/provider/branch_list_provider.dart';
import 'Model/user_role_model_new.dart';
import '../../service/check_user_role_permission_provider.dart';
import 'Provider/user_role_provider.dart';
import 'Repo/user_role_repo.dart';
class AddUserRoleScreen extends ConsumerStatefulWidget {
const AddUserRoleScreen({
super.key,
this.userRole,
});
final UserRoleListModelNew? userRole;
@override
_AddUserRoleScreenState createState() => _AddUserRoleScreenState();
}
class _AddUserRoleScreenState extends ConsumerState<AddUserRoleScreen> {
GlobalKey<FormState> globalKey = GlobalKey<FormState>();
bool _selectAll = false;
bool validateAndSave() {
final form = globalKey.currentState;
if (form!.validate()) {
form.save();
return true;
}
return false;
}
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
TextEditingController confirmPasswordController = TextEditingController();
TextEditingController titleController = TextEditingController();
Map<String, Permission> selectedPermissions = {};
@override
void initState() {
super.initState();
if (widget.userRole != null) {
emailController.text = widget.userRole!.email ?? '';
titleController.text = widget.userRole!.name ?? '';
// selectedBranch = widget.userRole.branchId ?? '';
selectedPermissions = widget.userRole!.visibility.map((key, value) {
return MapEntry(
key,
Permission(
read: value['read'],
create: value['create'],
update: value['update'],
delete: value['delete'],
price: value['price'],
));
});
}
}
bool _obscureText = true;
void _togglePasswordVisibility() {
setState(() {
_obscureText = !_obscureText;
});
}
BranchData? selectedBranch;
bool _branchInitialized = false;
@override
Widget build(BuildContext context) {
final _lang = l.S.of(context);
final modules = _basePermissions.modules;
final branchList = ref.watch(branchListProvider);
final businessInfo = ref.watch(businessInfoProvider);
final keys = modules.keys.toList(growable: false);
final theme = Theme.of(context);
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(widget.userRole != null ? _lang.updateRole : _lang.addRole),
centerTitle: true,
iconTheme: const IconThemeData(color: Colors.black),
elevation: 0.0,
bottom: PreferredSize(
preferredSize: const Size.fromHeight(1),
child: Container(
color: Color(0xFFE8E9F2),
height: 1,
),
),
),
body: businessInfo.when(data: (infoSnap) {
return SingleChildScrollView(
child: Form(
key: globalKey,
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Column(
children: [
if ((infoSnap.data?.addons?.multiBranchAddon == true) &&
(infoSnap.data?.enrolledPlan?.allowMultibranch == 1) &&
(infoSnap.data?.user?.activeBranch == null)) ...{
branchList.when(
data: (snapshot) {
if (widget.userRole != null && !_branchInitialized) {
final branchId = widget.userRole!.branchId;
try {
selectedBranch = snapshot.data!.firstWhere((branch) => branch.id == branchId);
} catch (e) {
selectedBranch = null;
}
_branchInitialized = true;
}
return DropdownButtonFormField<BranchData?>(
value: selectedBranch,
decoration: InputDecoration(
labelText: _lang.branch,
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
),
items: [
DropdownMenuItem<BranchData?>(
value: null,
child: Text(
_lang.branchList,
style: theme.textTheme.bodyMedium?.copyWith(
color: kTitleColor,
fontSize: 16,
fontWeight: FontWeight.w400,
),
),
),
...?snapshot.data?.map((branch) {
return DropdownMenuItem<BranchData?>(
value: branch,
child: Text(
branch.name ?? 'Unnamed',
style: theme.textTheme.bodyMedium?.copyWith(
color: kTitleColor,
fontSize: 16,
fontWeight: FontWeight.w400,
),
),
);
}).toList(),
],
onChanged: (value) {
setState(() {
selectedBranch = value;
print('---------------------------->${selectedBranch?.id ?? ''}');
});
},
);
},
error: (e, stack) => Center(child: Text(e.toString())),
loading: () => const Center(child: LinearProgressIndicator()),
),
SizedBox(height: 24),
},
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Name cannot be empty';
}
return null;
},
controller: titleController,
decoration: InputDecoration(
labelText: _lang.name,
hintText: _lang.enterUserName,
border: OutlineInputBorder(),
),
),
SizedBox(height: 24),
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return _lang.emailCannotBeEmpty;
} else if (!value.contains('@')) {
return _lang.pleaseEnterAValidEmail;
}
return null;
},
controller: emailController,
decoration: InputDecoration(
labelText: _lang.email,
hintText: _lang.enterYourEmailAddress,
border: OutlineInputBorder(),
),
),
SizedBox(height: 24),
TextFormField(
obscureText: _obscureText,
controller: passwordController,
validator: (value) {
if (widget.userRole != null) {
return null;
}
if (value == null || value.isEmpty) {
return _lang.passwordCannotBeEmpty;
} else if (value.length < 4) {
return _lang.pleaseEnterABiggerPassword;
}
return null;
},
decoration: InputDecoration(
labelText: _lang.password,
hintText: _lang.enterYourPassword,
border: const OutlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(
_obscureText ? Icons.visibility_off : Icons.visibility,
color: Color(0xff7B7C84),
),
onPressed: _togglePasswordVisibility,
),
),
),
],
),
),
/// Select All Checkbox
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Checkbox(
activeColor: kMainColor,
side: BorderSide(color: Color(0xffA3A3A3)),
value: _selectAll,
onChanged: (bool? value) {
if (value != null) {
setState(() {
_selectAll = value;
_toggleAllPermissions(value);
});
}
},
visualDensity: VisualDensity.compact,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
RichText(
text: TextSpan(
text: _lang.selectAll,
style: theme.textTheme.bodyMedium?.copyWith(color: kGreyTextColor, fontSize: 16),
recognizer: TapGestureRecognizer()
..onTap = () {
setState(() {
_selectAll = !_selectAll;
_toggleAllPermissions(_selectAll);
});
},
),
),
],
),
),
/// Permissions Table
LayoutBuilder(
builder: (context, constraints) {
return FittedBox(
child: DataTable(
headingRowColor: WidgetStateProperty.all(Color(0xffF7F7F7)),
columnSpacing: 16,
border: const TableBorder(
verticalInside: BorderSide(color: Color(0xffE6E6E6)),
),
headingTextStyle: theme.textTheme.titleSmall?.copyWith(fontWeight: FontWeight.bold),
columns: [
DataColumn(label: Text(_lang.sNo)),
DataColumn(label: Text(_lang.feature)),
DataColumn(label: Text(_lang.read)),
DataColumn(label: Text(_lang.create)),
DataColumn(label: Text(_lang.update)),
DataColumn(label: Text(_lang.update)),
DataColumn(label: Text(_lang.viewPrice)),
],
rows: List<DataRow>.generate(keys.length, (index) {
final key = keys[index];
final perm = selectedPermissions[key] ?? modules[key];
return DataRow(cells: [
DataCell(Text('${index + 1}')),
DataCell(
Text(permissionDisplayTitles[key] ?? key,
style: theme.textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w600)),
),
_buildCheckboxCell(
value: perm?.read,
onChanged: (v) => _togglePermission(key, 'read', v),
),
_buildCheckboxCell(
value: perm?.create,
onChanged: (v) => _togglePermission(key, 'create', v),
),
_buildCheckboxCell(
value: perm?.update,
onChanged: (v) => _togglePermission(key, 'update', v),
),
_buildCheckboxCell(
value: perm?.delete,
onChanged: (v) => _togglePermission(key, 'delete', v),
),
_buildCheckboxCell(
value: perm?.price,
onChanged: (v) => _togglePermission(key, 'price', v),
),
]);
}),
),
);
},
)
],
),
),
);
}, error: (e, stack) {
return Text(e.toString());
}, loading: () {
return const Center(child: CircularProgressIndicator());
}),
bottomNavigationBar: Padding(
padding: const EdgeInsets.all(10.0),
child: ElevatedButton(
// onPressed: _createUserRole,
onPressed: () async {
print('--------------------------->>>>${selectedBranch?.id}');
if (validateAndSave()) {
UserRoleRepo repo = UserRoleRepo();
if (selectedPermissions.isEmpty) {
selectedPermissions = _basePermissions.modules.map((key, perm) {
return MapEntry(
key,
Permission(
read: perm.read != null ? "0" : null,
create: perm.create != null ? "0" : null,
update: perm.update != null ? "0" : null,
delete: perm.delete != null ? "0" : null,
price: perm.price != null ? "0" : null,
));
});
}
final visibilityMap = selectedPermissions.map((key, perm) {
final Map<String, String> permissionMap = {};
if (perm.read != null) {
permissionMap["read"] = perm.read ?? "0";
}
if (perm.create != null) {
permissionMap["create"] = perm.create ?? "0";
}
if (perm.update != null) {
permissionMap["update"] = perm.update ?? "0";
}
if (perm.delete != null) {
permissionMap["delete"] = perm.delete ?? "0";
}
if (perm.price != null) {
permissionMap["price"] = perm.price ?? "0";
}
return MapEntry(key, permissionMap);
});
print('=========================$visibilityMap');
if (widget.userRole == null) {
// Create
await repo.addUser(
ref: ref,
context: context,
branchId: selectedBranch?.id.toString() ?? '',
name: titleController.text,
email: emailController.text,
password: passwordController.text,
visibility: visibilityMap,
);
} else {
// Update
await repo.updateUser(
ref: ref,
context: context,
userId: widget.userRole?.id.toString() ?? '',
branchId: selectedBranch?.id.toString() ?? '',
name: titleController.text,
email: emailController.text,
password: passwordController.text,
visibility: visibilityMap,
);
}
ref.refresh(userRoleProvider);
Navigator.pop(context);
}
},
child: Text(widget.userRole != null ? _lang.update : _lang.create),
),
),
);
}
void _togglePermission(String key, String action, bool? value) {
final basePerm = selectedPermissions[key] ?? _basePermissions.modules[key];
if (basePerm == null) return;
final updated = basePerm.copyWith(
read: action == 'read' ? (value == true ? "1" : "0") : basePerm.read,
create: action == 'create' ? (value == true ? "1" : "0") : basePerm.create,
update: action == 'update' ? (value == true ? "1" : "0") : basePerm.update,
delete: action == 'delete' ? (value == true ? "1" : "0") : basePerm.delete,
price: action == 'price' ? (value == true ? "1" : "0") : basePerm.price,
);
setState(() {
selectedPermissions[key] = updated;
});
}
void _toggleAllPermissions(bool isSelected) {
final updated = <String, Permission>{};
_basePermissions.modules.forEach((key, perm) {
updated[key] = Permission(
read: perm.read != null ? (isSelected ? "1" : "0") : null,
create: perm.create != null ? (isSelected ? "1" : "0") : null,
update: perm.update != null ? (isSelected ? "1" : "0") : null,
delete: perm.delete != null ? (isSelected ? "1" : "0") : null,
price: perm.price != null ? (isSelected ? "1" : "0") : null,
);
});
setState(() {
selectedPermissions = updated;
});
}
DataCell _buildCheckboxCell({
required String? value,
required ValueChanged<bool?> onChanged,
}) {
return DataCell(
value == null
? const SizedBox.shrink()
: Center(
child: Checkbox(
value: value == "1",
onChanged: onChanged,
),
),
);
}
final _basePermissions = PermissionModules.fromJson({
"dashboard": {"read": "0"},
"sales": {
"read": "0",
"create": "0",
"update": "0",
"delete": "0",
},
"inventory": {
"read": "0",
"create": "0",
},
"sale-returns": {"read": "0", "create": "0", "price": "0"},
"purchases": {"read": "0", "create": "0", "update": "0", "delete": "0", "price": "0"},
"purchase-returns": {"read": "0", "create": "0", "price": "0"},
"products": {"read": "0", "create": "0", "update": "0", "delete": "0", "price": "0"},
// "branches": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"products-expired": {"read": "0"},
"barcodes": {"read": "0", "create": "0"},
"bulk-uploads": {"read": "0", "create": "0"},
"categories": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"brands": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"units": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"product-models": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"stocks": {
"read": "0",
"price": "0",
},
"expired-products": {"read": "0"},
"parties": {
"read": "0",
"create": "0",
"update": "0",
"delete": "0",
},
"incomes": {
"read": "0",
"create": "0",
"update": "0",
"delete": "0",
},
"income-categories": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"expenses": {
"read": "0",
"create": "0",
"update": "0",
"delete": "0",
},
"expense-categories": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"vats": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"dues": {"read": "0"},
"subscriptions": {"read": "0"},
"loss-profits": {"read": "0"},
"payment-types": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"roles": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"department": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"designations": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"shifts": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"employees": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"leave-types": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"leaves": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"holidays": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"attendances": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"payrolls": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"attendance-reports": {"read": "0"},
"payroll-reports": {"read": "0"},
"leave-reports": {"read": "0"},
"warehouses": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"transfers": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"racks": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"shelfs": {"read": "0", "create": "0", "update": "0", "delete": "0"},
"manage-settings": {"read": "0", "update": "0"},
"download-apk": {"read": "0"},
"sale-reports": {"read": "0"},
"sale-return-reports": {"read": "0"},
"purchase-reports": {"read": "0"},
"purchase-return-reports": {"read": "0"},
"vat-reports": {"read": "0"},
"income-reports": {"read": "0"},
"expense-reports": {"read": "0"},
"loss-profits-details": {"read": "0"},
"stock-reports": {"read": "0"},
"due-reports": {"read": "0"},
"supplier-due-reports": {"read": "0"},
"loss-profit-reports": {"read": "0"},
"transaction-history-reports": {"read": "0"},
"subscription-reports": {"read": "0"},
"expired-product-reports": {"read": "0"},
"day-book-reports": {"read": "0"},
"bill-wise-profit": {"read": "0"},
"cashflow": {"read": "0"},
"balance-sheet": {"read": "0"},
"tax-report": {"read": "0"},
"customer-ledger": {"read": "0"},
"supplier-ledger": {"read": "0"},
"parity-wise-profit": {"read": "0"},
"top-5-customer": {"read": "0"},
"top-5-supplier": {"read": "0"},
"combo-report": {"read": "0"},
"top-5-product": {"read": "0"},
"product-wise-profit-loss": {"read": "0"},
"product-purchase-report": {"read": "0"},
"product-sales-report": {"read": "0"},
"product-purchase-history": {"read": "0"},
"product-sale-history": {"read": "0"},
});
final Map<String, String> permissionDisplayTitles = {
"dashboard": l.S.current.dashboard,
"sales": l.S.current.sales,
"inventory": l.S.current.inventory,
"sale-returns": l.S.current.saleReturn,
"purchases": l.S.current.purchase,
"purchase-returns": l.S.current.purchaseReturns,
"products": l.S.current.products,
// "branches": "Branches",
"products-expired": l.S.current.expiredProduct,
"barcodes": l.S.current.barcodes,
"bulk-uploads": l.S.current.bulkUploads,
"categories": l.S.current.categories,
"brands": l.S.current.brands,
"units": l.S.current.units,
"product-models": l.S.current.productModels,
"stocks": l.S.current.stocks,
"expired-products": l.S.current.expiredProduct,
"parties": l.S.current.parties,
"incomes": l.S.current.income,
"income-categories": l.S.current.incomes,
"expenses": l.S.current.expense,
"expense-categories": l.S.current.expenseCat,
"vats": l.S.current.vat,
"dues": l.S.current.dues,
"subscriptions": l.S.current.subscriptions,
"loss-profits": l.S.current.profitAndLoss,
"payment-types": l.S.current.paymentTypes,
"roles": l.S.current.roles,
"department": l.S.current.department,
"designations": l.S.current.designation,
"shifts": l.S.current.shift,
"employees": l.S.current.employee,
"leave-types": l.S.current.leaveType,
"leaves": l.S.current.leave,
"holidays": l.S.current.holiday,
"attendances": l.S.current.attendance,
"payrolls": l.S.current.payroll,
"attendance-reports": l.S.current.attendanceReport,
"payroll-reports": l.S.current.payrollReports,
"leave-reports": l.S.current.leaveReports,
"warehouses": l.S.current.warehouse,
"transfers": l.S.current.transfer,
"racks": l.S.current.racks,
"shelfs": l.S.current.shelves,
"manage-settings": l.S.current.manageSetting,
"download-apk": l.S.current.downloadApk,
"sale-reports": l.S.current.salesReport,
"sale-return-reports": l.S.current.salesReturnReport,
"purchase-reports": l.S.current.purchaseReport,
"purchase-return-reports": l.S.current.purchaseReturnReport,
"vat-reports": l.S.current.vatReports,
"income-reports": l.S.current.incomeReport,
"expense-reports": l.S.current.expenseReport,
"loss-profits-details": l.S.current.profitAndLossDetailsReport,
"stock-reports": l.S.current.stockReport,
"due-reports": l.S.current.dueReport,
"supplier-due-reports": l.S.current.supplierDue,
"loss-profit-reports": l.S.current.profitAndLoss,
"transaction-history-reports": l.S.current.transactionsHistoryReport,
"subscription-reports": l.S.current.subscriptionReports,
"expired-product-reports": l.S.current.expireProductReports,
"day-book-reports": l.S.current.dayBook,
"bill-wise-profit": l.S.current.billWiseProfit,
"cashflow": l.S.current.cashFlow,
"balance-sheet": l.S.current.balanceSheet,
"tax-report": l.S.current.taxReport,
"customer-ledger": l.S.current.customerLedger,
"supplier-ledger": l.S.current.supplierLedger,
"parity-wise-profit": l.S.current.partyWiseProfit,
"top-5-customer": l.S.current.top5Customer,
"top-5-supplier": l.S.current.top5Supplier,
"combo-report": l.S.current.comboReport,
"top-5-product": l.S.current.top5Product,
"product-wise-profit-loss": l.S.current.productWiseProfitAndLoss,
"product-purchase-report": l.S.current.productPurchaseReport,
"product-sales-report": l.S.current.productSalesReport,
"product-purchase-history": l.S.current.productPurchaseHistory,
"product-sale-history": l.S.current.productSaleHistory,
};
}
class Permission {
final String? read;
final String? create;
final String? update;
final String? delete;
final String? price;
const Permission({
this.read,
this.create,
this.update,
this.delete,
this.price,
});
Permission copyWith({
String? read,
String? create,
String? update,
String? delete,
String? price,
}) {
return Permission(
read: read ?? this.read,
create: create ?? this.create,
update: update ?? this.update,
delete: delete ?? this.delete,
price: price ?? this.price,
);
}
factory Permission.fromJson(Map<String, dynamic> json) {
return Permission(
read: json['read'] as String?,
create: json['create'] as String?,
update: json['update'] as String?,
delete: json['delete'] as String?,
price: json['price'] as String?,
);
}
Map<String, dynamic> toJson() {
return {
if (read != null) 'read': read,
if (create != null) 'create': create,
if (update != null) 'update': update,
if (delete != null) 'delete': delete,
if (price != null) 'price': price,
};
}
}
class PermissionModules {
final Map<String, Permission> modules;
PermissionModules(this.modules);
factory PermissionModules.fromJson(Map<String, dynamic> json) {
return PermissionModules(
json.map((key, value) => MapEntry(key, Permission.fromJson(value))),
);
}
}

View File

@@ -0,0 +1,693 @@
// // ignore_for_file: unused_result
// import 'package:flutter/material.dart';
// import 'package:flutter_easyloading/flutter_easyloading.dart';
// import 'package:flutter_riverpod/flutter_riverpod.dart';
// import 'package:mobile_pos/Screens/User%20Roles/Model/user_role_model.dart' as user;
// import 'package:mobile_pos/Screens/User%20Roles/Repo/user_role_repo.dart';
// import 'package:mobile_pos/constant.dart';
// import 'package:mobile_pos/generated/l10n.dart' as lang;
// import 'package:nb_utils/nb_utils.dart';
//
// import '../../GlobalComponents/glonal_popup.dart';
// import 'Model/user_role_model.dart';
//
// class UserRoleDetails extends StatefulWidget {
// const UserRoleDetails({Key? key, required this.userRoleModel}) : super(key: key);
//
// final UserRoleModel userRoleModel;
//
// @override
// // ignore: library_private_types_in_public_api
// _UserRoleDetailsState createState() => _UserRoleDetailsState();
// }
//
// class _UserRoleDetailsState extends State<UserRoleDetails> {
// GlobalKey<FormState> globalKey = GlobalKey<FormState>();
//
// bool validateAndSave() {
// final form = globalKey.currentState;
// if (form!.validate()) {
// form.save();
// return true;
// }
// return false;
// }
//
// TextEditingController passwordController = TextEditingController();
//
// bool allPermissions = false;
// bool salePermission = false;
// bool partiesPermission = false;
// bool purchasePermission = false;
// bool productPermission = false;
// bool profileEditPermission = false;
// bool addExpensePermission = false;
// bool addIncomePermission = false;
// bool dashBoardPermission = false;
// bool lossProfitPermission = false;
// bool dueListPermission = false;
// bool stockPermission = false;
// bool reportsPermission = false;
// bool salesListPermission = false;
// bool purchaseListPermission = false;
//
// // TextEditingController phoneController = TextEditingController();
// TextEditingController emailController = TextEditingController();
// TextEditingController titleController = TextEditingController();
// bool isMailSent = false;
//
// @override
// void dispose() {
// // TODO: implement dispose
// super.dispose();
// // phoneController.dispose();
// emailController.dispose();
// titleController.dispose();
// passwordController.dispose();
// }
//
// @override
// void initState() {
// // TODO: implement initState
// super.initState();
// salePermission = widget.userRoleModel.visibility?.salePermission ?? false;
// partiesPermission = widget.userRoleModel.visibility?.partiesPermission ?? false;
// purchasePermission = widget.userRoleModel.visibility?.purchasePermission ?? false;
// productPermission = widget.userRoleModel.visibility?.productPermission ?? false;
//
// profileEditPermission = widget.userRoleModel.visibility?.profileEditPermission ?? false;
// addExpensePermission = widget.userRoleModel.visibility?.addExpensePermission ?? false;
// lossProfitPermission = widget.userRoleModel.visibility?.lossProfitPermission ?? false;
// dueListPermission = widget.userRoleModel.visibility?.dueListPermission ?? false;
// stockPermission = widget.userRoleModel.visibility?.stockPermission ?? false;
// reportsPermission = widget.userRoleModel.visibility?.reportsPermission ?? false;
// salesListPermission = widget.userRoleModel.visibility?.salesListPermission ?? false;
// purchaseListPermission = widget.userRoleModel.visibility?.purchaseListPermission ?? false;
// dashBoardPermission = widget.userRoleModel.visibility?.dashboardPermission ?? false;
// addIncomePermission = widget.userRoleModel.visibility?.addIncomePermission ?? false;
// emailController.text = widget.userRoleModel.email ?? '';
// // phoneController.text = widget.userRoleModel.phone ?? '';
// titleController.text = widget.userRoleModel.name ?? '';
// }
//
// List<UserRoleModel> adminRoleList = [];
// List<UserRoleModel> userRoleList = [];
//
// @override
// Widget build(BuildContext context) {
// final theme = Theme.of(context);
// return Consumer(builder: (context, ref, __) {
// return GlobalPopup(
// child: Scaffold(
// backgroundColor: Colors.white,
// appBar: AppBar(
// backgroundColor: Colors.white,
// title: Text(
// lang.S.of(context).userRoleDetails,
// // 'User Role Details',
// // style: GoogleFonts.poppins(
// // color: Colors.black,
// // ),
// ),
// actions: [
// IconButton(
// onPressed: () async {
// showDialog(
// context: context,
// barrierDismissible: false,
// builder: (BuildContext context1) {
// return Padding(
// padding: const EdgeInsets.all(30.0),
// child: Center(
// child: Container(
// width: double.infinity,
// decoration: const BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.all(Radius.circular(30)),
// ),
// child: Padding(
// padding: const EdgeInsets.all(20.0),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// children: [
// Text(lang.S.of(context).doYouWantToDeleteTheUser,
// //'Do you want to delete the user?',
// style: const TextStyle(fontSize: 20)),
// const SizedBox(height: 20),
// Row(
// children: [
// Expanded(
// child: ElevatedButton(
// //buttontext: 'Cancel',
// onPressed: (() {
// Navigator.pop(context1);
// }),
// //buttontext: 'Cancel',
// child: Text(lang.S.of(context).cancel),
// ),
// ),
// Expanded(
// child: ElevatedButton(
// //buttontext: 'Delete',
// onPressed: (() async {
// EasyLoading.show(
// status: lang.S.of(context).loading,
// //'loading..'
// );
// UserRoleRepo repo = UserRoleRepo();
// await repo.deleteUser(id: widget.userRoleModel.id.toString(), context: context, ref: ref);
// }),
// //buttontext: 'Delete',
// child: Text(lang.S.of(context).delete)),
// ),
// ],
// ),
// ],
// ),
// ),
// ),
// ),
// );
// },
// );
// },
// icon: const Icon(
// Icons.delete,
// color: Colors.red,
// ))
// ],
// centerTitle: true,
// iconTheme: const IconThemeData(color: Colors.black),
// elevation: 0.0,
// ),
// body: SingleChildScrollView(
// child: Padding(
// padding: const EdgeInsets.all(10.0),
// child: Column(
// children: [
// Padding(
// padding: const EdgeInsets.all(10.0),
// child: Container(
// decoration: BoxDecoration(
// border: Border.all(width: 0.5, color: kGreyTextColor),
// borderRadius: const BorderRadius.all(Radius.circular(10)),
// ),
// child: Column(
// children: [
// ///_______all_&_sale____________________________________________
// Row(
// children: [
// ///_______all__________________________
// SizedBox(
// width: context.width() / 2 - 20,
// child: CheckboxListTile(
// value: allPermissions,
// onChanged: (value) {
// if (value == true) {
// setState(() {
// allPermissions = value!;
// salePermission = true;
// partiesPermission = true;
// purchasePermission = true;
// productPermission = true;
// profileEditPermission = true;
// addExpensePermission = true;
// lossProfitPermission = true;
// dueListPermission = true;
// stockPermission = true;
// reportsPermission = true;
// salesListPermission = true;
// purchaseListPermission = true;
// addIncomePermission = true;
// dashBoardPermission = true;
// });
// } else {
// setState(() {
// allPermissions = value!;
// salePermission = false;
// partiesPermission = false;
// purchasePermission = false;
// productPermission = false;
// profileEditPermission = false;
// addExpensePermission = false;
// lossProfitPermission = false;
// dueListPermission = false;
// stockPermission = false;
// reportsPermission = false;
// salesListPermission = false;
// purchaseListPermission = false;
// addIncomePermission = false;
// dashBoardPermission = false;
// });
// }
// },
// title: Text(
// lang.S.of(context).all,
// //'All',
// style: TextStyle(fontSize: 14),
// ),
// ),
// ),
// ],
// ),
//
// ///_______Edit Profile_&_sale____________________________________________
// Row(
// children: [
// ///_______Edit_Profile_________________________
// Expanded(
// child: CheckboxListTile(
// value: profileEditPermission,
// onChanged: (value) {
// setState(() {
// profileEditPermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).profileEdit,
// //'Profile Edit',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
//
// ///______sales____________________________
// Expanded(
// child: CheckboxListTile(
// value: salePermission,
// onChanged: (value) {
// setState(() {
// salePermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).sales,
// //'Sales',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// ],
// ),
//
// ///_____parties_&_Purchase_________________________________________
// Row(
// children: [
// Expanded(
// child: CheckboxListTile(
// value: partiesPermission,
// onChanged: (value) {
// setState(() {
// partiesPermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).parties,
// //'Parties',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// Expanded(
// child: CheckboxListTile(
// value: purchasePermission,
// onChanged: (value) {
// setState(() {
// purchasePermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).purchase,
// // 'Purchase',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// ],
// ),
//
// ///_____Product_&_DueList_________________________________________
// Row(
// children: [
// Expanded(
// child: CheckboxListTile(
// value: productPermission,
// onChanged: (value) {
// setState(() {
// productPermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).products,
// // 'Products',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// Expanded(
// child: CheckboxListTile(
// value: dueListPermission,
// onChanged: (value) {
// setState(() {
// dueListPermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).dueList,
// //'Due List',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// ],
// ),
//
// ///_____Stock_&_Reports_________________________________________
// Row(
// children: [
// Expanded(
// child: CheckboxListTile(
// value: stockPermission,
// onChanged: (value) {
// setState(() {
// stockPermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).stock,
// //'Stock',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// Expanded(
// child: CheckboxListTile(
// value: reportsPermission,
// onChanged: (value) {
// setState(() {
// reportsPermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).reports,
// //'Reports',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// ],
// ),
//
// ///_____SalesList_&_Purchase List_________________________________________
// Row(
// children: [
// Expanded(
// child: CheckboxListTile(
// value: salesListPermission,
// onChanged: (value) {
// setState(() {
// salesListPermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).salesList,
// //'Sales List',
// style: const TextStyle(fontSize: 14),
// maxLines: 1,
// overflow: TextOverflow.ellipsis,
// ),
// ),
// ),
// Expanded(
// child: CheckboxListTile(
// value: purchaseListPermission,
// onChanged: (value) {
// setState(() {
// purchaseListPermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).purchaseList,
// // 'Purchase List',
// style: const TextStyle(fontSize: 14),
// maxLines: 1,
// overflow: TextOverflow.ellipsis,
// ),
// ),
// ),
// ],
// ),
//
// ///_____LossProfit_&_Expense_________________________________________
// Row(
// children: [
// Expanded(
// child: CheckboxListTile(
// value: lossProfitPermission,
// onChanged: (value) {
// setState(() {
// lossProfitPermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).lossProfit,
// //'Loss Profit',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// Expanded(
// child: CheckboxListTile(
// value: addExpensePermission,
// onChanged: (value) {
// setState(() {
// addExpensePermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).expense,
// //'Expense',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// ],
// ),
//
// ///_____LossProfit_&_Expense_________________________________________
// Row(
// children: [
// Expanded(
// child: CheckboxListTile(
// value: dashBoardPermission,
// onChanged: (value) {
// setState(() {
// dashBoardPermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).dashboard,
// //'Loss Profit',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// Expanded(
// child: CheckboxListTile(
// value: addIncomePermission,
// onChanged: (value) {
// setState(() {
// addIncomePermission = value!;
// });
// },
// title: Text(
// lang.S.of(context).income,
// //'Expense',
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// ],
// ),
// ],
// ),
// ),
// ),
//
// ///___________Text_fields_____________________________________________
// Padding(
// padding: const EdgeInsets.all(10.0),
// child: Form(
// key: globalKey,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// ///__________email_________________________________________________________
// AppTextField(
// // readOnly: true,
// controller: emailController,
// // initialValue: widget.userRoleModel.email,
// // cursorColor: kTitleColor,
// validator: (value) {
// if (value == null || value.isEmpty) {
// //return 'Email can\'n be empty';
// return lang.S.of(context).emailCannotBeEmpty;
// } else if (!value.contains('@')) {
// //return 'Please enter a valid email';
// return lang.S.of(context).pleaseEnterAValidEmail;
// }
// return null;
// },
// decoration: kInputDecoration.copyWith(
// //labelText: 'Email',
// labelText: lang.S.of(context).email,
// // labelStyle: kTextStyle.copyWith(color: kTitleColor),
// //hintText: 'Enter your email address',
// hintText: lang.S.of(context).enterYourEmailAddress,
// // hintStyle: kTextStyle.copyWith(color: kLitGreyColor),
// contentPadding: const EdgeInsets.all(10.0),
// enabledBorder: const OutlineInputBorder(
// borderRadius: BorderRadius.all(
// Radius.circular(4.0),
// ),
// borderSide: BorderSide(color: kBorderColorTextField, width: 1),
// ),
// errorBorder: const OutlineInputBorder(borderSide: BorderSide(color: Colors.red)),
// focusedBorder: const OutlineInputBorder(
// borderRadius: BorderRadius.all(Radius.circular(4.0)),
// borderSide: BorderSide(color: kBorderColorTextField, width: 2),
// ),
// ),
// textFieldType: TextFieldType.EMAIL,
// ),
// const SizedBox(height: 20.0),
//
// ///__________Title_________________________________________________________
// TextFormField(
// validator: (value) {
// if (value == null || value.isEmpty) {
// //return 'User title can\'n be empty';
// return lang.S.of(context).useTitleCanNotBeEmpty;
// }
// return null;
// },
// showCursor: true,
// controller: titleController,
// decoration: kInputDecoration.copyWith(
// //labelText: 'User Title',
// labelText: lang.S.of(context).userTitle,
// // hintText: 'Enter User Title',
// hintText: lang.S.of(context).enterUserTitle,
// contentPadding: const EdgeInsets.all(10.0),
// errorBorder: const OutlineInputBorder(borderSide: BorderSide(color: Colors.red)),
// enabledBorder: const OutlineInputBorder(
// borderRadius: BorderRadius.all(
// Radius.circular(4.0),
// ),
// borderSide: BorderSide(color: kBorderColorTextField, width: 1),
// ),
// focusedBorder: const OutlineInputBorder(
// borderRadius: BorderRadius.all(Radius.circular(4.0)),
// borderSide: BorderSide(color: kBorderColorTextField, width: 2),
// ),
// ),
// ),
// const SizedBox(height: 20.0),
//
// ///_____________Update_Password__________________________________
// AppTextField(
// validator: (value) {
// return null;
// },
// controller: passwordController,
// showCursor: true,
// decoration: kInputDecoration.copyWith(
// labelText: 'Update Password',
// floatingLabelAlignment: FloatingLabelAlignment.start,
// hintText: 'Update your password',
// contentPadding: const EdgeInsets.all(10.0),
// enabledBorder: const OutlineInputBorder(
// borderRadius: BorderRadius.all(
// Radius.circular(4.0),
// ),
// borderSide: BorderSide(color: kBorderColorTextField, width: 1),
// ),
// errorBorder: const OutlineInputBorder(borderSide: BorderSide(color: Colors.red)),
// focusedBorder: const OutlineInputBorder(
// borderRadius: BorderRadius.all(Radius.circular(4.0)),
// borderSide: BorderSide(color: kBorderColorTextField, width: 2),
// ),
// ),
// textFieldType: TextFieldType.PASSWORD,
// ),
// ],
// ),
// ),
// ),
// ],
// ),
// ),
// ),
// bottomNavigationBar: Padding(
// padding: const EdgeInsets.all(10.0),
// child: ElevatedButton(
// onPressed: (() async {
// if (salePermission ||
// partiesPermission ||
// purchasePermission ||
// productPermission ||
// profileEditPermission ||
// addExpensePermission ||
// lossProfitPermission ||
// dueListPermission ||
// stockPermission ||
// reportsPermission ||
// salesListPermission ||
// addIncomePermission ||
// dashBoardPermission ||
// purchaseListPermission) {
// if (validateAndSave()) {
// EasyLoading.show(
// status: lang.S.of(context).loading,
// //'loading..'
// );
// user.Permission permission = user.Permission(
// salePermission: salePermission,
// partiesPermission: partiesPermission,
// purchasePermission: purchasePermission,
// productPermission: productPermission,
// profileEditPermission: profileEditPermission,
// addExpensePermission: addExpensePermission,
// lossProfitPermission: lossProfitPermission,
// dueListPermission: dueListPermission,
// stockPermission: stockPermission,
// reportsPermission: reportsPermission,
// salesListPermission: salesListPermission,
// purchaseListPermission: purchaseListPermission,
// dashboardPermission: dashBoardPermission,
// addIncomePermission: addIncomePermission,
// );
// UserRoleRepo repo = UserRoleRepo();
// await repo.updateUser(
// userId: widget.userRoleModel.id.toString(),
// ref: ref,
// context: context,
// userName: titleController.text,
// email: emailController.text,
// password: passwordController.text,
// permission: permission,
// );
// }
// } else {
// EasyLoading.showError(lang.S.of(context).youHaveToGivePermission
// //'You Have To Give Permission'
// );
// }
// }),
// child: Text(lang.S.of(context).update)),
// ),
// ),
// );
// });
// }
// }

View File

@@ -0,0 +1,270 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:iconly/iconly.dart';
import 'package:mobile_pos/Screens/User%20Roles/user_role_details.dart';
import 'package:mobile_pos/generated/l10n.dart' as lang;
import 'package:nb_utils/nb_utils.dart';
import '../../GlobalComponents/glonal_popup.dart';
import '../../constant.dart';
import '../Products/product_details.dart';
import 'Model/user_role_model_new.dart';
import '../../service/check_user_role_permission_provider.dart';
import 'Provider/user_role_provider.dart';
import 'Repo/user_role_repo.dart';
import 'add_user_role_screen.dart';
class UserRoleScreen extends StatefulWidget {
const UserRoleScreen({super.key});
@override
State<UserRoleScreen> createState() => _UserRoleScreenState();
}
class _UserRoleScreenState extends State<UserRoleScreen> {
bool _isRefreshing = false;
Future<void> refreshData(WidgetRef ref) async {
if (_isRefreshing) return;
_isRefreshing = true;
ref.refresh(userRoleProvider);
await Future.delayed(const Duration(seconds: 1));
_isRefreshing = false;
}
@override
Widget build(BuildContext context) {
final _lang = lang.S.of(context);
return Consumer(
builder: (context, ref, __) {
final userRoleData = ref.watch(userRoleProvider);
final _theme = Theme.of(context);
return GlobalPopup(
child: Scaffold(
backgroundColor: kWhite,
resizeToAvoidBottomInset: true,
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
_lang.roleAndPermission,
),
centerTitle: true,
iconTheme: const IconThemeData(color: Colors.black),
elevation: 0.0,
bottom: PreferredSize(
preferredSize: const Size.fromHeight(1),
child: Container(
color: Color(0xFFE8E9F2),
height: 1,
),
),
),
body: RefreshIndicator(
onRefresh: () => refreshData(ref),
child: userRoleData.when(
data: (users) {
return users.isNotEmpty
? ListView.separated(
padding: EdgeInsets.symmetric(vertical: 16),
itemCount: users.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
final user = users[index];
return ListTile(
visualDensity: const VisualDensity(vertical: -4, horizontal: -4),
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 0),
title: Text(
user.name ?? '',
style: _theme.textTheme.bodyMedium?.copyWith(
color: kTitleColor,
fontWeight: FontWeight.w500,
fontSize: 15,
),
),
subtitle: Text(
'${_lang.role}: ${user.role ?? ''}',
style: _theme.textTheme.bodyMedium?.copyWith(
color: Color(0xff5B5B5B),
fontWeight: FontWeight.w400,
fontSize: 13,
),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (PermissionService(ref).hasPermission(Permit.rolesUpdate.value))
IconButton(
icon: const Icon(
IconlyLight.edit_square,
color: Color(0xff00932C),
size: 20,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddUserRoleScreen(userRole: user),
),
);
},
padding: EdgeInsets.zero,
visualDensity: VisualDensity.compact,
constraints: const BoxConstraints(),
tooltip: _lang.edit,
),
if (PermissionService(ref).hasPermission(Permit.rolesDelete.value))
IconButton(
icon: const Icon(
IconlyLight.delete,
color: kMainColor,
size: 20,
),
onPressed: () {
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext dialogContext) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Center(
child: Container(
padding: EdgeInsets.all(16),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(8),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
_lang.areYouSureWantToDeleteThisRole,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 26),
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Color(0xffF68A3D).withValues(alpha: 0.1),
),
padding: EdgeInsets.all(20),
child: SvgPicture.asset(
height: 126,
width: 126,
'images/trash.svg',
),
),
SizedBox(height: 26),
Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: () async {
Navigator.pop(context);
},
child: Text(_lang.cancel),
),
),
SizedBox(width: 16),
Expanded(
child: ElevatedButton(
onPressed: () async {
await Future.delayed(Duration.zero);
UserRoleRepo repo = UserRoleRepo();
bool success;
success = await repo.deleteUser(
id: user.id.toString() ?? '',
context: context,
ref: ref);
if (success) {
ref.refresh(userRoleProvider);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(_lang.deletedSuccessFully)));
Navigator.pop(context);
}
},
child: Text(_lang.delete),
),
),
],
),
],
),
),
),
);
},
);
},
padding: EdgeInsets.zero,
visualDensity: VisualDensity.compact,
constraints: const BoxConstraints(),
tooltip: 'Delete',
),
],
),
);
},
separatorBuilder: (BuildContext context, int index) {
return Divider(
thickness: 1,
color: Color(0xffDADADA),
);
},
)
: Center(child: Text(lang.S.of(context).noRoleFound));
},
error: (e, stack) => Text(e.toString()),
loading: () => const Center(child: CircularProgressIndicator()),
),
),
bottomNavigationBar: (PermissionService(ref).hasPermission(Permit.rolesCreate.value))
? Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: GestureDetector(
onTap: () {
if (!PermissionService(ref).hasPermission(Permit.rolesCreate.value)) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.red,
content: Text(
'You do not have permission to create Role.',
),
),
);
return;
}
const AddUserRoleScreen().launch(context);
},
child: Container(
height: 50,
decoration: const BoxDecoration(
color: kMainColor,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Center(
child: Text(
lang.S.of(context).addUserRole,
style: const TextStyle(fontSize: 18, color: Colors.white),
),
),
),
),
)
: null,
),
);
},
);
}
}