Skip to content

Commit ecd31b7

Browse files
committed
포스트 목록 페이지에 카테고리 필터링을 위한 확장 패널 추가
1 parent 6d1bd6a commit ecd31b7

File tree

2 files changed

+157
-30
lines changed

2 files changed

+157
-30
lines changed

lib/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class CustomAppBarScreenTest extends StatefulWidget {
4545
}
4646

4747
class _CustomAppBarScreenState extends State<CustomAppBarScreenTest> {
48-
int _selectedIndex = 1;
48+
int _selectedIndex = 0;
4949
String _seletedMenu = "Posts";
5050

5151
static final List<Widget> _widgetOptions = <Widget>[

lib/pages/post_list_page.dart

Lines changed: 156 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,31 @@ import 'dart:js_interop';
77
import 'package:markdown_widget/markdown_widget.dart';
88
import 'package:sando_diary/model/post_meta.dart';
99

10+
class Item {
11+
Item({
12+
required this.headerValue,
13+
this.expandedValues = const [],
14+
this.isExpanded = false,
15+
});
16+
17+
String headerValue;
18+
List<String> expandedValues;
19+
bool isExpanded;
20+
21+
bool get hasExpandedValues => expandedValues.isNotEmpty;
22+
}
23+
24+
List<Item> generateItems(List<String> categories) {
25+
categories.insert(0, 'All');
26+
return [
27+
Item(
28+
headerValue: 'Post Categories',
29+
expandedValues: categories,
30+
isExpanded: false,
31+
)
32+
];
33+
}
34+
1035
class PostListPage extends StatefulWidget {
1136
const PostListPage({super.key});
1237
@override
@@ -19,11 +44,22 @@ class _PostListPageState extends State<PostListPage> {
1944
bool isShowPostDetail = false;
2045
late MdDoc currentPost;
2146

47+
List<Item> _data = [];
48+
List<String> categories = [];
49+
2250
@override
2351
void initState() {
2452
super.initState();
2553
future = loadMarkdownDocs(context);
2654
df = DateFormat('yyyy-MM-dd'); // 한국어 로케일이면 intl 초기화 추가 가능
55+
56+
future.then((docs) {
57+
final cats = docs.map((d) => d.meta.category).toSet().toList();
58+
setState(() {
59+
categories = cats;
60+
_data = generateItems(categories);
61+
});
62+
});
2763
}
2864

2965
void _launchURLInNewTab(String url) {
@@ -73,33 +109,44 @@ class _PostListPageState extends State<PostListPage> {
73109

74110
@override
75111
Widget build(BuildContext context) {
76-
return Scaffold(
77-
appBar: !isShowPostDetail
78-
? AppBar(
79-
title: const Text('Blog Posts'),
80-
)
81-
: AppBar(
82-
elevation: 0,
83-
scrolledUnderElevation: 0,
84-
shadowColor: Colors.transparent,
85-
surfaceTintColor: Colors.transparent,
86-
forceMaterialTransparency: true,
87-
title: Text(currentPost.meta.title),
88-
leading: BackButton(
89-
onPressed: () => setState(() {
90-
isShowPostDetail = false;
91-
web.window.history.pushState(null, 'Posts', '/');
92-
}),
93-
),
94-
actions: [
95-
IconButton(
96-
icon: const Icon(Icons.share),
97-
tooltip: 'Share this Post',
98-
onPressed: _copyCurrentPostUrlToClipboard,
99-
),
100-
],
101-
),
102-
body: !isShowPostDetail
112+
Widget _buildPanel() {
113+
return ExpansionPanelList(
114+
expansionCallback: (int index, bool isExpanded) {
115+
setState(() {
116+
_data[index].isExpanded = isExpanded;
117+
});
118+
},
119+
children: _data.map<ExpansionPanel>((Item item) {
120+
return ExpansionPanel(
121+
canTapOnHeader: true,
122+
headerBuilder: (BuildContext context, bool isExpanded) {
123+
return ListTile(title: Text(item.headerValue));
124+
},
125+
body: item.hasExpandedValues
126+
? Column(
127+
children: item.expandedValues.map((value) {
128+
return ListTile(
129+
title: Text(value),
130+
onTap: () {
131+
// TODO: Implement category filtering
132+
print('Tapped on $value');
133+
},
134+
trailing: const Icon(Icons.chevron_right),
135+
);
136+
}).toList(),
137+
)
138+
: const SizedBox.shrink(),
139+
isExpanded: item.isExpanded,
140+
);
141+
}).toList(),
142+
);
143+
}
144+
145+
Widget _buildPostList(String? category) {
146+
// all 카테고리면 전체, 아니면 해당 카테고리만 필터링
147+
// til 카테고리는 따로 구현?
148+
149+
return !isShowPostDetail
103150
? FutureBuilder<List<MdDoc>>(
104151
future: future,
105152
builder: (context, snap) {
@@ -137,7 +184,87 @@ class _PostListPageState extends State<PostListPage> {
137184
);
138185
},
139186
)
140-
: _postDetail(currentPost),
141-
);
187+
: _postDetail(currentPost);
188+
}
189+
190+
return Scaffold(
191+
appBar: !isShowPostDetail
192+
? AppBar(
193+
title: const Text('Blog Posts'),
194+
)
195+
: AppBar(
196+
elevation: 0,
197+
scrolledUnderElevation: 0,
198+
shadowColor: Colors.transparent,
199+
surfaceTintColor: Colors.transparent,
200+
forceMaterialTransparency: true,
201+
title: Text(currentPost.meta.title),
202+
leading: BackButton(
203+
onPressed: () => setState(() {
204+
isShowPostDetail = false;
205+
web.window.history.pushState(null, 'Posts', '/');
206+
}),
207+
),
208+
actions: [
209+
IconButton(
210+
icon: const Icon(Icons.share),
211+
tooltip: 'Share this Post',
212+
onPressed: _copyCurrentPostUrlToClipboard,
213+
),
214+
],
215+
),
216+
body: LayoutBuilder(
217+
builder: (BuildContext context, BoxConstraints constraints) {
218+
double width = constraints.maxWidth;
219+
if (width > 600) {
220+
return Row(
221+
children: [
222+
SizedBox(
223+
width: width * 0.3,
224+
child: Column(
225+
children: [
226+
_buildPanel(),
227+
ListTile(
228+
title: const Text('TIL (Today I Learned)'),
229+
onTap: () {
230+
// TODO: Implement TIL navigation
231+
},
232+
),
233+
],
234+
),
235+
),
236+
VerticalDivider(color: Colors.grey[400], width: 3),
237+
Expanded(child: _buildPostList('All')),
238+
],
239+
);
240+
} else {
241+
return Column(
242+
children: [
243+
Visibility(
244+
visible: !isShowPostDetail,
245+
child: Column(
246+
children: [
247+
_buildPanel(),
248+
ListTile(
249+
title: const Text('TIL (Today I Learned)'),
250+
onTap: () {
251+
// TODO: Implement TIL navigation
252+
},
253+
),
254+
],
255+
),
256+
),
257+
Divider(color: Colors.grey[400], height: 3),
258+
SizedBox(height: 16),
259+
Text('Recent Posts',
260+
style: TextStyle(
261+
fontWeight: FontWeight.bold,
262+
fontSize: 20,
263+
color: Colors.grey[700])),
264+
Expanded(child: _buildPostList('All')),
265+
],
266+
);
267+
}
268+
}));
142269
}
143270
}

0 commit comments

Comments
 (0)