- Move room navigation from sidebar to top header bar as icons - Add circular "bulge" extending below header for larger logo (120px) - Logo centered in bulge with 20% circle below header line - Profile dropdown with Settings and Logout options - Header overlays content (Stack layout) instead of pushing it down - Remove AppBar from FrontHallPage (provided by AppScaffold) - Add transparent logo asset 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
71 lines
2.6 KiB
Dart
71 lines
2.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:go_router/go_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(AppRoutes.controlRoom)) 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 => AppRoutes.controlRoom,
|
|
2 => AppRoutes.parlor,
|
|
_ => AppRoutes.frontHall,
|
|
};
|
|
context.go(route);
|
|
}
|
|
}
|