diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..ccbd38a --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +DB_HOST = '' +DB_USER = '' +DB_PSWD = '' +DB_NAME = '' \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0e5ac79..318bb28 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .venv -__pycache__ \ No newline at end of file +__pycache__ +.env \ No newline at end of file diff --git a/app.py b/app.py index 5d06d49..2ba0860 100644 --- a/app.py +++ b/app.py @@ -1,7 +1,37 @@ -from flask import Flask, render_template +from flask import Flask, redirect, render_template, request, url_for +from model.tarefa import Tarefa app = Flask(__name__) -@app.route("/") -def home(): - return render_template("agenda.html", title='Adicionar Tarefa') \ No newline at end of file +@app.route('/', methods=['GET', 'POST']) +def index(): + if request.method == 'POST': + titulo = request.form['titulo'] + data_conclusao = request.form['data_conclusao'] + tarefa = Tarefa(titulo=titulo, data_conclusao=data_conclusao) + tarefa.salvarTarefa() + return redirect(url_for('index')) + + tarefas = Tarefa.listarTarefas() + return render_template("index.html", tarefas=tarefas, title='Minhas Tarefas') + +@app.route('/delete/') +def delete(idtarefa): + tarefa = Tarefa(id=idtarefa) + tarefa.apagarTarefa() + return redirect(url_for('index')) + +@app.route('/editar/', methods=['GET', 'POST']) +def editar(idtarefa): + tarefa = Tarefa(id=idtarefa) + + if request.method == 'POST': + novo_titulo = request.form['titulo'] + nova_data_conclusao = request.form['data_conclusao'] + tarefa.editarTarefa(novo_titulo, nova_data_conclusao) + return redirect(url_for('index')) + + return render_template("editar.html", tarefa=tarefa) + +if __name__ == "__main__": + app.run(debug=True) diff --git a/data/agenda.sql b/data/agenda.sql new file mode 100644 index 0000000..92e7bf8 --- /dev/null +++ b/data/agenda.sql @@ -0,0 +1,11 @@ +create database if not exists `agenda`; + +use `agenda`; + +drop table if exists `tarefa`; + +create table if not exists `tarefa`( + `id` int not null `auto_increment` primary key, + `titulo` varchar(60) not null, + `data_conclusao` datetime null +); diff --git a/model/database.py b/model/database.py new file mode 100644 index 0000000..4cc679c --- /dev/null +++ b/model/database.py @@ -0,0 +1,70 @@ +import mysql.connector as mc +from mysql.connector import Error +from dotenv import load_dotenv +from os import getenv + +class Database: + def __init__(self): + load_dotenv() + self.host = getenv('DB_HOST') + self.username = getenv('DB_USER') + self.password = getenv('DB_PSWD') + self.database = getenv('DB_NAME') + self.connection = None + self.cursor = None + + def conectar(self): + """Estabelece uma conexão com o banco de dados.""" + try: + self.connection = mc.connect( + host = self.host, + database = self.database, + user = self.username, + password = self.password + ) + if self.connection.is_connected(): + self.cursor = self.connection.cursor(dictionary=True) + print('Conexão ao banco de dados realizada com sucesso!') + except Error as e: + print(f'Erro de conexão: {e}') + self.connection = None + self.cursor = None + + def desconectar(self): + """Encerra a conexão com o vanco de dados e o cursor, se existirem.""" + if self.cursor: + self.cursor.close() + if self.connection: + self.connection.close() + print('Conexão com o banco de dados encerrada com sucesso!') + + def executar(self,sql,params=None): + """Executa uma instrução no banco de dados.""" + if self.connection is None and self.cursor is None: + print('Conexão ao banco de dados não estabelecida!') + return None + + try: + self.cursor.execute(sql,params) + self.connection.commit() + return self.cursor + except Error as e: + print(f'Erro de execução: {e}') + return None + + def consultar(self,sql,params=None): + """Executa uma instrução no banco de dados.""" + if self.connection is None and self.cursor is None: + print('Conexão ao banco de dados não estabelecida!') + return None + + try: + self.cursor.execute(sql,params) + return self.cursor.fetchall() + except Error as e: + print(f'Erro de execução: {e}') + return None + +db = Database() +db.conectar() +db.desconectar() \ No newline at end of file diff --git a/model/tarefa.py b/model/tarefa.py new file mode 100644 index 0000000..8e60f10 --- /dev/null +++ b/model/tarefa.py @@ -0,0 +1,49 @@ +from model.database import Database + +class Tarefa: + def __init__(self, id=None, titulo=None, data_conclusao=None): + self.id = id + self.titulo = titulo + self.data_conclusao = data_conclusao + + def salvarTarefa(self): + """Salva uma nova tarefa no banco de dados.""" + db = Database() + db.conectar() + sql = 'INSERT INTO tarefa (titulo, data_conclusao) VALUES (%s, %s)' + params = (self.titulo, self.data_conclusao) + db.executar(sql, params) + db.desconectar() + + @staticmethod + def listarTarefas(): + """Retorna uma lista de tarefas cadastradas.""" + db = Database() + db.conectar() + sql = 'SELECT id, titulo, data_conclusao FROM tarefa' + tarefas = db.consultar(sql) + db.desconectar() + return tarefas if tarefas else [] + + def editarTarefa(self, novo_titulo=None, nova_data_conclusao=None): + """Edita os dados da tarefa no banco de dados.""" + db = Database() + db.conectar() + + if novo_titulo: + sql = 'UPDATE tarefa SET titulo = %s WHERE id = %s' + db.executar(sql, (novo_titulo, self.id)) + + if nova_data_conclusao: + sql = 'UPDATE tarefa SET data_conclusao = %s WHERE id = %s' + db.executar(sql, (nova_data_conclusao, self.id)) + + db.desconectar() + + def apagarTarefa(self): + """Apaga uma tarefa cadastrada no banco de dados.""" + db = Database() + db.conectar() + sql = 'DELETE FROM tarefa WHERE id = %s' + db.executar(sql, (self.id,)) + db.desconectar() diff --git a/requirements.txt b/requirements.txt index e69de29..74bb65b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,10 @@ +blinker==1.9.0 +click==8.1.8 +colorama==0.4.6 +Flask==3.1.0 +itsdangerous==2.2.0 +Jinja2==3.1.5 +MarkupSafe==3.0.2 +mysql-connector-python==9.2.0 +python-dotenv==1.0.1 +Werkzeug==3.1.3 diff --git a/static/jinx.css b/static/jinx.css index 9b79496..0301354 100644 --- a/static/jinx.css +++ b/static/jinx.css @@ -1,10 +1,13 @@ - body { - background-color: #0d0d0d; + background-color: #0d0d0d; color: #f5f5f5; - font-family: 'Comic Sans MS', 'Arial', sans-serif; + font-family: 'Comic Sans MS', 'Arial', sans-serif; margin: 0; padding: 0; + display: flex; + align-items: center; + height: 100vh; + flex-direction: column; } h1#lt { @@ -61,6 +64,7 @@ button#botao:hover { max-width: 600px; background-color: #1a1a1a; padding: 20px; + justify-content: center; border-radius: 12px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.5); border: 2px solid #ff007f; @@ -68,7 +72,7 @@ button#botao:hover { #lista-de-tarefas div { display: flex; - justify-content: space-between; + justify-content:center; align-items: center; background-color: #0d0d0d; padding: 10px; diff --git a/templates/agenda.html b/templates/agenda.html deleted file mode 100644 index 36807a2..0000000 --- a/templates/agenda.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - {{ title }} - - - - -

Lista de Tarefas

-
- - - -
-

-
- - - - - \ No newline at end of file diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..756948e --- /dev/null +++ b/templates/base.html @@ -0,0 +1,15 @@ + + + + + + {{ title }} + + + + +

Agenda de Tarefas

+ {% block content %} + {% endblock %} + + \ No newline at end of file diff --git a/templates/editar.html b/templates/editar.html new file mode 100644 index 0000000..00f92a5 --- /dev/null +++ b/templates/editar.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} + +{% block content %} +

Editar Tarefa

+ +
+ + + + + + + +
+ Voltar +{% endblock %} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..ee27f98 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} + +{% block content %} +
+ + + + +
+ +{% endblock %}