Bug fixes

This commit is contained in:
kratikpal 2024-10-16 10:12:17 +05:30
parent 7d424edc11
commit bced613c1d
16 changed files with 218 additions and 58 deletions

View File

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:cheminova/constants/constant.dart';
import 'package:cheminova/provider/add_sales_provider.dart';
import 'package:cheminova/provider/collect_kyc_provider.dart';
import 'package:cheminova/provider/notification_provider.dart';
import 'package:cheminova/provider/pd_rd_provider.dart';
import 'package:cheminova/provider/product_manual_provider.dart';
import 'package:cheminova/provider/product_provider.dart';
@ -109,6 +110,7 @@ Future<void> main() async {
ChangeNotifierProvider(create: (_) => TaskProvider()),
ChangeNotifierProvider(create: (_) => ProductManualProvider()),
ChangeNotifierProvider(create: (_) => AddSalesProvider()),
ChangeNotifierProvider(create: (_) => NotificationProvider()),
],
child: const MyApp(),
),

View File

@ -0,0 +1,19 @@
class AnnouncementModel {
String id;
String message;
String date;
AnnouncementModel({
required this.id,
required this.message,
required this.date,
});
factory AnnouncementModel.fromJson(Map<String, dynamic> json) {
return AnnouncementModel(
id: json['_id'],
message: json['message'],
date: json['createdAt'],
);
}
}

View File

@ -65,7 +65,7 @@ class ShippingAddress {
postalCode: json['postalCode'] ?? '',
country: json['country'] ?? '',
panNumber: json['panNumber'] ?? '',
tradeName: json['tradeName'] ?? '',
tradeName: json['tradeName'] ?? 'XYZ',
gstNumber: json['gstNumber'] ?? '',
isDefault: json['isDefault'] ?? false,
);

View File

@ -5,7 +5,6 @@ import 'package:cheminova/services/secure__storage_service.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
class LoginProvider extends ChangeNotifier {
final _storageService = SecureStorageService();
@ -29,7 +28,8 @@ class LoginProvider extends ChangeNotifier {
'email': emailController.text.trim(),
'password': passwordController.text.trim()
});
setLoading(false);
// Handle successful response
if (response.statusCode == 200) {
await _storageService.write(
key: 'access_token', value: response.data['token']);
@ -37,12 +37,25 @@ class LoginProvider extends ChangeNotifier {
print('fcmToken: $fcmToken');
await _apiClient.post(ApiUrls.fcmUrl, data: {'fcmToken': fcmToken});
return (true, response.data['message'].toString());
} else {
return (false, response.data['message'].toString());
}
} catch (e) {
// Handle other status codes
setLoading(false);
return (false, response.data['message'].toString());
} catch (e) {
// Handle DioError specifically
if (e is DioException) {
setLoading(false);
if (e.response != null && e.response!.statusCode == 400) {
return (false, e.response!.data['message'].toString());
}
}
setLoading(false);
// Return a more informative error message if there's an exception
return (false, 'Something went wrong: ${e.toString()}');
} finally {
setLoading(false);
return (false, 'Something want wrong');
}
}
}

View File

