detail refactor
This commit is contained in:
@@ -74,7 +74,6 @@ class AppStrings {
|
|||||||
static const String tenderDeliveryLocationsLabel = 'Delivery Locations';
|
static const String tenderDeliveryLocationsLabel = 'Delivery Locations';
|
||||||
static const String tenderReferenceNumberLabel = 'Reference Number';
|
static const String tenderReferenceNumberLabel = 'Reference Number';
|
||||||
static const String tenderLocationLabel = 'Locations';
|
static const String tenderLocationLabel = 'Locations';
|
||||||
static const String tenderLocationCountry = 'UK';
|
|
||||||
static const String tenderPdfDocument = 'PDF , Document';
|
static const String tenderPdfDocument = 'PDF , Document';
|
||||||
static const String tenderMatchProfile = 'Match with your profile';
|
static const String tenderMatchProfile = 'Match with your profile';
|
||||||
static const String tenderIncompleteResume = 'Incomplete Resume Information';
|
static const String tenderIncompleteResume = 'Incomplete Resume Information';
|
||||||
@@ -82,10 +81,17 @@ class AppStrings {
|
|||||||
'No experience in e-platform development';
|
'No experience in e-platform development';
|
||||||
static const String tenderSubmitButton = 'Submit';
|
static const String tenderSubmitButton = 'Submit';
|
||||||
static const String tenderRejectButton = 'Reject';
|
static const String tenderRejectButton = 'Reject';
|
||||||
|
|
||||||
static const String tenderClientExample =
|
static const String tenderClientExample =
|
||||||
'Procurement Notice Procurement Notice';
|
'Procurement Notice Procurement Notice';
|
||||||
|
|
||||||
static const String estimatedValue = 'Estimated Value ';
|
static const String estimatedValue = 'Estimated Value ';
|
||||||
static const String duration = 'Duration';
|
static const String duration = 'Duration';
|
||||||
|
static const String tenderSubmittedSuccessfully =
|
||||||
|
'tender submitted successfully!';
|
||||||
|
static const String tenderRejectedSuccessfully =
|
||||||
|
'tender rejected successfully!';
|
||||||
|
static const String tenderUnrejectedSuccessfully =
|
||||||
|
'tender unrejected successfully!';
|
||||||
|
static const String tenderUnsubmittedSuccessfully =
|
||||||
|
'tender unsubmitted successfully!';
|
||||||
|
static const String tenderNoData = 'No tender details available';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
class DateUtils {
|
/// Extension on int to provide date formatting utilities for Unix timestamps
|
||||||
|
extension UnixTimestampExtension on int? {
|
||||||
/// Converts Unix timestamp (seconds since epoch) to a formatted date string
|
/// Converts Unix timestamp (seconds since epoch) to a formatted date string
|
||||||
static String unixToDate(int? unixTimestamp, {String format = 'yyyy-MM-dd'}) {
|
String toDate({String format = 'yyyy-MM-dd'}) {
|
||||||
if (unixTimestamp == null) {
|
if (this == null) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert seconds to milliseconds if needed
|
// Convert seconds to milliseconds if needed
|
||||||
int timestampInMs =
|
int timestampInMs = this! > 1000000000000 ? this! : this! * 1000;
|
||||||
unixTimestamp > 1000000000000 ? unixTimestamp : unixTimestamp * 1000;
|
|
||||||
|
|
||||||
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
||||||
timestampInMs,
|
timestampInMs,
|
||||||
@@ -18,13 +18,12 @@ class DateUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Converts Unix timestamp to a readable date string
|
/// Converts Unix timestamp to a readable date string
|
||||||
static String unixToReadableDate(int? unixTimestamp) {
|
String toReadableDate() {
|
||||||
if (unixTimestamp == null) {
|
if (this == null) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
int timestampInMs =
|
int timestampInMs = this! > 1000000000000 ? this! : this! * 1000;
|
||||||
unixTimestamp > 1000000000000 ? unixTimestamp : unixTimestamp * 1000;
|
|
||||||
|
|
||||||
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
||||||
timestampInMs,
|
timestampInMs,
|
||||||
@@ -44,13 +43,12 @@ class DateUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Converts Unix timestamp to a short date format
|
/// Converts Unix timestamp to a short date format
|
||||||
static String unixToShortDate(int? unixTimestamp) {
|
String toShortDate() {
|
||||||
if (unixTimestamp == null) {
|
if (this == null) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
int timestampInMs =
|
int timestampInMs = this! > 1000000000000 ? this! : this! * 1000;
|
||||||
unixTimestamp > 1000000000000 ? unixTimestamp : unixTimestamp * 1000;
|
|
||||||
|
|
||||||
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
||||||
timestampInMs,
|
timestampInMs,
|
||||||
@@ -59,13 +57,12 @@ class DateUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Converts Unix timestamp to a full date and time format
|
/// Converts Unix timestamp to a full date and time format
|
||||||
static String unixToDateTime(int? unixTimestamp) {
|
String toDateTime() {
|
||||||
if (unixTimestamp == null) {
|
if (this == null) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
int timestampInMs =
|
int timestampInMs = this! > 1000000000000 ? this! : this! * 1000;
|
||||||
unixTimestamp > 1000000000000 ? unixTimestamp : unixTimestamp * 1000;
|
|
||||||
|
|
||||||
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
||||||
timestampInMs,
|
timestampInMs,
|
||||||
@@ -74,13 +71,12 @@ class DateUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if a Unix timestamp is in the past
|
/// Checks if a Unix timestamp is in the past
|
||||||
static bool isPast(int? unixTimestamp) {
|
bool get isPast {
|
||||||
if (unixTimestamp == null) {
|
if (this == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int timestampInMs =
|
int timestampInMs = this! > 1000000000000 ? this! : this! * 1000;
|
||||||
unixTimestamp > 1000000000000 ? unixTimestamp : unixTimestamp * 1000;
|
|
||||||
|
|
||||||
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
||||||
timestampInMs,
|
timestampInMs,
|
||||||
@@ -89,13 +85,12 @@ class DateUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the number of days remaining until a Unix timestamp
|
/// Gets the number of days remaining until a Unix timestamp
|
||||||
static int daysRemaining(int? unixTimestamp) {
|
int get daysRemaining {
|
||||||
if (unixTimestamp == null) {
|
if (this == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int timestampInMs =
|
int timestampInMs = this! > 1000000000000 ? this! : this! * 1000;
|
||||||
unixTimestamp > 1000000000000 ? unixTimestamp : unixTimestamp * 1000;
|
|
||||||
|
|
||||||
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
||||||
timestampInMs,
|
timestampInMs,
|
||||||
@@ -106,3 +101,69 @@ class DateUtils {
|
|||||||
return difference.inDays;
|
return difference.inDays;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extension on DateTime to provide additional formatting utilities
|
||||||
|
extension DateTimeExtension on DateTime {
|
||||||
|
/// Formats the DateTime to a readable string
|
||||||
|
String toReadableString() {
|
||||||
|
final DateTime now = DateTime.now();
|
||||||
|
final Duration difference = now.difference(this);
|
||||||
|
|
||||||
|
if (difference.inDays == 0) {
|
||||||
|
return 'Today';
|
||||||
|
} else if (difference.inDays == 1) {
|
||||||
|
return 'Yesterday';
|
||||||
|
} else if (difference.inDays < 7) {
|
||||||
|
return '${difference.inDays} days ago';
|
||||||
|
} else {
|
||||||
|
return DateFormat('MMM dd, yyyy').format(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Formats the DateTime to a short date string
|
||||||
|
String toShortDate() {
|
||||||
|
return DateFormat('MMM dd').format(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Formats the DateTime to a full date and time string
|
||||||
|
String toDateTimeString() {
|
||||||
|
return DateFormat('MMM dd, yyyy HH:mm').format(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if the DateTime is in the past
|
||||||
|
bool get isPast {
|
||||||
|
return isBefore(DateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the number of days remaining until this DateTime
|
||||||
|
int get daysRemaining {
|
||||||
|
final DateTime now = DateTime.now();
|
||||||
|
final Duration difference = this.difference(now);
|
||||||
|
return difference.inDays;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Utility class for date operations
|
||||||
|
class DateUtils {
|
||||||
|
/// Converts Unix timestamp to a formatted date string
|
||||||
|
|
||||||
|
static String unixToDate(int? timestamp) {
|
||||||
|
if (timestamp == null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert seconds to milliseconds if needed
|
||||||
|
int timestampInMs =
|
||||||
|
timestamp > 1000000000000 ? timestamp : timestamp * 1000;
|
||||||
|
|
||||||
|
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
||||||
|
timestampInMs,
|
||||||
|
);
|
||||||
|
return DateFormat('MMM dd, yyyy').format(dateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Global function for backward compatibility
|
||||||
|
String unixToDate(int? timestamp) {
|
||||||
|
return DateUtils.unixToDate(timestamp);
|
||||||
|
}
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ class TenderDetailViewModel with ChangeNotifier {
|
|||||||
final result = await _tendersRepository.getTenderApprovals(
|
final result = await _tendersRepository.getTenderApprovals(
|
||||||
tenderId: tenderId,
|
tenderId: tenderId,
|
||||||
);
|
);
|
||||||
|
approvalStatus = false;
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Ok<TenderApprovalsByIdResponse>():
|
case Ok<TenderApprovalsByIdResponse>():
|
||||||
_tenderApprovalData = result.value.data;
|
_tenderApprovalData = result.value.data;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:tm_app/views/detail/widgets/tender_detail_action.dart';
|
|||||||
import 'package:tm_app/views/detail/widgets/tender_detail_card.dart';
|
import 'package:tm_app/views/detail/widgets/tender_detail_card.dart';
|
||||||
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
|
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
|
||||||
|
|
||||||
|
import '../../../core/constants/strings.dart';
|
||||||
import '../../../view_models/home_view_model.dart';
|
import '../../../view_models/home_view_model.dart';
|
||||||
import '../../../view_models/tenders_view_model.dart';
|
import '../../../view_models/tenders_view_model.dart';
|
||||||
import '../../shared/desktop_navigation_widget.dart';
|
import '../../shared/desktop_navigation_widget.dart';
|
||||||
@@ -34,39 +35,39 @@ class _TenderDetailDesktopPageState extends State<TenderDetailDesktopPage> {
|
|||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'submitted' &&
|
viewModel.status == 'submitted' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
context,
|
SnackBar(content: Text(AppStrings.tenderSubmittedSuccessfully)),
|
||||||
).showSnackBar(SnackBar(content: Text('tender submitted successfully!')));
|
);
|
||||||
}
|
}
|
||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'unsubmitted' &&
|
viewModel.status == 'unsubmitted' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('tender submitted removed sucessfully!')),
|
SnackBar(content: Text(AppStrings.tenderUnsubmittedSuccessfully)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'rejected' &&
|
viewModel.status == 'rejected' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
context,
|
SnackBar(content: Text(AppStrings.tenderRejectedSuccessfully)),
|
||||||
).showSnackBar(SnackBar(content: Text('tender rejected sucessfully!')));
|
);
|
||||||
}
|
}
|
||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'unrejected' &&
|
viewModel.status == 'unrejected' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('tender reject removed sucessfully!')),
|
SnackBar(content: Text(AppStrings.tenderUnrejectedSuccessfully)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (viewModel.approvalStatus != false && viewModel.errorMessage != null) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
backgroundColor: AppColors.errorColor,
|
||||||
|
content: Text(viewModel.errorMessage!),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// if (viewModel.errorMessage != null) {
|
|
||||||
// ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
// SnackBar(
|
|
||||||
// backgroundColor: AppColors.errorColor,
|
|
||||||
// content: Text(viewModel.errorMessage!),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -99,7 +100,7 @@ class _TenderDetailDesktopPageState extends State<TenderDetailDesktopPage> {
|
|||||||
|
|
||||||
final detail = tenderViewModel.tenderDetail;
|
final detail = tenderViewModel.tenderDetail;
|
||||||
if (detail == null) {
|
if (detail == null) {
|
||||||
return const Center(child: Text('No tender details available'));
|
return const Center(child: Text(AppStrings.tenderNoData));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
|
|||||||
@@ -30,39 +30,39 @@ class _TenderDetailMobilePageState extends State<TenderDetailMobilePage> {
|
|||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'submitted' &&
|
viewModel.status == 'submitted' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
context,
|
SnackBar(content: Text(AppStrings.tenderSubmittedSuccessfully)),
|
||||||
).showSnackBar(SnackBar(content: Text('tender submitted successfully!')));
|
);
|
||||||
}
|
}
|
||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'unsubmitted' &&
|
viewModel.status == 'unsubmitted' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('tender submitted removed sucessfully!')),
|
SnackBar(content: Text(AppStrings.tenderUnsubmittedSuccessfully)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'rejected' &&
|
viewModel.status == 'rejected' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
context,
|
SnackBar(content: Text(AppStrings.tenderRejectedSuccessfully)),
|
||||||
).showSnackBar(SnackBar(content: Text('tender rejected sucessfully!')));
|
);
|
||||||
}
|
}
|
||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'unrejected' &&
|
viewModel.status == 'unrejected' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('tender reject removed sucessfully!')),
|
SnackBar(content: Text(AppStrings.tenderUnrejectedSuccessfully)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (viewModel.approvalStatus != false && viewModel.errorMessage != null) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
backgroundColor: AppColors.errorColor,
|
||||||
|
content: Text(viewModel.errorMessage!),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// if (viewModel.errorMessage != null) {
|
|
||||||
// ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
// SnackBar(
|
|
||||||
// backgroundColor: AppColors.errorColor,
|
|
||||||
// content: Text(viewModel.errorMessage!),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -90,7 +90,7 @@ class _TenderDetailMobilePageState extends State<TenderDetailMobilePage> {
|
|||||||
|
|
||||||
final detail = tenderViewModel.tenderDetail;
|
final detail = tenderViewModel.tenderDetail;
|
||||||
if (detail == null) {
|
if (detail == null) {
|
||||||
return const Center(child: Text('No tender details available'));
|
return const Center(child: Text(AppStrings.tenderNoData));
|
||||||
}
|
}
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import 'package:tm_app/views/detail/widgets/tender_detail_card.dart';
|
|||||||
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
|
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
|
||||||
import 'package:tm_app/views/shared/tablet_navigation_widget.dart';
|
import 'package:tm_app/views/shared/tablet_navigation_widget.dart';
|
||||||
|
|
||||||
|
import '../../../core/constants/strings.dart';
|
||||||
|
|
||||||
class TenderDetailTabletPage extends StatefulWidget {
|
class TenderDetailTabletPage extends StatefulWidget {
|
||||||
final String tenderId;
|
final String tenderId;
|
||||||
const TenderDetailTabletPage({required this.tenderId, super.key});
|
const TenderDetailTabletPage({required this.tenderId, super.key});
|
||||||
@@ -33,39 +35,39 @@ class _TenderDetailTabletPageState extends State<TenderDetailTabletPage> {
|
|||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'submitted' &&
|
viewModel.status == 'submitted' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
context,
|
SnackBar(content: Text(AppStrings.tenderSubmittedSuccessfully)),
|
||||||
).showSnackBar(SnackBar(content: Text('tender submitted successfully!')));
|
);
|
||||||
}
|
}
|
||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'unsubmitted' &&
|
viewModel.status == 'unsubmitted' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('tender submitted removed sucessfully!')),
|
SnackBar(content: Text(AppStrings.tenderUnsubmittedSuccessfully)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'rejected' &&
|
viewModel.status == 'rejected' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
context,
|
SnackBar(content: Text(AppStrings.tenderRejectedSuccessfully)),
|
||||||
).showSnackBar(SnackBar(content: Text('tender rejected sucessfully!')));
|
);
|
||||||
}
|
}
|
||||||
if (viewModel.status.isNotEmpty &&
|
if (viewModel.status.isNotEmpty &&
|
||||||
viewModel.status == 'unrejected' &&
|
viewModel.status == 'unrejected' &&
|
||||||
viewModel.approvalStatus == true) {
|
viewModel.approvalStatus == true) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('tender reject removed sucessfully!')),
|
SnackBar(content: Text(AppStrings.tenderUnrejectedSuccessfully)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (viewModel.approvalStatus != false && viewModel.errorMessage != null) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
backgroundColor: AppColors.errorColor,
|
||||||
|
content: Text(viewModel.errorMessage!),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// if (viewModel.errorMessage != null) {
|
|
||||||
// ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
// SnackBar(
|
|
||||||
// backgroundColor: AppColors.errorColor,
|
|
||||||
// content: Text(viewModel.errorMessage!),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -138,7 +140,7 @@ class _TenderDetailTabletPageState extends State<TenderDetailTabletPage> {
|
|||||||
|
|
||||||
final detail = tenderViewModel.tenderDetail;
|
final detail = tenderViewModel.tenderDetail;
|
||||||
if (detail == null) {
|
if (detail == null) {
|
||||||
return const Center(child: Text('No tender details available'));
|
return const Center(child: Text(AppStrings.tenderNoData));
|
||||||
}
|
}
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Center(
|
child: Center(
|
||||||
|
|||||||
@@ -1,21 +1,18 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:tm_app/core/theme/colors.dart';
|
import 'package:tm_app/core/theme/colors.dart';
|
||||||
|
import 'package:tm_app/core/utils/date_utils.dart';
|
||||||
import 'package:tm_app/core/utils/size_config.dart';
|
import 'package:tm_app/core/utils/size_config.dart';
|
||||||
|
|
||||||
|
import '../../../core/constants/strings.dart';
|
||||||
|
import '../../../data/services/model/tender_data/tender_data.dart';
|
||||||
|
|
||||||
class DeadlineItem extends StatelessWidget {
|
class DeadlineItem extends StatelessWidget {
|
||||||
final String title;
|
final TenderData detail;
|
||||||
final String approvalText;
|
|
||||||
final String approvalDate;
|
|
||||||
final String submissionText;
|
|
||||||
final String submissionDate;
|
|
||||||
final bool isScreenBig;
|
final bool isScreenBig;
|
||||||
|
|
||||||
const DeadlineItem({
|
const DeadlineItem({
|
||||||
required this.title,
|
required this.detail,
|
||||||
required this.approvalText,
|
|
||||||
required this.approvalDate,
|
|
||||||
required this.submissionText,
|
|
||||||
required this.submissionDate,
|
|
||||||
required this.isScreenBig,
|
required this.isScreenBig,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
@@ -31,7 +28,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
height: 45.0.h(),
|
height: 45.0.h(),
|
||||||
child: Text(
|
child: Text(
|
||||||
title,
|
detail.title ?? '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.grey80,
|
color: AppColors.grey80,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -47,7 +44,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
approvalText,
|
AppStrings.tenderApprovalText,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.grey70,
|
color: AppColors.grey70,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@@ -56,7 +53,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 4.0.h()),
|
SizedBox(height: 4.0.h()),
|
||||||
Text(
|
Text(
|
||||||
approvalDate,
|
unixToDate(detail.submissionDeadline),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.grey80,
|
color: AppColors.grey80,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@@ -76,7 +73,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
submissionText,
|
AppStrings.tenderSubmissionText,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.grey70,
|
color: AppColors.grey70,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@@ -85,7 +82,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 4.0.h()),
|
SizedBox(height: 4.0.h()),
|
||||||
Text(
|
Text(
|
||||||
submissionDate,
|
unixToDate(detail.applicationDeadline),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.grey80,
|
color: AppColors.grey80,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@@ -99,7 +96,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 8.0.h()),
|
SizedBox(height: 8.0.h()),
|
||||||
Divider(color: AppColors.grey20,),
|
Divider(color: AppColors.grey20),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -111,7 +108,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
height: 45.0.h(),
|
height: 45.0.h(),
|
||||||
child: Text(
|
child: Text(
|
||||||
title,
|
detail.title ?? '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.grey80,
|
color: AppColors.grey80,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@@ -123,7 +120,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
approvalText,
|
AppStrings.tenderApprovalText,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.grey70,
|
color: AppColors.grey70,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@@ -131,7 +128,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
approvalDate,
|
unixToDate(detail.submissionDeadline),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.grey70,
|
color: AppColors.grey70,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@@ -145,7 +142,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
submissionText,
|
AppStrings.tenderSubmissionText,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.grey70,
|
color: AppColors.grey70,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@@ -153,7 +150,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
submissionDate,
|
unixToDate(detail.applicationDeadline),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.grey70,
|
color: AppColors.grey70,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@@ -163,7 +160,7 @@ class DeadlineItem extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 8.0.h()),
|
SizedBox(height: 8.0.h()),
|
||||||
Divider(color: AppColors.grey20,),
|
Divider(color: AppColors.grey20),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:tm_app/core/theme/colors.dart';
|
import 'package:tm_app/core/theme/colors.dart';
|
||||||
|
import 'package:tm_app/core/utils/date_utils.dart';
|
||||||
import 'package:tm_app/core/utils/size_config.dart';
|
import 'package:tm_app/core/utils/size_config.dart';
|
||||||
import 'package:tm_app/data/services/model/tender_data/tender_data.dart';
|
import 'package:tm_app/data/services/model/tender_data/tender_data.dart';
|
||||||
import 'package:tm_app/views/detail/widgets/status_tag.dart';
|
import 'package:tm_app/views/detail/widgets/status_tag.dart';
|
||||||
@@ -73,16 +73,3 @@ class TenderDetailHeader extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String unixToDate(int? unixTimestamp, {String format = 'yyyy-MM-dd'}) {
|
|
||||||
if (unixTimestamp == null) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert seconds to milliseconds if needed
|
|
||||||
int timestampInMs =
|
|
||||||
unixTimestamp > 1000000000000 ? unixTimestamp : unixTimestamp * 1000;
|
|
||||||
|
|
||||||
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestampInMs);
|
|
||||||
return DateFormat(format).format(dateTime);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:tm_app/core/constants/strings.dart';
|
import 'package:tm_app/core/constants/strings.dart';
|
||||||
import 'package:tm_app/data/services/model/tender_data/tender_data.dart';
|
import 'package:tm_app/data/services/model/tender_data/tender_data.dart';
|
||||||
import 'package:tm_app/views/detail/widgets/deadline_item.dart';
|
import 'package:tm_app/views/detail/widgets/deadline_item.dart';
|
||||||
@@ -21,14 +20,7 @@ class TenderDetailInfoSection extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
InfoItem(title: AppStrings.tenderIdLabel, value: detail.tenderId ?? ''),
|
InfoItem(title: AppStrings.tenderIdLabel, value: detail.tenderId ?? ''),
|
||||||
DeadlineItem(
|
DeadlineItem(detail: detail, isScreenBig: isScreenBig),
|
||||||
title: AppStrings.tenderDeadlineLabel,
|
|
||||||
approvalText: AppStrings.tenderApprovalText,
|
|
||||||
approvalDate: unixToDate(detail.submissionDeadline),
|
|
||||||
submissionText: AppStrings.tenderSubmissionText,
|
|
||||||
submissionDate: unixToDate(detail.applicationDeadline),
|
|
||||||
isScreenBig: isScreenBig,
|
|
||||||
),
|
|
||||||
InfoItem(
|
InfoItem(
|
||||||
title: AppStrings.tenderClientLabel,
|
title: AppStrings.tenderClientLabel,
|
||||||
value: detail.buyerOrganization!.name ?? '',
|
value: detail.buyerOrganization!.name ?? '',
|
||||||
@@ -49,16 +41,3 @@ class TenderDetailInfoSection extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String unixToDate(int? unixTimestamp, {String format = 'yyyy-MM-dd'}) {
|
|
||||||
if (unixTimestamp == null) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert seconds to milliseconds if needed
|
|
||||||
int timestampInMs =
|
|
||||||
unixTimestamp > 1000000000000 ? unixTimestamp : unixTimestamp * 1000;
|
|
||||||
|
|
||||||
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestampInMs);
|
|
||||||
return DateFormat(format).format(dateTime);
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user