From c3c4764f59b7bc0e31204ca7a03ea102cbcae0ca Mon Sep 17 00:00:00 2001
From: Balasubramaniam12007 <balasubramaniam12007@gmail.com>
Date: Thu, 13 Mar 2025 03:18:39 +0530
Subject: [PATCH] feat(status): Implement global status bar and request body in
 get validation -  Create StatusMessage model with support for
 info/warning/error types - Design GlobalStatusBar UI component with dynamic
 styling based on status type and located at the bottom of the editorpane
 -Implement GlobalStatusBarManager for state management via Riverpod - Add
 StatusValidator with initial validation for GET requests with bodies

Signed-off-by: Balasubramaniam12007 <balasubramaniam12007@gmail.com>
---
 lib/providers/providers.dart                  |  1 +
 lib/providers/status_message_provider.dart    | 37 ++++++++++++
 .../home_page/editor_pane/editor_pane.dart    | 21 ++++---
 .../editor_pane/global_status_bar.dart        | 60 +++++++++++++++++++
 lib/utils/status_validator.dart               | 20 +++++++
 5 files changed, 131 insertions(+), 8 deletions(-)
 create mode 100644 lib/providers/status_message_provider.dart
 create mode 100644 lib/screens/home_page/editor_pane/global_status_bar.dart
 create mode 100644 lib/utils/status_validator.dart

diff --git a/lib/providers/providers.dart b/lib/providers/providers.dart
index 29fc6e595..438226eba 100644
--- a/lib/providers/providers.dart
+++ b/lib/providers/providers.dart
@@ -3,3 +3,4 @@ export 'environment_providers.dart';
 export 'history_providers.dart';
 export 'settings_providers.dart';
 export 'ui_providers.dart';
+export 'status_message_provider.dart';
\ No newline at end of file
diff --git a/lib/providers/status_message_provider.dart b/lib/providers/status_message_provider.dart
new file mode 100644
index 000000000..aeed7fc9b
--- /dev/null
+++ b/lib/providers/status_message_provider.dart
@@ -0,0 +1,37 @@
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:apidash_core/apidash_core.dart';
+import 'package:apidash/providers/collection_providers.dart';
+import 'package:apidash/utils/status_validator.dart';
+
+enum StatusMessageType { defaultType, info, warning, error }
+
+class StatusMessage {
+  final String message;
+  final StatusMessageType type;
+
+  StatusMessage(this.message, this.type);
+}
+
+final statusMessageProvider =
+    StateNotifierProvider<GlobalStatusBarManager, StatusMessage>((ref) {
+  return GlobalStatusBarManager(ref);
+});
+
+class GlobalStatusBarManager extends StateNotifier<StatusMessage> {
+  final Ref ref;
+
+  GlobalStatusBarManager(this.ref)
+      : super(StatusMessage("Global Status Bar", StatusMessageType.defaultType)) {
+    // Listen for request changes and validate
+    ref.listen(selectedRequestModelProvider, (previous, next) {
+      final method = next?.httpRequestModel?.method ?? HTTPVerb.get;
+      final body = next?.httpRequestModel?.body;
+      _updateStatusMessage(StatusValidator().validateRequest(method, body));
+    });
+  }
+
+  // Updates the status message
+  void _updateStatusMessage(StatusMessage newMessage) {
+    state = newMessage;
+  }
+}
diff --git a/lib/screens/home_page/editor_pane/editor_pane.dart b/lib/screens/home_page/editor_pane/editor_pane.dart
index 7ff67f5c1..36da4bd03 100644
--- a/lib/screens/home_page/editor_pane/editor_pane.dart
+++ b/lib/screens/home_page/editor_pane/editor_pane.dart
@@ -3,19 +3,24 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:apidash/providers/providers.dart';
 import 'editor_default.dart';
 import 'editor_request.dart';
+import 'global_status_bar.dart';
 
 class RequestEditorPane extends ConsumerWidget {
-  const RequestEditorPane({
-    super.key,
-  });
+  const RequestEditorPane({super.key});
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     final selectedId = ref.watch(selectedIdStateProvider);
-    if (selectedId == null) {
-      return const RequestEditorDefault();
-    } else {
-      return const RequestEditor();
-    }
+
+    return Column(
+      children: [
+        Expanded(
+          child: selectedId == null
+              ? const RequestEditorDefault()
+              : const RequestEditor(),
+        ),
+        const GlobalStatusBar(),
+      ],
+    );
   }
 }
diff --git a/lib/screens/home_page/editor_pane/global_status_bar.dart b/lib/screens/home_page/editor_pane/global_status_bar.dart
new file mode 100644
index 000000000..9cb3a3e1b
--- /dev/null
+++ b/lib/screens/home_page/editor_pane/global_status_bar.dart
@@ -0,0 +1,60 @@
+import 'package:flutter/material.dart';
+import 'package:apidash_design_system/apidash_design_system.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:apidash/providers/providers.dart';
+
+class GlobalStatusBar extends ConsumerWidget {
+  const GlobalStatusBar({super.key});
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final statusMessage = ref.watch(statusMessageProvider);
+
+    // Get color based on message type
+    final color = statusMessage.type == StatusMessageType.info
+        ? kColorSchemeSeed
+        : statusMessage.type == StatusMessageType.warning
+            ? kColorHttpMethodPut
+            : statusMessage.type == StatusMessageType.error
+                ? kColorDarkDanger
+                : kColorBlack;
+
+    // Get icon based on message type
+    final icon = statusMessage.type == StatusMessageType.error
+        ? Icons.error_outline
+        : statusMessage.type == StatusMessageType.warning
+            ? Icons.warning_amber_outlined
+            : statusMessage.type == StatusMessageType.info
+                ? Icons.info_outline
+                : null;
+
+    return Container(
+      padding: kPh12,
+      width: double.infinity,
+      height: 40,
+      // Use background color only for status messages (info/warning/error)
+      color: icon != null ? color.withOpacity(kForegroundOpacity) : kColorWhite,
+      child: Row(
+        children: [
+          // Only display icons for info, warning, and error states
+          if (icon != null) ...[
+            Icon(icon, size: kButtonIconSizeSmall, color: color),
+            kHSpacer8,
+          ],
+          Expanded(
+            child: Text(
+              statusMessage.message,
+              style: TextStyle(
+                color: color,
+                fontSize: 14,
+                fontWeight: FontWeight.w500,
+              ),
+              // Prevent text overflow issues
+              overflow: TextOverflow.ellipsis,
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/utils/status_validator.dart b/lib/utils/status_validator.dart
new file mode 100644
index 000000000..75f91b838
--- /dev/null
+++ b/lib/utils/status_validator.dart
@@ -0,0 +1,20 @@
+import 'package:apidash_core/apidash_core.dart';
+import 'package:apidash/providers/status_message_provider.dart'; 
+import 'package:apidash_design_system/apidash_design_system.dart';
+
+class StatusValidator {
+  StatusMessage validateRequest(HTTPVerb method, String? body) {
+    if (_isInvalidGetRequest(method, body)) {
+      return StatusMessage(
+        "GET requests cannot have a body. Remove the body or change the method to POST.",
+        StatusMessageType.info,
+      );
+    }
+    return StatusMessage("Global Status Bar", StatusMessageType.defaultType);
+  }
+
+  bool _isInvalidGetRequest(HTTPVerb method, String? body) {
+    return method == HTTPVerb.get && body != null && body.isNotEmpty;
+  }
+
+}