Skip to content

Commit 8f18dce

Browse files
feat(ref: no-ref): todo mvc app
feat(ref: no-ref): todo mvc app
2 parents 4e92927 + d78da0a commit 8f18dce

19 files changed

+561
-1
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import 'package:flutter/material.dart';
2+
3+
class ButtonWidget extends StatelessWidget {
4+
const ButtonWidget(
5+
{
6+
required this.title,
7+
required this.onTap,
8+
this.isActive = false,
9+
super.key});
10+
11+
final String title;
12+
final bool isActive;
13+
final VoidCallback onTap;
14+
15+
@override
16+
Widget build(BuildContext context) => InkWell(
17+
onTap: onTap,
18+
borderRadius: BorderRadius.circular(14),
19+
child: Container(
20+
height: 40,
21+
padding: const EdgeInsets.symmetric(horizontal: 8),
22+
decoration: BoxDecoration(
23+
border: Border.all(
24+
color: isActive ? Colors.red : Colors.transparent,
25+
width: 2,
26+
),
27+
borderRadius: BorderRadius.circular(14)),
28+
child: Center(
29+
child: Text(title,
30+
style: const TextStyle(
31+
fontSize: 14,
32+
),
33+
)
34+
)
35+
)
36+
);
37+
}

lib/common/input/input.widget.dart

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import 'package:flutter/material.dart';
2+
3+
class InputWidget extends StatelessWidget {
4+
const InputWidget({
5+
required this.textController,
6+
required this.focusNode,
7+
required this.onSubmitted,
8+
this.hintText = '',
9+
super.key,
10+
});
11+
12+
final TextEditingController textController;
13+
final FocusNode focusNode;
14+
final String hintText;
15+
final Function(String) onSubmitted;
16+
17+
18+
@override
19+
Widget build(BuildContext context) => TextField(
20+
controller: textController,
21+
focusNode: focusNode,
22+
decoration: InputDecoration(
23+
hintText: hintText,
24+
hintStyle: const TextStyle(
25+
fontSize: 18,
26+
fontStyle: FontStyle.italic,
27+
color: Colors.grey,
28+
),
29+
border: InputBorder.none,
30+
contentPadding:
31+
const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
32+
focusedBorder: const OutlineInputBorder(
33+
borderSide: BorderSide(color: Colors.red, width: 2),
34+
),
35+
),
36+
style: const TextStyle(fontSize: 18),
37+
onSubmitted: onSubmitted,
38+
onTapOutside: (PointerDownEvent event) {
39+
focusNode.unfocus();
40+
},
41+
);
42+
}

lib/main.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:get/get.dart';
3+
import 'screens/home/home.screen.dart';
4+
import 'screens/home/home.binding.dart';
5+
6+
void main() {
7+
runApp(const MyApp());
8+
}
9+
10+
class MyApp extends StatelessWidget {
11+
const MyApp({super.key});
12+
13+
@override
14+
Widget build(BuildContext context) => GetMaterialApp(
15+
initialBinding: HomeBinding(),
16+
home: const HomeScreen(),
17+
);
18+
}

lib/screens/home/home.binding.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import 'package:get/get.dart';
2+
import 'todo/add-task/add-task.controller.dart';
3+
import 'todo/filter-panel/filter-panel.controller.dart';
4+
import 'todo/task-list-item/task-list-item.controller.dart';
5+
import 'todo/todo.service.dart';
6+
7+
class HomeBinding extends Bindings {
8+
@override
9+
Future<void> dependencies() async {
10+
Get
11+
..lazyPut(TodoService.new)
12+
..lazyPut(() => AddTaskController(Get.find()))
13+
..lazyPut(() => FilterPanelController(Get.find()))
14+
..lazyPut(() => TaskListItemController(Get.find(), Get.find()));
15+
}
16+
}

