Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
885d680
fix(app_configuration): update SwitchListTile title text for role vis…
fulleni Sep 26, 2025
b756060
style(content_management): reduce spacing and margin sizes
fulleni Sep 26, 2025
8974a29
feat(l10n): add Arabic translations for admob_flutter plugin
fulleni Sep 26, 2025
9468749
refactor(local_ads_management): update events and add deletion handling
fulleni Sep 26, 2025
3bfbd09
refactor(local_ads_management): replace lastDeletedLocalAd with snack…
fulleni Sep 26, 2025
2756a0b
refactor(local_ads_management): improve ad deletion and filtering
fulleni Sep 26, 2025
d318aaf
feat(local_ads_management): implement filter local ads bloc
fulleni Sep 26, 2025
2420824
feat(local_ads_management): implement filter local ads events
fulleni Sep 26, 2025
c372e4f
feat(local_ads_management): add FilterLocalAdsState for filter dialog
fulleni Sep 26, 2025
9bde6d2
feat(local_ads_management): add banner ads management page
fulleni Sep 26, 2025
c2af400
feat(local_ads_management): add interstitial ads management page
fulleni Sep 26, 2025
3479fbf
refactor(local_ads_management): migrate to separate ad type pages
fulleni Sep 26, 2025
712f5f9
feat(local_ads_management): implement Native Ads management page
fulleni Sep 26, 2025
01f5701
feat(local_ads_management): add video ads management page
fulleni Sep 26, 2025
272b961
feat(local_ads_management): add local ads filter dialog
fulleni Sep 26, 2025
1aaa841
feat(local_ads_management): implement LocalAdsFilterDialogBloc
fulleni Sep 26, 2025
e9b95dc
feat(local_ads_management): add LocalAdsFilterDialogBloc events
fulleni Sep 26, 2025
8a5e174
feat(local_ads_management): add filter dialog state
fulleni Sep 26, 2025
01fc522
feat(local_ads_management): add FilterLocalAdsBloc to app providers
fulleni Sep 26, 2025
0ce6b2a
feat(router): add local ads filter dialog route
fulleni Sep 26, 2025
e02a15e
chore: delete absolete files
fulleni Sep 26, 2025
b029f23
feat(local_ads_management): auto-refresh local ads list after archive…
fulleni Sep 26, 2025
5fd5866
refactor(local_ads_management): replace action buttons with widget
fulleni Sep 26, 2025
b907ca1
refactor(local_ads_management): extract ad action buttons to widget
fulleni Sep 26, 2025
49c4011
refactor(local_ads_management): improve native ads page functionality
fulleni Sep 26, 2025
08584d4
refactor(local_ads_management): implement LocalAdActionButtons widget
fulleni Sep 26, 2025
aaeac03
feat(local_ads_management): add LocalAdActionButtons widget
fulleni Sep 26, 2025
bce458e
refactor(local_ads_management): remove unused constructor parameter
fulleni Sep 26, 2025
52c98ec
refactor(router): remove explicit constructor parameters
fulleni Sep 26, 2025
2f78b4f
feat(local_ads): implement LocalAdsManagementBloc
fulleni Sep 26, 2025
0a5e3f1
style: format
fulleni Sep 26, 2025
4beb770
feat(localization): add translations for ad ID copy feature
fulleni Sep 26, 2025
fee9a35
style: format
fulleni Sep 26, 2025
547f440
feat(local_ads_management): add adType filter to LoadLocalAdsRequeste…
fulleni Sep 26, 2025
cb0b0f0
refactor(local_ads_management): improve ad filtering and loading
fulleni Sep 26, 2025
9c6edef
refactor(local_ads_management): remove unused ad type filter function…
fulleni Sep 26, 2025
dcf9263
refactor(local_ads_management): remove ad type filter
fulleni Sep 26, 2025
f2f119b
refactor(local_ads_management): remove unused ad type filter
fulleni Sep 26, 2025
19d4a3e
refactor(local_ads_management): update banner ads page filtering logic
fulleni Sep 26, 2025
208c929
refactor(local_ads_management): improve interstitial ads filtering
fulleni Sep 26, 2025
eafcbcd
feat(local_ads_management): replace add icon button with floating act…
fulleni Sep 26, 2025
1cf570f
refactor(local_ads_management): improve native ads filtering
fulleni Sep 26, 2025
eb40586
refactor(local_ads_management): update video ads page filtering logic
fulleni Sep 26, 2025
815af40
feat(local_ads_management): add copy ID option for active ads
fulleni Sep 26, 2025
90779ac
refactor(local_ads_management): remove ad type filter from local ads …
fulleni Sep 26, 2025
f4209f8
refactor(local_ads_management): remove unused ad type filter
fulleni Sep 26, 2025
b11ff6e
feat(local_ads_management): add events for saving and publishing inte…
fulleni Sep 26, 2025
0c4f1a8
feat(local_ads_management): add contentStatus to CreateLocalInterstit…
fulleni Sep 26, 2025
dc7c5ca
feat(local_ads_management): add handlers for saving and publishing lo…
fulleni Sep 26, 2025
c846e7e
feat(local_ads_management): add events for saving draft and publishin…
fulleni Sep 26, 2025
da20e18
feat(local_ads_management): add content status to CreateLocalVideoAdS…
fulleni Sep 26, 2025
3abdd73
feat(local_ads_management): add handlers for saving and publishing lo…
fulleni Sep 26, 2025
042dd12
feat(local_ads_management): add events for saving and publishing loca…
fulleni Sep 26, 2025
3439f4d
feat(local_ads_management): add contentStatus to CreateLocalBannerAdS…
fulleni Sep 26, 2025
5a7e615
feat(local_ads_management): implement save as draft and publish funct…
fulleni Sep 26, 2025
fd9d6fd
feat(local_ads_management): add events for saving draft and publishin…
fulleni Sep 26, 2025
d23ac50
feat(local_ads_management): add content status to native ad creation …
fulleni Sep 26, 2025
e02d66b
feat(local_ads_management): implement save as draft and publish funct…
fulleni Sep 26, 2025
49533c2
feat(local_ads_management): add save options dialog for local banner ads
fulleni Sep 26, 2025
ac2f878
feat(local_ads_management): add option to save interstitial ad as dra…
fulleni Sep 26, 2025
d99dbcd
feat(local_ads_management): add option to save local native ads as draft
fulleni Sep 26, 2025
d550bef
feat(local_ads_management): add option to save local video ad as draft
fulleni Sep 26, 2025
859e335
feat(localization): add Arabic translations for save ad dialog
fulleni Sep 26, 2025
acb23c7
fix(local_ads_management): update action button functionality
fulleni Sep 26, 2025
d4bb1b4
feat(local_ads_management): add about icon with tooltip and description
fulleni Sep 26, 2025
bc4e7e2
fix(app): update icon and text color in navigation rail
fulleni Sep 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/app/view/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import 'package:flutter_news_app_web_dashboard_full_source_code/content_manageme
import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/sources_filter/sources_filter_bloc.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/topics_filter/topics_filter_bloc.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/local_ads_management/bloc/filter_local_ads/filter_local_ads_bloc.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/local_ads_management/bloc/local_ads_management_bloc.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/overview/bloc/overview_bloc.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/router/router.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/shared/services/pending_deletions_service.dart';
Expand Down Expand Up @@ -131,6 +133,9 @@ class App extends StatelessWidget {
BlocProvider(
create: (context) => SourcesFilterBloc(),
),
BlocProvider(
create: (context) => FilterLocalAdsBloc(),
),
BlocProvider(
create: (context) => ContentManagementBloc(
headlinesRepository: context.read<DataRepository<Headline>>(),
Expand All @@ -142,6 +147,13 @@ class App extends StatelessWidget {
pendingDeletionsService: context.read<PendingDeletionsService>(),
),
),
BlocProvider(
create: (context) => LocalAdsManagementBloc(
localAdsRepository: context.read<DataRepository<LocalAd>>(),
filterLocalAdsBloc: context.read<FilterLocalAdsBloc>(),
pendingDeletionsService: context.read<PendingDeletionsService>(),
),
),
BlocProvider(
create: (context) => OverviewBloc(
dashboardSummaryRepository: context
Expand Down
18 changes: 11 additions & 7 deletions lib/app/view/app_shell.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,25 @@ class AppShell extends StatelessWidget {
label: l10n.appConfiguration,
),
],
leadingUnextendedNavRail: const Padding(
padding: EdgeInsets.symmetric(vertical: AppSpacing.lg),
child: Icon(Icons.newspaper_outlined),
leadingUnextendedNavRail: Padding(
padding: const EdgeInsets.symmetric(vertical: AppSpacing.lg),
child: Icon(
Icons.newspaper_outlined,
color: theme.colorScheme.primary,
),
),
leadingExtendedNavRail: Padding(
padding: const EdgeInsets.all(AppSpacing.lg),
child: Row(
children: [
const Icon(Icons.newspaper_outlined),
Icon(
Icons.newspaper_outlined,
color: theme.colorScheme.primary,
),
const SizedBox(width: AppSpacing.md),
Text(
l10n.dashboardTitle,
style: theme.textTheme.titleLarge?.copyWith(
color: theme.colorScheme.primary,
),
style: theme.textTheme.titleLarge,
),
],
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class _ArticleAdSettingsFormState extends State<ArticleAdSettingsForm>
return Column(
children: [
SwitchListTile(
title: Text(l10n.enableInArticleAdsForRoleLabel(role.l10n(context))),
title: Text(l10n.visibleToRoleLabel(role.l10n(context))),
value: roleSlots != null,
onChanged: (value) {
final newVisibleTo =
Expand Down
1 change: 0 additions & 1 deletion lib/app_configuration/widgets/feed_decorator_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ class _FeedDecoratorFormState extends State<FeedDecoratorForm>
controller: _itemsToDisplayController,
),
const SizedBox(height: AppSpacing.lg),
// Replaced SegmentedButton with TabBar for role selection
Align(
alignment: AlignmentDirectional.centerStart,
child: SizedBox(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ class _UserPreferenceLimitsFormState extends State<UserPreferenceLimitsForm>
),
),
const SizedBox(height: AppSpacing.lg),
// Replaced SegmentedButton with TabBar for role selection
Align(
alignment: AlignmentDirectional.centerStart,
child: SizedBox(
Expand Down
2 changes: 1 addition & 1 deletion lib/content_management/view/headlines_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class _HeadlinesPageState extends State<HeadlinesPage> {
headingRowHeight: 56,
dataRowHeight: 56,
columnSpacing: AppSpacing.sm,
horizontalMargin: AppSpacing.md,
horizontalMargin: AppSpacing.sm,
);
},
),
Expand Down
26 changes: 14 additions & 12 deletions lib/content_management/view/sources_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,11 @@ class _SourcesPageState extends State<SourcesPage> {
label: Text(l10n.sourceName),
size: ColumnSize.L,
),
DataColumn2(
label: Text(l10n.sourceType),
size: ColumnSize.S,
),
if (!isMobile)
DataColumn2(
label: Text(l10n.sourceType),
size: ColumnSize.S,
),
DataColumn2(
label: Text(l10n.lastUpdated),
size: ColumnSize.S,
Expand Down Expand Up @@ -173,8 +174,8 @@ class _SourcesPageState extends State<SourcesPage> {
fit: FlexFit.tight,
headingRowHeight: 56,
dataRowHeight: 56,
columnSpacing: AppSpacing.md,
horizontalMargin: AppSpacing.md,
columnSpacing: AppSpacing.sm,
horizontalMargin: AppSpacing.sm,
);
},
),
Expand Down Expand Up @@ -225,13 +226,14 @@ class _SourcesDataSource extends DataTableSource {
overflow: TextOverflow.ellipsis,
),
),
DataCell(
Text(
source.sourceType.localizedName(l10n),
maxLines: 2,
overflow: TextOverflow.ellipsis,
if (!isMobile)
DataCell(
Text(
source.sourceType.localizedName(l10n),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
),
DataCell(
Text(
DateFormat('dd-MM-yyyy').format(source.updatedAt.toLocal()),
Expand Down
4 changes: 2 additions & 2 deletions lib/content_management/view/topics_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ class _TopicPageState extends State<TopicPage> {
fit: FlexFit.tight,
headingRowHeight: 56,
dataRowHeight: 56,
columnSpacing: AppSpacing.md,
horizontalMargin: AppSpacing.md,
columnSpacing: AppSpacing.sm,
horizontalMargin: AppSpacing.sm,
);
},
),
Expand Down
102 changes: 102 additions & 0 deletions lib/l10n/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2725,6 +2725,108 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Close'**
String get closeButtonText;

/// Title for the filter dialog when filtering local ads.
///
/// In en, this message translates to:
/// **'Filter Local Ads'**
String get filterLocalAds;

/// Hint text for the ad title or URL search field.
///
/// In en, this message translates to:
/// **'Search by ad title or URL...'**
String get searchByAdTitleOrUrl;

/// Label for the ad type filter.
///
/// In en, this message translates to:
/// **'Ad Type'**
String get adType;

/// Headline for loading state of native ads.
///
/// In en, this message translates to:
/// **'Loading Native Ads'**
String get loadingNativeAds;

/// Message when no native ads are found.
///
/// In en, this message translates to:
/// **'No native ads found.'**
String get noNativeAdsFound;

/// Headline for loading state of banner ads.
///
/// In en, this message translates to:
/// **'Loading Banner Ads'**
String get loadingBannerAds;

/// Message when no banner ads are found.
///
/// In en, this message translates to:
/// **'No banner ads found.'**
String get noBannerAdsFound;

/// Column header for ad image URL.
///
/// In en, this message translates to:
/// **'Image URL'**
String get adImageUrl;

/// Headline for loading state of interstitial ads.
///
/// In en, this message translates to:
/// **'Loading Interstitial Ads'**
String get loadingInterstitialAds;

/// Message when no interstitial ads are found.
///
/// In en, this message translates to:
/// **'No interstitial ads found.'**
String get noInterstitialAdsFound;

/// Headline for loading state of video ads.
///
/// In en, this message translates to:
/// **'Loading Video Ads'**
String get loadingVideoAds;

/// Message when no video ads are found.
///
/// In en, this message translates to:
/// **'No video ads found.'**
String get noVideoAdsFound;

/// Column header for ad video URL.
///
/// In en, this message translates to:
/// **'Video URL'**
String get adVideoUrl;

/// Snackbar message displayed when an ad ID is successfully copied to the clipboard.
///
/// In en, this message translates to:
/// **'ID copied to clipboard'**
String get idCopied;

/// Tooltip for the copy ID action button.
///
/// In en, this message translates to:
/// **'Copy Ad ID'**
String get copyIdTooltip;

/// Title for the dialog asking to save an ad
///
/// In en, this message translates to:
/// **'Save Ad'**
String get saveAdTitle;

/// Message for the dialog asking to save an ad
///
/// In en, this message translates to:
/// **'Do you want to publish this ad or save it as a draft?'**
String get saveAdMessage;
}

class _AppLocalizationsDelegate
Expand Down
51 changes: 51 additions & 0 deletions lib/l10n/app_localizations_ar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1454,4 +1454,55 @@ class AppLocalizationsAr extends AppLocalizations {

@override
String get closeButtonText => 'إغلاق';

@override
String get filterLocalAds => 'تصفية الإعلانات المحلية';

@override
String get searchByAdTitleOrUrl => 'البحث بعنوان الإعلان أو الرابط...';

@override
String get adType => 'نوع الإعلان';

@override
String get loadingNativeAds => 'جاري تحميل الإعلانات الأصلية';

@override
String get noNativeAdsFound => 'لم يتم العثور على إعلانات أصلية.';

@override
String get loadingBannerAds => 'جاري تحميل إعلانات البانر';

@override
String get noBannerAdsFound => 'لم يتم العثور على إعلانات بانر.';

@override
String get adImageUrl => 'رابط الصورة';

@override
String get loadingInterstitialAds => 'جاري تحميل الإعلانات البينية';

@override
String get noInterstitialAdsFound => 'لم يتم العثور على إعلانات بينية.';

@override
String get loadingVideoAds => 'جاري تحميل إعلانات الفيديو';

@override
String get noVideoAdsFound => 'لم يتم العثور على إعلانات فيديو.';

@override
String get adVideoUrl => 'رابط الفيديو';

@override
String get idCopied => 'تم نسخ المعرف إلى الحافظة';

@override
String get copyIdTooltip => 'نسخ معرف الإعلان';

@override
String get saveAdTitle => 'حفظ الإعلان';

@override
String get saveAdMessage => 'هل تريد نشر هذا الإعلان أم حفظه كمسودة؟';
}
52 changes: 52 additions & 0 deletions lib/l10n/app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1459,4 +1459,56 @@ class AppLocalizationsEn extends AppLocalizations {

@override
String get closeButtonText => 'Close';

@override
String get filterLocalAds => 'Filter Local Ads';

@override
String get searchByAdTitleOrUrl => 'Search by ad title or URL...';

@override
String get adType => 'Ad Type';

@override
String get loadingNativeAds => 'Loading Native Ads';

@override
String get noNativeAdsFound => 'No native ads found.';

@override
String get loadingBannerAds => 'Loading Banner Ads';

@override
String get noBannerAdsFound => 'No banner ads found.';

@override
String get adImageUrl => 'Image URL';

@override
String get loadingInterstitialAds => 'Loading Interstitial Ads';

@override
String get noInterstitialAdsFound => 'No interstitial ads found.';

@override
String get loadingVideoAds => 'Loading Video Ads';

@override
String get noVideoAdsFound => 'No video ads found.';

@override
String get adVideoUrl => 'Video URL';

@override
String get idCopied => 'ID copied to clipboard';

@override
String get copyIdTooltip => 'Copy Ad ID';

@override
String get saveAdTitle => 'Save Ad';

@override
String get saveAdMessage =>
'Do you want to publish this ad or save it as a draft?';
}
Loading
Loading