From 86d581f5ea30b76455ab11526264d5b2b1345ec3 Mon Sep 17 00:00:00 2001 From: efrilm Date: Tue, 12 May 2026 14:48:53 +0700 Subject: [PATCH] update remove animation --- lib/l10n/app_en.arb | 4 +- lib/l10n/app_id.arb | 4 +- lib/l10n/app_localizations.dart | 6 + lib/l10n/app_localizations_en.dart | 3 + lib/l10n/app_localizations_id.dart | 3 + .../components/appbar/appbar.dart | 232 ++++----- .../pages/finance/finance_page.dart | 2 +- lib/presentation/pages/home/home_page.dart | 6 +- .../pages/home/widgets/feature.dart | 2 +- .../pages/home/widgets/header.dart | 453 ++++++------------ .../pages/home/widgets/omset_balance.dart | 163 +++++++ pubspec.lock | 38 +- 12 files changed, 439 insertions(+), 477 deletions(-) create mode 100644 lib/presentation/pages/home/widgets/omset_balance.dart diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index ccf296d..44777f0 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -429,5 +429,7 @@ "package_name": "Package Name", "@package_name": {}, "device": "Device", - "@device": {} + "@device": {}, + "profit_loss": "Laba Rugi", + "@profit_loss": {} } diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 601dd7d..f07c475 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -429,5 +429,7 @@ "package_name": "Nama Paket", "@package_name": {}, "device": "Perangkat", - "@device": {} + "@device": {}, + "profit_loss": "Laba Rugi", + "@profit_loss": {} } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 2dd685d..91ab6c4 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -1300,6 +1300,12 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Device'** String get device; + + /// No description provided for @profit_loss. + /// + /// In en, this message translates to: + /// **'Laba Rugi'** + String get profit_loss; } class _AppLocalizationsDelegate extends LocalizationsDelegate { diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 2883d3f..4f371d7 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -618,4 +618,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get device => 'Device'; + + @override + String get profit_loss => 'Laba Rugi'; } diff --git a/lib/l10n/app_localizations_id.dart b/lib/l10n/app_localizations_id.dart index bf1b641..2c66dcf 100644 --- a/lib/l10n/app_localizations_id.dart +++ b/lib/l10n/app_localizations_id.dart @@ -618,4 +618,7 @@ class AppLocalizationsId extends AppLocalizations { @override String get device => 'Perangkat'; + + @override + String get profit_loss => 'Laba Rugi'; } diff --git a/lib/presentation/components/appbar/appbar.dart b/lib/presentation/components/appbar/appbar.dart index 51713e2..afe8f0d 100644 --- a/lib/presentation/components/appbar/appbar.dart +++ b/lib/presentation/components/appbar/appbar.dart @@ -1,76 +1,21 @@ import 'package:flutter/material.dart'; -import 'dart:math' as math; -import '../../../../common/theme/theme.dart'; import '../../../common/painter/wave_painter.dart'; +import '../../../common/theme/theme.dart'; -class CustomAppBar extends StatefulWidget { +class CustomAppBar extends StatelessWidget { final String title; final bool isBack; const CustomAppBar({super.key, required this.title, this.isBack = true}); - @override - State createState() => _CustomAppBarState(); -} - -class _CustomAppBarState extends State - with TickerProviderStateMixin { - late AnimationController _particleController; - late AnimationController _waveController; - late AnimationController _breathController; - - late Animation _particleAnimation; - late Animation _waveAnimation; - late Animation _breathAnimation; - - @override - void initState() { - super.initState(); - - _particleController = AnimationController( - duration: const Duration(seconds: 8), - vsync: this, - )..repeat(); - - _waveController = AnimationController( - duration: const Duration(seconds: 6), - vsync: this, - )..repeat(); - - _breathController = AnimationController( - duration: const Duration(seconds: 4), - vsync: this, - )..repeat(reverse: true); - - _particleAnimation = Tween( - begin: 0.0, - end: 2 * math.pi, - ).animate(_particleController); - - _waveAnimation = Tween( - begin: 0.0, - end: 2 * math.pi, - ).animate(_waveController); - - _breathAnimation = Tween(begin: 0.8, end: 1.2).animate( - CurvedAnimation(parent: _breathController, curve: Curves.easeInOut), - ); - } - - @override - void dispose() { - _particleController.dispose(); - _waveController.dispose(); - _breathController.dispose(); - super.dispose(); - } - @override Widget build(BuildContext context) { + final size = MediaQuery.of(context).size; + return FlexibleSpaceBar( - titlePadding: EdgeInsets.only(left: widget.isBack ? 50 : 20, bottom: 16), + titlePadding: EdgeInsets.only(left: isBack ? 50 : 20, bottom: 16), title: Text( - widget.title, + title, style: AppStyle.xl.copyWith( color: AppColor.textWhite, fontSize: 18, @@ -85,105 +30,88 @@ class _CustomAppBarState extends State end: Alignment.bottomCenter, ), ), - child: AnimatedBuilder( - animation: Listenable.merge([ - _particleController, - _waveController, - _breathController, - ]), - builder: (context, child) { - return Stack( - children: [ - // Animated background elements - _buildAnimatedBackground(context), - ], - ); - }, - ), - ), - ); - } - - Widget _buildAnimatedBackground(BuildContext context) { - final size = MediaQuery.of(context).size; - - return Stack( - children: [ - // Floating particles with orbital motion - ...List.generate(8, (index) { - final double radius = 40 + (index * 15); - final double angle = _particleAnimation.value + (index * 0.8); - final double centerX = size.width * 0.7; - final double centerY = 60; - - return Positioned( - left: centerX + math.cos(angle) * radius - 3, - top: centerY + math.sin(angle) * (radius * 0.5) - 3, - child: Transform.scale( - scale: _breathAnimation.value * 0.5, + child: Stack( + children: [ + // Static decorative circles (right side) + Positioned( + top: -20, + right: -30, child: Container( - width: 4 + (index % 3), - height: 4 + (index % 3), + width: 120, + height: 120, decoration: BoxDecoration( shape: BoxShape.circle, - color: AppColor.textWhite.withOpacity(0.6), - boxShadow: [ - BoxShadow( - color: AppColor.textWhite.withOpacity(0.3), - blurRadius: 6, - spreadRadius: 1, - ), + color: AppColor.textWhite.withOpacity(0.08), + ), + ), + ), + Positioned( + top: 30, + right: 20, + child: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: AppColor.textWhite.withOpacity(0.05), + ), + ), + ), + + // Static decorative circles (left side) + Positioned( + top: 10, + left: -20, + child: Container( + width: 80, + height: 80, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: AppColor.textWhite.withOpacity(0.04), + ), + ), + ), + + // Static sparkle icons + ...List.generate(4, (index) { + return Positioned( + left: (index * 90.0) % size.width, + top: 20 + (index * 25.0), + child: Icon( + Icons.auto_awesome, + size: 10 + (index % 3) * 3, + color: AppColor.textWhite.withOpacity(0.2), + ), + ); + }), + + // Wave pattern (static) + Positioned.fill( + child: CustomPaint( + painter: WavePainter( + animation: 0.0, + color: AppColor.textWhite.withOpacity(0.1), + ), + ), + ), + + // Gradient overlay for depth + Container( + decoration: BoxDecoration( + gradient: RadialGradient( + center: const Alignment(0.3, -0.2), + radius: 1.2, + colors: [ + Colors.transparent, + AppColor.primaryGradient.first.withOpacity(0.1), + Colors.transparent, ], ), ), ), - ); - }), - - // Wave patterns - Positioned.fill( - child: CustomPaint( - painter: WavePainter( - animation: _waveAnimation.value, - color: AppColor.textWhite.withOpacity(0.1), - ), - ), + ], ), - - // Sparkle effects - ...List.generate(4, (index) { - return Positioned( - left: (index * 90.0) % size.width, - top: 20 + (index * 25.0), - child: Transform.rotate( - angle: _particleAnimation.value * 2 + index, - child: Transform.scale( - scale: math.sin(_particleAnimation.value + index) * 0.5 + 1, - child: Icon( - Icons.auto_awesome, - size: 10 + (index % 3) * 3, - color: AppColor.textWhite.withOpacity(0.4), - ), - ), - ), - ); - }), - - // Gradient overlay for depth - Container( - decoration: BoxDecoration( - gradient: RadialGradient( - center: const Alignment(0.3, -0.2), - radius: 1.2, - colors: [ - Colors.transparent, - AppColor.primaryGradient.first.withOpacity(0.1), - Colors.transparent, - ], - ), - ), - ), - ], + ), ); } } diff --git a/lib/presentation/pages/finance/finance_page.dart b/lib/presentation/pages/finance/finance_page.dart index 63beb84..77e9ae7 100644 --- a/lib/presentation/pages/finance/finance_page.dart +++ b/lib/presentation/pages/finance/finance_page.dart @@ -126,7 +126,7 @@ class _FinancePageState extends State pinned: true, backgroundColor: AppColor.primary, elevation: 0, - flexibleSpace: CustomAppBar(title: context.lang.finance), + flexibleSpace: CustomAppBar(title: context.lang.profit_loss), ), // Header dengan filter periode diff --git a/lib/presentation/pages/home/home_page.dart b/lib/presentation/pages/home/home_page.dart index 114ccc9..62625bc 100644 --- a/lib/presentation/pages/home/home_page.dart +++ b/lib/presentation/pages/home/home_page.dart @@ -81,10 +81,10 @@ class _HomePageState extends State with TickerProviderStateMixin { slivers: [ // SliverAppBar with HomeHeader as background SliverAppBar( - expandedHeight: 260, // Adjust based on HomeHeader height - floating: true, + expandedHeight: 300, // Adjust based on HomeHeader height + floating: false, pinned: true, - snap: true, + snap: false, elevation: 0, scrolledUnderElevation: 8, backgroundColor: AppColor.primary, diff --git a/lib/presentation/pages/home/widgets/feature.dart b/lib/presentation/pages/home/widgets/feature.dart index 2a05816..36b2fe6 100644 --- a/lib/presentation/pages/home/widgets/feature.dart +++ b/lib/presentation/pages/home/widgets/feature.dart @@ -49,7 +49,7 @@ class HomeFeature extends StatelessWidget { onTap: () => context.router.push(PurchaseRoute()), ), HomeFeatureTile( - title: context.lang.finance, + title: context.lang.profit_loss, color: const Color(0xFF8BC34A), icon: LineIcons.moneyCheck, onTap: () => context.router.push(FinanceRoute()), diff --git a/lib/presentation/pages/home/widgets/header.dart b/lib/presentation/pages/home/widgets/header.dart index 2c03366..b7ee1f6 100644 --- a/lib/presentation/pages/home/widgets/header.dart +++ b/lib/presentation/pages/home/widgets/header.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'dart:math' as math; import '../../../../application/auth/auth_bloc.dart'; import '../../../../common/constant/app_constant.dart'; @@ -9,6 +8,7 @@ import '../../../../common/painter/wave_painter.dart'; import '../../../../common/theme/theme.dart'; import '../../../../domain/user/user.dart'; import '../../../components/spacer/spacer.dart'; +import 'omset_balance.dart'; class HomeHeader extends StatefulWidget { final int totalRevenue; @@ -18,45 +18,22 @@ class HomeHeader extends StatefulWidget { State createState() => _HomeHeaderState(); } -class _HomeHeaderState extends State with TickerProviderStateMixin { +class _HomeHeaderState extends State with SingleTickerProviderStateMixin { late AnimationController _animationController; - late AnimationController _particleController; - late AnimationController _waveController; - late AnimationController _breathController; late Animation _fadeInAnimation; late Animation _slideAnimation; late Animation _scaleAnimation; - late Animation _particleAnimation; - late Animation _waveAnimation; - late Animation _breathAnimation; @override void initState() { super.initState(); - // Main content animations _animationController = AnimationController( duration: const Duration(milliseconds: 1200), vsync: this, ); - _particleController = AnimationController( - duration: const Duration(seconds: 8), - vsync: this, - )..repeat(); - - _waveController = AnimationController( - duration: const Duration(seconds: 6), - vsync: this, - )..repeat(); - - _breathController = AnimationController( - duration: const Duration(seconds: 4), - vsync: this, - )..repeat(reverse: true); - - // Content animations _fadeInAnimation = Tween(begin: 0.0, end: 1.0).animate( CurvedAnimation( parent: _animationController, @@ -79,29 +56,12 @@ class _HomeHeaderState extends State with TickerProviderStateMixin { ), ); - _particleAnimation = Tween( - begin: 0.0, - end: 2 * math.pi, - ).animate(_particleController); - - _waveAnimation = Tween( - begin: 0.0, - end: 2 * math.pi, - ).animate(_waveController); - - _breathAnimation = Tween(begin: 0.8, end: 1.2).animate( - CurvedAnimation(parent: _breathController, curve: Curves.easeInOut), - ); - _animationController.forward(); } @override void dispose() { _animationController.dispose(); - _particleController.dispose(); - _waveController.dispose(); - _breathController.dispose(); super.dispose(); } @@ -109,161 +69,140 @@ class _HomeHeaderState extends State with TickerProviderStateMixin { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - return AnimatedBuilder( - animation: Listenable.merge([ - _particleController, - _waveController, - _breathController, - ]), - builder: (context, child) { - return Container( - height: 280, - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - AppColor.primary, - AppColor.primaryLight, - AppColor.primaryLight.withOpacity(0.8), - ], - begin: Alignment.topLeft, - end: Alignment.bottomRight, - stops: const [0.0, 0.7, 1.0], - ), - boxShadow: [ - BoxShadow( - color: AppColor.primary.withOpacity(0.3), - blurRadius: 20, - offset: const Offset(0, 10), + return Container( + height: 280, + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + AppColor.primary, + AppColor.primaryLight, + AppColor.primaryLight.withOpacity(0.8), + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + stops: const [0.0, 0.7, 1.0], + ), + boxShadow: [ + BoxShadow( + color: AppColor.primary.withOpacity(0.3), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Stack( + children: [ + // Static decorative circles (right side) + Positioned( + top: -50, + right: -50, + child: Container( + width: 150, + height: 150, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: AppColor.white.withOpacity(0.10), ), - ], + ), + ), + Positioned( + top: 80, + right: -20, + child: Container( + width: 80, + height: 80, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: AppColor.white.withOpacity(0.05), + ), + ), + ), + Positioned( + top: 150, + right: 30, + child: Container( + width: 40, + height: 40, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: AppColor.white.withOpacity(0.07), + ), + ), ), - child: Stack( - children: [ - // Enhanced animated background - _buildAnimatedBackground(), - // Main content - SafeArea(child: _buildContent(context, state.user)), - ], + // Static decorative circles (left side) + Positioned( + top: 60, + left: -30, + child: Container( + width: 100, + height: 100, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: AppColor.white.withOpacity(0.03), + ), + ), ), - ); - }, + Positioned( + bottom: 20, + left: -20, + child: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: AppColor.white.withOpacity(0.04), + ), + ), + ), + + // Static sparkle icons + ...List.generate(8, (index) { + return Positioned( + left: (index * 60.0) % (MediaQuery.of(context).size.width), + top: 30 + (index * 25.0), + child: Icon( + Icons.auto_awesome, + size: 8 + (index % 3) * 3, + color: AppColor.white.withOpacity(0.25), + ), + ); + }), + + // Wave pattern (static) + Positioned.fill( + child: CustomPaint( + painter: WavePainter( + animation: 0.0, + color: AppColor.white.withOpacity(0.08), + ), + ), + ), + + // Gradient overlay for depth + Container( + decoration: BoxDecoration( + gradient: RadialGradient( + center: const Alignment(0.8, -0.3), + radius: 1.5, + colors: [ + Colors.transparent, + AppColor.primary.withOpacity(0.1), + Colors.transparent, + ], + ), + ), + ), + + // Main content + SafeArea(child: _buildContent(context, state.user)), + ], + ), ); }, ); } - Widget _buildAnimatedBackground() { - return Stack( - children: [ - // Floating particles with orbital motion - ...List.generate(12, (index) { - final double radius = 60 + (index * 15); - final double angle = _particleAnimation.value + (index * 0.5); - final double centerX = MediaQuery.of(context).size.width * 0.8; - final double centerY = 100; - - return Positioned( - left: centerX + math.cos(angle) * radius - 4, - top: centerY + math.sin(angle) * (radius * 0.5) - 4, - child: Transform.scale( - scale: _breathAnimation.value * 0.4, - child: Container( - width: 2 + (index % 3), - height: 2 + (index % 3), - decoration: BoxDecoration( - shape: BoxShape.circle, - color: AppColor.white.withOpacity(0.7), - boxShadow: [ - BoxShadow( - color: AppColor.white.withOpacity(0.3), - blurRadius: 6, - spreadRadius: 1, - ), - ], - ), - ), - ), - ); - }), - - // Wave patterns - Positioned.fill( - child: CustomPaint( - painter: WavePainter( - animation: _waveAnimation.value, - color: AppColor.white.withOpacity(0.08), - ), - ), - ), - - // Sparkle effects - ...List.generate(8, (index) { - return Positioned( - left: (index * 60.0) % MediaQuery.of(context).size.width, - top: 30 + (index * 25.0), - child: Transform.rotate( - angle: _particleAnimation.value * 2 + index, - child: Transform.scale( - scale: math.sin(_particleAnimation.value + index) * 0.3 + 0.8, - child: Icon( - Icons.auto_awesome, - size: 8 + (index % 3) * 3, - color: AppColor.white.withOpacity(0.5), - ), - ), - ), - ); - }), - - // Gradient overlay for depth - Container( - decoration: BoxDecoration( - gradient: RadialGradient( - center: const Alignment(0.8, -0.3), - radius: 1.5, - colors: [ - Colors.transparent, - AppColor.primary.withOpacity(0.1), - Colors.transparent, - ], - ), - ), - ), - - // Additional left side particles - ...List.generate(6, (index) { - final double radius = 40 + (index * 10); - final double angle = _particleAnimation.value * 0.5 + (index * 1.2); - final double centerX = MediaQuery.of(context).size.width * 0.1; - final double centerY = 120; - - return Positioned( - left: centerX + math.cos(angle) * radius - 2, - top: centerY + math.sin(angle) * (radius * 0.7) - 2, - child: Transform.scale( - scale: _breathAnimation.value * 0.3 + 0.5, - child: Container( - width: 2 + (index % 2), - height: 2 + (index % 2), - decoration: BoxDecoration( - shape: BoxShape.circle, - color: AppColor.white.withOpacity(0.4), - boxShadow: [ - BoxShadow( - color: AppColor.white.withOpacity(0.2), - blurRadius: 4, - ), - ], - ), - ), - ), - ); - }), - ], - ); - } - Widget _buildContent(BuildContext context, User user) { String greeting(BuildContext context) { final hour = DateTime.now().hour; @@ -326,37 +265,29 @@ class _HomeHeaderState extends State with TickerProviderStateMixin { ], ), ), - // Enhanced notification icon with breathing animation - AnimatedBuilder( - animation: _breathController, - builder: (context, child) { - return Transform.scale( - scale: _breathAnimation.value * 0.1 + 1.0, - child: Container( - padding: const EdgeInsets.all(10), - decoration: BoxDecoration( - color: AppColor.white.withOpacity(0.25), - borderRadius: BorderRadius.circular(14), - border: Border.all( - color: AppColor.white.withOpacity(0.3), - width: 1, - ), - boxShadow: [ - BoxShadow( - color: AppColor.white.withOpacity(0.2), - blurRadius: 8 + (_breathAnimation.value * 2), - offset: const Offset(0, 2), - ), - ], - ), - child: const Icon( - Icons.notifications_none_rounded, - color: AppColor.white, - size: 20, - ), + // Notification icon + Container( + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: AppColor.white.withOpacity(0.25), + borderRadius: BorderRadius.circular(14), + border: Border.all( + color: AppColor.white.withOpacity(0.3), + width: 1, + ), + boxShadow: [ + BoxShadow( + color: AppColor.white.withOpacity(0.2), + blurRadius: 8, + offset: const Offset(0, 2), ), - ); - }, + ], + ), + child: const Icon( + Icons.notifications_none_rounded, + color: AppColor.white, + size: 20, + ), ), ], ), @@ -377,8 +308,8 @@ class _HomeHeaderState extends State with TickerProviderStateMixin { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '${greeting(context)},', - style: AppStyle.lg.copyWith( + '${greeting(context)}, ${user.name}! 👋', + style: AppStyle.md.copyWith( color: AppColor.white, fontWeight: FontWeight.w500, shadows: [ @@ -390,33 +321,6 @@ class _HomeHeaderState extends State with TickerProviderStateMixin { ], ), ), - const SpaceHeight(2), - Text( - '${user.name}! 👋', - style: AppStyle.h4.copyWith( - color: AppColor.white, - fontWeight: FontWeight.w800, - letterSpacing: -0.5, - shadows: [ - Shadow( - color: Colors.black.withOpacity(0.2), - offset: const Offset(0, 2), - blurRadius: 4, - ), - ], - ), - ), - const SpaceHeight(8), - Text( - context.lang.home_header_desc, - style: AppStyle.md.copyWith( - color: AppColor.white.withOpacity(0.85), - fontWeight: FontWeight.w400, - height: 1.3, - ), - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), ], ), ), @@ -424,63 +328,14 @@ class _HomeHeaderState extends State with TickerProviderStateMixin { ), const SpaceHeight(16), + - // Today's highlight with enhanced breathing animation + // Today's highlight FadeTransition( opacity: _fadeInAnimation, child: SlideTransition( position: _slideAnimation, - child: AnimatedBuilder( - animation: _breathController, - builder: (context, child) { - return Transform.scale( - scale: _breathAnimation.value * 0.05 + 1.0, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 6, - ), - decoration: BoxDecoration( - color: AppColor.white.withOpacity(0.25), - borderRadius: BorderRadius.circular(16), - border: Border.all( - color: AppColor.white.withOpacity(0.3), - width: 1, - ), - boxShadow: [ - BoxShadow( - color: AppColor.white.withOpacity(0.1), - blurRadius: 6 + (_breathAnimation.value * 2), - offset: const Offset(0, 2), - ), - ], - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Transform.scale( - scale: _breathAnimation.value * 0.1 + 1.0, - child: Icon( - Icons.trending_up_rounded, - color: AppColor.white, - size: 14, - ), - ), - const SizedBox(width: 6), - Text( - '${context.lang.sales_today} ${widget.totalRevenue.currencyFormatRp}', - style: AppStyle.sm.copyWith( - color: AppColor.white, - fontWeight: FontWeight.w600, - letterSpacing: 0.3, - ), - ), - ], - ), - ), - ); - }, - ), + child: HomeOmsetBalance(totalOmset: widget.totalRevenue, user: user), ), ), ], diff --git a/lib/presentation/pages/home/widgets/omset_balance.dart b/lib/presentation/pages/home/widgets/omset_balance.dart new file mode 100644 index 0000000..425f91b --- /dev/null +++ b/lib/presentation/pages/home/widgets/omset_balance.dart @@ -0,0 +1,163 @@ +import 'package:flutter/material.dart'; +import 'package:line_icons/line_icon.dart'; +import 'package:line_icons/line_icons.dart'; + +import '../../../../../../common/theme/theme.dart'; +import '../../../../common/extension/extension.dart'; +import '../../../../domain/user/user.dart'; +import '../../../components/spacer/spacer.dart'; + +class HomeOmsetBalance extends StatelessWidget { + final int totalOmset; + final User user; + const HomeOmsetBalance({super.key, required this.totalOmset, required this.user}); + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.symmetric(horizontal: 8), + clipBehavior: Clip.none, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + border: Border.all(color: AppColor.white.withOpacity(0.3), width: 1), + boxShadow: [ + BoxShadow( + color: AppColor.white.withOpacity(0.1), + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + children: [_top(context), _middle(context), _bottom(context)], + ), + ); + } + + Widget _bottom(BuildContext context) { + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + // context.router.push(BillingHistoryRoute()); + }, + child: Container( + width: double.infinity, + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + decoration: BoxDecoration( + color: AppColor.white.withOpacity(0.2), + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(16), + ), + ), + child: Row( + children: [ + LineIcon(LineIcons.calendar, color: AppColor.white, size: 14), + SpaceWidth(6), + Expanded( + child: IgnorePointer( + child: Text( + DateTime.now().toDate, + style: AppStyle.sm.copyWith( + color: AppColor.white, + fontWeight: FontWeight.w600, + letterSpacing: 0.3, + ), + ), + ), + ), + ], + ), + ), + ); + } + + Container _middle(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), + decoration: BoxDecoration(color: AppColor.white.withOpacity(0.3)), + child: Row( + children: [ + Expanded( + child: GestureDetector( + onTap: () {}, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + context.lang.sales_today, + style: AppStyle.sm.copyWith( + color: AppColor.white, + fontWeight: FontWeight.w400, + letterSpacing: 0.3, + ), + ), + SpaceHeight(2), + Text( + totalOmset.currencyFormatRp, + style: AppStyle.xl.copyWith( + color: AppColor.white, + fontWeight: FontWeight.w900, + letterSpacing: 0.3, + ), + ), + ], + ), + ), + ), + LineIcon(LineIcons.eye, color: AppColor.white, size: 16), + ], + ), + ); + } + + GestureDetector _top(BuildContext context) { + return GestureDetector( + onTap: () {}, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + decoration: BoxDecoration( + color: AppColor.white.withOpacity(0.2), + borderRadius: BorderRadius.vertical( + top: Radius.circular(16), + ), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Enaklo Bakso Bakmi 343', + style: AppStyle.sm.copyWith( + color: AppColor.white, + fontWeight: FontWeight.w600, + letterSpacing: 0.3, + ), + ), + SpaceHeight(2), + Text( + 'Jl. Tawes No.53, Rawamangun, Kec. Pulo Gadung', + style: AppStyle.sm.copyWith( + color: AppColor.white, + fontWeight: FontWeight.w600, + letterSpacing: 0.3, + ), + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ], + ), + ), + SpaceWidth(6), + LineIcon( + LineIcons.alternateExchange, + color: AppColor.white, + size: 14, + ), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 7a22179..d84b1fb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -213,10 +213,10 @@ packages: dependency: transitive description: name: characters - sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.0" checked_yaml: dependency: transitive description: @@ -857,26 +857,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" url: "https://pub.dev" source: hosted - version: "11.0.2" + version: "10.0.9" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.10" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.1" line_icons: dependency: "direct main" description: @@ -913,26 +913,26 @@ packages: dependency: transitive description: name: matcher - sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.19" + version: "0.12.17" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.13.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.16.0" mime: dependency: transitive description: @@ -1502,10 +1502,10 @@ packages: dependency: transitive description: name: test_api - sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.7.10" + version: "0.7.4" time: dependency: transitive description: @@ -1638,10 +1638,10 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.1.4" vm_service: dependency: transitive description: @@ -1723,5 +1723,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.9.0-0 <4.0.0" + dart: ">=3.8.1 <4.0.0" flutter: ">=3.29.0"