first commit
This commit is contained in:
165
lib/Screens/warehouse/add_new_warehouse.dart
Normal file
165
lib/Screens/warehouse/add_new_warehouse.dart
Normal file
@@ -0,0 +1,165 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mobile_pos/Screens/warehouse/warehouse_model/warehouse_list_model.dart';
|
||||
import 'package:mobile_pos/Screens/warehouse/warehouse_provider/warehouse_provider.dart';
|
||||
import 'package:mobile_pos/Screens/warehouse/warehouse_repo/warehouse_repo.dart';
|
||||
import 'package:mobile_pos/constant.dart';
|
||||
|
||||
class AddNewWarehouse extends ConsumerStatefulWidget {
|
||||
const AddNewWarehouse({super.key, this.editData});
|
||||
final WarehouseData? editData;
|
||||
|
||||
@override
|
||||
ConsumerState<AddNewWarehouse> createState() => _AddNewWarehouseState();
|
||||
}
|
||||
|
||||
class _AddNewWarehouseState extends ConsumerState<AddNewWarehouse> {
|
||||
final warehouseNameController = TextEditingController();
|
||||
final emailController = TextEditingController();
|
||||
final phoneNumberController = TextEditingController();
|
||||
final addressController = TextEditingController();
|
||||
String? selectedValue;
|
||||
GlobalKey<FormState> key = GlobalKey();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
warehouseNameController.dispose();
|
||||
emailController.dispose();
|
||||
phoneNumberController.dispose();
|
||||
addressController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.editData != null) {
|
||||
warehouseNameController.text = widget.editData?.name.toString() ?? '';
|
||||
emailController.text = widget.editData?.email?.toString() ?? '';
|
||||
phoneNumberController.text = widget.editData?.phone ?? '';
|
||||
addressController.text = widget.editData?.address ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: kWhite,
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: Text(
|
||||
widget.editData != null ? 'Edit Warehouse' : 'Add New Warehouse',
|
||||
),
|
||||
bottom: PreferredSize(
|
||||
preferredSize: Size.fromHeight(1),
|
||||
child: Divider(
|
||||
height: 2,
|
||||
color: kBackgroundColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Form(
|
||||
key: key,
|
||||
child: Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
controller: warehouseNameController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Warehouse Name',
|
||||
hintText: 'Enter warehouse name',
|
||||
),
|
||||
validator: (value) => value!.isEmpty ? 'Enter warehouse name' : null,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
TextFormField(
|
||||
keyboardType: TextInputType.number,
|
||||
controller: phoneNumberController,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Phone',
|
||||
hintText: 'Enter phone number',
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
TextFormField(
|
||||
controller: emailController,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
autofillHints: [AutofillHints.email],
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Email',
|
||||
hintText: 'Enter your email address (optional)',
|
||||
),
|
||||
validator: (value) {
|
||||
if (value != null && value.isNotEmpty) {
|
||||
final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
|
||||
if (!emailRegex.hasMatch(value)) {
|
||||
return 'Enter a valid email address';
|
||||
}
|
||||
}
|
||||
return null; // Valid (either empty or valid email)
|
||||
},
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
TextFormField(
|
||||
controller: addressController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Address',
|
||||
hintText: 'Enter your address',
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
if ((key.currentState?.validate() ?? false)) {
|
||||
WarehouseRepo warehouse = WarehouseRepo();
|
||||
bool success;
|
||||
CreateWareHouseModel data = CreateWareHouseModel(
|
||||
address: addressController.text,
|
||||
email: emailController.text,
|
||||
name: warehouseNameController.text,
|
||||
phone: phoneNumberController.text,
|
||||
warehouseId: widget.editData?.id.toString());
|
||||
if (widget.editData != null) {
|
||||
print('update');
|
||||
success = await warehouse.updateWareHouse(data: data);
|
||||
} else {
|
||||
print('create');
|
||||
success = await warehouse.createWareHouse(data: data);
|
||||
}
|
||||
if (success) {
|
||||
EasyLoading.showSuccess(widget.editData != null ? 'Warehouse Updated Successfully!' : 'Warehouse created successfully!');
|
||||
ref.refresh(fetchWarehouseListProvider);
|
||||
Navigator.pop(context);
|
||||
} else {
|
||||
EasyLoading.showError('Please Try Again!');
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Text(widget.editData != null ? 'Update' : 'Save'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CreateWareHouseModel {
|
||||
CreateWareHouseModel({
|
||||
this.warehouseId,
|
||||
this.name,
|
||||
this.phone,
|
||||
this.email,
|
||||
this.address,
|
||||
});
|
||||
String? warehouseId;
|
||||
String? name;
|
||||
String? phone;
|
||||
String? email;
|
||||
String? address;
|
||||
}
|
||||
161
lib/Screens/warehouse/tab_item/transfer_list.dart
Normal file
161
lib/Screens/warehouse/tab_item/transfer_list.dart
Normal file
@@ -0,0 +1,161 @@
|
||||
import 'package:community_material_icon/community_material_icon.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mobile_pos/constant.dart';
|
||||
|
||||
Widget transferWidget({
|
||||
required String invoiceNumber,
|
||||
required String date,
|
||||
required String from,
|
||||
required String to,
|
||||
required String quantity,
|
||||
required String stockValue,
|
||||
required BuildContext context,
|
||||
}) {
|
||||
final _theme = Theme.of(context);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Invoice: #$invoiceNumber',
|
||||
style: _theme.textTheme.titleSmall?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
date,
|
||||
style: _theme.textTheme.bodyMedium?.copyWith(
|
||||
color: kPeraColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||
onPressed: () {},
|
||||
icon: Icon(
|
||||
CommunityMaterialIcons.printer,
|
||||
color: kSubPeraColor,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||
onPressed: () {},
|
||||
icon: Icon(
|
||||
CommunityMaterialIcons.share,
|
||||
color: kSubPeraColor,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 20,
|
||||
child: IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||
onPressed: () => PopupMenuButton(
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(child: Text('Edit')),
|
||||
PopupMenuItem(child: Text('Delete')),
|
||||
]),
|
||||
icon: Icon(
|
||||
Icons.more_vert,
|
||||
color: kSubPeraColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: 6),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'From',
|
||||
style: _theme.textTheme.bodySmall?.copyWith(
|
||||
color: kPeraColor,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
from,
|
||||
style: _theme.textTheme.titleSmall,
|
||||
)
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'To',
|
||||
style: _theme.textTheme.bodySmall?.copyWith(
|
||||
color: kPeraColor,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
from,
|
||||
style: _theme.textTheme.titleSmall,
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: 6),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Quantity',
|
||||
style: _theme.textTheme.bodySmall?.copyWith(
|
||||
color: kPeraColor,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
quantity,
|
||||
style: _theme.textTheme.titleSmall,
|
||||
)
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'Stock Value',
|
||||
style: _theme.textTheme.bodySmall?.copyWith(
|
||||
color: kPeraColor,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
stockValue,
|
||||
textAlign: TextAlign.end,
|
||||
style: _theme.textTheme.titleSmall,
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
10
lib/Screens/warehouse/tab_item/warehouse_list.dart
Normal file
10
lib/Screens/warehouse/tab_item/warehouse_list.dart
Normal file
@@ -0,0 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class WarehouseList extends StatelessWidget {
|
||||
const WarehouseList({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
||||
419
lib/Screens/warehouse/warehouse.dart
Normal file
419
lib/Screens/warehouse/warehouse.dart
Normal file
@@ -0,0 +1,419 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:mobile_pos/Screens/warehouse/add_new_warehouse.dart';
|
||||
import 'package:mobile_pos/Screens/warehouse/tab_item/transfer_list.dart';
|
||||
import 'package:mobile_pos/Screens/warehouse/warehouse_model/warehouse_list_model.dart';
|
||||
import 'package:mobile_pos/Screens/warehouse/warehouse_provider/warehouse_provider.dart';
|
||||
import 'package:mobile_pos/Screens/warehouse/warehouse_repo/warehouse_repo.dart';
|
||||
import 'package:mobile_pos/constant.dart';
|
||||
import 'package:mobile_pos/currency.dart';
|
||||
|
||||
class WarehouseScreen extends ConsumerStatefulWidget {
|
||||
const WarehouseScreen({super.key});
|
||||
@override
|
||||
ConsumerState<WarehouseScreen> createState() => _WarehouseScreenState();
|
||||
}
|
||||
|
||||
class _WarehouseScreenState extends ConsumerState<WarehouseScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final _theme = Theme.of(context);
|
||||
final warehouse = ref.watch(fetchWarehouseListProvider);
|
||||
return DefaultTabController(
|
||||
length: 2,
|
||||
child: Scaffold(
|
||||
backgroundColor: kWhite,
|
||||
appBar: AppBar(
|
||||
title: Text('Warehouse'),
|
||||
centerTitle: true,
|
||||
bottom: PreferredSize(
|
||||
preferredSize: Size.fromHeight(45),
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(
|
||||
height: 2,
|
||||
color: kBackgroundColor,
|
||||
),
|
||||
Theme(
|
||||
data: _theme.copyWith(
|
||||
tabBarTheme: TabBarThemeData(dividerColor: kBackgroundColor),
|
||||
),
|
||||
child: TabBar(
|
||||
labelStyle: _theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
labelColor: Colors.red,
|
||||
unselectedLabelColor: kPeraColor,
|
||||
indicatorSize: TabBarIndicatorSize.tab,
|
||||
tabs: [
|
||||
Tab(
|
||||
text: 'Warehouse List',
|
||||
),
|
||||
Tab(
|
||||
text: 'Transfer List',
|
||||
)
|
||||
]),
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
body: TabBarView(children: [
|
||||
warehouse.when(
|
||||
data: (snapshot) {
|
||||
return snapshot.data?.isNotEmpty ?? false
|
||||
? ListView.separated(
|
||||
padding: EdgeInsets.zero,
|
||||
itemBuilder: (_, index) {
|
||||
final warehouseList = snapshot.data?[index];
|
||||
return ListTile(
|
||||
onTap: () {
|
||||
showEditDeletePopUp(
|
||||
context: context,
|
||||
item: {
|
||||
"Name": warehouseList?.name?.toString() ?? 'n/a',
|
||||
"Phone": warehouseList?.phone?.toString() ?? 'n/a',
|
||||
"Email": warehouseList?.email?.toString() ?? 'n/a',
|
||||
"Address": warehouseList?.address?.toString() ?? 'n/a',
|
||||
// "Category": "120",
|
||||
"Stock Qty": warehouseList?.totalQuantity?.toString() ?? '0',
|
||||
"Stock Value": "$currency${warehouseList?.totalValue?.toString() ?? '0'}",
|
||||
},
|
||||
editData: warehouseList,
|
||||
ref: ref);
|
||||
},
|
||||
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 6),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
warehouseList?.name?.toString() ?? '',
|
||||
style: _theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"$currency${warehouseList?.totalValue?.toString() ?? '0'}",
|
||||
style: _theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
subtitle: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
warehouseList?.phone?.toString() ?? 'n/a',
|
||||
style: _theme.textTheme.bodyMedium?.copyWith(
|
||||
color: kPeraColor,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(
|
||||
'Stock Value',
|
||||
style: _theme.textTheme.bodyMedium?.copyWith(
|
||||
color: kPeraColor,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, __) => Divider(
|
||||
color: kBackgroundColor,
|
||||
height: 2,
|
||||
),
|
||||
itemCount: snapshot.data?.length ?? 0)
|
||||
: emptyWidget(_theme);
|
||||
},
|
||||
error: (e, stack) => Center(child: Text(e.toString())),
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.zero,
|
||||
itemBuilder: (_, index) {
|
||||
return transferWidget(
|
||||
invoiceNumber: transferList[index]['inv'] ?? 'n/a',
|
||||
date: transferList[index]['date'] ?? 'n/a',
|
||||
stockValue: transferList[index]['stock'] ?? 'n/a',
|
||||
quantity: transferList[index]['quantity'] ?? 'n/a',
|
||||
from: transferList[index]['from'] ?? 'n/a',
|
||||
to: transferList[index]['to'] ?? 'n/a',
|
||||
context: context,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, __) => Divider(
|
||||
color: kBackgroundColor,
|
||||
height: 2,
|
||||
),
|
||||
itemCount: warehouseList.length),
|
||||
]),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
||||
floatingActionButton: Container(
|
||||
height: 48,
|
||||
width: 190,
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0xFFC52127).withValues(alpha: 0.2), // #C5212733 (33 is ~20% opacity)
|
||||
offset: Offset(0, 11),
|
||||
blurRadius: 14,
|
||||
spreadRadius: 0,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: FloatingActionButton(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadiusGeometry.circular(8),
|
||||
),
|
||||
isExtended: true,
|
||||
backgroundColor: kMainColor,
|
||||
onPressed: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => AddNewWarehouse()));
|
||||
},
|
||||
child: Text(
|
||||
'+ Add Warehouse',
|
||||
style: _theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// empty widget
|
||||
Column emptyWidget(ThemeData _theme) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 50),
|
||||
SvgPicture.asset(
|
||||
width: 319,
|
||||
height: 250,
|
||||
'images/empty_image.svg',
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
Text(
|
||||
'Ooph... it\'s empty in here',
|
||||
style: _theme.textTheme.bodyMedium?.copyWith(
|
||||
color: kTitleColor,
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Add some warehouse first',
|
||||
style: _theme.textTheme.bodyMedium?.copyWith(
|
||||
color: Color(0xff4B5563),
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
List<Map<String, String>> transferList = [
|
||||
{"inv": "65324", "date": "15 Jan 2025 10:35AM", "from": "Warehouse 1", "to": "Warehouse 2", "quantity": "30", "stock": "\$6000.00"},
|
||||
{"inv": "65324", "date": "15 Jan 2025 10:35AM", "from": "Warehouse 1", "to": "Warehouse 2", "quantity": "30", "stock": "\$6000.00"},
|
||||
{"inv": "65324", "date": "15 Jan 2025 10:35AM", "from": "Warehouse 1", "to": "Warehouse 2", "quantity": "30", "stock": "\$6000.00"},
|
||||
{"inv": "65324", "date": "15 Jan 2025 10:35AM", "from": "Warehouse 1", "to": "Warehouse 2", "quantity": "30", "stock": "\$6000.00"},
|
||||
{"inv": "65324", "date": "15 Jan 2025 10:35AM", "from": "Warehouse 1", "to": "Warehouse 2", "quantity": "30", "stock": "\$6000.00"},
|
||||
{"inv": "65324", "date": "15 Jan 2025 10:35AM", "from": "Warehouse 1", "to": "Warehouse 2", "quantity": "30", "stock": "\$6000.00"},
|
||||
{"inv": "65324", "date": "15 Jan 2025 10:35AM", "from": "Warehouse 1", "to": "Warehouse 2", "quantity": "30", "stock": "\$6000.00"},
|
||||
{"inv": "65324", "date": "15 Jan 2025 10:35AM", "from": "Warehouse 1", "to": "Warehouse 2", "quantity": "30", "stock": "\$6000.00"},
|
||||
{"inv": "65324", "date": "15 Jan 2025 10:35AM", "from": "Warehouse 1", "to": "Warehouse 2", "quantity": "30", "stock": "\$6000.00"},
|
||||
{"inv": "65324", "date": "15 Jan 2025 10:35AM", "from": "Warehouse 1", "to": "Warehouse 2", "quantity": "30", "stock": "\$6000.00"},
|
||||
{"inv": "65324", "date": "15 Jan 2025 10:35AM", "from": "Warehouse 1", "to": "Warehouse 2", "quantity": "30", "stock": "\$6000.00"},
|
||||
];
|
||||
|
||||
List<Map<String, String>> warehouseList = [
|
||||
{
|
||||
"title": "Warehouse 1",
|
||||
"amount": "\$5,00,000",
|
||||
"phone": "017123456789",
|
||||
},
|
||||
{
|
||||
"title": "Warehouse 2",
|
||||
"amount": "\$5,00,000",
|
||||
"phone": "017123456789",
|
||||
},
|
||||
{
|
||||
"title": "Warehouse 3",
|
||||
"amount": "\$5,00,000",
|
||||
"phone": "017123456789",
|
||||
},
|
||||
{
|
||||
"title": "Warehouse 4",
|
||||
"amount": "\$5,00,000",
|
||||
"phone": "017123456789",
|
||||
},
|
||||
{
|
||||
"title": "Warehouse 5",
|
||||
"amount": "\$5,00,000",
|
||||
"phone": "017123456789",
|
||||
},
|
||||
{
|
||||
"title": "Warehouse 6",
|
||||
"amount": "\$5,00,000",
|
||||
"phone": "017123456789",
|
||||
},
|
||||
{
|
||||
"title": "Warehouse 7",
|
||||
"amount": "\$5,00,000",
|
||||
"phone": "017123456789",
|
||||
},
|
||||
{
|
||||
"title": "Warehouse 8",
|
||||
"amount": "\$5,00,000",
|
||||
"phone": "017123456789",
|
||||
},
|
||||
{
|
||||
"title": "Warehouse 9",
|
||||
"amount": "\$5,00,000",
|
||||
"phone": "017123456789",
|
||||
},
|
||||
{
|
||||
"title": "Warehouse 10",
|
||||
"amount": "\$5,00,000",
|
||||
"phone": "017123456789",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
Future<void> showEditDeletePopUp({required BuildContext context, required Map<String, String> item, WarehouseData? editData, required WidgetRef ref}) async {
|
||||
final _theme = Theme.of(context);
|
||||
return await showDialog(
|
||||
barrierDismissible: false,
|
||||
context: context,
|
||||
builder: (BuildContext dialogContext) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Center(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.only(start: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'View Details',
|
||||
style: _theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
icon: Icon(Icons.close, size: 18),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(color: kBorderColor, height: 1),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
||||
child: Column(
|
||||
children: item.entries.map((entry) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Flexible(
|
||||
fit: FlexFit.tight,
|
||||
flex: 2,
|
||||
child: Text(
|
||||
'${entry.key} ',
|
||||
style: _theme.textTheme.bodyLarge?.copyWith(
|
||||
color: kNeutral800,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Flexible(
|
||||
fit: FlexFit.tight,
|
||||
flex: 4,
|
||||
child: Text(
|
||||
': ${entry.value}',
|
||||
style: _theme.textTheme.bodyLarge,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: OutlinedButton(
|
||||
onPressed: () async {
|
||||
await Future.delayed(Duration.zero);
|
||||
WarehouseRepo repo = WarehouseRepo();
|
||||
bool success;
|
||||
success = await repo.deleteWarehouse(
|
||||
id: editData?.id.toString() ?? '',
|
||||
);
|
||||
if (success) {
|
||||
ref.refresh(fetchWarehouseListProvider);
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Deleted Successfully')));
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: Text('Delete'),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () async {
|
||||
Navigator.pop(context);
|
||||
await Future.delayed(Duration.zero);
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => AddNewWarehouse(editData: editData),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text('Edit'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
class WarehouseListModel {
|
||||
WarehouseListModel({
|
||||
this.message,
|
||||
this.data,
|
||||
});
|
||||
|
||||
WarehouseListModel.fromJson(dynamic json) {
|
||||
message = json['message'];
|
||||
if (json['data'] != null) {
|
||||
data = [];
|
||||
json['data'].forEach((v) {
|
||||
data?.add(WarehouseData.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
String? message;
|
||||
List<WarehouseData>? data;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['message'] = message;
|
||||
if (data != null) {
|
||||
map['data'] = data?.map((v) => v.toJson()).toList();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
class WarehouseData {
|
||||
WarehouseData({
|
||||
this.id,
|
||||
this.businessId,
|
||||
this.name,
|
||||
this.phone,
|
||||
this.email,
|
||||
this.address,
|
||||
this.totalQuantity,
|
||||
this.totalValue,
|
||||
});
|
||||
|
||||
WarehouseData.fromJson(dynamic json) {
|
||||
id = json['id'];
|
||||
businessId = json['business_id'];
|
||||
name = json['name'];
|
||||
phone = json['phone'];
|
||||
email = json['email'];
|
||||
address = json['address'];
|
||||
totalQuantity = json['total_quantity'];
|
||||
totalValue = json['total_value'];
|
||||
}
|
||||
num? id;
|
||||
num? businessId;
|
||||
String? name;
|
||||
String? phone;
|
||||
String? email;
|
||||
String? address;
|
||||
num? totalQuantity;
|
||||
num? totalValue;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['id'] = id;
|
||||
map['business_id'] = businessId;
|
||||
map['name'] = name;
|
||||
map['phone'] = phone;
|
||||
map['email'] = email;
|
||||
map['address'] = address;
|
||||
map['total_quantity'] = totalQuantity;
|
||||
map['total_value'] = totalValue;
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../warehouse_model/warehouse_list_model.dart';
|
||||
import '../warehouse_repo/warehouse_repo.dart';
|
||||
|
||||
WarehouseRepo repo = WarehouseRepo();
|
||||
|
||||
// fetch warehouse list
|
||||
final fetchWarehouseListProvider = FutureProvider<WarehouseListModel>((ref) {
|
||||
return repo.fetchWareHouseList();
|
||||
});
|
||||
146
lib/Screens/warehouse/warehouse_repo/warehouse_repo.dart
Normal file
146
lib/Screens/warehouse/warehouse_repo/warehouse_repo.dart
Normal file
@@ -0,0 +1,146 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_easyloading/flutter_easyloading.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 '../../../http_client/customer_http_client_get.dart';
|
||||
import '../add_new_warehouse.dart';
|
||||
import '../warehouse_model/warehouse_list_model.dart';
|
||||
|
||||
class WarehouseRepo {
|
||||
// Create Warehouse
|
||||
Future<bool> createWareHouse({required CreateWareHouseModel data}) async {
|
||||
EasyLoading.show(status: 'Creating Warehouse...');
|
||||
final url = Uri.parse('${APIConfig.url}/warehouses');
|
||||
|
||||
// Create a multipart request
|
||||
var request = http.MultipartRequest('POST', url);
|
||||
request.headers.addAll({
|
||||
'Accept': 'application/json',
|
||||
'Authorization': await getAuthToken(),
|
||||
});
|
||||
|
||||
request.fields['name'] = data.name.toString();
|
||||
request.fields['phone'] = data.phone.toString();
|
||||
request.fields['email'] = data.email.toString();
|
||||
request.fields['address'] = data.address.toString();
|
||||
try {
|
||||
var response = await request.send();
|
||||
|
||||
var responseData = await http.Response.fromStream(response);
|
||||
EasyLoading.dismiss();
|
||||
print('warehouse create ${response.statusCode}');
|
||||
print('warehouse create ${response.request}');
|
||||
if (response.statusCode == 200) {
|
||||
return true;
|
||||
} else {
|
||||
var data = jsonDecode(responseData.body);
|
||||
EasyLoading.showError(data['message'] ?? 'Failed to create warehouse');
|
||||
print('Error: ${data['message']}');
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
EasyLoading.dismiss();
|
||||
EasyLoading.showError('Error: ${e.toString()}');
|
||||
print('Error: ${e.toString()}');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// warehouse List
|
||||
Future<WarehouseListModel> fetchWareHouseList() async {
|
||||
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
|
||||
final url = Uri.parse('${APIConfig.url}/warehouses');
|
||||
try {
|
||||
var response = await clientGet.get(url: url);
|
||||
EasyLoading.dismiss();
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
var jsonData = jsonDecode(response.body);
|
||||
return WarehouseListModel.fromJson(jsonData);
|
||||
} else {
|
||||
var data = jsonDecode(response.body);
|
||||
EasyLoading.showError(data['message'] ?? 'Failed to fetch warehouse');
|
||||
throw Exception(data['message'] ?? 'Failed to fetch warehouse');
|
||||
}
|
||||
} catch (e) {
|
||||
// Hide loading indicator and show error
|
||||
EasyLoading.dismiss();
|
||||
EasyLoading.showError('Error: ${e.toString()}');
|
||||
throw Exception('Error: ${e.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
// Update Warehouse
|
||||
Future<bool> updateWareHouse({required CreateWareHouseModel data}) async {
|
||||
EasyLoading.show(status: 'Updating Warehouse...');
|
||||
final url = Uri.parse('${APIConfig.url}/warehouses/${data.warehouseId}');
|
||||
|
||||
// Create a multipart request
|
||||
var request = http.MultipartRequest('POST', url);
|
||||
request.headers.addAll({
|
||||
'Accept': 'application/json',
|
||||
'Authorization': await getAuthToken(),
|
||||
});
|
||||
request.fields['name'] = data.name.toString();
|
||||
request.fields['phone'] = data.phone.toString();
|
||||
request.fields['email'] = data.email.toString();
|
||||
request.fields['address'] = data.address.toString();
|
||||
request.fields['_method'] = 'put';
|
||||
try {
|
||||
var response = await request.send();
|
||||
|
||||
var responseData = await http.Response.fromStream(response);
|
||||
EasyLoading.dismiss();
|
||||
print(response.statusCode);
|
||||
if (response.statusCode == 200) {
|
||||
return true;
|
||||
} else {
|
||||
var data = jsonDecode(responseData.body);
|
||||
EasyLoading.showError(data['message'] ?? 'Failed to update');
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
EasyLoading.dismiss();
|
||||
EasyLoading.showError('Error: ${e.toString()}');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// delete warehouse
|
||||
Future<bool> deleteWarehouse({required String id}) async {
|
||||
EasyLoading.show(status: 'Processing');
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
String token = prefs.getString('token') ?? '';
|
||||
final url = Uri.parse('${APIConfig.url}/warehouses/$id');
|
||||
final headers = {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
try {
|
||||
var response = await http.delete(
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user