Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sai Srinivas
gen_rentals
Commits
97cb09f8
"assets/git@183.82.99.133:saisrinivas/gen_services.git" did not exist on "fc0fa1ba4f9dbaccaba3cef06ef44af02a2f4df5"
Commit
97cb09f8
authored
Oct 18, 2025
by
Sai Srinivas
Browse files
Profile and some more changes
parent
b8c2cae9
Changes
34
Hide whitespace changes
Inline
Side-by-side
lib/Screens/HelpScreens/TicketChatScreen.dart
View file @
97cb09f8
...
@@ -5,6 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart';
...
@@ -5,6 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import
'package:provider/provider.dart'
;
import
'package:provider/provider.dart'
;
import
'../../Notifier/HelpAndEnquiryProvider.dart'
;
import
'../../Notifier/HelpAndEnquiryProvider.dart'
;
import
'../../Utility/AppColors.dart'
;
import
'../../Utility/AppColors.dart'
;
import
'../../Utility/FullScreenImageViewer.dart'
;
import
'../../Utility/Reusablewidgets.dart'
;
import
'../../Utility/Reusablewidgets.dart'
;
import
'package:image_picker/image_picker.dart'
;
import
'package:image_picker/image_picker.dart'
;
...
@@ -84,17 +85,17 @@ class _TicketChatScreenState extends State<TicketChatScreen> {
...
@@ -84,17 +85,17 @@ class _TicketChatScreenState extends State<TicketChatScreen> {
const
Spacer
(),
const
Spacer
(),
Container
(
Container
(
padding:
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
1
0
,
vertical:
6
),
const
EdgeInsets
.
symmetric
(
horizontal:
1
2
,
vertical:
6
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
status
?
Color
s
.
green
.
shade50
:
Colors
.
red
.
shade50
,
color:
status
?
Color
(
0xFFD7FFD2
)
:
Color
(
0xFFFFEBEB
)
,
borderRadius:
BorderRadius
.
circular
(
1
6
),
borderRadius:
BorderRadius
.
circular
(
6
),
),
),
child:
Text
(
child:
Text
(
widget
.
status
,
widget
.
status
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
12
,
fontSize:
12
,
fontWeight:
FontWeight
.
w400
,
fontWeight:
FontWeight
.
w400
,
color:
status
?
Colors
.
green
:
Colors
.
red
,
color:
status
?
Colors
.
black87
:
Colors
.
red
,
),
),
),
),
),
),
...
@@ -134,6 +135,7 @@ class _TicketChatScreenState extends State<TicketChatScreen> {
...
@@ -134,6 +135,7 @@ class _TicketChatScreenState extends State<TicketChatScreen> {
),
),
),
),
),
),
if
(
widget
.
status
!=
"Closed"
)
Container
(
Container
(
width:
double
.
infinity
,
width:
double
.
infinity
,
padding:
const
EdgeInsets
.
all
(
16
),
padding:
const
EdgeInsets
.
all
(
16
),
...
@@ -243,17 +245,6 @@ class _TicketChatScreenState extends State<TicketChatScreen> {
...
@@ -243,17 +245,6 @@ class _TicketChatScreenState extends State<TicketChatScreen> {
),
),
),
),
const
SizedBox
(
height:
6
),
const
SizedBox
(
height:
6
),
Text
(
message
,
style:
const
TextStyle
(
fontSize:
14
,
fontStyle:
FontStyle
.
normal
,
fontWeight:
FontWeight
.
w400
,
color:
Colors
.
black87
,
height:
1.5
,
),
),
const
SizedBox
(
height:
8
),
// 🔹 Image container section
// 🔹 Image container section
if
(
images
.
isNotEmpty
)
if
(
images
.
isNotEmpty
)
...
@@ -269,21 +260,36 @@ class _TicketChatScreenState extends State<TicketChatScreen> {
...
@@ -269,21 +260,36 @@ class _TicketChatScreenState extends State<TicketChatScreen> {
children:
[
children:
[
ClipRRect
(
ClipRRect
(
borderRadius:
BorderRadius
.
circular
(
12
),
borderRadius:
BorderRadius
.
circular
(
12
),
child:
Image
.
network
(
child:
GestureDetector
(
images
[
index
],
onTap:
()
{
width:
100
,
Navigator
.
push
(
height:
80
,
context
,
fit:
BoxFit
.
cover
,
MaterialPageRoute
(
errorBuilder:
(
context
,
error
,
stackTrace
)
{
builder:
(
_
)
=>
FullScreenImageViewer
(
return
Container
(
imageUrl:
images
[
index
],
width:
100
,
),
height:
80
,
),
color:
Colors
.
grey
.
shade200
,
child:
const
Icon
(
Icons
.
broken_image
,
color:
Colors
.
grey
),
);
);
},
},
child:
ClipRRect
(
borderRadius:
BorderRadius
.
circular
(
12
),
child:
Image
.
network
(
images
[
index
],
width:
100
,
height:
80
,
fit:
BoxFit
.
cover
,
errorBuilder:
(
context
,
error
,
stackTrace
)
{
return
Container
(
width:
100
,
height:
80
,
color:
Colors
.
grey
.
shade200
,
child:
const
Icon
(
Icons
.
broken_image
,
color:
Colors
.
grey
),
);
},
),
),
),
),
),
),
if
(
imageName
.
length
>
index
)
if
(
imageName
.
length
>
index
)
Padding
(
Padding
(
...
@@ -304,6 +310,19 @@ class _TicketChatScreenState extends State<TicketChatScreen> {
...
@@ -304,6 +310,19 @@ class _TicketChatScreenState extends State<TicketChatScreen> {
),
),
),
),
Text
(
message
,
style:
const
TextStyle
(
fontSize:
14
,
fontStyle:
FontStyle
.
normal
,
fontWeight:
FontWeight
.
w400
,
color:
Colors
.
black87
,
height:
1.5
,
),
),
const
SizedBox
(
height:
8
),
// Divider line
// Divider line
Container
(
Container
(
height:
1
,
height:
1
,
...
...
lib/Screens/ProductsDetailScreen.dart
View file @
97cb09f8
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_svg/flutter_svg.dart'
;
import
'package:flutter_svg/flutter_svg.dart'
;
import
'package:gen_rentals/Screens/BillDetailListScreen.dart'
;
import
'package:gen_rentals/Screens/
BillScreens/
BillDetailListScreen.dart'
;
import
'package:gen_rentals/Utility/Reusablewidgets.dart'
;
import
'package:gen_rentals/Utility/Reusablewidgets.dart'
;
import
'package:provider/provider.dart'
;
import
'package:provider/provider.dart'
;
import
'../Models/SubscribeOrderDetailsResponse.dart'
;
import
'../Models/SubscribeOrderDetailsResponse.dart'
;
...
@@ -108,9 +108,14 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
...
@@ -108,9 +108,14 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
width:
double
.
infinity
,
width:
double
.
infinity
,
child:
ElevatedButton
(
child:
ElevatedButton
(
onPressed:
()
{
onPressed:
()
{
final
order
=
provider
.
orderDetails
!;
Navigator
.
push
(
Navigator
.
push
(
context
,
context
,
MaterialPageRoute
(
builder:
(
context
)
=>
BillDetailListScreen
())
MaterialPageRoute
(
builder:
(
context
)
=>
BillDetailListScreen
(
sessionId:
widget
.
sessionId
,
orderId:
order
.
orderid
.
toString
(),
accId:
widget
.
accId
,
))
);
);
// Handle view bill action
// Handle view bill action
FocusScope
.
of
(
context
).
unfocus
();
FocusScope
.
of
(
context
).
unfocus
();
...
@@ -193,113 +198,129 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
...
@@ -193,113 +198,129 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
children:
[
children:
[
SizedBox
(
height:
1
,),
SizedBox
(
height:
1
,),
// Order header (not in card)
// Order header (not in card)
Container
(
Padding
(
width:
double
.
infinity
,
padding:
const
EdgeInsets
.
all
(
14
),
margin:
const
EdgeInsets
.
all
(
0
),
child:
Container
(
padding:
const
EdgeInsets
.
all
(
0
),
width:
double
.
infinity
,
decoration:
BoxDecoration
(
margin:
const
EdgeInsets
.
all
(
0
),
borderRadius:
BorderRadius
.
circular
(
2
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
0
,
vertical:
16
),
gradient:
LinearGradient
(
decoration:
BoxDecoration
(
begin:
Alignment
.
topCenter
,
borderRadius:
BorderRadius
.
circular
(
22
),
end:
Alignment
.
bottomCenter
,
gradient:
LinearGradient
(
colors:
[
begin:
Alignment
.
topCenter
,
Color
(
0xDDFFFFFF
),
end:
Alignment
.
bottomCenter
,
Color
(
0xAAFFFFFF
),
colors:
[
Color
(
0x88FFFFFF
),
Color
(
0xFFFFFFFF
),
Color
(
0x66FFFFFF
),
Color
(
0xAAFFFFFF
),
Color
(
0x44FFFFFF
),
Color
(
0xFFFFFFFF
),
Color
(
0x11FFFFFF
),
]
]
)
)
),
),
child:
Padding
(
padding:
const
EdgeInsets
.
all
(
18
),
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
children:
[
Row
(
SizedBox
(
height:
2
,),
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
const
Text
(
"Order ID "
,
style:
TextStyle
(
fontSize:
24
,
fontFamily:
"Poppins"
,
fontWeight:
FontWeight
.
w400
,
color:
Colors
.
black87
,
),
),
Text
(
"#
${order.orderNum ?? order.orderid ?? 'N/A'}
"
,
style:
TextStyle
(
fontSize:
24
,
fontFamily:
"Poppins"
,
fontWeight:
FontWeight
.
w400
,
color:
AppColors
.
amountText
,
),
),
],
),
const
SizedBox
(
height:
12
),
//
Text
(
"Duration"
,
style:
TextStyle
(
fontSize:
12
,
fontFamily:
"Poppins"
,
fontWeight:
FontWeight
.
w400
,
color:
Colors
.
black87
,
),
),
const
SizedBox
(
height:
2
),
Text
(
"
${order.fromDate}
-
${order.toDate ?? 'Duration unavailable'}
"
,
style:
TextStyle
(
fontSize:
12
,
fontFamily:
"Poppins"
,
fontWeight:
FontWeight
.
w400
,
color:
AppColors
.
subtitleText
,
),
),
const
SizedBox
(
height:
12
),
Container
(
Container
(
padding:
const
EdgeInsets
.
symmetric
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
14
,
vertical:
6
),
horizontal:
10
,
vertical:
6
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
gradient:
_getGradientByColor
(
order
.
expiringInColor
),
gradient:
LinearGradient
(
borderRadius:
BorderRadius
.
circular
(
8
),
begin:
Alignment
.
topLeft
,
end:
Alignment
.
topRight
,
colors:
[
Color
(
0xffD4EFFF
),
// Color(0xFFFFFFFF),
Color
(
0xFFFFFFFF
),
]
)
),
),
child:
Text
(
child:
Row
(
order
.
expiringText
??
'Expiring info not available'
,
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
style:
const
TextStyle
(
children:
[
fontSize:
12
,
Column
(
fontFamily:
"Poppins"
,
children:
[
fontWeight:
FontWeight
.
w400
,
Text
(
color:
Colors
.
black87
,
"Order ID #
${order.orderNum ?? order.orderid ?? 'N/A'}
"
,
),
style:
TextStyle
(
fontSize:
14
,
fontFamily:
"Poppins"
,
fontWeight:
FontWeight
.
w400
,
color:
AppColors
.
amountText
,
),
),
SizedBox
(
height:
4
,),
Text
(
"
${order.fromDate}
-
${order.toDate ?? 'Duration unavailable'}
"
,
style:
TextStyle
(
fontSize:
12
,
fontFamily:
"Poppins"
,
fontWeight:
FontWeight
.
w400
,
color:
AppColors
.
subtitleText
,
),
),
],
),
Container
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
10
,
vertical:
6
),
decoration:
BoxDecoration
(
gradient:
_getGradientByColor
(
order
.
expiringInColor
),
borderRadius:
BorderRadius
.
circular
(
8
),
),
child:
Text
(
order
.
expiringText
??
'Expiring info not available'
,
style:
const
TextStyle
(
fontSize:
12
,
fontFamily:
"Poppins"
,
fontWeight:
FontWeight
.
w400
,
color:
Colors
.
black87
,
),
),
),
],
),
),
),
),
const
SizedBox
(
height:
1
4
),
const
SizedBox
(
height:
1
2
),
//
//
Text
(
Padding
(
order
.
accName
??
' A/c not available'
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
14
,
vertical:
4
),
style:
TextStyle
(
child:
Column
(
fontSize:
12
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
fontFamily:
"Poppins"
,
children:
[
fontWeight:
FontWeight
.
w400
,
Text
(
color:
Colors
.
black87
,
"Address"
,
),
style:
TextStyle
(
),
fontSize:
12
,
const
SizedBox
(
height:
10
),
fontFamily:
"Poppins"
,
Text
(
fontWeight:
FontWeight
.
w400
,
order
.
adress
??
"Address unavailable"
,
color:
Colors
.
black87
,
style:
TextStyle
(
),
fontSize:
12
,
),
fontFamily:
"Poppins"
,
const
SizedBox
(
height:
8
),
fontWeight:
FontWeight
.
w400
,
//
color:
AppColors
.
subtitleText
,
Text
(
order
.
accName
??
' A/c not available'
,
style:
TextStyle
(
fontSize:
12
,
fontFamily:
"Poppins"
,
fontWeight:
FontWeight
.
w400
,
color:
Colors
.
black87
,
),
),
const
SizedBox
(
height:
10
),
Text
(
order
.
adress
??
"Address unavailable"
,
style:
TextStyle
(
fontSize:
12
,
fontFamily:
"Poppins"
,
fontWeight:
FontWeight
.
w400
,
color:
AppColors
.
subtitleText
,
),
textAlign:
TextAlign
.
start
,
),
],
),
),
textAlign:
TextAlign
.
center
,
),
),
],
],
),
),
...
@@ -539,14 +560,14 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
...
@@ -539,14 +560,14 @@ class _ProductsDetailScreenState extends State<ProductsDetailScreen> {
switch
(
color
)
{
switch
(
color
)
{
case
"Red"
:
case
"Red"
:
return
const
LinearGradient
(
return
const
LinearGradient
(
colors:
[
Color
(
0xFFFFE
0E0
),
Color
(
0xFFFF
C0C0
)],
colors:
[
Color
(
0xFFFFE
BEB
),
Color
(
0xFFFF
EBEB
)],
begin:
Alignment
.
topLeft
,
begin:
Alignment
.
topLeft
,
end:
Alignment
.
bottomRight
,
end:
Alignment
.
bottomRight
,
);
);
case
"Green"
:
case
"Green"
:
default
:
default
:
return
const
LinearGradient
(
return
const
LinearGradient
(
colors:
[
Color
(
0xFFE
9
FF
DD
),
Color
(
0xFF
B
5FF
D1
)],
colors:
[
Color
(
0xFFE
5
FF
E2
),
Color
(
0xFF
E
5FF
E2
)],
begin:
Alignment
.
topLeft
,
begin:
Alignment
.
topLeft
,
end:
Alignment
.
bottomRight
,
end:
Alignment
.
bottomRight
,
);
);
...
...
lib/Screens/ProfileScreen.dart
View file @
97cb09f8
...
@@ -7,6 +7,10 @@ import '../../Notifier/HelpAndEnquiryProvider.dart';
...
@@ -7,6 +7,10 @@ import '../../Notifier/HelpAndEnquiryProvider.dart';
import
'../../Utility/AppColors.dart'
;
import
'../../Utility/AppColors.dart'
;
import
'package:provider/provider.dart'
;
import
'package:provider/provider.dart'
;
import
'../Notifier/RentalContactProvider .dart'
;
import
'../Utility/SharedpreferencesService.dart'
;
import
'authScreen/LoginScreen.dart'
;
class
ProfileScreen
extends
StatefulWidget
{
class
ProfileScreen
extends
StatefulWidget
{
final
String
sessionId
;
final
String
sessionId
;
...
@@ -37,99 +41,595 @@ class _ProfileScreenState extends State<ProfileScreen> {
...
@@ -37,99 +41,595 @@ class _ProfileScreenState extends State<ProfileScreen> {
});
});
}
}
// ✅ (unchanged)
Future
<
void
>
onLogout
(
BuildContext
context
)
async
{
final
List
<
Map
<
String
,
dynamic
>>
createNewTickets
=
[
final
provider
=
Provider
.
of
<
RentalProvider
>(
context
,
listen:
false
);
{
'title'
:
'Payment Issues'
,
'description'
:
'Get help with payment related problems'
,
'icon'
:
"assets/svg/rupee_coin_ic.svg"
,
'color'
:
Color
(
0xFFFFEFBE
),
},
{
'title'
:
'Bill Related Issues'
,
'description'
:
'Resolve bill and invoice matters'
,
'icon'
:
"assets/svg/know_pay.svg"
,
'color'
:
Color
(
0xFFCEF9FF
),
},
{
'title'
:
'Other Issues'
,
'description'
:
'Any other support you need'
,
'icon'
:
'assets/svg/help_ic.svg'
,
'color'
:
Color
(
0xFFE4E5FF
),
},
];
@override
// 🧭 Step 1: Ask confirmation
Widget
build
(
BuildContext
context
)
{
final
confirm
=
await
showDialog
<
bool
>(
return
SafeArea
(
context:
context
,
top:
false
,
builder:
(
context
)
{
child:
Scaffold
(
return
Dialog
(
backgroundColor:
AppColors
.
backgroundRegular
,
appBar:
AppBar
(
automaticallyImplyLeading:
false
,
backgroundColor:
Colors
.
white
,
backgroundColor:
Colors
.
white
,
title:
Row
(
shape:
RoundedRectangleBorder
(
children:
[
borderRadius:
BorderRadius
.
circular
(
20
),
InkResponse
(
),
onTap:
()
=>
Navigator
.
pop
(
context
,
true
),
elevation:
0
,
child:
SvgPicture
.
asset
(
child:
Container
(
"assets/svg/continue_left_ic.svg"
,
padding:
const
EdgeInsets
.
all
(
24
),
height:
30
,
decoration:
BoxDecoration
(
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
20
),
boxShadow:
[
BoxShadow
(
color:
Colors
.
black
.
withOpacity
(
0.1
),
blurRadius:
20
,
offset:
const
Offset
(
0
,
4
),
),
],
),
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
// Icon
Container
(
width:
60
,
height:
60
,
decoration:
BoxDecoration
(
color:
AppColors
.
buttonColor
.
withOpacity
(
0.1
),
shape:
BoxShape
.
circle
,
),
child:
Icon
(
Icons
.
logout_rounded
,
color:
AppColors
.
buttonColor
,
size:
30
,
),
),
),
const
SizedBox
(
height:
16
),
// Title
Text
(
"Logout"
,
style:
TextStyle
(
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w700
,
fontSize:
20
,
color:
Colors
.
black87
,
),
),
const
SizedBox
(
height:
8
),
// Subtitle
Text
(
"Are you sure you want to logout?"
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
fontFamily:
"Plus Jakarta Sans"
,
fontSize:
14
,
fontWeight:
FontWeight
.
w400
,
color:
Colors
.
grey
[
600
],
height:
1.4
,
),
),
const
SizedBox
(
height:
24
),
// Buttons Row
Row
(
children:
[
// Cancel Button
Expanded
(
child:
OutlinedButton
(
onPressed:
()
=>
Navigator
.
pop
(
context
,
false
),
style:
OutlinedButton
.
styleFrom
(
backgroundColor:
Colors
.
transparent
,
foregroundColor:
Colors
.
grey
[
600
],
side:
BorderSide
(
color:
Colors
.
grey
[
300
]!,
width:
1.5
,
),
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
12
),
),
padding:
const
EdgeInsets
.
symmetric
(
vertical:
14
),
elevation:
0
,
),
child:
Text
(
"Cancel"
,
style:
TextStyle
(
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w600
,
fontSize:
14
,
color:
Colors
.
grey
[
700
],
),
),
),
),
const
SizedBox
(
width:
12
),
// Logout Button
Expanded
(
child:
ElevatedButton
(
onPressed:
()
=>
Navigator
.
pop
(
context
,
true
),
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
AppColors
.
buttonColor
,
foregroundColor:
Colors
.
white
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
12
),
),
padding:
const
EdgeInsets
.
symmetric
(
vertical:
14
),
elevation:
0
,
shadowColor:
Colors
.
transparent
,
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Text
(
"Logout"
,
style:
TextStyle
(
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w600
,
fontSize:
14
,
color:
Colors
.
white
,
),
),
],
),
),
),
],
),
],
),
),
);
},
);
// Step 2: If user cancelled, just return
if
(
confirm
!=
true
)
return
;
// Step 3: Show loading indicator
showDialog
(
context:
context
,
barrierDismissible:
false
,
builder:
(
context
)
=>
Center
(
child:
Container
(
padding:
const
EdgeInsets
.
all
(
20
),
decoration:
BoxDecoration
(
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
16
),
boxShadow:
[
BoxShadow
(
color:
Colors
.
black
.
withOpacity
(
0.1
),
blurRadius:
10
,
offset:
const
Offset
(
0
,
4
),
),
],
),
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
CircularProgressIndicator
(
color:
AppColors
.
buttonColor
,
strokeWidth:
3
,
),
),
const
SizedBox
(
width
:
1
0
),
const
SizedBox
(
height
:
1
6
),
const
Text
(
Text
(
"
Profile
"
,
"
Logging out...
"
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
16
,
fontFamily:
"Plus Jakarta Sans"
,
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w
6
00
,
fontWeight:
FontWeight
.
w
5
00
,
color:
Colors
.
black87
,
color:
Colors
.
grey
[
700
]
,
),
),
),
),
],
],
),
),
),
),
),
);
try
{
// Step 4: Call provider to logout
final
deviceDetails
=
{
"device_name"
:
"Android Device"
,
"os_version"
:
"14"
,
};
await
provider
.
logout
(
context
,
widget
.
accId
,
widget
.
sessionId
,
deviceDetails
,
);
// ✅ Provider Consumer used here
// Step 5: Clear SharedPreferences
body:
Consumer
<
HelpAndEnquiryProvider
>(
final
prefs
=
SharedPreferencesService
.
instance
;
builder:
(
context
,
provider
,
_
)
{
await
prefs
.
clearPreferences
();
if
(
provider
.
isLoading
)
{
return
const
Center
(
child:
CircularProgressIndicator
());
// Close loading dialog
}
if
(
context
.
mounted
)
Navigator
.
pop
(
context
);
if
(
provider
.
errorMessage
!=
null
)
{
// Step 6: Navigate to login screen with success feedback
return
Center
(
if
(
context
.
mounted
)
{
child:
Text
(
provider
.
errorMessage
!,
// Show success message briefly
style:
const
TextStyle
(
color:
Colors
.
red
)),
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
);
SnackBar
(
}
backgroundColor:
AppColors
.
buttonColor
,
content:
Row
(
final
ticketData
=
provider
.
ticketListResponse
?.
tickets
;
children:
[
final
processingTickets
=
ticketData
?.
inProgress
??
[];
Icon
(
Icons
.
check_circle
,
color:
Colors
.
white
,
size:
20
),
final
closedTickets
=
ticketData
?.
closed
??
[];
const
SizedBox
(
width:
8
),
Text
(
return
SingleChildScrollView
(
"Logged out successfully"
,
padding:
const
EdgeInsets
.
all
(
16
),
style:
TextStyle
(
child:
Column
(
fontFamily:
"Plus Jakarta Sans"
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
fontWeight:
FontWeight
.
w500
,
children:
[
// Create New Ticket Section
const
SectionHeading
(
title:
'User Profile'
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
2
,
vertical:
4
),
),
),
),
],
),
duration:
const
Duration
(
seconds:
2
),
behavior:
SnackBarBehavior
.
floating
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
8
),
),
),
);
],
// Navigate after brief delay
),
await
Future
.
delayed
(
const
Duration
(
milliseconds:
1500
));
);
},
if
(
context
.
mounted
)
{
Navigator
.
pushAndRemoveUntil
(
context
,
MaterialPageRoute
(
builder:
(
_
)
=>
const
LoginScreen
()),
(
route
)
=>
false
,
);
}
}
}
catch
(
e
)
{
// Close loading dialog
if
(
context
.
mounted
)
Navigator
.
pop
(
context
);
// Show error message
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
backgroundColor:
Colors
.
redAccent
,
content:
Row
(
children:
[
Icon
(
Icons
.
error_outline
,
color:
Colors
.
white
,
size:
20
),
const
SizedBox
(
width:
8
),
Text
(
"Logout failed. Please try again."
,
style:
TextStyle
(
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w500
,
),
),
],
),
duration:
const
Duration
(
seconds:
3
),
behavior:
SnackBarBehavior
.
floating
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
8
),
),
),
);
}
}
}
@override
Widget
build
(
BuildContext
context
)
{
double
screenWidth
=
MediaQuery
.
of
(
context
).
size
.
width
;
double
screenHeight
=
MediaQuery
.
of
(
context
).
size
.
height
;
double
bottomPadding
=
MediaQuery
.
of
(
context
).
padding
.
bottom
;
return
SafeArea
(
top:
false
,
child:
Scaffold
(
body:
Container
(
color:
const
Color
(
0xFFF3F3F3
),
height:
screenHeight
,
child:
SingleChildScrollView
(
child:
Column
(
children:
[
// Top background image section
Stack
(
children:
[
// Background image
Container
(
width:
double
.
infinity
,
decoration:
BoxDecoration
(
gradient:
const
LinearGradient
(
begin:
Alignment
.
topCenter
,
end:
Alignment
.
bottomCenter
,
colors:
[
Colors
.
white54
,
Color
(
0xFFF3F3F3
),
],
),
),
child:
Image
.
asset
(
'assets/images/sky_blue_bg.jpg'
,
width:
double
.
infinity
,
height:
400
,
fit:
BoxFit
.
cover
,
),
),
// Content overlay
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
// Header with profile
Container
(
width:
double
.
infinity
,
height:
400
,
decoration:
const
BoxDecoration
(
gradient:
LinearGradient
(
begin:
Alignment
.
topCenter
,
end:
Alignment
.
bottomCenter
,
colors:
[
Color
(
0x22FFFFFF
),
Color
(
0x33FFFFFF
),
Color
(
0x88FFFFFF
),
Color
(
0xFFF3F3F3
),
Color
(
0xFFF3F3F3
),
],
),
),
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
end
,
children:
[
const
SizedBox
(
height:
0
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
start
,
children:
[
const
SizedBox
(
width:
20
),
// Profile icon
InkResponse
(
onTap:
()
{
Navigator
.
pop
(
context
);
},
child:
Container
(
width:
32
,
height:
32
,
decoration:
BoxDecoration
(
color:
Colors
.
transparent
,
),
child:
SvgPicture
.
asset
(
"assets/svg/continue_left_ic.svg"
,
fit:
BoxFit
.
contain
,
),
),
),
SizedBox
(
width:
5
,),
Text
(
"Profile"
,
style:
TextStyle
(
fontSize:
16
,
fontFamily:
"Poppins"
,
fontWeight:
FontWeight
.
w400
,
color:
AppColors
.
normalText
,
),
),
],
),
SizedBox
(
height:
120
,),
Container
(
height:
140
,
width:
140
,
decoration:
const
BoxDecoration
(
color:
Color
(
0xFFE6F6FF
),
shape:
BoxShape
.
circle
,
),
clipBehavior:
Clip
.
antiAlias
,
child:
(
widget
.
accId
.
isNotEmpty
)
?
Image
.
network
(
widget
.
accId
,
fit:
BoxFit
.
cover
,
errorBuilder:
(
context
,
error
,
stackTrace
)
{
return
const
Icon
(
Icons
.
person
,
color:
Color
(
0xFF2d2d2d
),
size:
100
,);
},
loadingBuilder:
(
context
,
child
,
loadingProgress
)
{
if
(
loadingProgress
==
null
)
return
child
;
return
const
Center
(
child:
CircularProgressIndicator
(
strokeWidth:
2
));
},
)
:
CircleAvatar
(
radius:
80
,
backgroundColor:
Colors
.
blue
.
shade100
,
child:
SvgPicture
.
asset
(
"assets/svg/person_ic.svg"
,
fit:
BoxFit
.
contain
,
),
),
),
const
SizedBox
(
height:
10
),
Text
(
"Blink Commerce PVT. LTD - TN"
,
style:
TextStyle
(
fontSize:
16
,
fontFamily:
"Poppins"
,
fontWeight:
FontWeight
.
w400
,
color:
AppColors
.
normalText
,
),
),
const
SizedBox
(
height:
10
),
],
),
),
// Main content section
Container
(
margin:
const
EdgeInsets
.
all
(
14
),
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
,
vertical:
20
),
decoration:
BoxDecoration
(
color:
Colors
.
transparent
,
borderRadius:
BorderRadius
.
circular
(
18
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
[
// 📞 Phone
_infoItem
(
iconPath:
"assets/svg/phone_ic.svg"
,
title:
"Phone No."
,
value:
"+91 9639919XX"
,
iconBgColor:
const
Color
(
0xFFDFF6E3
),
),
const
SizedBox
(
height:
16
),
// 📧 Email
_infoItem
(
iconPath:
"assets/svg/email_ic.svg"
,
title:
"Email ID"
,
value:
"xyz@gmail.com"
,
iconBgColor:
const
Color
(
0xFFDDEEFF
),
),
const
SizedBox
(
height:
16
),
// 📍 Address
_infoItem
(
iconPath:
"assets/svg/location_ic.svg"
,
title:
"Address"
,
value:
"No.1/398 O.M. Road, Navallur, Chennai - 600130"
,
iconBgColor:
const
Color
(
0xFFFFE9E9
),
),
const
SizedBox
(
height:
20
),
// 🌏 State / Sub locality
Center
(
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceEvenly
,
children:
[
_twoColumnItem
(
"State"
,
"Tamil Nadu"
),
_twoColumnItem
(
"Sub Locality"
,
"Chennai"
),
],
),
),
const
SizedBox
(
height:
30
),
// 🚪 Logout Button
SizedBox
(
width:
double
.
infinity
,
child:
ElevatedButton
(
onPressed:
()
=>
onLogout
(
context
),
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
AppColors
.
amountText
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
50
),
),
padding:
const
EdgeInsets
.
symmetric
(
vertical:
14
),
),
child:
const
Text
(
"Logout"
,
style:
TextStyle
(
fontSize:
16
,
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w600
,
color:
Colors
.
white
,
),
),
),
),
],
),
)
],
),
],
),
],
),
),
),
),
),
),
);
);
}
}
Widget
_infoItem
({
required
String
iconPath
,
required
String
title
,
required
String
value
,
required
Color
iconBgColor
,
})
{
return
Column
(
children:
[
Container
(
padding:
const
EdgeInsets
.
all
(
10
),
decoration:
BoxDecoration
(
color:
iconBgColor
,
borderRadius:
BorderRadius
.
circular
(
14
),
),
child:
SvgPicture
.
asset
(
iconPath
,
height:
28
,
width:
28
,
),
),
const
SizedBox
(
height:
6
),
Text
(
title
,
style:
const
TextStyle
(
fontSize:
13
,
fontWeight:
FontWeight
.
w600
,
fontFamily:
"Plus Jakarta Sans"
,
color:
Colors
.
black87
,
),
),
const
SizedBox
(
height:
2
),
Text
(
value
,
textAlign:
TextAlign
.
center
,
style:
const
TextStyle
(
fontSize:
13
,
fontWeight:
FontWeight
.
w400
,
fontFamily:
"Plus Jakarta Sans"
,
color:
Colors
.
black54
,
),
),
],
);
}
Widget
_twoColumnItem
(
String
title
,
String
value
)
{
return
Column
(
children:
[
Text
(
title
,
style:
const
TextStyle
(
fontSize:
13
,
fontWeight:
FontWeight
.
w600
,
fontFamily:
"Plus Jakarta Sans"
,
color:
Colors
.
black87
,
),
),
const
SizedBox
(
height:
4
),
Text
(
value
,
style:
const
TextStyle
(
fontSize:
13
,
fontWeight:
FontWeight
.
w400
,
fontFamily:
"Plus Jakarta Sans"
,
color:
Colors
.
black54
,
),
),
],
);
}
}
}
lib/Screens/SplashScreen.dart
View file @
97cb09f8
...
@@ -3,10 +3,10 @@ import 'dart:io';
...
@@ -3,10 +3,10 @@ import 'dart:io';
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_svg/flutter_svg.dart'
;
import
'package:flutter_svg/flutter_svg.dart'
;
import
'package:connectivity_plus/connectivity_plus.dart'
;
import
'package:connectivity_plus/connectivity_plus.dart'
;
import
'package:gen_rentals/Screens/BillDetailListScreen.dart'
;
import
'package:gen_rentals/Screens/
BillScreens/
BillDetailListScreen.dart'
;
import
'package:gen_rentals/Screens/DashboardScreen.dart'
;
import
'package:gen_rentals/Screens/DashboardScreen.dart'
;
import
'package:gen_rentals/Screens/ProductsDetailScreen.dart'
;
import
'package:gen_rentals/Screens/ProductsDetailScreen.dart'
;
import
'package:gen_rentals/Screens/TransactionsScreen.dart'
;
import
'package:gen_rentals/Screens/
TransactionScreens/
TransactionsScreen.dart'
;
import
'../Utility/CustomSnackbar.dart'
;
import
'../Utility/CustomSnackbar.dart'
;
import
'../Utility/SharedpreferencesService.dart'
;
import
'../Utility/SharedpreferencesService.dart'
;
import
'authScreen/LoginScreen.dart'
;
import
'authScreen/LoginScreen.dart'
;
...
...
lib/Screens/TransactionScreens/BillStatusToast.dart
0 → 100644
View file @
97cb09f8
import
'package:flutter/material.dart'
;
import
'package:flutter_svg/flutter_svg.dart'
;
import
'package:gen_rentals/Utility/AppColors.dart'
;
enum
BillStatusType
{
paid
,
pending
}
class
BillStatusToast
extends
StatelessWidget
{
final
BillStatusType
type
;
final
String
amount
;
final
String
orderId
;
final
String
date
;
final
String
product
;
final
String
productPrice
;
final
String
total
;
final
VoidCallback
onDownload
;
final
VoidCallback
?
onPayNow
;
const
BillStatusToast
({
super
.
key
,
required
this
.
type
,
required
this
.
amount
,
required
this
.
orderId
,
required
this
.
date
,
required
this
.
product
,
required
this
.
productPrice
,
required
this
.
total
,
required
this
.
onDownload
,
this
.
onPayNow
,
});
@override
Widget
build
(
BuildContext
context
)
{
final
isPaid
=
type
==
BillStatusType
.
paid
;
return
Dialog
(
insetPadding:
const
EdgeInsets
.
all
(
16
),
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
16
)),
child:
Padding
(
padding:
const
EdgeInsets
.
all
(
20
),
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
// ✅ or ❌ icon
Container
(
decoration:
BoxDecoration
(
color:
isPaid
?
Colors
.
green
.
withOpacity
(
0.1
)
:
Colors
.
red
.
withOpacity
(
0.1
),
shape:
BoxShape
.
circle
,
),
padding:
const
EdgeInsets
.
all
(
12
),
child:
Icon
(
isPaid
?
Icons
.
check_circle
:
Icons
.
access_time_filled
,
color:
isPaid
?
Colors
.
green
:
Colors
.
red
,
size:
40
,
),
),
const
SizedBox
(
height:
12
),
Text
(
isPaid
?
"Payment Receipt"
:
"Bill Pending"
,
style:
const
TextStyle
(
fontSize:
18
,
fontWeight:
FontWeight
.
w600
,
fontFamily:
"Plus Jakarta Sans"
,
),
),
const
SizedBox
(
height:
6
),
Text
(
"₹
$amount
"
,
style:
const
TextStyle
(
fontSize:
28
,
fontWeight:
FontWeight
.
w700
,
color:
Colors
.
black
,
),
),
const
SizedBox
(
height:
18
),
// Details
const
Divider
(
thickness:
1
),
Align
(
alignment:
Alignment
.
centerLeft
,
child:
Text
(
"Payment Details"
,
style:
TextStyle
(
fontSize:
15
,
color:
Colors
.
grey
[
700
],
fontWeight:
FontWeight
.
w500
,
),
),
),
const
SizedBox
(
height:
10
),
_detailRow
(
"Order ID"
,
"#
$orderId
"
,
true
),
_detailRow
(
"Date"
,
date
,
false
),
if
(
isPaid
)
_detailRow
(
"Payment Mode"
,
"UPI"
,
false
),
const
SizedBox
(
height:
10
),
const
Divider
(
thickness:
1
),
Align
(
alignment:
Alignment
.
centerLeft
,
child:
Text
(
"Products"
,
style:
TextStyle
(
fontSize:
15
,
color:
Colors
.
grey
[
700
],
fontWeight:
FontWeight
.
w500
,
),
),
),
const
SizedBox
(
height:
10
),
_detailRow
(
product
,
"₹
${productPrice}
"
,
false
),
const
SizedBox
(
height:
10
),
const
Divider
(
thickness:
1
),
_detailRow
(
"Total"
,
"₹
$total
"
,
true
),
const
SizedBox
(
height:
20
),
// Bottom buttons
if
(
isPaid
)
SizedBox
(
width:
double
.
infinity
,
child:
ElevatedButton
.
icon
(
onPressed:
onDownload
,
icon:
const
Icon
(
Icons
.
download
,
color:
Colors
.
white
),
label:
const
Text
(
"Download Receipt"
,
style:
TextStyle
(
fontSize:
16
,
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w600
,
color:
Colors
.
white
,
),
),
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
AppColors
.
amountText
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
50
),
),
padding:
const
EdgeInsets
.
symmetric
(
vertical:
14
),
),
),
)
else
Row
(
children:
[
Expanded
(
child:
OutlinedButton
.
icon
(
onPressed:
onDownload
,
icon:
const
Icon
(
Icons
.
download
,
color:
Colors
.
black
),
label:
const
Text
(
"Download"
,
style:
TextStyle
(
color:
Colors
.
black
,
fontWeight:
FontWeight
.
w600
,
),
),
style:
OutlinedButton
.
styleFrom
(
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
50
),
),
side:
const
BorderSide
(
color:
Colors
.
black26
),
padding:
const
EdgeInsets
.
symmetric
(
vertical:
14
),
),
),
),
const
SizedBox
(
width:
10
),
Expanded
(
child:
ElevatedButton
(
onPressed:
onPayNow
,
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
AppColors
.
amountText
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
50
),
),
padding:
const
EdgeInsets
.
symmetric
(
vertical:
14
),
),
child:
const
Text
(
"Pay Now"
,
style:
TextStyle
(
fontSize:
16
,
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w600
,
color:
Colors
.
white
,
),
),
),
),
],
),
],
),
),
);
}
Widget
_detailRow
(
String
title
,
String
value
,
bool
highlight
)
{
return
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
vertical:
4
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
Text
(
title
,
style:
const
TextStyle
(
fontSize:
14
,
color:
Colors
.
black54
,
)),
Text
(
value
,
style:
TextStyle
(
fontSize:
14
,
fontWeight:
highlight
?
FontWeight
.
w600
:
FontWeight
.
w500
,
color:
highlight
?
Colors
.
black
:
Colors
.
black87
,
),
),
],
),
);
}
}
lib/Screens/TransactionsScreen.dart
→
lib/Screens/
TransactionScreens/
TransactionsScreen.dart
View file @
97cb09f8
...
@@ -2,9 +2,11 @@ import 'package:flutter/material.dart';
...
@@ -2,9 +2,11 @@ import 'package:flutter/material.dart';
import
'package:flutter_svg/flutter_svg.dart'
;
import
'package:flutter_svg/flutter_svg.dart'
;
import
'package:provider/provider.dart'
;
import
'package:provider/provider.dart'
;
import
'../Notifier/TransactionsProvider.dart'
;
import
'../../Notifier/TransactionsProvider.dart'
;
import
'../Utility/AppColors.dart'
;
import
'../../Utility/AppColors.dart'
;
import
'DashboardScreen.dart'
;
import
'../../Utility/CustomSnackbar.dart'
;
import
'../DashboardScreen.dart'
;
import
'BillStatusToast.dart'
;
class
TransactionsScreen
extends
StatefulWidget
{
class
TransactionsScreen
extends
StatefulWidget
{
final
String
sessionId
;
final
String
sessionId
;
...
@@ -95,12 +97,74 @@ class _TransactionsScreenState extends State<TransactionsScreen> {
...
@@ -95,12 +97,74 @@ class _TransactionsScreenState extends State<TransactionsScreen> {
color:
Colors
.
black
,
color:
Colors
.
black
,
),
),
),
),
const
SizedBox
(
height:
8
),
SizedBox
(
height:
8
),
...
items
.
map
((
txn
)
=>
_buildTransactionItem
(
...
items
.
map
((
txn
)
=>
InkResponse
(
type:
txn
.
type
??
""
,
onTap:
()
async
{
title:
txn
.
purpose
??
"-"
,
date:
txn
.
date
??
""
,
// Step 1: Fetch receipt details
amount:
"₹
${txn.amount ?? "0.00"}
"
,
await
provider
.
fetchPaymentReceiptDetails
(
widget
.
sessionId
,
widget
.
accId
,
txn
.
paymentId
.
toString
(),
);
// Step 2: If found, show the toast dialog
if
(
provider
.
receiptDetails
!=
null
)
{
final
receipt
=
provider
.
receiptDetails
!;
showDialog
(
context:
context
,
builder:
(
_
)
=>
BillStatusToast
(
type:
BillStatusType
.
paid
,
amount:
receipt
.
cAmount
??
"0"
,
orderId:
receipt
.
billId
??
""
,
date:
receipt
.
prDate
??
""
,
product:
receipt
.
narration
??
"N/A"
,
productPrice:
receipt
.
dAmount
??
""
,
total:
receipt
.
cAmount
??
"0"
,
/// Use provider for Download
onDownload:
()
async
{
Navigator
.
pop
(
context
);
// Close toast before downloading
await
provider
.
downloadPaymentReceipt
(
context
,
widget
.
sessionId
,
receipt
.
id
??
""
,
widget
.
accId
,
);
},
/// Handle Pay Now
onPayNow:
()
{
Navigator
.
pop
(
context
);
// Navigate to payment screen or trigger payment flow
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (_) => PaymentScreen(
// accId: widget.accId,
// sessionId: widget.sessionId,
// ledgerId: receipt.id ?? "",
// ),
// ),
// );
},
),
);
}
else
{
CustomSnackBar
.
showError
(
context:
context
,
message:
"Unable to fetch receipt details"
,
);
}
},
child:
_buildTransactionItem
(
type:
txn
.
type
??
""
,
title:
txn
.
purpose
??
"-"
,
date:
txn
.
date
??
""
,
amount:
"₹
${txn.amount ?? "0.00"}
"
,
),
)),
)),
],
],
);
);
...
@@ -418,7 +482,8 @@ class _TransactionsScreenState extends State<TransactionsScreen> {
...
@@ -418,7 +482,8 @@ class _TransactionsScreenState extends State<TransactionsScreen> {
return
PaymentBottomSheetContent
(
return
PaymentBottomSheetContent
(
payTotal:
payTotal
,
payTotal:
payTotal
,
payBill:
payBill
,
payBill:
payBill
,
flag:
false
,
billFlag:
false
,
partFlag:
true
,
);
);
},
},
);
);
...
...
lib/Screens/authScreen/OTP_Screen.dart
View file @
97cb09f8
...
@@ -207,11 +207,11 @@ class _OtpScreenState extends State<OtpScreen> {
...
@@ -207,11 +207,11 @@ class _OtpScreenState extends State<OtpScreen> {
filled:
true
,
filled:
true
,
fillColor:
Colors
.
white
,
fillColor:
Colors
.
white
,
enabledBorder:
OutlineInputBorder
(
enabledBorder:
OutlineInputBorder
(
borderRadius:
BorderRadius
.
circular
(
5
0
),
borderRadius:
BorderRadius
.
circular
(
6
0
),
borderSide:
BorderSide
(
color:
Colors
.
grey
.
withOpacity
(
0.5
),
width:
1
),
borderSide:
BorderSide
(
color:
Colors
.
grey
.
withOpacity
(
0.5
),
width:
1
),
),
),
focusedBorder:
OutlineInputBorder
(
focusedBorder:
OutlineInputBorder
(
borderRadius:
BorderRadius
.
circular
(
5
0
),
borderRadius:
BorderRadius
.
circular
(
6
0
),
borderSide:
const
BorderSide
(
color:
Color
(
0xFF008CDE
),
width:
2
),
borderSide:
const
BorderSide
(
color:
Color
(
0xFF008CDE
),
width:
2
),
),
),
),
),
...
...
lib/Services/api_URLs.dart
View file @
97cb09f8
...
@@ -11,7 +11,9 @@ const transactionsUrl = "${baseUrl}transactions";
...
@@ -11,7 +11,9 @@ const transactionsUrl = "${baseUrl}transactions";
const
balanceUrl
=
"
${baseUrl}
balance"
;
const
balanceUrl
=
"
${baseUrl}
balance"
;
const
billDetailsUrl
=
"
${baseUrl}
bill_details"
;
const
billDetailsUrl
=
"
${baseUrl}
bill_details"
;
const
billListUrl
=
"
${baseUrl}
bill_list"
;
const
billListUrl
=
"
${baseUrl}
bill_list"
;
const
billProductUrl
=
"
${baseUrl}
bill_product"
;
const
downloadBillUrl
=
"
${baseUrl}
download_bill"
;
const
paymentReceiptDetailsUrl
=
"
${baseUrl}
payment_receipt_details"
;
const
downloadReceiptUrl
=
"
${baseUrl}
download_receipt"
;
/// info
/// info
const
checkInOutSubmitUrl
=
"
${baseUrl}
check_in_out_submit"
;
const
checkInOutSubmitUrl
=
"
${baseUrl}
check_in_out_submit"
;
...
@@ -36,4 +38,5 @@ const ticketListUrl = "${baseUrl}ticket_list";
...
@@ -36,4 +38,5 @@ const ticketListUrl = "${baseUrl}ticket_list";
/// dashboard and login
/// dashboard and login
const
fetchMobileUrl
=
"
${baseUrl2}
Rental_Auth/fetch_mobile_number"
;
const
fetchMobileUrl
=
"
${baseUrl2}
Rental_Auth/fetch_mobile_number"
;
const
fetchOtpUrl
=
"
${baseUrl2}
Rental_Auth/login"
;
const
fetchOtpUrl
=
"
${baseUrl2}
Rental_Auth/login"
;
const
dashboardUrl
=
"
${baseUrl2}
Rental_Home/dashboard"
;
const
dashboardUrl
=
"
${baseUrl2}
Rental_Home/dashboard"
;
\ No newline at end of file
const
logoutUrl
=
"
${baseUrl2}
Rental_Auth/logout"
;
\ No newline at end of file
lib/Services/api_calling.dart
View file @
97cb09f8
import
'dart:convert'
;
import
'dart:convert'
;
import
'dart:io'
;
import
'dart:io'
;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:gen_rentals/Models/CommonResponse.dart'
;
import
'package:gen_rentals/Models/CommonResponse.dart'
;
import
'package:gen_rentals/Models/HelpAndEnquiryModels/TicketChatDisplayResponse.dart'
;
import
'package:gen_rentals/Models/HelpAndEnquiryModels/TicketChatDisplayResponse.dart'
;
import
'package:gen_rentals/Models/billListResponse.dart'
;
import
'package:gen_rentals/Models/BillsModels/billListResponse.dart'
;
import
'package:gen_rentals/Models/TransactionModels/PaymentReceiptDetailsResponse.dart'
;
import
'package:gen_rentals/Models/billProductResponse.dart'
;
import
'package:gen_rentals/Models/billProductResponse.dart'
;
import
'package:gen_rentals/Models/orderDetailsBillResponse.dart'
;
import
'package:gen_rentals/Models/orderDetailsMainResponse.dart'
;
import
'package:gen_rentals/Models/orderDetailsMainResponse.dart'
;
import
'package:gen_rentals/Models/orderDetailsProductResponse.dart'
;
import
'package:gen_rentals/Models/orderDetailsProductResponse.dart'
;
import
'package:gen_rentals/Models/SubscribeOrderDetailsResponse.dart'
;
import
'package:gen_rentals/Models/SubscribeOrderDetailsResponse.dart'
;
import
'package:gen_rentals/Models/HelpAndEnquiryModels/ticketListResponse.dart'
;
import
'package:gen_rentals/Models/HelpAndEnquiryModels/ticketListResponse.dart'
;
import
'
package:gen_rentals/Notifier/b
illDetailsResponse.dart'
;
import
'
../Models/BillsModels/B
illDetailsResponse.dart'
;
import
'../Models/DashboardResponse.dart'
;
import
'../Models/DashboardResponse.dart'
;
import
'../Models/RentalPaymentDetailsResponse.dart'
;
import
'../Models/RentalPaymentDetailsResponse.dart'
;
import
'../Models/TransactionsResponse.dart'
;
import
'../Models/TransactionModels/TransactionsResponse.dart'
;
import
'../Models/orderDetailsBillResponse.dart'
;
import
'../Models/rentalAccountResponse.dart'
;
import
'../Models/rentalAccountResponse.dart'
;
import
'../Models/rentalContactResponse.dart'
;
import
'../Models/rentalContactResponse.dart'
;
import
'../Notifier/RentalContactProvider .dart'
;
import
'../Notifier/RentalContactProvider .dart'
;
import
'api_URLs.dart'
;
import
'api_URLs.dart'
;
import
'api_post_request.dart'
;
import
'api_post_request.dart'
;
import
'package:http/http.dart'
as
http
show
MultipartFile
;
class
ApiCalling
{
class
ApiCalling
{
...
@@ -74,6 +74,31 @@ class ApiCalling {
...
@@ -74,6 +74,31 @@ class ApiCalling {
}
}
}
}
static
Future
<
CommonResponse
?>
logoutApi
(
String
accId
,
String
sessionId
,
Map
<
String
,
String
>
deviceDetails
)
async
{
debugPrint
(
"############################### Api calling "
);
try
{
Map
<
String
,
String
>
data
=
{
"acc_id"
:
accId
,
"session_id"
:
sessionId
,
};
final
res
=
await
post
(
data
,
fetchOtpUrl
,
{});
if
(
res
!=
null
)
{
return
CommonResponse
.
fromJson
(
jsonDecode
(
res
.
body
));
}
else
{
debugPrint
(
"Null Response"
);
return
null
;
}
}
catch
(
e
)
{
debugPrint
(
"❌ API Error:
$e
"
);
return
null
;
}
}
/// Fetch Rental Account Info
/// Fetch Rental Account Info
static
Future
<
RentalAccountResponse
?>
fetchRentalAccountInfoApi
(
static
Future
<
RentalAccountResponse
?>
fetchRentalAccountInfoApi
(
...
@@ -103,13 +128,13 @@ class ApiCalling {
...
@@ -103,13 +128,13 @@ class ApiCalling {
/// Fetch Bill List
/// Fetch Bill List
static
Future
<
BillListResponse
?>
fetchBillListApi
(
static
Future
<
BillListResponse
?>
fetchBillListApi
(
String
sessionId
,
String
sessionId
,
String
emp
Id
,
String
order
Id
,
String
accId
,
String
accId
,
)
async
{
)
async
{
try
{
try
{
Map
<
String
,
String
>
data
=
{
Map
<
String
,
String
>
data
=
{
"session_id"
:
sessionId
,
"session_id"
:
sessionId
,
"
emp
_id"
:
emp
Id
,
"
order
_id"
:
order
Id
,
"acc_id"
:
accId
,
"acc_id"
:
accId
,
};
};
...
@@ -130,13 +155,13 @@ class ApiCalling {
...
@@ -130,13 +155,13 @@ class ApiCalling {
/// Fetch Bill Details
/// Fetch Bill Details
static
Future
<
BillDetailsResponse
?>
fetchBillDetailsApi
(
static
Future
<
BillDetailsResponse
?>
fetchBillDetailsApi
(
String
sessionId
,
String
sessionId
,
String
emp
Id
,
String
acc
Id
,
String
billId
,
String
billId
,
)
async
{
)
async
{
try
{
try
{
Map
<
String
,
String
>
data
=
{
Map
<
String
,
String
>
data
=
{
"session_id"
:
sessionId
,
"session_id"
:
sessionId
,
"
emp
_id"
:
emp
Id
,
"
acc
_id"
:
acc
Id
,
"bill_id"
:
billId
,
"bill_id"
:
billId
,
};
};
...
@@ -155,8 +180,8 @@ class ApiCalling {
...
@@ -155,8 +180,8 @@ class ApiCalling {
}
}
///
Fetch
Bill
Product
/// Bill
Download api
static
Future
<
BillProductResponse
?>
fetchBillProduct
Api
(
static
Future
<
CommonResponse
?>
billDownload
Api
(
String
sessionId
,
String
sessionId
,
String
empId
,
String
empId
,
String
accId
,
String
accId
,
...
@@ -164,51 +189,82 @@ class ApiCalling {
...
@@ -164,51 +189,82 @@ class ApiCalling {
try
{
try
{
Map
<
String
,
String
>
data
=
{
Map
<
String
,
String
>
data
=
{
"session_id"
:
sessionId
,
"session_id"
:
sessionId
,
"emp_id"
:
empId
,
"bill_id"
:
empId
,
"acc_id"
:
accId
,
};
final
res
=
await
post
(
data
,
downloadBillUrl
,
{});
if
(
res
!=
null
)
{
return
CommonResponse
.
fromJson
(
jsonDecode
(
res
.
body
));
}
else
{
debugPrint
(
"Null Response"
);
return
null
;
}
}
catch
(
e
)
{
debugPrint
(
"❌ API Error (billDownload):
$e
"
);
return
null
;
}
}
/// Payment Receipt Details api
static
Future
<
PaymentReceiptDetailsResponse
?>
fetchPaymentReceiptDetailsApi
(
String
sessionId
,
String
accId
,
String
ledgerId
,
)
async
{
try
{
Map
<
String
,
String
>
data
=
{
"session_id"
:
sessionId
,
"acc_id"
:
accId
,
"acc_id"
:
accId
,
"ledger_id"
:
ledgerId
,
};
};
final
res
=
await
post
(
data
,
billProductUrl
,
{});
final
res
=
await
post
(
data
,
paymentReceiptDetailsUrl
,
{});
debugPrint
(
"TR Response
${res?.body}
"
);
if
(
res
!=
null
)
{
if
(
res
!=
null
)
{
return
BillProduct
Response
.
fromJson
(
jsonDecode
(
res
.
body
));
return
PaymentReceiptDetails
Response
.
fromJson
(
jsonDecode
(
res
.
body
));
}
else
{
}
else
{
debugPrint
(
"Null Response"
);
debugPrint
(
"Null Response"
);
return
null
;
return
null
;
}
}
}
catch
(
e
)
{
}
catch
(
e
)
{
debugPrint
(
"❌ API Error (
fetchBillProduct
):
$e
"
);
debugPrint
(
"❌ API Error (
paymentReceiptDetails
):
$e
"
);
return
null
;
return
null
;
}
}
}
}
///
Fetch Order Detail Bill
///
Payment Receipt DownloadApi
static
Future
<
OrderDetailsBillResponse
?>
fetchOrderDetailBill
Api
(
static
Future
<
CommonResponse
?>
paymentReceiptDownload
Api
(
String
sessionId
,
String
sessionId
,
String
emp
Id
,
String
ledger
Id
,
String
order
Id
,
String
acc
Id
,
)
async
{
)
async
{
try
{
try
{
Map
<
String
,
String
>
data
=
{
Map
<
String
,
String
>
data
=
{
"session_id"
:
sessionId
,
"session_id"
:
sessionId
,
"
emp_id"
:
emp
Id
,
"
ledger_id"
:
ledger
Id
,
"
ord
_id"
:
order
Id
,
"
acc
_id"
:
acc
Id
,
};
};
final
res
=
await
post
(
data
,
orderDetailsBillUrl
,
{});
final
res
=
await
post
(
data
,
downloadReceiptUrl
,
{});
debugPrint
(
"DownloadApi Response
${res}
"
);
if
(
res
!=
null
)
{
if
(
res
!=
null
)
{
return
OrderDetailsBill
Response
.
fromJson
(
jsonDecode
(
res
.
body
));
return
Common
Response
.
fromJson
(
jsonDecode
(
res
.
body
));
}
else
{
}
else
{
debugPrint
(
"Null Response"
);
debugPrint
(
"Null Response"
);
return
null
;
return
null
;
}
}
}
catch
(
e
)
{
}
catch
(
e
)
{
debugPrint
(
"❌ API Error (
fetchOrderDetailBill
):
$e
"
);
debugPrint
(
"❌ API Error (
billDownload
):
$e
"
);
return
null
;
return
null
;
}
}
}
}
/// Fetch Subscribe Order Details
/// Fetch Subscribe Order Details
static
Future
<
SubscribeOrderDetailsResponse
?>
fetchSubsOrderDetailApi
(
static
Future
<
SubscribeOrderDetailsResponse
?>
fetchSubsOrderDetailApi
(
String
sessionId
,
String
sessionId
,
...
@@ -371,15 +427,42 @@ class ApiCalling {
...
@@ -371,15 +427,42 @@ class ApiCalling {
return
null
;
return
null
;
}
}
}
}
//
// static Future<addTicketResponse?> addTicketAPI(
// type, description, List<http.MultipartFile> newList) async {
// if (await CheckHeaderValidity()) {
// try {
// Map<String, String> data = {
// 'type': type.toString(),
// 'description': description.toString(),
// //ticket_image
// };
// // print("Add ticket ${data}");
// final header = await HeaderValues();
// final res = await PostMultipleImagesNew(
// data, addTicketsUrl, header, newList);
// if (res != null) {
// return addTicketResponse.fromJson(jsonDecode(res));
// } else {
// return null;
// }
// } catch (e) {
// debugPrint('hello bev=bug $e ');
// return null;
// }
// } else {
// return addTicketResponse(error: "401");
// }
// }
/// Send Message Chat Api
/// Send Message Chat Api
/// Send Message Chat Api
static
Future
<
CommonResponse
?>
addMessageApi
(
static
Future
<
CommonResponse
?>
addMessageApi
(
String
sessionId
,
String
sessionId
,
String
accId
,
String
accId
,
String
ticketId
,
String
ticketId
,
String
msgText
,
String
msgText
,
List
<
File
>?
images
,
List
<
http
.
Multipart
File
>?
images
,
)
async
{
)
async
{
try
{
try
{
Map
<
String
,
String
>
body
=
{
Map
<
String
,
String
>
body
=
{
...
@@ -394,13 +477,15 @@ class ApiCalling {
...
@@ -394,13 +477,15 @@ class ApiCalling {
// Add any other headers you need (auth tokens, etc.)
// Add any other headers you need (auth tokens, etc.)
};
};
final
res
=
await
postMessageWithImages
(
debugPrint
(
"Data to addTicketApi
${body}
"
);
final
res
=
await
PostMultipleImagesNew
(
body
,
body
,
addMessageUrl
,
// Your API endpoint
addMessageUrl
,
// Your API endpoint
headers
,
headers
,
images
??
[],
// Pass empty list if no images
images
??
[],
// Pass empty list if no images
);
);
debugPrint
(
"Response from addMessageApi
${res}
"
);
if
(
res
!=
null
)
{
if
(
res
!=
null
)
{
return
CommonResponse
.
fromJson
(
jsonDecode
(
res
));
return
CommonResponse
.
fromJson
(
jsonDecode
(
res
));
}
else
{
}
else
{
...
@@ -420,6 +505,7 @@ class ApiCalling {
...
@@ -420,6 +505,7 @@ class ApiCalling {
String
type
,
String
type
,
String
description
,
String
description
,
String
orderId
,
String
orderId
,
String
otherReason
,
List
<
File
>?
images
,
List
<
File
>?
images
,
)
async
{
)
async
{
...
@@ -430,7 +516,7 @@ class ApiCalling {
...
@@ -430,7 +516,7 @@ class ApiCalling {
"type"
:
type
,
"type"
:
type
,
"des"
:
description
,
"des"
:
description
,
"order_id"
:
orderId
,
"order_id"
:
orderId
,
"other_reason"
:
otherReason
,
};
};
Map
<
String
,
String
>
headers
=
{
Map
<
String
,
String
>
headers
=
{
...
...
lib/Services/api_post_request.dart
View file @
97cb09f8
...
@@ -181,20 +181,50 @@ Future<String?> postImageNew(
...
@@ -181,20 +181,50 @@ Future<String?> postImageNew(
//hotel_image
//hotel_image
//other_image
//other_image
Future
<
String
?>
PostMultipleImagesNew
(
// Future<String?> PostMultipleImagesNew(
// Map<String, String> body,
// String urlLink,
// Map<String, String> headers,
// List<http.MultipartFile> newList,
// List<http.MultipartFile> newList1,
// List<http.MultipartFile> newList2,
// ) async {
// try {
// var req = http.MultipartRequest('POST', Uri.parse(urlLink));
// req.headers.addAll(headers);
// req.files.addAll(newList);
// req.files.addAll(newList1);
// req.files.addAll(newList2);
// req.fields.addAll(body);
//
// var res = await req.send();
// final resBody = await res.stream.bytesToString();
//
// if (res.statusCode >= 200 && res.statusCode < 300) {
// print("**** $resBody .... $res");
// return resBody;
// } else {
// print("error: ${res.reasonPhrase}");
// return null;
// }
// } catch (e) {
// debugPrint(e.toString());
// return null;
// }
// }
Future
<
String
?>
PostMultipleImagesNew2
(
Map
<
String
,
String
>
body
,
Map
<
String
,
String
>
body
,
String
urlLink
,
String
urlLink
,
Map
<
String
,
String
>
headers
,
Map
<
String
,
String
>
headers
,
List
<
http
.
MultipartFile
>
newList
,
List
<
http
.
MultipartFile
>
newList
,
List
<
http
.
MultipartFile
>
newList1
,
List
<
http
.
MultipartFile
>
newList1
,
List
<
http
.
MultipartFile
>
newList2
,
)
async
{
)
async
{
try
{
try
{
var
req
=
http
.
MultipartRequest
(
'POST'
,
Uri
.
parse
(
urlLink
));
var
req
=
http
.
MultipartRequest
(
'POST'
,
Uri
.
parse
(
urlLink
));
req
.
headers
.
addAll
(
headers
);
req
.
headers
.
addAll
(
headers
);
req
.
files
.
addAll
(
newList
);
req
.
files
.
addAll
(
newList
);
req
.
files
.
addAll
(
newList1
);
req
.
files
.
addAll
(
newList1
);
req
.
files
.
addAll
(
newList2
);
req
.
fields
.
addAll
(
body
);
req
.
fields
.
addAll
(
body
);
var
res
=
await
req
.
send
();
var
res
=
await
req
.
send
();
...
@@ -213,18 +243,16 @@ Future<String?> PostMultipleImagesNew(
...
@@ -213,18 +243,16 @@ Future<String?> PostMultipleImagesNew(
}
}
}
}
Future
<
String
?>
PostMultipleImages
New2
(
Future
<
String
?>
PostMultipleImages
(
Map
<
String
,
String
>
body
,
Map
<
String
,
String
>
body
,
String
urlLink
,
String
urlLink
,
Map
<
String
,
String
>
headers
,
Map
<
String
,
String
>
headers
,
List
<
http
.
MultipartFile
>
newList
,
List
<
http
.
MultipartFile
>
newList
,
List
<
http
.
MultipartFile
>
newList1
,
)
async
{
)
async
{
try
{
try
{
var
req
=
http
.
MultipartRequest
(
'POST'
,
Uri
.
parse
(
urlLink
));
var
req
=
http
.
MultipartRequest
(
'POST'
,
Uri
.
parse
(
urlLink
));
req
.
headers
.
addAll
(
headers
);
req
.
headers
.
addAll
(
headers
);
req
.
files
.
addAll
(
newList
);
req
.
files
.
addAll
(
newList
);
req
.
files
.
addAll
(
newList1
);
req
.
fields
.
addAll
(
body
);
req
.
fields
.
addAll
(
body
);
var
res
=
await
req
.
send
();
var
res
=
await
req
.
send
();
...
@@ -242,13 +270,11 @@ Future<String?> PostMultipleImagesNew2(
...
@@ -242,13 +270,11 @@ Future<String?> PostMultipleImagesNew2(
return
null
;
return
null
;
}
}
}
}
Future
<
String
?>
PostMultipleImagesNew
(
Future
<
String
?>
PostMultipleImages
(
Map
<
String
,
String
>
body
,
Map
<
String
,
String
>
body
,
String
urlLink
,
String
urlLink
,
Map
<
String
,
String
>
headers
,
Map
<
String
,
String
>
headers
,
List
<
http
.
MultipartFile
>
newList
)
async
{
List
<
http
.
MultipartFile
>
newList
,
)
async
{
try
{
try
{
var
req
=
http
.
MultipartRequest
(
'POST'
,
Uri
.
parse
(
urlLink
));
var
req
=
http
.
MultipartRequest
(
'POST'
,
Uri
.
parse
(
urlLink
));
req
.
headers
.
addAll
(
headers
);
req
.
headers
.
addAll
(
headers
);
...
@@ -271,6 +297,7 @@ Future<String?> PostMultipleImages(
...
@@ -271,6 +297,7 @@ Future<String?> PostMultipleImages(
}
}
}
}
/// Send message with multiple images
/// Send message with multiple images
Future
<
String
?>
postMessageWithImages
(
Future
<
String
?>
postMessageWithImages
(
Map
<
String
,
String
>
body
,
Map
<
String
,
String
>
body
,
...
...
lib/Utility/FullScreenImageViewer.dart
0 → 100644
View file @
97cb09f8
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/material.dart'
;
import
'package:photo_view/photo_view.dart'
;
class
FullScreenImageViewer
extends
StatefulWidget
{
final
String
imageUrl
;
const
FullScreenImageViewer
({
super
.
key
,
required
this
.
imageUrl
});
@override
State
<
FullScreenImageViewer
>
createState
()
=>
_FullScreenImageViewerState
();
}
class
_FullScreenImageViewerState
extends
State
<
FullScreenImageViewer
>
{
PhotoViewController
controller
=
PhotoViewController
();
PhotoViewScaleStateController
scaleStateController
=
PhotoViewScaleStateController
();
bool
_showControls
=
true
;
@override
void
initState
()
{
super
.
initState
();
// Auto-hide controls after 3 seconds
Future
.
delayed
(
const
Duration
(
seconds:
3
),
()
{
if
(
mounted
)
{
setState
(()
{
_showControls
=
false
;
});
}
});
}
void
_toggleControls
()
{
setState
(()
{
_showControls
=
!
_showControls
;
});
}
void
_resetImage
()
{
controller
.
reset
();
scaleStateController
.
reset
();
}
void
_rotateImage
()
{
final
double
currentRotation
=
controller
.
rotation
;
controller
.
rotation
=
currentRotation
+
90.0
;
}
@override
Widget
build
(
BuildContext
context
)
{
return
SafeArea
(
top:
false
,
child:
Scaffold
(
backgroundColor:
Color
(
0xFFFFFFFF
),
body:
Stack
(
children:
[
// Main Photo View
GestureDetector
(
onTap:
_toggleControls
,
child:
PhotoView
(
imageProvider:
NetworkImage
(
widget
.
imageUrl
),
controller:
controller
,
scaleStateController:
scaleStateController
,
backgroundDecoration:
const
BoxDecoration
(
color:
Color
(
0xFF444444
),
),
minScale:
PhotoViewComputedScale
.
contained
*
0.8
,
maxScale:
PhotoViewComputedScale
.
covered
*
4
,
initialScale:
PhotoViewComputedScale
.
contained
,
basePosition:
Alignment
.
center
,
filterQuality:
FilterQuality
.
high
,
enableRotation:
true
,
gestureDetectorBehavior:
HitTestBehavior
.
opaque
,
loadingBuilder:
(
context
,
event
)
=>
Center
(
child:
Container
(
width:
40
,
height:
40
,
child:
const
CircularProgressIndicator
(
color:
Colors
.
white
,
strokeWidth:
2
,
),
),
),
errorBuilder:
(
context
,
error
,
stackTrace
)
=>
Center
(
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
const
Icon
(
Icons
.
error_outline
,
color:
Colors
.
white
,
size:
50
,
),
const
SizedBox
(
height:
16
),
Text
(
'Failed to load image'
,
style:
TextStyle
(
color:
Colors
.
white
.
withOpacity
(
0.8
),
fontSize:
16
,
),
),
],
),
),
),
),
// Controls Overlay
if
(
_showControls
)
...[
// Top Bar
Positioned
(
top:
MediaQuery
.
of
(
context
).
padding
.
top
,
left:
0
,
right:
0
,
child:
Container
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
,
vertical:
12
),
decoration:
BoxDecoration
(
gradient:
LinearGradient
(
begin:
Alignment
.
topCenter
,
end:
Alignment
.
bottomCenter
,
colors:
[
Colors
.
black
.
withOpacity
(
0.7
),
Colors
.
black
.
withOpacity
(
0.3
),
Colors
.
transparent
,
],
),
),
child:
Row
(
children:
[
// Close Button
GestureDetector
(
onTap:
()
=>
Navigator
.
pop
(
context
),
child:
Container
(
padding:
const
EdgeInsets
.
all
(
8
),
decoration:
BoxDecoration
(
color:
Colors
.
black
.
withOpacity
(
0.5
),
shape:
BoxShape
.
circle
,
),
child:
const
Icon
(
Icons
.
close
,
color:
Colors
.
white
,
size:
24
,
),
),
),
const
Spacer
(),
// Reset Button
GestureDetector
(
onTap:
_resetImage
,
child:
Container
(
padding:
const
EdgeInsets
.
all
(
8
),
decoration:
BoxDecoration
(
color:
Colors
.
black
.
withOpacity
(
0.5
),
shape:
BoxShape
.
circle
,
),
child:
const
Icon
(
Icons
.
refresh
,
color:
Colors
.
white
,
size:
24
,
),
),
),
const
SizedBox
(
width:
12
),
// Rotate Button
GestureDetector
(
onTap:
_rotateImage
,
child:
Container
(
padding:
const
EdgeInsets
.
all
(
8
),
decoration:
BoxDecoration
(
color:
Colors
.
black
.
withOpacity
(
0.5
),
shape:
BoxShape
.
circle
,
),
child:
const
Icon
(
Icons
.
rotate_90_degrees_ccw
,
color:
Colors
.
white
,
size:
24
,
),
),
),
],
),
),
),
// Bottom Info Bar
Positioned
(
bottom:
0
,
left:
0
,
right:
0
,
child:
Container
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
,
vertical:
20
),
decoration:
BoxDecoration
(
gradient:
LinearGradient
(
begin:
Alignment
.
bottomCenter
,
end:
Alignment
.
topCenter
,
colors:
[
Colors
.
black
.
withOpacity
(
0.7
),
Colors
.
black
.
withOpacity
(
0.3
),
Colors
.
transparent
,
],
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
// Zoom Instructions
Row
(
children:
[
_buildInstructionIcon
(
Icons
.
touch_app
,
"Double tap to zoom"
),
const
SizedBox
(
width:
16
),
_buildInstructionIcon
(
Icons
.
pan_tool
,
"Pan to move"
),
const
SizedBox
(
width:
16
),
_buildInstructionIcon
(
Icons
.
rotate_right
,
"Pinch to rotate"
),
],
),
const
SizedBox
(
height:
12
),
// Image Info
Text
(
"Image Preview"
,
style:
TextStyle
(
color:
Colors
.
white
.
withOpacity
(
0.9
),
fontSize:
14
,
fontWeight:
FontWeight
.
w500
,
),
),
],
),
),
),
],
// Double Tap Zoom Hint (appears briefly)
Positioned
(
bottom:
MediaQuery
.
of
(
context
).
padding
.
bottom
+
100
,
left:
0
,
right:
0
,
child:
AnimatedOpacity
(
opacity:
_showControls
?
1.0
:
0.0
,
duration:
const
Duration
(
milliseconds:
300
),
child:
const
Center
(
child:
Text
(
"Double tap to zoom"
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
14
,
fontWeight:
FontWeight
.
w400
,
),
),
),
),
),
],
),
// Bottom Navigation Bar with additional controls
bottomNavigationBar:
_showControls
?
Container
(
height:
60
,
decoration:
BoxDecoration
(
color:
Colors
.
black
.
withOpacity
(
0.7
),
borderRadius:
const
BorderRadius
.
only
(
topLeft:
Radius
.
circular
(
12
),
topRight:
Radius
.
circular
(
12
),
),
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceEvenly
,
children:
[
// Zoom In
IconButton
(
onPressed:
()
{
final
double
currentScale
=
controller
.
scale
??
1.0
;
controller
.
scale
=
currentScale
*
1.5
;
},
icon:
const
Icon
(
Icons
.
zoom_in
,
color:
Colors
.
white
),
tooltip:
"Zoom In"
,
),
// Zoom Out
IconButton
(
onPressed:
()
{
final
double
currentScale
=
controller
.
scale
??
1.0
;
controller
.
scale
=
currentScale
/
1.5
;
},
icon:
const
Icon
(
Icons
.
zoom_out
,
color:
Colors
.
white
),
tooltip:
"Zoom Out"
,
),
// Reset
IconButton
(
onPressed:
_resetImage
,
icon:
const
Icon
(
Icons
.
fit_screen
,
color:
Colors
.
white
),
tooltip:
"Reset"
,
),
// Rotate
IconButton
(
onPressed:
_rotateImage
,
icon:
const
Icon
(
Icons
.
rotate_90_degrees_ccw
,
color:
Colors
.
white
),
tooltip:
"Rotate 90°"
,
),
],
),
)
:
null
,
),
);
}
Widget
_buildInstructionIcon
(
IconData
icon
,
String
text
)
{
return
Row
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
Icon
(
icon
,
color:
Colors
.
white
.
withOpacity
(
0.7
),
size:
16
),
const
SizedBox
(
width:
4
),
Text
(
text
,
style:
TextStyle
(
color:
Colors
.
white
.
withOpacity
(
0.7
),
fontSize:
12
,
),
),
],
);
}
@override
void
dispose
()
{
controller
.
dispose
();
scaleStateController
.
dispose
();
super
.
dispose
();
}
}
\ No newline at end of file
lib/main.dart
View file @
97cb09f8
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:gen_rentals/Notifier/BillProvider.dart'
;
import
'package:gen_rentals/Notifier/DashboardProvider.dart'
;
import
'package:gen_rentals/Notifier/DashboardProvider.dart'
;
import
'package:gen_rentals/Notifier/HelpAndEnquiryProvider.dart'
;
import
'package:gen_rentals/Notifier/HelpAndEnquiryProvider.dart'
;
import
'package:gen_rentals/Notifier/TransactionsProvider.dart'
;
import
'package:gen_rentals/Notifier/TransactionsProvider.dart'
;
...
@@ -34,6 +35,7 @@ class MyApp extends StatelessWidget {
...
@@ -34,6 +35,7 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider
(
create:
(
_
)
=>
SubscribeOrderDetailsProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
SubscribeOrderDetailsProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
TransactionsProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
TransactionsProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
HelpAndEnquiryProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
HelpAndEnquiryProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
BillProvider
()),
],
],
child:
Consumer
<
ThemeProvider
>(
child:
Consumer
<
ThemeProvider
>(
builder:
(
context
,
themeProvider
,
child
)
{
builder:
(
context
,
themeProvider
,
child
)
{
...
@@ -41,24 +43,7 @@ class MyApp extends StatelessWidget {
...
@@ -41,24 +43,7 @@ class MyApp extends StatelessWidget {
debugShowCheckedModeBanner:
false
,
debugShowCheckedModeBanner:
false
,
title:
'Gen Rentals'
,
title:
'Gen Rentals'
,
theme:
ThemeData
(
theme:
ThemeData
(
brightness:
themeProvider
.
isDark
?
Brightness
.
dark
:
Brightness
.
light
,
fontFamily:
'PoppinsRegular'
,
fontFamily:
'Poppins'
,
textTheme:
const
TextTheme
(
bodyMedium:
TextStyle
(
fontSize:
14
,
fontWeight:
FontWeight
.
w400
,
height:
1.5
,
letterSpacing:
-
0.12
,
),
titleMedium:
TextStyle
(
fontSize:
16
,
fontWeight:
FontWeight
.
w500
,
),
labelLarge:
TextStyle
(
fontSize:
12
,
fontWeight:
FontWeight
.
w700
,
),
),
),
),
home:
const
SplashScreen
(),
home:
const
SplashScreen
(),
);
);
...
...
pubspec.lock
View file @
97cb09f8
...
@@ -157,10 +157,10 @@ packages:
...
@@ -157,10 +157,10 @@ packages:
dependency: transitive
dependency: transitive
description:
description:
name: fake_async
name: fake_async
sha256: "
6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc
"
sha256: "
5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44
"
url: "https://pub.dev"
url: "https://pub.dev"
source: hosted
source: hosted
version: "1.3.
2
"
version: "1.3.
3
"
ffi:
ffi:
dependency: transitive
dependency: transitive
description:
description:
...
@@ -412,26 +412,26 @@ packages:
...
@@ -412,26 +412,26 @@ packages:
dependency: transitive
dependency: transitive
description:
description:
name: leak_tracker
name: leak_tracker
sha256:
c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
sha256:
"33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
url: "https://pub.dev"
url: "https://pub.dev"
source: hosted
source: hosted
version: "1
0
.0.
8
"
version: "1
1
.0.
2
"
leak_tracker_flutter_testing:
leak_tracker_flutter_testing:
dependency: transitive
dependency: transitive
description:
description:
name: leak_tracker_flutter_testing
name: leak_tracker_flutter_testing
sha256:
f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
sha256:
"1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.dev"
url: "https://pub.dev"
source: hosted
source: hosted
version: "3.0.
9
"
version: "3.0.
10
"
leak_tracker_testing:
leak_tracker_testing:
dependency: transitive
dependency: transitive
description:
description:
name: leak_tracker_testing
name: leak_tracker_testing
sha256: "
6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3
"
sha256: "
8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1
"
url: "https://pub.dev"
url: "https://pub.dev"
source: hosted
source: hosted
version: "3.0.
1
"
version: "3.0.
2
"
lints:
lints:
dependency: transitive
dependency: transitive
description:
description:
...
@@ -504,6 +504,14 @@ packages:
...
@@ -504,6 +504,14 @@ packages:
url: "https://pub.dev"
url: "https://pub.dev"
source: hosted
source: hosted
version: "2.1.0"
version: "2.1.0"
open_filex:
dependency: "direct dev"
description:
name: open_filex
sha256: "9976da61b6a72302cf3b1efbce259200cd40232643a467aac7370addf94d6900"
url: "https://pub.dev"
source: hosted
version: "4.7.0"
package_info_plus:
package_info_plus:
dependency: "direct dev"
dependency: "direct dev"
description:
description:
...
@@ -537,7 +545,7 @@ packages:
...
@@ -537,7 +545,7 @@ packages:
source: hosted
source: hosted
version: "1.1.0"
version: "1.1.0"
path_provider:
path_provider:
dependency:
transitive
dependency:
"direct dev"
description:
description:
name: path_provider
name: path_provider
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
...
@@ -640,6 +648,14 @@ packages:
...
@@ -640,6 +648,14 @@ packages:
url: "https://pub.dev"
url: "https://pub.dev"
source: hosted
source: hosted
version: "6.1.0"
version: "6.1.0"
photo_view:
dependency: "direct dev"
description:
name: photo_view
sha256: "8036802a00bae2a78fc197af8a158e3e2f7b500561ed23b4c458107685e645bb"
url: "https://pub.dev"
source: hosted
version: "0.14.0"
platform:
platform:
dependency: transitive
dependency: transitive
description:
description:
...
@@ -841,10 +857,10 @@ packages:
...
@@ -841,10 +857,10 @@ packages:
dependency: transitive
dependency: transitive
description:
description:
name: test_api
name: test_api
sha256:
fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
sha256:
"522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
url: "https://pub.dev"
url: "https://pub.dev"
source: hosted
source: hosted
version: "0.7.
4
"
version: "0.7.
6
"
typed_data:
typed_data:
dependency: transitive
dependency: transitive
description:
description:
...
@@ -889,10 +905,10 @@ packages:
...
@@ -889,10 +905,10 @@ packages:
dependency: transitive
dependency: transitive
description:
description:
name: vector_math
name: vector_math
sha256:
"80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
sha256:
d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.dev"
url: "https://pub.dev"
source: hosted
source: hosted
version: "2.
1.4
"
version: "2.
2.0
"
vm_service:
vm_service:
dependency: transitive
dependency: transitive
description:
description:
...
@@ -942,5 +958,5 @@ packages:
...
@@ -942,5 +958,5 @@ packages:
source: hosted
source: hosted
version: "6.5.0"
version: "6.5.0"
sdks:
sdks:
dart: ">=3.
7.2
<4.0.0"
dart: ">=3.
8.0-0
<4.0.0"
flutter: ">=3.29.0"
flutter: ">=3.29.0"
pubspec.yaml
View file @
97cb09f8
...
@@ -60,6 +60,9 @@ dev_dependencies:
...
@@ -60,6 +60,9 @@ dev_dependencies:
firebase_core
:
^4.1.1
firebase_core
:
^4.1.1
device_info_plus
:
^10.0.0
device_info_plus
:
^10.0.0
image_picker
:
^1.0.4
image_picker
:
^1.0.4
path_provider
:
^2.1.4
open_filex
:
^4.4.0
photo_view
:
^0.14.0
#flutter_local_notifications: ^17.2.0
#flutter_local_notifications: ^17.2.0
...
@@ -94,18 +97,24 @@ flutter:
...
@@ -94,18 +97,24 @@ flutter:
# list giving the asset and other descriptors for the font. For
# list giving the asset and other descriptors for the font. For
# example:
# example:
fonts
:
fonts
:
-
family
:
Poppins
# - family: Trajan Pro
-
family
:
PoppinsRegular
fonts
:
fonts
:
-
asset
:
assets/fonts/Poppins/Poppins-Regular.ttf
-
asset
:
assets/fonts/Poppins/Poppins-Regular.ttf
style
:
normal
-
family
:
PoppinsMedium
fonts
:
-
asset
:
assets/fonts/Poppins/Poppins-Medium.ttf
-
asset
:
assets/fonts/Poppins/Poppins-Medium.ttf
weight
:
500
style
:
normal
-
family
:
PoppinsBold
fonts
:
-
asset
:
assets/fonts/Poppins/Poppins-Bold.ttf
-
asset
:
assets/fonts/Poppins/Poppins-Bold.ttf
weight
:
700
style
:
normal
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
#
# For details regarding fonts from package dependencies,
# For details regarding fonts from package dependencies,
# see https://flutter.dev/to/font-from-package
# see https://flutter.dev/to/font-from-package
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment