Skip to content

Commit da59c9c

Browse files
committed
chore: misc
1 parent 7f0eb5f commit da59c9c

File tree

2 files changed

+186
-1
lines changed

2 files changed

+186
-1
lines changed

lib/content_management/view/archived_headlines_page.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
66
import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/archived_headlines/archived_headlines_bloc.dart';
77
import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart';
88
import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart';
9-
import 'package:flutter_news_app_web_dashboard_full_source_code/shared/shared.dart';
109
import 'package:intl/intl.dart';
1110
import 'package:ui_kit/ui_kit.dart';
1211

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import 'package:core/core.dart';
2+
import 'package:data_repository/data_repository.dart';
3+
import 'package:data_table_2/data_table_2.dart';
4+
import 'package:flutter/material.dart';
5+
import 'package:flutter_bloc/flutter_bloc.dart';
6+
import 'package:flutter_news_app_web_dashboard_full_source_code/content_management/bloc/archived_sources/archived_sources_bloc.dart';
7+
import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/app_localizations.dart';
8+
import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart';
9+
import 'package:intl/intl.dart';
10+
import 'package:ui_kit/ui_kit.dart';
11+
12+
class ArchivedSourcesPage extends StatelessWidget {
13+
const ArchivedSourcesPage({super.key});
14+
15+
@override
16+
Widget build(BuildContext context) {
17+
return BlocProvider(
18+
create: (context) => ArchivedSourcesBloc(
19+
sourcesRepository: context.read<DataRepository<Source>>(),
20+
)..add(const LoadArchivedSourcesRequested(limit: kDefaultRowsPerPage)),
21+
child: const _ArchivedSourcesView(),
22+
);
23+
}
24+
}
25+
26+
class _ArchivedSourcesView extends StatelessWidget {
27+
const _ArchivedSourcesView();
28+
29+
@override
30+
Widget build(BuildContext context) {
31+
final l10n = AppLocalizationsX(context).l10n;
32+
return Scaffold(
33+
appBar: AppBar(
34+
title: Text('Archived Sources'), // TODO(you): Will be fixed in l10n phase.
35+
),
36+
body: Padding(
37+
padding: const EdgeInsets.all(AppSpacing.lg),
38+
child: BlocBuilder<ArchivedSourcesBloc, ArchivedSourcesState>(
39+
builder: (context, state) {
40+
if (state.status == ArchivedSourcesStatus.loading &&
41+
state.sources.isEmpty) {
42+
return LoadingStateWidget(
43+
icon: Icons.source,
44+
headline: 'Loading Archived Sources', // TODO(you): Will be fixed in l10n phase.
45+
subheadline: l10n.pleaseWait,
46+
);
47+
}
48+
49+
if (state.status == ArchivedSourcesStatus.failure) {
50+
return FailureStateWidget(
51+
exception: state.exception!,
52+
onRetry: () => context.read<ArchivedSourcesBloc>().add(
53+
const LoadArchivedSourcesRequested(
54+
limit: kDefaultRowsPerPage,
55+
),
56+
),
57+
);
58+
}
59+
60+
if (state.sources.isEmpty) {
61+
return Center(child: Text('No archived sources found.')); // TODO(you): Will be fixed in l10n phase.
62+
}
63+
64+
return Column(
65+
children: [
66+
if (state.status == ArchivedSourcesStatus.loading &&
67+
state.sources.isNotEmpty)
68+
const LinearProgressIndicator(),
69+
Expanded(
70+
child: PaginatedDataTable2(
71+
columns: [
72+
DataColumn2(
73+
label: Text(l10n.sourceName),
74+
size: ColumnSize.L,
75+
),
76+
DataColumn2(
77+
label: Text(l10n.lastUpdated),
78+
size: ColumnSize.M,
79+
),
80+
DataColumn2(
81+
label: Text(l10n.actions),
82+
size: ColumnSize.S,
83+
fixedWidth: 120,
84+
),
85+
],
86+
source: _SourcesDataSource(
87+
context: context,
88+
sources: state.sources,
89+
hasMore: state.hasMore,
90+
l10n: l10n,
91+
),
92+
rowsPerPage: kDefaultRowsPerPage,
93+
availableRowsPerPage: const [kDefaultRowsPerPage],
94+
onPageChanged: (pageIndex) {
95+
final newOffset = pageIndex * kDefaultRowsPerPage;
96+
if (newOffset >= state.sources.length &&
97+
state.hasMore &&
98+
state.status != ArchivedSourcesStatus.loading) {
99+
context.read<ArchivedSourcesBloc>().add(
100+
LoadArchivedSourcesRequested(
101+
startAfterId: state.cursor,
102+
limit: kDefaultRowsPerPage,
103+
),
104+
);
105+
}
106+
},
107+
empty: Center(child: Text(l10n.noSourcesFound)),
108+
showCheckboxColumn: false,
109+
showFirstLastButtons: true,
110+
fit: FlexFit.tight,
111+
headingRowHeight: 56,
112+
dataRowHeight: 56,
113+
columnSpacing: AppSpacing.md,
114+
horizontalMargin: AppSpacing.md,
115+
),
116+
),
117+
],
118+
);
119+
},
120+
),
121+
),
122+
);
123+
}
124+
}
125+
126+
class _SourcesDataSource extends DataTableSource {
127+
_SourcesDataSource({
128+
required this.context,
129+
required this.sources,
130+
required this.hasMore,
131+
required this.l10n,
132+
});
133+
134+
final BuildContext context;
135+
final List<Source> sources;
136+
final bool hasMore;
137+
final AppLocalizations l10n;
138+
139+
@override
140+
DataRow? getRow(int index) {
141+
if (index >= sources.length) {
142+
return null;
143+
}
144+
final source = sources[index];
145+
return DataRow2(
146+
cells: [
147+
DataCell(
148+
Text(
149+
source.name,
150+
maxLines: 2,
151+
overflow: TextOverflow.ellipsis,
152+
),
153+
),
154+
DataCell(
155+
Text(
156+
DateFormat('dd-MM-yyyy').format(source.updatedAt.toLocal()),
157+
),
158+
),
159+
DataCell(
160+
Row(
161+
children: [
162+
IconButton(
163+
icon: const Icon(Icons.restore),
164+
tooltip: l10n.restore,
165+
onPressed: () {
166+
context.read<ArchivedSourcesBloc>().add(
167+
RestoreSourceRequested(source.id),
168+
);
169+
},
170+
),
171+
],
172+
),
173+
),
174+
],
175+
);
176+
}
177+
178+
@override
179+
bool get isRowCountApproximate => hasMore;
180+
181+
@override
182+
int get rowCount => sources.length;
183+
184+
@override
185+
int get selectedRowCount => 0;
186+
}

0 commit comments

Comments
 (0)