feat: update home page

This commit is contained in:
efrilm 2025-08-12 23:43:07 +07:00
parent 795281f52d
commit 138640d47d

View File

@ -21,21 +21,12 @@ class HomePage extends StatefulWidget {
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
late ScrollController _scrollController;
late AnimationController _headerAnimationController;
late AnimationController _contentAnimationController;
late AnimationController _appBarAnimationController;
late Animation<double> _appBarOpacityAnimation;
late Animation<Offset> _appBarSlideAnimation;
bool _showAppBar = false;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_scrollController.addListener(_scrollListener);
_headerAnimationController = AnimationController(
duration: const Duration(milliseconds: 800),
@ -47,28 +38,6 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
vsync: this,
);
// AppBar Animation Controller
_appBarAnimationController = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
// AppBar Animations
_appBarOpacityAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _appBarAnimationController,
curve: Curves.easeInOut,
),
);
_appBarSlideAnimation =
Tween<Offset>(begin: const Offset(0.0, -1.0), end: Offset.zero).animate(
CurvedAnimation(
parent: _appBarAnimationController,
curve: Curves.easeOutCubic,
),
);
_startAnimations();
}
@ -79,76 +48,66 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
});
}
void _scrollListener() {
const double threshold = 200.0;
if (_scrollController.offset > threshold && !_showAppBar) {
setState(() {
_showAppBar = true;
});
_appBarAnimationController.forward();
} else if (_scrollController.offset <= threshold && _showAppBar) {
_appBarAnimationController.reverse().then((_) {
if (mounted) {
setState(() {
_showAppBar = false;
});
}
});
}
}
@override
void dispose() {
_scrollController.removeListener(_scrollListener);
_scrollController.dispose();
_headerAnimationController.dispose();
_contentAnimationController.dispose();
_appBarAnimationController.dispose();
super.dispose();
}
PreferredSizeWidget? _buildAnimatedAppBar() {
if (!_showAppBar) return null;
return PreferredSize(
preferredSize: const Size.fromHeight(kToolbarHeight),
child: SlideTransition(
position: _appBarSlideAnimation,
child: FadeTransition(
opacity: _appBarOpacityAnimation,
child: AppBar(
title: const Text(
'AppSkel POS Owner',
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 18,
letterSpacing: -0.5,
),
),
foregroundColor: AppColor.textPrimary,
elevation: 0,
scrolledUnderElevation: 0,
shadowColor: AppColor.primary.withOpacity(0.1),
actions: [ActionIconButton(onTap: () {}, icon: LineIcons.bell)],
),
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColor.background,
appBar: _buildAnimatedAppBar(),
body: CustomScrollView(
controller: _scrollController,
physics: const BouncingScrollPhysics(),
physics: const BouncingScrollPhysics(parent: ClampingScrollPhysics()),
slivers: [
// Enhanced Header
SliverToBoxAdapter(
child: AnimatedBuilder(
// SliverAppBar with HomeHeader as background
SliverAppBar(
expandedHeight: 250, // Adjust based on HomeHeader height
floating: true,
pinned: true,
snap: true,
elevation: 0,
scrolledUnderElevation: 8,
backgroundColor: AppColor.primary,
surfaceTintColor: Colors.transparent,
flexibleSpace: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
// Calculate collapse progress (0.0 = expanded, 1.0 = collapsed)
final double expandedHeight = 200;
final double collapsedHeight =
kToolbarHeight + MediaQuery.of(context).padding.top;
final double currentHeight = constraints.maxHeight;
double collapseProgress =
1.0 -
((currentHeight - collapsedHeight) /
(expandedHeight - collapsedHeight));
collapseProgress = collapseProgress.clamp(0.0, 1.0);
return FlexibleSpaceBar(
title: Opacity(
opacity: collapseProgress, // Title muncul saat collapse
child: Row(
children: [
Expanded(
child: Text(
'AppSkel POS Owner',
style: AppStyle.xl.copyWith(
fontWeight: FontWeight.w700,
fontSize: 18,
letterSpacing: -0.5,
color: AppColor.white,
),
),
),
ActionIconButton(onTap: () {}, icon: LineIcons.bell),
],
),
),
titlePadding: const EdgeInsets.only(left: 16, bottom: 16),
background: AnimatedBuilder(
animation: _headerAnimationController,
builder: (context, child) {
return Transform.translate(
@ -163,6 +122,9 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
);
},
),
);
},
),
),
// Main Content