180 lines
7.3 KiB
Dart
180 lines
7.3 KiB
Dart
//lib/screens/river/river_home_page.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 RiverHomePage extends StatelessWidget {
|
|
const RiverHomePage({super.key});
|
|
|
|
// Define River's sub-menu structure (Manual, Continuous, Investigative)
|
|
final List<SidebarItem> _riverSubMenus = const [
|
|
SidebarItem(
|
|
icon: Icons.handshake,
|
|
label: "Manual",
|
|
isParent: true,
|
|
children: [
|
|
// MODIFIED: Added Info Centre Document link for consistency
|
|
SidebarItem(icon: Icons.description, label: "Info Centre Document", route: '/river/manual/info'),
|
|
SidebarItem(icon: Icons.pin_drop, label: "In-Situ Sampling", route: '/river/manual/in-situ'),
|
|
SidebarItem(icon: Icons.date_range, label: "Triennial Sampling", route: '/river/manual/triennial'),
|
|
SidebarItem(icon: Icons.article, label: "Data Log", route: '/river/manual/data-log'),
|
|
SidebarItem(icon: Icons.image, label: "Image Request", route: '/river/manual/image-request'),
|
|
],
|
|
),
|
|
SidebarItem(
|
|
icon: Icons.trending_up,
|
|
label: "Continuous",
|
|
isParent: true,
|
|
children: [
|
|
// MODIFIED: Updated to point to the new Info Centre screen
|
|
SidebarItem(icon: Icons.description, label: "Info Centre Document", route: '/river/continuous/info'),
|
|
//SidebarItem(icon: Icons.info, label: "Overview", route: '/river/continuous/overview'),
|
|
//SidebarItem(icon: Icons.input, label: "Entry", route: '/river/continuous/entry'),
|
|
//SidebarItem(icon: Icons.receipt_long, label: "Report", route: '/river/continuous/report'),
|
|
],
|
|
),
|
|
SidebarItem(
|
|
icon: Icons.search,
|
|
label: "Investigative",
|
|
isParent: true,
|
|
children: [
|
|
// MODIFIED: Updated to point to the new Info Centre screen
|
|
SidebarItem(icon: Icons.description, label: "Info Centre Document", route: '/river/investigative/info'),
|
|
// *** ADDED: Link to River Investigative Manual Sampling ***
|
|
SidebarItem(icon: Icons.biotech, label: "Investigative Sampling", route: '/river/investigative/manual-sampling'), // Added Icon
|
|
// SidebarItem(icon: Icons.info, label: "Overview", route: '/river/investigative/overview'), // Keep placeholder/future items commented
|
|
//SidebarItem(icon: Icons.input, label: "Entry", route: '/river/investigative/entry'), // Keep placeholder/future items commented
|
|
//SidebarItem(icon: Icons.receipt_long, label: "Report", route: '/river/investigative/report'), // Keep placeholder/future items commented
|
|
],
|
|
),
|
|
];
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text("River Department"),
|
|
),
|
|
body: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(24.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"Explore River Monitoring Sections",
|
|
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
Column(
|
|
children: _riverSubMenus.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),
|
|
// Grid of sub-menu items - changed to 2 columns
|
|
GridView.builder(
|
|
shrinkWrap: true,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
|
crossAxisCount: 2, // Changed from 3 to 2 columns
|
|
crossAxisSpacing: 0.0,
|
|
mainAxisSpacing: 0.0,
|
|
childAspectRatio: 4.0, // Adjusted aspect ratio for better 2-column layout
|
|
),
|
|
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), // No rounded corners for grid items
|
|
child: Container(
|
|
margin: const EdgeInsets.all(4.0), // Added margin for better spacing
|
|
decoration: BoxDecoration(
|
|
border: Border.all(color: Colors.white24, width: 0.5), // Optional: subtle border
|
|
// No background color unless desired
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.start, // Align content to start
|
|
children: [
|
|
subItem.icon != null
|
|
? Icon(subItem.icon, color: Colors.white70, size: 24) // Adjusted icon size
|
|
: const SizedBox.shrink(), // Or provide a placeholder
|
|
const SizedBox(width: 8),
|
|
Expanded( // Allow text to take remaining space
|
|
child: Text(
|
|
subItem.label,
|
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
|
color: Colors.white70, // Slightly lighter text
|
|
fontSize: 12, // Slightly increased font size
|
|
),
|
|
textAlign: TextAlign.left, // Left align text
|
|
overflow: TextOverflow.ellipsis, // Prevent overflow
|
|
maxLines: 2, // Allow for two lines if needed
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
const SizedBox(height: 16), // Spacing between categories
|
|
],
|
|
);
|
|
}
|
|
} |