- Desktop sidebar (262px, blue gradient, white pill nav), topbar (search + bell + avatar), responsive shell rewritten - Desktop homepage: immersive hero with Ken Burns animation, pill category chips, date badge cards matching mvnew.eventifyplus.com/home - Desktop calendar: 60/40 two-column layout with white background - Desktop profile: full-width banner + 3-column event grids - Desktop learn more: hero image + about/venue columns + gallery strip - Desktop settings/contribute: polished to match design system - Mobile hero slider: RepaintBoundary, animated dots with 44px tap targets, 5s auto-scroll, 8s post-swipe delay, shimmer loading, dynamic event type badge, human-readable dates - Guest access: requiresAuth false on read endpoints - Location fix: show place names instead of lat/lng coordinates - Version 1.6.1+17 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
85 lines
2.1 KiB
Dart
85 lines
2.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import '../core/constants.dart';
|
|
import 'desktop_sidebar.dart';
|
|
import 'desktop_topbar.dart';
|
|
|
|
class ResponsiveShell extends StatefulWidget {
|
|
final int currentIndex;
|
|
final ValueChanged<int> onIndexChanged;
|
|
final Widget child;
|
|
final bool showTopBar;
|
|
|
|
const ResponsiveShell({
|
|
Key? key,
|
|
required this.currentIndex,
|
|
required this.onIndexChanged,
|
|
required this.child,
|
|
this.showTopBar = true,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
State<ResponsiveShell> createState() => _ResponsiveShellState();
|
|
}
|
|
|
|
class _ResponsiveShellState extends State<ResponsiveShell> {
|
|
String _username = 'Guest';
|
|
String? _profileImage;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadPreferences();
|
|
}
|
|
|
|
Future<void> _loadPreferences() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
if (!mounted) return;
|
|
setState(() {
|
|
_username = prefs.getString('display_name') ??
|
|
prefs.getString('username') ??
|
|
'Guest';
|
|
_profileImage = prefs.getString('profileImage');
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return LayoutBuilder(builder: (context, constraints) {
|
|
final width = constraints.maxWidth;
|
|
|
|
// Mobile — no shell
|
|
if (width < AppConstants.desktopBreakpoint) {
|
|
return widget.child;
|
|
}
|
|
|
|
return Scaffold(
|
|
body: Row(
|
|
children: [
|
|
DesktopSidebar(
|
|
selectedIndex: widget.currentIndex,
|
|
onIndexChanged: widget.onIndexChanged,
|
|
),
|
|
Expanded(
|
|
child: Column(
|
|
children: [
|
|
if (widget.showTopBar)
|
|
DesktopTopBar(
|
|
username: _username,
|
|
profileImage: _profileImage,
|
|
onAvatarTap: () => widget.onIndexChanged(2),
|
|
),
|
|
Expanded(
|
|
child: RepaintBoundary(child: widget.child),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
});
|
|
}
|
|
}
|