- Add NavPanel widget for room-level section navigation - Add Control Room feature router with URL routes: - /control-room/containers - /control-room/networks - /control-room/volumes - /control-room/images - Sections: Containers, Networks, Volumes, Images - Navigation updates URL and vice versa (deep-linkable) - Remove redundant Stacks section (handled by filter panel) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
72 lines
2.6 KiB
Dart
72 lines
2.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:tatlock_ui/features/control_room/router.dart';
|
|
import 'package:tatlock_ui/routing/app_router.dart';
|
|
import 'package:tatlock_ui/shared/layouts/widgets/top_header_bar.dart';
|
|
|
|
/// Main application scaffold with top header navigation.
|
|
///
|
|
/// Layout structure per UI_LAYOUT.md:
|
|
/// ```
|
|
/// ┌─────────────────────────────────────────────────────────────────┐
|
|
/// │ HEADER: [Logo] [Room Tabs] [Profile] │
|
|
/// ├─────────────────────────────────────────────────────────────────┤
|
|
/// │ BODY: Room page content (may include room-specific sidebar) │
|
|
/// └─────────────────────────────────────────────────────────────────┘
|
|
/// ```
|
|
class AppScaffold extends StatelessWidget {
|
|
const AppScaffold({super.key, required this.child});
|
|
|
|
final Widget child;
|
|
|
|
// Header height must match TopHeaderBar._headerHeight
|
|
static const double _headerHeight = 56.0;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: Stack(
|
|
children: [
|
|
// Main content area with top padding for header
|
|
Positioned.fill(
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(top: _headerHeight),
|
|
child: child,
|
|
),
|
|
),
|
|
|
|
// Top header overlays content (bulge extends into content area)
|
|
Positioned(
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
child: TopHeaderBar(
|
|
selectedIndex: _selectedIndex(context),
|
|
onRoomSelected: (index) => _onNavSelected(context, index),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
int _selectedIndex(BuildContext context) {
|
|
final location = GoRouterState.of(context).matchedLocation;
|
|
|
|
if (location.startsWith(ControlRoomRoutes.base)) return 1;
|
|
if (location.startsWith(AppRoutes.parlor)) return 2;
|
|
// Settings is no longer in main nav (accessed via Profile dropdown)
|
|
return 0; // Front Hall
|
|
}
|
|
|
|
void _onNavSelected(BuildContext context, int index) {
|
|
final route = switch (index) {
|
|
0 => AppRoutes.frontHall,
|
|
1 => ControlRoomRoutes.containers,
|
|
2 => AppRoutes.parlor,
|
|
_ => AppRoutes.frontHall,
|
|
};
|
|
context.go(route);
|
|
}
|
|
}
|