feat: rebuild desktop UI to match Figma + website, hero slider improvements
- 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>
This commit is contained in:
84
lib/widgets/responsive_shell.dart
Normal file
84
lib/widgets/responsive_shell.dart
Normal file
@@ -0,0 +1,84 @@
|
||||
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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user