@ -1,3 +1,4 @@
import 'package:cheminova/models/announcement_model.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -13,10 +14,12 @@ class NotificationProvider extends ChangeNotifier {
final _apiClient = ApiClient();
List<Notifications> notificationList = [];
List<AnnouncementModel> _announcementList = [];
bool _isLoading = false;
bool get isLoading => _isLoading;
List<AnnouncementModel> get announcementList => _announcementList;
void setLoading(bool loading) {
_isLoading = loading;
@ -26,15 +29,32 @@ class NotificationProvider extends ChangeNotifier {
Future<void> getNotification() async {
setLoading(true);
try {
Response response = await _apiClient.get(ApiUrls.notificationUrl);
setLoading(false);
if (response.statusCode == 200) {
final data = NotificationListResponse.fromJson(response.data);
notificationList = data.notifications ?? [];
notifyListeners();
}
Response response = await _apiClient.get(ApiUrls.notificationUrl);
setLoading(false);
if (response.statusCode == 200) {
final data = NotificationListResponse.fromJson(response.data);
notificationList = data.notifications ?? [];
notifyListeners();
}
} catch (e) {
setLoading(false);
}
}
Future<void> getAnnouncement() async {
setLoading(true);
try {
Response response = await _apiClient.get(ApiUrls.announcements);
if (response.statusCode == 200) {
_announcementList = (response.data as List)
.map((e) => AnnouncementModel.fromJson(e))
.toList();
notifyListeners();
}
setLoading(false);
} catch (e) {
print(e);
setLoading(false);
}
}
}

View File

@ -0,0 +1,93 @@
import 'package:cheminova/provider/notification_provider.dart';
import 'package:cheminova/utils/string_extension.dart';
import 'package:cheminova/widgets/common_app_bar.dart';
import 'package:cheminova/widgets/common_background.dart';
import 'package:cheminova/widgets/common_drawer.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
class AnnouncementScreen extends StatefulWidget {
const AnnouncementScreen({super.key});
@override
State<AnnouncementScreen> createState() => _AnnouncementScreenState();
}
class _AnnouncementScreenState extends State<AnnouncementScreen> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<NotificationProvider>().getAnnouncement();
});
}
@override
Widget build(BuildContext context) {
final notificationProvider = context.watch<NotificationProvider>();
return CommonBackground(
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: CommonAppBar(
actions: [
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Image.asset('assets/Back_attendance.png'),
padding: const EdgeInsets.only(right: 20),
),
],
title: const Text('Announcement',
style: TextStyle(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w400,
fontFamily: 'Anek')),
backgroundColor: Colors.transparent,
elevation: 0,
),
drawer: const CommonDrawer(),
body: Stack(
children: [
ListView.builder(
itemCount: notificationProvider.announcementList.length,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.only(
bottom: 10,
left: 10,
right: 10,
),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10))),
child: ListTile(
title: const Text('Message:'),
subtitle: Text(
'${notificationProvider.announcementList[index].message.capitalize()}\nDate: ${DateFormat("dd/MM/yyyy").format(
DateTime.parse(notificationProvider
.announcementList[index].date),
)}',
),
),
);
}),
if (notificationProvider.isLoading)
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.2),
),
child: const Center(
child: CircularProgressIndicator(),
),
),
],
),
),
);
}
}

View File