lib/screens/home/home.screen.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import 'package:flutter/material.dart';
2+
import 'todo/todo.widget.dart';
3+
import '../home/title/title.widget.dart';
4+
5+
class HomeScreen extends StatelessWidget {
6+
const HomeScreen({super.key});
7+
@override
8+
Widget build(BuildContext context) => Scaffold(
9+
backgroundColor: Colors.white,
10+
body: ListView(
11+
children: const <Widget>[
12+
Center(child: TitleWidget()),
13+
TodoWidget(),
14+
],
15+
),
16+
);
17+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'package:flutter/material.dart';
2+
3+
class TitleWidget extends StatelessWidget {
4+
const TitleWidget({super.key});
5+
6+
@override
7+
Widget build(BuildContext context) => const Padding(
8+
padding: EdgeInsets.only(top: 50, bottom: 20),
9+
child: Text(
10+
'todos',
11+
style: TextStyle(
12+
fontSize: 80,
13+
fontWeight: FontWeight.w300,
14+
color: Colors.red,
15+
),
16+
),
17+
);
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'package:flutter/cupertino.dart';
2+
import 'package:get/get.dart';
3+
import '../todo.service.dart';
4+
5+
class AddTaskController extends GetxController {
6+
AddTaskController(this._todoService);
7+
8+
final TodoService _todoService;
9+
final TextEditingController textController = TextEditingController();
10+
final FocusNode focusNode = FocusNode();
11+
12+
void addTask(String task) {
13+
if(task.isNotEmpty) {
14+
_todoService.addTask(task);
15+
textController.clear();
16+
}
17+
}
18+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:get/get.dart';
3+
import '../../../../common/input/input.widget.dart';
4+
import 'add-task.controller.dart';
5+
6+
class AddTaskWidget extends GetView<AddTaskController> {
7+
const AddTaskWidget({ super.key });
8+
9+
10+
@override
11+
Widget build(BuildContext context) => Container(
12+
decoration: BoxDecoration(
13+
border: Border(
14+
bottom: BorderSide(color: Colors.grey.shade300),
15+
),
16+
),
17+
child: InputWidget(
18+
textController: controller.textController,
19+
focusNode: controller.focusNode,
20+
hintText: 'What needs to be done?',
21+
onSubmitted: controller.addTask,
22+
),
23+
);
24+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:get/get.dart';
3+
import '../../../../../../common/button/button.widget.dart';
4+
import '../filter-panel.enum.dart';
5+
import '../filter-panel.controller.dart';
6+
7+
class FilterPanelButtons extends GetView<FilterPanelController> {
8+
const FilterPanelButtons({super.key});
9+
10+
@override
11+
Widget build(BuildContext context) => Obx(() {
12+
return Wrap(
13+
spacing: 10,
14+
children: controller.filters
15+
.map<Widget>(
16+
(FilterType filter) => ButtonWidget(
17+
title: filter.type,
18+
isActive: controller.currentFilter.value == filter,
19+
onTap: () => controller.setFilter(filter),
20+
),
21+
)
22+
.toList(),
23+
);
24+
});
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'package:get/get.dart';
2+
import '../todo.model.dart';
3+
import '../todo.service.dart';
4+
import 'filter-panel.enum.dart';
5+
6+
class FilterPanelController extends GetxController {
7+
FilterPanelController(this._todoService);
8+
9+
final TodoService _todoService;
10+
final Rx<FilterType> currentFilter = FilterType.all.obs;
11+
final List<FilterType> filters = FilterType.values;
12+
13+
List<TaskModel> get filteredTasks => _todoService.filteredTasks(currentFilter.value);
14+
List<TaskModel> get tasks => _todoService.tasks;
15+
16+
int get activeCount => _todoService.activeCount;
17+
18+
void clearCompleted() {
19+
_todoService.clearCompleted();
20+
}
21+
22+
void setFilter(FilterType filter) {
23+
currentFilter.value = filter;
24+
}
25+
}

0 commit comments

Comments
 (0)