diff --git a/lib/views/home/infography/infography_screen.dart b/lib/views/home/infography/infography_screen.dart index 1d48f62..2424e1b 100644 --- a/lib/views/home/infography/infography_screen.dart +++ b/lib/views/home/infography/infography_screen.dart @@ -7,10 +7,14 @@ import 'package:didvan/models/view/action_sheet_data.dart'; import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/views/home/infography/infography_screen_state.dart'; import 'package:didvan/views/home/main/widgets/infography_item.dart'; +import 'package:didvan/views/widgets/didvan/card.dart'; import 'package:didvan/views/widgets/didvan/checkbox.dart'; +import 'package:didvan/views/widgets/didvan/divider.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/item_title.dart'; +import 'package:didvan/views/widgets/overview/news.dart'; import 'package:didvan/views/widgets/search_field.dart'; +import 'package:didvan/views/widgets/shimmer_placeholder.dart'; import 'package:didvan/views/widgets/state_handlers/empty_result.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:flutter/material.dart'; @@ -144,61 +148,109 @@ class _InfographyScreenState extends State { @override Widget build(BuildContext context) { - return StateHandler( - emptyState: EmptyResult( - onNewSearch: () => _focusNode.requestFocus(), + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.surface, + elevation: 0.0, + scrolledUnderElevation: 0.0, + title: DidvanText( + "اینفوگرافی", + style: Theme.of(context).textTheme.bodyLarge, + fontSize: 20, + ), ), - enableEmptyState: context.watch().contents.isEmpty, - onRetry: context.read().init, - state: context.watch(), - builder: (context, state) { - return Scaffold( - appBar: AppBar( - backgroundColor: Theme.of(context).colorScheme.surface, - elevation: 0.0, - scrolledUnderElevation: 0.0, - title: DidvanText( - "اینفوگرافی", - style: Theme.of(context).textTheme.bodyLarge, - fontSize: 20, - ), + body: Column( + children: [ + Container( + height: 80, + color: Theme.of(context).colorScheme.surface, + padding: + const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + child: SearchField( + title: "اینفوگرافی", + onChanged: _onChanged, + focusNode: _focusNode, + onFilterButtonPressed: _showFilterBottomSheet, + value: context.watch().lastSearch, + isFiltered: context.watch().filtering), ), - body: Column( - children: [ - Container( - height: 80, - color: Theme.of(context).colorScheme.surface, - padding: const EdgeInsets.symmetric( - horizontal: 16.0, vertical: 16.0), - child: SearchField( - title: "اینفوگرافی", - onChanged: _onChanged, - focusNode: _focusNode, - onFilterButtonPressed: _showFilterBottomSheet, - value: state.lastSearch, - isFiltered: state.filtering), - ), - Expanded( - child: ListView.builder( - controller: _scrollController, - itemCount: state.contents.length, - itemBuilder: (context, index) => InfographyItem( - id: state.contents[index].id, - onMarkChanged: (id, value, _) => - state.changeMark(id, value), - image: state.contents[index].image, - category: state.contents[index].category, - createdAt: state.contents[index].createdAt, - title: state.contents[index].title, - tag: state.contents[index].tags, - marked: state.contents[index].marked, + StateHandler( + placeholder: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + placeholder, + const SizedBox( + height: 4, ), + placeholder + ], + ), + ), + emptyState: EmptyResult( + onNewSearch: () => _focusNode.requestFocus(), + ), + enableEmptyState: + context.watch().contents.isEmpty, + onRetry: context.read().init, + state: context.watch(), + builder: (context, state) => Expanded( + child: ListView.builder( + controller: _scrollController, + itemCount: state.contents.length, + itemBuilder: (context, index) => InfographyItem( + id: state.contents[index].id, + onMarkChanged: (id, value, _) => state.changeMark(id, value), + image: state.contents[index].image, + category: state.contents[index].category, + createdAt: state.contents[index].createdAt, + title: state.contents[index].title, + tag: state.contents[index].tags, + marked: state.contents[index].marked, ), ), - ], + ), ), - ); - }, + ], + ), ); } + + static Widget get placeholder => const DidvanCard( + margin: EdgeInsets.all(8), + padding: EdgeInsets.all(8), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ShimmerPlaceholder( + height: 16, + width: 240, + ), + ], + ), + SizedBox(height: 12), + ShimmerPlaceholder(height: 200, width: 400), + SizedBox(height: 12), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ShimmerPlaceholder( + height: 32, + width: 100, + ), + ], + ), + DidvanDivider( + verticalPadding: 12, + ), + ShimmerPlaceholder( + height: 16, + width: double.infinity, + ), + ], + ), + ); } diff --git a/lib/views/home/new_statistic/new_statistic.dart b/lib/views/home/new_statistic/new_statistic.dart index fd22ce8..bbfb89f 100644 --- a/lib/views/home/new_statistic/new_statistic.dart +++ b/lib/views/home/new_statistic/new_statistic.dart @@ -9,6 +9,7 @@ import 'package:didvan/views/home/new_statistic/widgets/statistic_cat.dart'; import 'package:didvan/views/widgets/didvan/card.dart'; import 'package:didvan/views/widgets/didvan/divider.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; +import 'package:didvan/views/widgets/shimmer_placeholder.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:flutter/material.dart'; @@ -37,193 +38,272 @@ class _NewStatisticState extends State { @override Widget build(BuildContext context) { - return StateHandler( - onRetry: context.read().init, - state: context.watch(), - builder: (context, state) => Padding( - padding: const EdgeInsets.all(8.0), - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Center( - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 12), - color: Theme.of(context).colorScheme.background, - child: DidvanText( - 'دسته‌بندی‌های کلان', - color: Theme.of(context).colorScheme.title, - style: Theme.of(context).textTheme.titleMedium, - ), + return Padding( + padding: const EdgeInsets.all(8.0), + child: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Center( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12), + color: Theme.of(context).colorScheme.background, + child: DidvanText( + 'دسته‌بندی‌های کلان', + color: Theme.of(context).colorScheme.title, + style: Theme.of(context).textTheme.titleMedium, ), ), - const Padding( - padding: EdgeInsets.only( - left: 20, - right: 20, - top: 16, - ), - child: NewStatisticCategories(), + ), + const Padding( + padding: EdgeInsets.only( + left: 20, + right: 20, + top: 16, ), - const DidvanDivider( - verticalPadding: 4, - ), - GestureDetector( - onTap: () => Future.delayed(Duration.zero, () { - Navigator.of(context) - .pushNamed(Routes.statGeneral, arguments: { - "id": 7, - "title": state.contents[0].header, - }).then((value) => state.getStatistic()); - }), - child: StatHeader( - header: state.contents[0].header, - icon: DidvanIcons.star_circle_solid, - )), - SizedBox( - height: 100, - width: 80, - child: ListView.builder( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - physics: const ScrollPhysics(), - itemCount: state.contents[0].contents.length, - itemBuilder: (context, index) => StatMainCard( - statistic: state.contents[0].contents[index], - ), + child: NewStatisticCategories(), + ), + const DidvanDivider( + verticalPadding: 4, + ), + StateHandler( + enableEmptyState: false, + onRetry: context.read().init, + state: context.watch(), + placeholder: Padding( + padding: const EdgeInsets.only(top: 48.0), + child: Column( + children: [ + placeholder, + SizedBox( + height: 8, + ), + placeholder, + SizedBox( + height: 8, + ), + placeholder, + SizedBox( + height: 8, + ), + placeholder, + ], ), ), - const DidvanDivider( - verticalPadding: 4, - ), - GestureDetector( - onTap: () => Future.delayed(Duration.zero, () { - Navigator.of(context).pushNamed(Routes.statGeneral, - arguments: { - "id": 1, - "title": state.contents[1].header - }); - }).then((value) => _reset()), - child: StatHeader( - header: state.contents[1].header, - icon: DidvanIcons.currency_solid, - )), - SizedBox( - height: 100, - width: 80, - child: ListView.builder( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - physics: const ScrollPhysics(), - itemCount: state.contents[1].contents.length, - itemBuilder: (context, index) => StatMainCard( - statistic: state.contents[1].contents[index]))), - const DidvanDivider( - verticalPadding: 4, - ), - GestureDetector( - onTap: () => Future.delayed(Duration.zero, () { - Navigator.of(context).pushNamed(Routes.statGeneral, - arguments: { - "id": 2, - "title": state.contents[2].header + builder: (context, state) => Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + GestureDetector( + onTap: () => Future.delayed(Duration.zero, () { + Navigator.of(context) + .pushNamed(Routes.statGeneral, arguments: { + "id": 7, + "title": state.contents[0].header, }).then((value) => _reset()); - }), - child: StatHeader( - header: state.contents[2].header, - icon: DidvanIcons.bitcoin_solid, - )), - SizedBox( - height: 100, - width: 80, - child: ListView.builder( + }), + child: StatHeader( + header: state.contents[0].header, + icon: DidvanIcons.star_circle_solid, + )), + SizedBox( + height: 100, + width: 80, + child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, physics: const ScrollPhysics(), - itemCount: state.contents[2].contents.length, + itemCount: state.contents[0].contents.length, itemBuilder: (context, index) => StatMainCard( - statistic: state.contents[2].contents[index]))), - const DidvanDivider( - verticalPadding: 4, - ), - GestureDetector( - onTap: () => Future.delayed(Duration.zero, () { - Navigator.of(context).pushNamed(Routes.statGeneral, - arguments: {"id": 3, "title": state.contents[3].header}); - }).then((value) => _reset()), - child: StatHeader( - header: state.contents[3].header, - icon: DidvanIcons.commodity_solid, - ), - ), - SizedBox( - height: 100, - width: 80, - child: ListView.builder( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - physics: const ScrollPhysics(), - itemCount: state.contents[3].contents.length, - itemBuilder: (context, index) => StatMainCard( - statistic: state.contents[3].contents[index]))), - const DidvanDivider( - verticalPadding: 4, - ), - GestureDetector( - onTap: () => Future.delayed(Duration.zero, () { - Navigator.of(context).pushNamed(Routes.statGeneral, - arguments: { - "id": 4, - "title": state.contents[4].header + statistic: state.contents[0].contents[index], + ), + ), + ), + const DidvanDivider( + verticalPadding: 4, + ), + GestureDetector( + onTap: () => Future.delayed(Duration.zero, () { + Navigator.of(context).pushNamed(Routes.statGeneral, + arguments: { + "id": 1, + "title": state.contents[1].header + }); + }).then((value) => _reset()), + child: StatHeader( + header: state.contents[1].header, + icon: DidvanIcons.currency_solid, + )), + SizedBox( + height: 100, + width: 80, + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: const ScrollPhysics(), + itemCount: state.contents[1].contents.length, + itemBuilder: (context, index) => StatMainCard( + statistic: state.contents[1].contents[index]))), + const DidvanDivider( + verticalPadding: 4, + ), + GestureDetector( + onTap: () => Future.delayed(Duration.zero, () { + Navigator.of(context).pushNamed(Routes.statGeneral, + arguments: { + "id": 2, + "title": state.contents[2].header + }).then((value) => _reset()); + }), + child: StatHeader( + header: state.contents[2].header, + icon: DidvanIcons.bitcoin_solid, + )), + SizedBox( + height: 100, + width: 80, + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: const ScrollPhysics(), + itemCount: state.contents[2].contents.length, + itemBuilder: (context, index) => StatMainCard( + statistic: state.contents[2].contents[index]))), + const DidvanDivider( + verticalPadding: 4, + ), + GestureDetector( + onTap: () => Future.delayed(Duration.zero, () { + Navigator.of(context).pushNamed(Routes.statGeneral, + arguments: { + "id": 3, + "title": state.contents[3].header + }); + }).then((value) => _reset()), + child: StatHeader( + header: state.contents[3].header, + icon: DidvanIcons.commodity_solid, + ), + ), + SizedBox( + height: 100, + width: 80, + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: const ScrollPhysics(), + itemCount: state.contents[3].contents.length, + itemBuilder: (context, index) => StatMainCard( + statistic: state.contents[3].contents[index]))), + const DidvanDivider( + verticalPadding: 4, + ), + GestureDetector( + onTap: () => Future.delayed(Duration.zero, () { + Navigator.of(context).pushNamed(Routes.statGeneral, + arguments: { + "id": 4, + "title": state.contents[4].header + }).then((value) => _reset()); + }), + child: StatHeader( + header: state.contents[4].header, + icon: DidvanIcons.industry_solid, + )), + SizedBox( + height: 100, + width: 80, + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: const ScrollPhysics(), + itemCount: state.contents[4].contents.length, + itemBuilder: (context, index) => StatMainCard( + statistic: state.contents[4].contents[index]))), + const DidvanDivider( + verticalPadding: 4, + ), + GestureDetector( + onTap: () => Future.delayed(Duration.zero, () { + Navigator.of(context) + .pushNamed(Routes.statGeneral, arguments: { + "id": 5, + "title": state.contents[5].header, }).then((value) => _reset()); - }), - child: StatHeader( - header: state.contents[4].header, - icon: DidvanIcons.industry_solid, - )), - SizedBox( - height: 100, - width: 80, - child: ListView.builder( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - physics: const ScrollPhysics(), - itemCount: state.contents[4].contents.length, - itemBuilder: (context, index) => StatMainCard( - statistic: state.contents[4].contents[index]))), - const DidvanDivider( - verticalPadding: 4, + }), + child: StatHeader( + header: state.contents[5].header, + icon: DidvanIcons.metal_solid, + )), + SizedBox( + height: 100, + width: 80, + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: const ScrollPhysics(), + itemCount: state.contents[5].contents.length, + itemBuilder: (context, index) => StatMainCard( + id: 5, + statistic: state.contents[5].contents[index]))), + ], ), - GestureDetector( - onTap: () => Future.delayed(Duration.zero, () { - Navigator.of(context) - .pushNamed(Routes.statGeneral, arguments: { - "id": 5, - "title": state.contents[5].header, - }).then((value) => _reset()); - }), - child: StatHeader( - header: state.contents[5].header, - icon: DidvanIcons.metal_solid, - )), - SizedBox( - height: 100, - width: 80, - child: ListView.builder( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - physics: const ScrollPhysics(), - itemCount: state.contents[5].contents.length, - itemBuilder: (context, index) => StatMainCard( - id: 5, - statistic: state.contents[5].contents[index]))), - ], - ), + ), + ], ), ), ); } + + static Widget get placeholder => const Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ShimmerPlaceholder( + height: 16, + width: 100, + ), + ShimmerPlaceholder( + height: 16, + width: 50, + ) + ], + ), + SizedBox( + height: 8, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + DidvanCard( + child: ShimmerPlaceholder( + height: 80, + width: 60, + ), + ), + DidvanCard( + child: ShimmerPlaceholder( + height: 80, + width: 60, + ), + ), + DidvanCard( + child: ShimmerPlaceholder( + height: 80, + width: 60, + ), + ), + DidvanCard( + child: ShimmerPlaceholder( + height: 80, + width: 60, + ), + ), + ], + ), + ], + ); } class StatMainCard extends StatelessWidget { diff --git a/lib/views/home/new_statistic/statistics_details/stat_cats_general_screen.dart b/lib/views/home/new_statistic/statistics_details/stat_cats_general_screen.dart index fa58be6..1c89bea 100644 --- a/lib/views/home/new_statistic/statistics_details/stat_cats_general_screen.dart +++ b/lib/views/home/new_statistic/statistics_details/stat_cats_general_screen.dart @@ -2,8 +2,10 @@ import 'dart:async'; import 'package:didvan/views/home/new_statistic/statistics_details/stat_cats_general_state.dart'; import 'package:didvan/views/home/new_statistic/widgets/general_stat_card.dart'; +import 'package:didvan/views/widgets/didvan/card.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/search_field.dart'; +import 'package:didvan/views/widgets/shimmer_placeholder.dart'; import 'package:didvan/views/widgets/state_handlers/empty_result.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:flutter/material.dart'; @@ -74,62 +76,127 @@ class _StatGeneralScreenState extends State { @override Widget build(BuildContext context) { - return StateHandler( - onRetry: context.read().init, - state: context.watch(), - emptyState: EmptyResult( - onNewSearch: () => _focusNode.requestFocus(), + return Scaffold( + appBar: AppBar( + elevation: 0.0, + scrolledUnderElevation: 0.0, + backgroundColor: Theme.of(context).colorScheme.surface, + title: DidvanText( + widget.pageData['title'], + style: Theme.of(context).textTheme.bodyLarge, + fontSize: 20, + ), ), - enableEmptyState: - context.watch().contents.isEmpty, - builder: (context, state) { - return Scaffold( - appBar: AppBar( - elevation: 0.0, - scrolledUnderElevation: 0.0, - backgroundColor: Theme.of(context).colorScheme.surface, - title: DidvanText( - widget.pageData['title'], - style: Theme.of(context).textTheme.bodyLarge, - fontSize: 20, + body: Column( + children: [ + Container( + height: 80, + color: Theme.of(context).colorScheme.surface, + padding: + const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + child: SearchField( + title: widget.pageData['title'], + onChanged: _onChanged, + focusNode: _focusNode, + value: context.watch().lastSearch, ), ), - body: Column( - children: [ - Container( - height: 80, - color: Theme.of(context).colorScheme.surface, - padding: const EdgeInsets.symmetric( - horizontal: 16.0, vertical: 16.0), - child: SearchField( - title: widget.pageData['title'], - onChanged: _onChanged, - focusNode: _focusNode, - value: state.lastSearch, - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0, top: 12, bottom: 8), - child: Align( - alignment: Alignment.centerLeft, - child: DidvanText(formattedDate.toPersianDate())), - ), - Expanded( - child: ListView.builder( - controller: _scrollController, - physics: const ClampingScrollPhysics(), - itemCount: state.contents.length, - itemBuilder: (context, index) => NewStatisticOverviewCard( - statistic: state.contents[index], - onMarkChanged: state.changeMark, - isMarked: state.contents[index].marked, - ), - ), - ), - ], + Padding( + padding: const EdgeInsets.only(left: 8.0, top: 12, bottom: 8), + child: Align( + alignment: Alignment.centerLeft, + child: DidvanText(formattedDate.toPersianDate())), ), - ); - }, + StateHandler( + onRetry: context.read().init, + state: context.watch(), + emptyState: EmptyResult( + onNewSearch: () => _focusNode.requestFocus(), + ), + enableEmptyState: + context.watch().contents.isEmpty, + placeholder: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + placeHolder, + const SizedBox( + height: 8, + ), + placeHolder, + const SizedBox( + height: 8, + ), + ], + ), + builder: (context, state) => Expanded( + child: ListView.builder( + controller: _scrollController, + physics: const ClampingScrollPhysics(), + itemCount: state.contents.length, + itemBuilder: (context, index) => NewStatisticOverviewCard( + statistic: state.contents[index], + onMarkChanged: state.changeMark, + isMarked: state.contents[index].marked, + ), + ), + ), + ), + ], + ), ); } + + static Widget get placeHolder => const Column( + children: [ + DidvanCard( + child: Column( + children: [ + SizedBox(height: 4), + Row( + children: [ + ShimmerPlaceholder(width: 80, height: 16), + Spacer(), + ShimmerPlaceholder(width: 50, height: 14), + SizedBox(width: 8), + ShimmerPlaceholder(width: 50, height: 16), + ], + ), + SizedBox(height: 16), + Row( + children: [ + ShimmerPlaceholder(width: 150, height: 12), + Spacer(), + ShimmerPlaceholder(width: 80, height: 12), + ], + ), + ], + ), + ), + SizedBox(height: 20), + DidvanCard( + child: Column( + children: [ + SizedBox(height: 4), + Row( + children: [ + ShimmerPlaceholder(width: 80, height: 16), + Spacer(), + ShimmerPlaceholder(width: 50, height: 14), + SizedBox(width: 8), + ShimmerPlaceholder(width: 50, height: 16), + ], + ), + SizedBox(height: 16), + Row( + children: [ + ShimmerPlaceholder(width: 150, height: 12), + Spacer(), + ShimmerPlaceholder(width: 80, height: 12), + ], + ), + ], + ), + ), + ], + ); } diff --git a/lib/views/home/new_statistic/stock/new_stock.dart b/lib/views/home/new_statistic/stock/new_stock.dart index dcd3715..d2e3546 100644 --- a/lib/views/home/new_statistic/stock/new_stock.dart +++ b/lib/views/home/new_statistic/stock/new_stock.dart @@ -8,9 +8,11 @@ import 'package:didvan/views/home/new_statistic/stock/newStock_state.dart'; import 'package:didvan/views/home/new_statistic/stock/total_type3.dart'; import 'package:didvan/views/home/new_statistic/stock/total_type4.dart'; import 'package:didvan/views/widgets/didvan/card.dart'; +import 'package:didvan/views/widgets/didvan/divider.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/search_field.dart'; import 'package:didvan/views/widgets/shimmer_placeholder.dart'; +import 'package:didvan/views/widgets/state_handlers/empty_result.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -71,69 +73,78 @@ class _NewStockState extends State { @override Widget build(BuildContext context) { - return StateHandler( - onRetry: context.read().init, - state: context.watch(), - builder: (context, state) => Scaffold( - appBar: AppBar( - backgroundColor: Theme.of(context).colorScheme.surface, - elevation: 0.0, - scrolledUnderElevation: 0.0, - title: DidvanText( - "بازار سرمایه", - style: Theme.of(context).textTheme.bodyLarge, - fontSize: 20, - ), + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.surface, + elevation: 0.0, + scrolledUnderElevation: 0.0, + title: DidvanText( + "بازار سرمایه", + style: Theme.of(context).textTheme.bodyLarge, + fontSize: 20, ), - body: Column( - children: [ - Container( - height: 80, - color: Theme.of(context).colorScheme.surface, - padding: - const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), - child: SearchField( - title: "بازار سرمایه", - value: state.lastSearch, - onChanged: _onChanged, - focusNode: _focusNode, - ), - ), - SizedBox( - height: MediaQuery.of(context).size.height / 24, + ), + body: Column( + children: [ + Container( + height: 80, + color: Theme.of(context).colorScheme.surface, + padding: + const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + child: SearchField( + title: "بازار سرمایه", + value: context.watch().lastSearch, + onChanged: _onChanged, + focusNode: _focusNode, ), + ), + SizedBox( + height: MediaQuery.of(context).size.height / 24, + ), - // Here, default theme colors are used for activeBgColor, activeFgColor, inactiveBgColor and inactiveFgColor - ToggleSwitch( - borderWidth: 1, - activeBgColor: [Theme.of(context).colorScheme.surface], - radiusStyle: true, - borderColor: [Colors.grey.shade600], - centerText: true, - activeFgColor: Theme.of(context).colorScheme.title, - inactiveBgColor: Theme.of(context).colorScheme.secondCTA, - inactiveFgColor: Theme.of(context).colorScheme.disabledText, - dividerColor: Colors.grey.shade500, - initialLabelIndex: value, - customTextStyles: const [TextStyle(fontWeight: FontWeight.w500)], - minWidth: 90, - totalSwitches: 4, - labels: const ['بورس', 'فرابورس', 'شاخص کل', 'گروه فولاد'], - onToggle: (index) { - setState(() { - value = index!; - state.type = index + 1; - state.getStock(page: 1); - }); - }, + // Here, default theme colors are used for activeBgColor, activeFgColor, inactiveBgColor and inactiveFgColor + ToggleSwitch( + borderWidth: 1, + activeBgColor: [Theme.of(context).colorScheme.surface], + radiusStyle: true, + borderColor: [Colors.grey.shade600], + centerText: true, + activeFgColor: Theme.of(context).colorScheme.title, + inactiveBgColor: Theme.of(context).colorScheme.secondCTA, + inactiveFgColor: Theme.of(context).colorScheme.disabledText, + dividerColor: Colors.grey.shade500, + initialLabelIndex: value, + customTextStyles: const [TextStyle(fontWeight: FontWeight.w500)], + minWidth: 90, + totalSwitches: 4, + labels: const ['بورس', 'فرابورس', 'شاخص کل', 'گروه فولاد'], + onToggle: (index) { + setState(() { + value = index!; + context.read().type = index + 1; + context.read().getStock(page: 1); + }); + }, + ), + SizedBox( + height: MediaQuery.of(context).size.height / 48, + ), + StateHandler( + onRetry: context.read().init, + state: context.watch(), + emptyState: EmptyResult( + onNewSearch: () => _focusNode.requestFocus(), ), - SizedBox( - height: MediaQuery.of(context).size.height / 48, + enableEmptyState: context.watch().contents.isEmpty, + placeholder: Column( + children: [ + placeholder2, + placeholder2, + ], ), - Expanded( + builder: (context, state) => Expanded( child: ListView.builder( controller: _scrollController, - //physics: const ClampingScrollPhysics(), itemCount: state.length, itemBuilder: (context, index) { if (state.type == 1) { @@ -172,73 +183,94 @@ class _NewStockState extends State { totalContent: state.totalContent_type3[index]); }), ), - ], - ), + ), + ], ), ); } - static Widget get placeholder => const DidvanCard( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - ShimmerPlaceholder( - height: 40, - width: 40, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - ShimmerPlaceholder( - height: 40, - width: 40, - ), - ShimmerPlaceholder( - height: 40, - width: 40, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - ShimmerPlaceholder( - height: 40, - width: 40, - ), - ShimmerPlaceholder( - height: 40, - width: 40, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - ShimmerPlaceholder( - height: 40, - width: 40, - ), - ShimmerPlaceholder( - height: 40, - width: 40, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - ShimmerPlaceholder( - height: 40, - width: 40, - ), - ShimmerPlaceholder( - height: 40, - width: 40, - ), - ], - ) - ], - )); + static Widget get placeholder2 => const DidvanCard( + child: Column( + children: [ + ShimmerPlaceholder(height: 18, width: 400), + DidvanDivider( + verticalPadding: 8, + ), + SizedBox( + height: 12, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ShimmerPlaceholder( + width: 100, + height: 18, + ), + SizedBox( + height: 12, + ), + ShimmerPlaceholder( + width: 100, + height: 18, + ) + ], + ), + SizedBox( + height: 12, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ShimmerPlaceholder( + width: 100, + height: 18, + ), + SizedBox( + height: 12, + ), + ShimmerPlaceholder( + width: 100, + height: 18, + ) + ], + ), + SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ShimmerPlaceholder( + width: 100, + height: 18, + ), + SizedBox( + height: 12, + ), + ShimmerPlaceholder( + width: 100, + height: 18, + ) + ], + ), + SizedBox( + height: 12, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ShimmerPlaceholder( + width: 100, + height: 18, + ), + SizedBox( + height: 12, + ), + ShimmerPlaceholder( + width: 100, + height: 18, + ) + ], + ), + ], + ), + ); } diff --git a/lib/views/home/new_statistic/widgets/general_stat_card.dart b/lib/views/home/new_statistic/widgets/general_stat_card.dart index 6adfff7..5bc3349 100644 --- a/lib/views/home/new_statistic/widgets/general_stat_card.dart +++ b/lib/views/home/new_statistic/widgets/general_stat_card.dart @@ -59,7 +59,8 @@ class _NewStatisticOverviewCardState extends State { 'title': widget.statistic.title, 'marked': widget.statistic.marked, }).then( - (value) => state.getGeneralStatContent(page: 1), + (value) => + state.getGeneralStatContent(page: 1, id: state.cat), ); } }, @@ -91,6 +92,11 @@ class _NewStatisticOverviewCardState extends State { style: Theme.of(context).textTheme.bodyLarge, ), const Spacer(), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ if (_hasDiff) DidvanText( '(${widget.statistic.data.d})', diff --git a/lib/views/home/new_statistic/widgets/statistic_cat.dart b/lib/views/home/new_statistic/widgets/statistic_cat.dart index 8b098cb..f812a74 100644 --- a/lib/views/home/new_statistic/widgets/statistic_cat.dart +++ b/lib/views/home/new_statistic/widgets/statistic_cat.dart @@ -17,9 +17,14 @@ class StatMenuItemType { {required this.label, required this.asset, required this.id}); } -class NewStatisticCategories extends StatelessWidget { +class NewStatisticCategories extends StatefulWidget { const NewStatisticCategories({super.key}); + @override + State createState() => _NewStatisticCategoriesState(); +} + +class _NewStatisticCategoriesState extends State { void _onTap(int id, String title, BuildContext context, BuildContext ctx) { if (id != 6) { Navigator.of(context) @@ -31,45 +36,42 @@ class NewStatisticCategories extends StatelessWidget { @override Widget build(BuildContext context) { - return StateHandler( - onRetry: () {}, - state: context.watch(), - builder: (context, state) => Wrap( - alignment: WrapAlignment.center, - children: state.statCat - .map( - (e) => GestureDetector( - onTap: () => _onTap(e.id, e.label, context, context), - child: SizedBox( - width: (MediaQuery.of(context).size.width - 56) / 3, - child: Column( - children: [ - Container( - width: 56, - height: 56, - padding: const EdgeInsets.all(8), - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surface, - borderRadius: DesignConfig.lowBorderRadius, - boxShadow: DesignConfig.defaultShadow, - ), - child: SvgPicture.asset(e.asset), + final state = context.read(); + return Wrap( + alignment: WrapAlignment.center, + children: state.statCat + .map( + (e) => GestureDetector( + onTap: () => _onTap(e.id, e.label, context, context), + child: SizedBox( + width: (MediaQuery.of(context).size.width - 56) / 3, + child: Column( + children: [ + Container( + width: 56, + height: 56, + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: DesignConfig.lowBorderRadius, + boxShadow: DesignConfig.defaultShadow, ), - const SizedBox(height: 4), - DidvanText( - e.label, - color: Theme.of(context).colorScheme.title, - style: Theme.of(context).textTheme.labelSmall, - fontWeight: FontWeight.w600, - ), - const SizedBox(height: 12), - ], - ), + child: SvgPicture.asset(e.asset), + ), + const SizedBox(height: 4), + DidvanText( + e.label, + color: Theme.of(context).colorScheme.title, + style: Theme.of(context).textTheme.labelSmall, + fontWeight: FontWeight.w600, + ), + const SizedBox(height: 12), + ], ), ), - ) - .toList(), - ), + ), + ) + .toList(), ); } }