@ -394,15 +394,12 @@ class _AssignTasksScreenState extends State<AssignTasksScreen> {
.map((PdRdResponseModel distributor) {
return DropdownMenuItem<PdRdResponseModel>(
value: distributor,
child: Text(
(selectedDistributorType ==
'PrincipalDistributor'
? distributor
.shippingAddress!.tradeName
.capitalize()
: distributor.kyc!.tradeName
.capitalize()),
),
child: Text(((selectedDistributorType ==
'PrincipalDistributor')
? distributor
.shippingAddress!.tradeName
: distributor.kyc!.tradeName)
.capitalize()),
);
}).toList(),
onChanged: (value) {

View File

@ -123,6 +123,7 @@ class _ChangePasswordPageState extends State<ChangePasswordPage> {
const SizedBox(height: 20),
CommonTextFormField(
controller: _oldPasswordController,
textCapitalization: TextCapitalization.none,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';
@ -133,6 +134,7 @@ class _ChangePasswordPageState extends State<ChangePasswordPage> {
const SizedBox(height: 20),
CommonTextFormField(
controller: _newPasswordController,
textCapitalization: TextCapitalization.none,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';
@ -143,6 +145,7 @@ class _ChangePasswordPageState extends State<ChangePasswordPage> {
const SizedBox(height: 20),
CommonTextFormField(
controller: _confirmPasswordController,
textCapitalization: TextCapitalization.none,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';

View File

@ -141,6 +141,8 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
const SizedBox(height: 20),
CommonTextFormField(
title: ' Enter Your Email ID',
textCapitalization: TextCapitalization.none,
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your email id';

View File

@ -1,5 +1,6 @@
import 'package:cheminova/notification_service.dart';
import 'package:cheminova/provider/user_provider.dart';
import 'package:cheminova/screens/announcement_screen.dart';
import 'package:cheminova/screens/visit_rd_pd_screen.dart';
import 'package:cheminova/screens/assign_task_dash_board_screen.dart';
import 'package:cheminova/screens/calendar_screen.dart';
@ -188,21 +189,24 @@ class _HomePageState extends State<HomePage> {
],
),
const SizedBox(height: 5),
Row(
children: [
Expanded(
child: _buildCustomCard('Rejected Applications',
'Re-upload Rejected Documents', onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const RejectedApplicationScreen(),
));
}),
),
],
),
_buildCustomCard('Rejected Applications',
'Re-upload Rejected Documents', onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const RejectedApplicationScreen(),
));
}),
const SizedBox(height: 5),
_buildCustomCard('Announcements', 'Announcements for you',
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const AnnouncementScreen(),
));
}),
const SizedBox(height: 5),
Row(
children: [

View File

@ -87,6 +87,7 @@ class _LoginPageState extends State<LoginPage> {
Consumer<LoginProvider>(
builder: (context, value, child) =>
CommonTextFormField(
textCapitalization: TextCapitalization.none,
controller: value.emailController,
keyboardType: TextInputType.emailAddress,
validator: (value) {
@ -99,20 +100,24 @@ class _LoginPageState extends State<LoginPage> {
}
return null;
},
title: 'Username'),
title: 'Email'),
),
const SizedBox(height: 20),
Consumer<LoginProvider>(
builder: (context, value, child) =>
CommonTextFormField(
controller: value.passwordController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';
}
return null;
},
title: 'Password')),
builder: (context, value, child) =>
CommonTextFormField(
textCapitalization: TextCapitalization.none,
obscureText: true,
controller: value.passwordController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';
}
return null;
},
title: 'Password',
),
),
const SizedBox(height: 15),
Align(
alignment: Alignment.center,

View File

@ -178,11 +178,11 @@ class _SelectDistributerScreenState extends State<SelectDistributerScreen> {
return DropdownMenuItem<PdRdResponseModel>(
value: distributor,
child: Text(
selectedDistributorType ==
'PrincipalDistributor'
? distributor.shippingAddress!.tradeName
.capitalize()
: distributor.kyc!.tradeName.capitalize(),
((selectedDistributorType ==
'Principal Distributor')
? distributor.shippingAddress!.tradeName
: distributor.kyc!.tradeName)
.capitalize(),
),
);
}).toList(),

View File

@ -24,4 +24,5 @@ class ApiUrls {
static const String postSalesTaskUrl = '${baseUrl}sales/add-TM';
static const String visitRdPd = '$baseUrl/visit';
static const String allTaskByDate = '${baseUrl}task/alltask';
static const String announcements = '${baseUrl}announcement/TMs';
}

View File

@ -1,5 +1,6 @@
extension StringExtension on String {
String capitalize() {
return "${this[0].toUpperCase()}${substring(1).toLowerCase()}";
if (isEmpty) return this;
return "${this[0].toUpperCase()}${substring(1)}";
}
}

View File

@ -63,7 +63,7 @@ class CommonDrawer extends StatelessWidget {
leading: const Icon(Icons.home),
title: const Text('Home'),
onTap: () {
Navigator.push(
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const HomePage()),
);

View File

@ -48,8 +48,8 @@ class CommonTextFormField extends StatelessWidget {
controller: controller,
textCapitalization: textCapitalization,
readOnly: readOnly ?? false,
maxLines: maxLines,
maxLength: maxLength,
// maxLines: maxLines,
// maxLength: maxLength,
onChanged: onChanged,
onTapOutside: (event) => FocusScope.of(context).unfocus(),
validator: validator,