-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 53f039d
Showing
7 changed files
with
432 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:todo/pages/todo_list_page.dart'; | ||
|
||
void main(){ | ||
runApp(const MyApp());} | ||
|
||
class MyApp extends StatelessWidget{ | ||
const MyApp({Key? key}) : super (key:key); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return MaterialApp(//tras navegação, tema, localização(espanhol,ingles,...) | ||
title: 'Organizador de tarefas', | ||
theme: ThemeData( | ||
primarySwatch: Colors.green, | ||
), | ||
debugShowCheckedModeBanner: false, | ||
home:TodoListPage(), | ||
); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
class Todo{ | ||
Todo({required this.title, required this.dateTime}); | ||
Todo.fromJson(Map<String,dynamic> json) | ||
:title = json ['title'], | ||
dateTime = DateTime.parse(json['datetime']); | ||
|
||
String title; | ||
DateTime dateTime; | ||
|
||
Map<String,dynamic> toJson(){ | ||
return{ | ||
'title':title, | ||
'datetime':dateTime.toIso8601String(), | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:todo/repositories/todo_repository.dart'; | ||
import 'package:todo/widgets/todo_list_item.dart'; | ||
import '../models/todo.dart'; | ||
|
||
class TodoListPage extends StatefulWidget { | ||
TodoListPage({Key? key}) : super(key: key); | ||
|
||
@override | ||
State<TodoListPage> createState() => _TodoListPageState(); | ||
} | ||
|
||
class _TodoListPageState extends State<TodoListPage> { | ||
final TextEditingController todoController = TextEditingController(); | ||
late TodoRepository todoRepository; | ||
|
||
List<Todo> todos = []; | ||
Todo? deletedTodo; | ||
int? deletedTodoPos; // posição para voltar na mesma posição | ||
String? erroText; | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
todoRepository = TodoRepository(); // Instancia o TodoRepository | ||
todoRepository.getTodoList().then((value) { | ||
setState(() { | ||
todos = value; | ||
}); | ||
}); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return SafeArea( | ||
child: Scaffold( | ||
body: Container( | ||
decoration: | ||
BoxDecoration( | ||
gradient: LinearGradient( | ||
colors: [ | ||
Color(0xFFC4E0E5), // Cor pastel 1 | ||
Color(0xFFF7F7E8), // Cor pastel 2 | ||
], | ||
begin: Alignment.topCenter, | ||
end: Alignment.bottomCenter, | ||
), | ||
), | ||
child: Padding( | ||
padding: const EdgeInsets.all(16), | ||
child: Center( | ||
child: Column( | ||
mainAxisSize: MainAxisSize.min, | ||
children: [ | ||
Row( | ||
children: [ | ||
Expanded( | ||
child: TextField( | ||
controller: todoController, | ||
decoration: InputDecoration( | ||
border: OutlineInputBorder(), | ||
labelText: 'Adicione uma tarefa', | ||
hintText: 'Exemplo: Estudar Flutter', | ||
errorText: erroText, | ||
focusedBorder: OutlineInputBorder( | ||
borderSide: BorderSide( | ||
color: Color(0xff00d7f3), | ||
width: 2, | ||
), | ||
), | ||
), | ||
), | ||
), | ||
SizedBox(width: 16), | ||
ElevatedButton( | ||
onPressed: () { | ||
String text = todoController.text; | ||
if (text.isEmpty) { | ||
setState(() { | ||
erroText = 'O título não pode ser vazio'; | ||
}); | ||
return; | ||
} | ||
setState(() { | ||
Todo newTodo = Todo( | ||
title: text, | ||
dateTime: DateTime.now(), | ||
); | ||
todos.add(newTodo); | ||
erroText = null; | ||
}); | ||
todoController.clear(); | ||
todoRepository.saveTodoList( | ||
todos); // Salva a lista usando a instância do TodoRepository | ||
}, | ||
style: ElevatedButton.styleFrom( | ||
backgroundColor: Color(0xff00d7f3), | ||
padding: EdgeInsets.all(14), | ||
), | ||
child: Icon( | ||
Icons.add, | ||
size: 30, | ||
), | ||
), | ||
], | ||
), | ||
SizedBox(height: 16), | ||
Flexible( | ||
child: ListView( | ||
shrinkWrap: true, | ||
children: [ | ||
for (Todo todo in todos) | ||
TodoListItem( | ||
todo: todo, | ||
onDelete: onDelete, | ||
), | ||
], | ||
), | ||
), | ||
SizedBox(height: 16), | ||
Row( | ||
children: [ | ||
Expanded( | ||
child: Text( | ||
'Você possui ${todos.length} tarefas pendentes', | ||
), | ||
), | ||
SizedBox(width: 8), | ||
ElevatedButton( | ||
onPressed: showDeleteTodosConfirmationDialog, | ||
style: ElevatedButton.styleFrom( | ||
backgroundColor: Color(0xff00d7f3), | ||
padding: EdgeInsets.all(14), | ||
), | ||
child: Text('limpar tudo'), | ||
) | ||
], | ||
) | ||
], | ||
), | ||
), | ||
), | ||
), | ||
), | ||
); | ||
} | ||
|
||
void onDelete(Todo todo) { | ||
deletedTodo = todo; | ||
deletedTodoPos = todos.indexOf(todo); | ||
setState(() { | ||
todos.remove(todo); | ||
}); | ||
todoRepository.saveTodoList( | ||
todos); // Salva a lista usando a instância do TodoRepository | ||
|
||
ScaffoldMessenger.of(context).clearSnackBars(); | ||
ScaffoldMessenger.of(context).showSnackBar( | ||
SnackBar( | ||
content: Text( | ||
'tarefa ${todo.title} foi removida com sucesso!', | ||
style: TextStyle(color: Color(0xff060708)), | ||
), | ||
backgroundColor: Colors.white, | ||
action: SnackBarAction( | ||
label: 'Desfazer', | ||
textColor: const Color(0xff00d7f3), | ||
onPressed: () { | ||
setState(() { | ||
todos.insert(deletedTodoPos!, deletedTodo!); | ||
}); | ||
todoRepository.saveTodoList( | ||
todos); // Salva a lista usando a instância do TodoRepository | ||
}, | ||
), | ||
duration: const Duration(seconds: 5), | ||
), | ||
); | ||
} | ||
|
||
void showDeleteTodosConfirmationDialog() { | ||
showDialog( | ||
context: context, | ||
builder: (context) => AlertDialog( | ||
title: Text('Limpar tudo?'), | ||
content: Text('Você tem certeza que deseja apagar todas as tarefas?'), | ||
actions: [ | ||
TextButton( | ||
onPressed: () { | ||
Navigator.of(context).pop(); | ||
}, | ||
style: TextButton.styleFrom(foregroundColor: Color(0xff00d7f3)), | ||
child: Text('Cancelar'), | ||
), | ||
TextButton( | ||
onPressed: () { | ||
Navigator.of(context).pop(); | ||
deleteAllTodos(); | ||
}, | ||
style: TextButton.styleFrom(foregroundColor: Colors.red), | ||
child: Text('Limpar Tudo'), | ||
), | ||
], | ||
), | ||
); | ||
} | ||
|
||
void deleteAllTodos() { | ||
setState(() { | ||
todos.clear(); | ||
}); | ||
todoRepository.saveTodoList( | ||
todos); // Salva a lista usando a instância do TodoRepository | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import 'dart:convert'; | ||
|
||
import 'package:shared_preferences/shared_preferences.dart'; | ||
import '../models/todo.dart'; | ||
|
||
const todoListKey = 'todo_list'; | ||
class TodoRepository{ | ||
late SharedPreferences sharedPreferences; //ela vai ser inicializada no futuro e eu garanto isso | ||
|
||
Future<List<Todo>> getTodoList() async{ | ||
sharedPreferences = await SharedPreferences.getInstance(); | ||
final String jsonString = sharedPreferences.getString(todoListKey) ?? '[]'; | ||
final List jsonDecoded = json.decode(jsonString) as List; | ||
return jsonDecoded.map((e) => Todo.fromJson(e)).toList(); | ||
} | ||
|
||
void saveTodoList(List<Todo> todos){ | ||
final String jsonString = json.encode(todos); | ||
sharedPreferences.setString(todoListKey, jsonString); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_slidable/flutter_slidable.dart'; | ||
import 'package:intl/intl.dart'; | ||
|
||
import '../models/todo.dart'; | ||
|
||
class TodoListItem extends StatelessWidget { | ||
const TodoListItem({Key? key, required this.todo, required this.onDelete}) | ||
: super(key: key); | ||
|
||
final Todo todo; | ||
final Function(Todo) onDelete; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Padding( | ||
padding: const EdgeInsets.symmetric(vertical: 2), | ||
child: Slidable( | ||
child: Container( | ||
decoration: BoxDecoration( | ||
borderRadius: BorderRadius.circular(10), | ||
color: Colors.grey[200], | ||
), | ||
padding: const EdgeInsets.all(16), | ||
//espaçamento de dentro | ||
child: Column( | ||
crossAxisAlignment: CrossAxisAlignment.stretch, | ||
//PARA FICAR DO LADO ESQUERDO A COLUNA, | ||
children: [ | ||
Text( | ||
DateFormat('dd/MM/yyyy - EE - HH:mm').format(todo.dateTime), | ||
style: TextStyle(fontSize: 12), | ||
), | ||
Text( | ||
todo.title, | ||
style: TextStyle( | ||
fontSize: 16, | ||
fontWeight: FontWeight.w600, | ||
), | ||
), | ||
], | ||
), | ||
), | ||
actionExtentRatio: 0.20, | ||
actionPane: const SlidableDrawerActionPane(), | ||
secondaryActions: [ //aparedem botoes do lado direito | ||
IconSlideAction( | ||
color: Colors.red, | ||
icon: Icons.delete, | ||
caption: 'Delete', | ||
onTap: () { | ||
onDelete(todo); | ||
}, | ||
), | ||
], | ||
), | ||
); | ||
} | ||
} |
Oops, something went wrong.