repair marine investigative station parameter checking

This commit is contained in:
ALim Aidrus 2025-11-16 21:31:01 +08:00
parent eafa08b28c
commit 629c582aa9
5 changed files with 26 additions and 27 deletions

View File

@ -33,7 +33,7 @@ class _MarineInvesManualStep2SiteInfoState extends State<MarineInvesManualStep2S
late final TextEditingController _labRemarksController;
final List<String> _weatherOptions = ['Clear', 'Cloudy', 'Drizzle', 'Rainy', 'Windy'];
final List<String> _tideOptions = ['High', 'Low', 'Mid'];
final List<String> _tideOptions = ['High', 'Low'];
final List<String> _seaConditionOptions = ['Calm', 'Moderate Wave', 'High Wave'];
@override
@ -67,7 +67,7 @@ class _MarineInvesManualStep2SiteInfoState extends State<MarineInvesManualStep2S
setState(() => setImageCallback(file));
} else if (mounted) {
// Corrected snackbar message
_showSnackBar('Image selection failed. Please ensure all photos are taken in landscape (horizontal) mode.', isError: true);
_showSnackBar('Image selection failed. Please ensure all photos are taken in landscape (vertical) mode.', isError: true);
}
if (mounted) {
@ -150,7 +150,7 @@ class _MarineInvesManualStep2SiteInfoState extends State<MarineInvesManualStep2S
Text("Required Photos *", style: Theme.of(context).textTheme.titleLarge),
// MODIFIED: Matched in-situ text
const Text(
"All photos must be in landscape (horizontal) orientation. A watermark will be applied automatically.",
"All photos must be in landscape (vertical) orientation. A watermark will be applied automatically.",
style: TextStyle(color: Colors.grey)
),
const SizedBox(height: 8),

View File

@ -398,7 +398,7 @@ class _MarineInvesManualStep3DataCaptureState extends State<MarineInvesManualSte
int? stationId;
// This check is now redundant due to _validateAndProceed, but safe to keep
if (widget.data.stationTypeSelection == 'Existing Manual Station') {
stationId = widget.data.selectedStation?['man_station_id'];
stationId = widget.data.selectedStation?['station_id'];
}
debugPrint("--- Parameter Validation Start (Investigative) ---");

View File

@ -49,7 +49,7 @@ class _MarineInvesManualStep4SummaryState extends State<MarineInvesManualStep4Su
int? stationId;
if (widget.data.stationTypeSelection == 'Existing Manual Station') {
stationId = widget.data.selectedStation?['man_station_id'];
stationId = widget.data.selectedStation?['station_id'];
}
final readings = {

View File

@ -245,7 +245,7 @@ class MarineInvestigativeSamplingService {
// 1. Submit Form Data
apiDataResult = await _submissionApiService.submitPost(
moduleName: moduleName,
endpoint: 'marine/investigative/sample',
endpoint: 'marine-investigative/sample',
body: data.toApiFormData(),
);
@ -258,7 +258,7 @@ class MarineInvestigativeSamplingService {
// 2. Submit Images
apiImageResult = await _submissionApiService.submitMultipart(
moduleName: moduleName,
endpoint: 'marine/investigative/images',
endpoint: 'marine-investigative/images',
fields: {'man_inves_id': data.reportId!},
files: finalImageFiles,
);
@ -277,10 +277,10 @@ class MarineInvestigativeSamplingService {
anyApiSuccess = false;
apiDataResult = {'success': false, 'message': 'Session expired and re-login failed. API submission queued.'};
// Manually queue the API call since SubmissionApiService was never called or failed internally due to session
await _retryService.addApiToQueue(endpoint: 'marine/investigative/sample', method: 'POST', body: data.toApiFormData());
await _retryService.addApiToQueue(endpoint: 'marine-investigative/sample', method: 'POST', body: data.toApiFormData());
if (finalImageFiles.isNotEmpty && data.reportId != null) {
// Also queue images if data call might have partially succeeded before expiry
await _retryService.addApiToQueue(endpoint: 'marine/investigative/images', method: 'POST_MULTIPART', fields: {'man_inves_id': data.reportId!}, files: finalImageFiles);
await _retryService.addApiToQueue(endpoint: 'marine-investigative/images', method: 'POST_MULTIPART', fields: {'man_inves_id': data.reportId!}, files: finalImageFiles);
}
}
// We no longer catch SocketException or TimeoutException here.

View File

@ -1,30 +1,29 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
// Import main.dart to get access to the SplashScreen widget
import 'package:environment_monitoring_app/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
testWidgets('SplashScreen smoke test', (WidgetTester tester) async {
// Build the SplashScreen widget directly.
// We wrap it in a MaterialApp to provide the necessary structure
// (like text direction) that widgets like Text() need to render.
await tester.pumpWidget(
const MaterialApp(
home: SplashScreen(),
),
);
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Verify that the SplashScreen shows its loading text.
expect(find.text('Loading MMS data...'), findsOneWidget);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify it shows the CircularProgressIndicator.
expect(find.byType(CircularProgressIndicator), findsOneWidget);
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
// Verify it shows the Image.
expect(find.byType(Image), findsOneWidget);
});
}