11import 'package:core/core.dart' ;
22import 'package:flutter/material.dart' ;
3- import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/widgets/ad_config_form.dart' ;
3+ import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/widgets/ad_platform_config_form.dart' ;
4+ import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/widgets/article_ad_settings_form.dart' ;
5+ import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/widgets/feed_ad_settings_form.dart' ;
46import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart' ;
57import 'package:ui_kit/ui_kit.dart' ;
68
@@ -9,7 +11,7 @@ import 'package:ui_kit/ui_kit.dart';
911///
1012/// This tab allows configuration of various ad settings.
1113/// {@endtemplate}
12- class AdvertisementsConfigurationTab extends StatelessWidget {
14+ class AdvertisementsConfigurationTab extends StatefulWidget {
1315 /// {@macro advertisements_configuration_tab}
1416 const AdvertisementsConfigurationTab ({
1517 required this .remoteConfig,
@@ -23,25 +25,113 @@ class AdvertisementsConfigurationTab extends StatelessWidget {
2325 /// Callback to notify parent of changes to the [RemoteConfig] .
2426 final ValueChanged <RemoteConfig > onConfigChanged;
2527
28+ @override
29+ State <AdvertisementsConfigurationTab > createState () =>
30+ _AdvertisementsConfigurationTabState ();
31+ }
32+
33+ class _AdvertisementsConfigurationTabState
34+ extends State <AdvertisementsConfigurationTab > {
35+ /// Notifier for the index of the currently expanded top-level ExpansionTile.
36+ ///
37+ /// A value of `null` means no tile is expanded.
38+ final ValueNotifier <int ?> _expandedTileIndex = ValueNotifier <int ?>(null );
39+
40+ @override
41+ void dispose () {
42+ _expandedTileIndex.dispose ();
43+ super .dispose ();
44+ }
45+
2646 @override
2747 Widget build (BuildContext context) {
2848 final l10n = AppLocalizationsX (context).l10n;
2949
3050 return ListView (
3151 padding: const EdgeInsets .all (AppSpacing .lg),
3252 children: [
33- // Top-level ExpansionTile for Ad Settings
34- ExpansionTile (
35- title: Text (l10n.adSettingsTitle),
36- childrenPadding: const EdgeInsets .symmetric (
37- horizontal: AppSpacing .xxl,
38- ),
39- children: [
40- AdConfigForm (
41- remoteConfig: remoteConfig,
42- onConfigChanged: onConfigChanged,
43- ),
44- ],
53+ // Top-level ExpansionTile for Ad Platform Configuration
54+ ValueListenableBuilder <int ?>(
55+ valueListenable: _expandedTileIndex,
56+ builder: (context, expandedIndex, child) {
57+ const tileIndex = 0 ;
58+ return ExpansionTile (
59+ key: ValueKey ('adPlatformConfigTile_$expandedIndex ' ),
60+ title: Text (l10n.adPlatformConfigurationTitle),
61+ childrenPadding: const EdgeInsetsDirectional .only (
62+ start: AppSpacing .lg,
63+ top: AppSpacing .md,
64+ bottom: AppSpacing .md,
65+ ),
66+ expandedCrossAxisAlignment: CrossAxisAlignment .start,
67+ onExpansionChanged: (isExpanded) {
68+ _expandedTileIndex.value = isExpanded ? tileIndex : null ;
69+ },
70+ initiallyExpanded: expandedIndex == tileIndex,
71+ children: [
72+ AdPlatformConfigForm (
73+ remoteConfig: widget.remoteConfig,
74+ onConfigChanged: widget.onConfigChanged,
75+ ),
76+ ],
77+ );
78+ },
79+ ),
80+ const SizedBox (height: AppSpacing .lg),
81+ // Top-level ExpansionTile for Feed Ad Settings
82+ ValueListenableBuilder <int ?>(
83+ valueListenable: _expandedTileIndex,
84+ builder: (context, expandedIndex, child) {
85+ const tileIndex = 1 ;
86+ return ExpansionTile (
87+ key: ValueKey ('feedAdSettingsTile_$expandedIndex ' ),
88+ title: Text (l10n.feedAdSettingsTitle),
89+ childrenPadding: const EdgeInsetsDirectional .only (
90+ start: AppSpacing .lg,
91+ top: AppSpacing .md,
92+ bottom: AppSpacing .md,
93+ ),
94+ expandedCrossAxisAlignment: CrossAxisAlignment .start,
95+ onExpansionChanged: (isExpanded) {
96+ _expandedTileIndex.value = isExpanded ? tileIndex : null ;
97+ },
98+ initiallyExpanded: expandedIndex == tileIndex,
99+ children: [
100+ FeedAdSettingsForm (
101+ remoteConfig: widget.remoteConfig,
102+ onConfigChanged: widget.onConfigChanged,
103+ ),
104+ ],
105+ );
106+ },
107+ ),
108+ const SizedBox (height: AppSpacing .lg),
109+ // Top-level ExpansionTile for Article Ad Settings
110+ ValueListenableBuilder <int ?>(
111+ valueListenable: _expandedTileIndex,
112+ builder: (context, expandedIndex, child) {
113+ const tileIndex = 2 ;
114+ return ExpansionTile (
115+ key: ValueKey ('articleAdSettingsTile_$expandedIndex ' ),
116+ title: Text (l10n.articleAdSettingsTitle),
117+ childrenPadding: const EdgeInsetsDirectional .only (
118+ start: AppSpacing .lg,
119+ top: AppSpacing .md,
120+ bottom: AppSpacing .md,
121+ ),
122+ expandedCrossAxisAlignment: CrossAxisAlignment .start,
123+ onExpansionChanged: (isExpanded) {
124+ _expandedTileIndex.value = isExpanded ? tileIndex : null ;
125+ },
126+ initiallyExpanded: expandedIndex == tileIndex,
127+ children: [
128+ ArticleAdSettingsForm (
129+ remoteConfig: widget.remoteConfig,
130+ onConfigChanged: widget.onConfigChanged,
131+ ),
132+ ],
133+ );
134+ },
45135 ),
46136 ],
47137 );
0 commit comments