165 lines
6.4 KiB
Dart
165 lines
6.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
// Re-defining SidebarItem here for self-containment,
|
|
// ideally this would be in a shared utility file if used across many screens.
|
|
class SidebarItem {
|
|
final IconData? icon;
|
|
final String label;
|
|
final String? route;
|
|
final List<SidebarItem>? children;
|
|
final bool isParent;
|
|
final String? imagePath;
|
|
|
|
const SidebarItem({
|
|
this.icon,
|
|
required this.label,
|
|
this.route,
|
|
this.children,
|
|
this.isParent = false,
|
|
this.imagePath,
|
|
}) : assert(icon != null || imagePath != null, 'Either icon or imagePath must be provided');
|
|
}
|
|
|
|
class AirHomePage extends StatelessWidget {
|
|
const AirHomePage({super.key});
|
|
|
|
// Define Air's sub-menu structure (Manual, Continuous, Investigative)
|
|
// This mirrors the structure from collapsible_sidebar.dart for consistency.
|
|
final List<SidebarItem> _airSubMenus = const [
|
|
SidebarItem(
|
|
icon: Icons.handshake, // Example icon for Manual
|
|
label: "Manual",
|
|
isParent: true,
|
|
children: [
|
|
SidebarItem(icon: Icons.dashboard, label: "Dashboard", route: '/air/manual/dashboard'),
|
|
SidebarItem(icon: Icons.edit_note, label: "Manual Sampling", route: '/air/manual/manual-sampling'),
|
|
SidebarItem(icon: Icons.receipt_long, label: "Report", route: '/air/manual/report'),
|
|
SidebarItem(icon: Icons.article, label: "Data Log", route: '/air/manual/data-log'),
|
|
SidebarItem(icon: Icons.image, label: "Image Request", route: '/air/manual/image-request'),
|
|
],
|
|
),
|
|
SidebarItem(
|
|
icon: Icons.trending_up,
|
|
label: "Continuous",
|
|
isParent: true,
|
|
children: [
|
|
SidebarItem(icon: Icons.dashboard, label: "Dashboard", route: '/air/continuous/dashboard'),
|
|
SidebarItem(icon: Icons.info, label: "Overview", route: '/air/continuous/overview'),
|
|
SidebarItem(icon: Icons.input, label: "Entry", route: '/air/continuous/entry'),
|
|
SidebarItem(icon: Icons.receipt_long, label: "Report", route: '/air/continuous/report'),
|
|
],
|
|
),
|
|
SidebarItem(
|
|
icon: Icons.search,
|
|
label: "Investigative",
|
|
isParent: true,
|
|
children: [
|
|
SidebarItem(icon: Icons.dashboard, label: "Dashboard", route: '/air/investigative/dashboard'),
|
|
SidebarItem(icon: Icons.info, label: "Overview", route: '/air/investigative/overview'),
|
|
SidebarItem(icon: Icons.input, label: "Entry", route: '/air/investigative/entry'),
|
|
SidebarItem(icon: Icons.receipt_long, label: "Report", route: '/air/investigative/report'),
|
|
],
|
|
),
|
|
];
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text("Air Department"),
|
|
),
|
|
body: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(24.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"Explore Air Monitoring Sections",
|
|
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
Column(
|
|
children: _airSubMenus.map((category) {
|
|
return _buildCategorySection(context, category);
|
|
}).toList(),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// Method to build each category section (Manual, Continuous, Investigative)
|
|
Widget _buildCategorySection(BuildContext context, SidebarItem category) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// Category header (icon + label)
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
children: [
|
|
Icon(category.icon, size: 30, color: Theme.of(context).iconTheme.color),
|
|
const SizedBox(width: 12),
|
|
Text(
|
|
category.label,
|
|
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const Divider(height: 24, thickness: 1, color: Colors.white24), // Divider below category title
|
|
// Grid of sub-menu items
|
|
GridView.builder(
|
|
shrinkWrap: true,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
|
crossAxisCount: 3, // 3 columns for sub-menu items
|
|
crossAxisSpacing: 0.0, // Removed horizontal spacing
|
|
mainAxisSpacing: 0.0, // Removed vertical spacing
|
|
childAspectRatio: 2.8, // Adjusted aspect ratio for horizontal icon-label layout with bigger content
|
|
),
|
|
itemCount: category.children?.length ?? 0,
|
|
itemBuilder: (context, index) {
|
|
final subItem = category.children![index];
|
|
return InkWell(
|
|
onTap: () {
|
|
if (subItem.route != null) {
|
|
Navigator.pushNamed(context, subItem.route!);
|
|
}
|
|
},
|
|
borderRadius: BorderRadius.circular(0), // Removed border radius for seamless grid
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(8.0), // Padding around the row content
|
|
child: Row( // Changed from Column to Row
|
|
mainAxisAlignment: MainAxisAlignment.start, // Align content to start
|
|
children: [
|
|
subItem.icon != null
|
|
? Icon(subItem.icon, color: Colors.white70, size: 24) // Increased icon size from 22 to 24
|
|
: const SizedBox.shrink(),
|
|
const SizedBox(width: 8), // Space between icon and text (horizontal)
|
|
Expanded( // Allow text to take remaining space
|
|
child: Text(
|
|
subItem.label,
|
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: Colors.white70, fontSize: 11), // Increased text size from 10 to 11
|
|
textAlign: TextAlign.left, // Align text to left
|
|
overflow: TextOverflow.ellipsis,
|
|
maxLines: 1, // Single line for label
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
const SizedBox(height: 16), // Reduced gap after each category group
|
|
],
|
|
);
|
|
}
|
|
}
|