Versão Final

parent 2c2ea596
import os import os
from flask import Flask, redirect, render_template, request, url_for from flask import Flask, flash, redirect, render_template, request, url_for
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import func, text
app = Flask(__name__) app = Flask(__name__)
app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY", "dishly-dev-key")
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + os.path.join( app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + os.path.join(
app.instance_path, "database.db" app.instance_path, "database.db"
) )
...@@ -11,7 +12,9 @@ app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False ...@@ -11,7 +12,9 @@ app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app) db = SQLAlchemy(app)
# Modelo da Tabela CATEGORIAS = ["Todos", "Doces", "Salgados", "Bebidas"]
class Receita(db.Model): class Receita(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
nome = db.Column(db.String(100), nullable=False) nome = db.Column(db.String(100), nullable=False)
...@@ -20,71 +23,215 @@ class Receita(db.Model): ...@@ -20,71 +23,215 @@ class Receita(db.Model):
descricao = db.Column(db.Text, nullable=False) descricao = db.Column(db.Text, nullable=False)
ingredientes = db.Column(db.Text, nullable=False) ingredientes = db.Column(db.Text, nullable=False)
preparo = db.Column(db.Text, nullable=False) preparo = db.Column(db.Text, nullable=False)
categoria = db.Column(db.String(50), nullable=False, default="Salgados")
def _ensure_categoria_column():
with db.engine.connect() as conn:
cols = conn.execute(text("PRAGMA table_info(receita)")).fetchall()
if cols and not any(col[1] == "categoria" for col in cols):
conn.execute(
text("ALTER TABLE receita ADD COLUMN categoria VARCHAR(50) DEFAULT 'Salgados'")
)
conn.commit()
def _parse_receita_form():
nome = (request.form.get("nome") or "").strip()
porcoes = (request.form.get("porcoes") or "").strip()
tempo = (request.form.get("tempo") or "").strip()
descricao = (request.form.get("descricao") or "").strip()
ingredientes = (request.form.get("ingredientes") or "").strip()
preparo = (request.form.get("preparo") or "").strip()
categoria = (request.form.get("categoria") or "Salgados").strip()
if categoria not in CATEGORIAS[1:]:
categoria = "Salgados"
erros = []
if not nome:
erros.append("Informe o nome da receita.")
if not porcoes:
erros.append("Informe o número de porções.")
if not tempo:
erros.append("Informe o tempo de preparo.")
if not descricao:
erros.append("Informe uma descrição.")
if not ingredientes:
erros.append("Informe os ingredientes.")
if not preparo:
erros.append("Informe o modo de preparo.")
return {
"nome": nome,
"porcoes": porcoes,
"tempo": tempo,
"descricao": descricao,
"ingredientes": ingredientes,
"preparo": preparo,
"categoria": categoria,
"erros": erros,
}
def _filtrar_receitas():
busca = (request.args.get("q") or "").strip()
categoria = (request.args.get("categoria") or "Todos").strip()
query = Receita.query
if categoria in CATEGORIAS[1:]:
query = query.filter(Receita.categoria == categoria)
if busca:
termo = f"%{busca.lower()}%"
query = query.filter(
db.or_(
func.lower(Receita.nome).like(termo),
func.lower(Receita.descricao).like(termo),
func.lower(Receita.ingredientes).like(termo),
)
)
return query.order_by(Receita.id.desc()).all(), busca, categoria
@app.route("/") @app.route("/")
def index(): def index():
receitas = Receita.query.all() receitas, busca, categoria = _filtrar_receitas()
return render_template("index.html", receitas=receitas) return render_template(
"index.html",
receitas=receitas,
busca=busca,
categoria_ativa=categoria,
categorias=CATEGORIAS,
)
@app.route("/receita/<int:id>")
def receita(id):
receita_obj = Receita.query.get_or_404(id)
return render_template("receita.html", receita=receita_obj)
@app.route("/cadastro", methods=["GET", "POST"]) @app.route("/cadastro", methods=["GET", "POST"])
def cadastro(): def cadastro():
if request.method == "POST": dados = {
nome = request.form.get("nome") "nome": "",
porcoes = request.form.get("porcoes") "porcoes": "",
tempo = request.form.get("tempo") "tempo": "",
descricao = request.form.get("descricao") "descricao": "",
ingredientes = request.form.get("ingredientes") "ingredientes": "",
preparo = request.form.get("preparo") "preparo": "",
"categoria": "Salgados",
}
print(f"DADOS RECEBIDOS: {nome}, {porcoes}, {tempo}, {descricao}, {ingredientes}, {preparo}") if request.method == "POST":
dados = _parse_receita_form()
if dados["erros"]:
for erro in dados["erros"]:
flash(erro, "erro")
return render_template(
"cadastro.html", dados=dados, categorias=CATEGORIAS[1:]
)
nova = Receita( nova = Receita(
nome=nome, nome=dados["nome"],
porcoes=porcoes, porcoes=dados["porcoes"],
tempo=tempo, tempo=dados["tempo"],
descricao=descricao, descricao=dados["descricao"],
ingredientes=ingredientes, ingredientes=dados["ingredientes"],
preparo=preparo, preparo=dados["preparo"],
categoria=dados["categoria"],
) )
db.session.add(nova) db.session.add(nova)
db.session.commit() db.session.commit()
return redirect(url_for("index")) flash("Receita cadastrada com sucesso!", "sucesso")
return redirect(url_for("receita", id=nova.id))
return render_template("cadastro.html", dados=dados, categorias=CATEGORIAS[1:])
return render_template("cadastro.html")
@app.route("/editar/<int:id>", methods=["GET", "POST"]) @app.route("/editar/<int:id>", methods=["GET", "POST"])
def editar(id): def editar(id):
receita = Receita.query.get_or_404(id) receita_obj = Receita.query.get_or_404(id)
if request.method == "POST": if request.method == "POST":
receita.nome = request.form.get("nome") dados = _parse_receita_form()
receita.porcoes = request.form.get("porcoes") if dados["erros"]:
receita.tempo = request.form.get("tempo") for erro in dados["erros"]:
receita.descricao = request.form.get("descricao") flash(erro, "erro")
receita.ingredientes = request.form.get("ingredientes") return render_template(
receita.preparo = request.form.get("preparo") "editar.html",
receita=receita_obj,
dados=dados,
categorias=CATEGORIAS[1:],
)
receita_obj.nome = dados["nome"]
receita_obj.porcoes = dados["porcoes"]
receita_obj.tempo = dados["tempo"]
receita_obj.descricao = dados["descricao"]
receita_obj.ingredientes = dados["ingredientes"]
receita_obj.preparo = dados["preparo"]
receita_obj.categoria = dados["categoria"]
db.session.commit() db.session.commit()
return redirect(url_for("index")) flash("Receita atualizada com sucesso!", "sucesso")
return redirect(url_for("receita", id=receita_obj.id))
dados = {
"nome": receita_obj.nome,
"porcoes": receita_obj.porcoes,
"tempo": receita_obj.tempo,
"descricao": receita_obj.descricao,
"ingredientes": receita_obj.ingredientes,
"preparo": receita_obj.preparo,
"categoria": receita_obj.categoria or "Salgados",
}
return render_template(
"editar.html",
receita=receita_obj,
dados=dados,
categorias=CATEGORIAS[1:],
)
return render_template("editar.html", receita=receita)
@app.route("/excluir/<int:id>") @app.route("/excluir/<int:id>", methods=["POST"])
def excluir(id): def excluir(id):
receita = Receita.query.get_or_404(id) receita_obj = Receita.query.get_or_404(id)
db.session.delete(receita) nome = receita_obj.nome
db.session.delete(receita_obj)
db.session.commit() db.session.commit()
flash(f'Receita "{nome}" excluída.', "sucesso")
return redirect(url_for("index")) return redirect(url_for("index"))
@app.route("/perfil")
def acessoPerfil():
return render_template("perfil.html")
@app.route("/perfil")
def perfil():
total = Receita.query.count()
por_categoria = (
db.session.query(Receita.categoria, func.count(Receita.id))
.group_by(Receita.categoria)
.all()
)
recentes = Receita.query.order_by(Receita.id.desc()).limit(5).all()
return render_template(
"perfil.html",
total=total,
por_categoria=por_categoria,
recentes=recentes,
)
if __name__ == "__main__": def init_db():
os.makedirs(app.instance_path, exist_ok=True) os.makedirs(app.instance_path, exist_ok=True)
with app.app_context(): with app.app_context():
db.create_all() db.create_all()
_ensure_categoria_column()
init_db()
if __name__ == "__main__":
app.run(debug=True) app.run(debug=True)
<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" />
<title>{% block title %}Dishly{% endblock %}</title>
</head>
<body class="{% block body_class %}{% endblock %}">
{% block header %}
<header class="header">
<a class="header__user" href="{{ url_for('perfil') }}" title="Perfil">
<svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M12 12c2.7 0 4.8-2.1 4.8-4.8S14.7 2.4 12 2.4 7.2 4.5 7.2 7.2 9.3 12 12 12zm0 2.4c-3.2 0-9.6 1.6-9.6 4.8v2.4h19.2v-2.4c0-3.2-6.4-4.8-9.6-4.8z"/>
</svg>
</a>
<a class="header__logo" href="{{ url_for('index') }}">Dishly</a>
{% block search %}
<form class="header__search" action="{{ url_for('index') }}" method="get" role="search">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="11" cy="11" r="8" />
<line x1="21" y1="21" x2="16.65" y2="16.65" />
</svg>
<input type="search" name="q" value="{{ busca|default('') }}" placeholder="Buscar receitas..." aria-label="Buscar receitas" />
{% if categoria_ativa|default('Todos') != 'Todos' %}
<input type="hidden" name="categoria" value="{{ categoria_ativa }}" />
{% endif %}
</form>
{% endblock %}
</header>
{% endblock %}
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="flash-container" role="status">
{% for categoria, mensagem in messages %}
<p class="flash flash--{{ categoria }}">{{ mensagem }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
{% block footer %}
<footer>
<p>&copy; 2026 Dishly. Todos os direitos reservados.</p>
</footer>
{% endblock %}
</body>
</html>
<!doctype html> {% extends "base.html" %}
<html lang="pt-BR">
<head> {% block title %}Nova Receita — Dishly{% endblock %}
<meta charset="UTF-8"> {% block body_class %}form-page{% endblock %}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/static/style.css">
<title>Cadastro de Receita</title>
</head>
<body class="editar-page"> {% block header %}{% endblock %}
{% block footer %}{% endblock %}
<div class="editar-container"> {% block content %}
<div class="form-page__wrap">
<form class="editar-form" action="/cadastro" method="POST"> <div class="form-container">
<a class="form-back" href="{{ url_for('index') }}">&larr; Voltar ao feed</a>
<form class="form-card" action="{{ url_for('cadastro') }}" method="POST">
<h1>Nova Receita</h1> <h1>Nova Receita</h1>
<p class="form-subtitle">Compartilhe sua receita com a comunidade Dishly.</p>
<label for="nome">Nome da Receita</label> <label for="nome">Nome da receita</label>
<input id="nome" name="nome" type="text" placeholder="Ex: Lasanha" required> <input id="nome" name="nome" type="text" placeholder="Ex: Lasanha bolonhesa" value="{{ dados.nome }}" required>
<div class="form-row">
<div>
<label for="porcoes">Porções</label> <label for="porcoes">Porções</label>
<input id="porcoes" name="porcoes" type="text" placeholder="Ex: 6 porções"> <input id="porcoes" name="porcoes" type="text" placeholder="Ex: 6 porções" value="{{ dados.porcoes }}" required>
</div>
<div>
<label for="tempo">Tempo de preparo</label> <label for="tempo">Tempo de preparo</label>
<input id="tempo" name="tempo" type="text" placeholder="Ex: 45 minutos"> <input id="tempo" name="tempo" type="text" placeholder="Ex: 45 minutos" value="{{ dados.tempo }}" required>
</div>
</div>
<label for="categoria">Categoria</label>
<select id="categoria" name="categoria" required>
{% for cat in categorias %}
<option value="{{ cat }}" {% if dados.categoria == cat %}selected{% endif %}>{{ cat }}</option>
{% endfor %}
</select>
<label for="descricao">Descrição</label> <label for="descricao">Descrição</label>
<input id="descricao" name="descricao" type="text" placeholder="Breve descrição da receita"> <textarea id="descricao" name="descricao" placeholder="Breve descrição da receita" required>{{ dados.descricao }}</textarea>
<label for="ingredientes">Ingredientes</label> <label for="ingredientes">Ingredientes</label>
<input id="ingredientes" name="ingredientes" type="text" placeholder="Liste os ingredientes"> <textarea id="ingredientes" name="ingredientes" placeholder="Um ingrediente por linha" required>{{ dados.ingredientes }}</textarea>
<label for="preparo">Modo de preparo</label> <label for="preparo">Modo de preparo</label>
<input id="preparo" name="preparo" type="text" placeholder="Descreva o preparo"> <textarea id="preparo" name="preparo" placeholder="Descreva o passo a passo" required>{{ dados.preparo }}</textarea>
<div class="editar-botoes">
<button class="btn-secundario" type="reset">
Limpar
</button>
<button class="btn-principal" type="submit"> <div class="form-actions">
Salvar <button class="btn-secundario" type="reset">Limpar</button>
</button> <button class="btn-principal" type="submit">Salvar receita</button>
</div> </div>
</form> </form>
</div> </div>
</body> </div>
{% endblock %}
</html>
\ No newline at end of file
<!DOCTYPE html> {% extends "base.html" %}
<html lang="pt-BR">
<head> {% block title %}Editar Receita — Dishly{% endblock %}
<meta charset="UTF-8"> {% block body_class %}form-page{% endblock %}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/static/style.css">
<title>Editar Receita</title>
</head>
<body class="editar-page"> {% block header %}{% endblock %}
{% block footer %}{% endblock %}
<div class="editar-container"> {% block content %}
<form class="editar-form" action="/editar/{{ receita.id }}" method="POST"> <div class="form-page__wrap">
<div class="form-container">
<a class="form-back" href="{{ url_for('receita', id=receita.id) }}">&larr; Voltar à receita</a>
<form class="form-card" action="{{ url_for('editar', id=receita.id) }}" method="POST">
<h1>Editar Receita</h1> <h1>Editar Receita</h1>
<p class="form-subtitle">Atualize os detalhes de {{ receita.nome }}.</p>
<label for="nome">Nome da Receita</label> <label for="nome">Nome da receita</label>
<input <input id="nome" name="nome" type="text" value="{{ dados.nome }}" required>
id="nome"
name="nome"
type="text"
value="{{ receita.nome }}"
required
>
<div class="editar-botoes">
<button class="btn-secundario" type="reset">
Limpar
</button>
<button class="btn-principal" type="submit">
Salvar
</button>
<button
class="btn-excluir"
type="button"
onclick="location.href='/excluir/{{ receita.id }}'">
Excluir
</button>
</div>
</form> <div class="form-row">
<div>
<label for="porcoes">Porções</label>
<input id="porcoes" name="porcoes" type="text" value="{{ dados.porcoes }}" required>
</div>
<div>
<label for="tempo">Tempo de preparo</label>
<input id="tempo" name="tempo" type="text" value="{{ dados.tempo }}" required>
</div> </div>
</div>
<label for="categoria">Categoria</label>
<select id="categoria" name="categoria" required>
{% for cat in categorias %}
<option value="{{ cat }}" {% if dados.categoria == cat %}selected{% endif %}>{{ cat }}</option>
{% endfor %}
</select>
<label for="descricao">Descrição</label>
<textarea id="descricao" name="descricao" required>{{ dados.descricao }}</textarea>
</body> <label for="ingredientes">Ingredientes</label>
<textarea id="ingredientes" name="ingredientes" required>{{ dados.ingredientes }}</textarea>
</html> <label for="preparo">Modo de preparo</label>
\ No newline at end of file <textarea id="preparo" name="preparo" required>{{ dados.preparo }}</textarea>
<div class="form-actions">
<button class="btn-principal" type="submit">Salvar alterações</button>
</div>
</form>
<form class="form-delete" action="{{ url_for('excluir', id=receita.id) }}" method="POST"
onsubmit="return confirm('Tem certeza que deseja excluir esta receita?');">
<button class="btn-excluir" type="submit">Excluir receita</button>
</form>
</div>
</div>
{% endblock %}
<!doctype html> {% extends "base.html" %}
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/static/style.css" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<title>Dishly — Feed</title>
</head>
<body> {% block title %}Dishly — Feed{% endblock %}
<!-- Cabeçalho com logo e busca -->
<header class="header">
<a class="header_user" href="/templates/perfil"
><img src="{{ url_for('static', filename='img/user-solid.png') }}" alt="Perfil" width="30px"></a>
<a class="header__logo" href="/">Dishly</a>
<div class="header__search">
<!-- ícone de lupa -->
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="11" cy="11" r="8" />
<line x1="21" y1="21" x2="16.65" y2="16.65" />
</svg>
<input type="text" placeholder="Buscar receitas..." />
</div>
</header>
<!-- Navegação de categorias --> {% block content %}
<nav class="nav"> <nav class="nav" aria-label="Categorias">
<a href="" class="active">Todos</a> {% for cat in categorias %}
<a href="">Doces</a> <a href="{{ url_for('index', categoria=cat, q=busca) }}"
<a href="">Salgados</a> class="{% if categoria_ativa == cat %}active{% endif %}">{{ cat }}</a>
<a href="">Bebidas</a> {% endfor %}
</nav> </nav>
<!-- Grade de receitas estilo Pinterest --> <main class="feed">
<main class="feed"> {% if receitas %}
{% for receita in receitas %} {% for receita in receitas %}
<article class="card"> <article class="card">
<!-- Placeholder de imagem; substitua por <img src="{{ receita.imagem }}"> quando tiver imagens --> <a class="card__link" href="{{ url_for('receita', id=receita.id) }}">
<div class="card__img"> <div class="card__img card__img--{{ loop.index0 % 3 }}">
<svg <span class="card__categoria">{{ receita.categoria or 'Salgados' }}</span>
width="40" <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
height="40"
viewBox="0 0 24 24"
fill="none"
stroke="#999"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect x="3" y="3" width="18" height="18" rx="2" /> <rect x="3" y="3" width="18" height="18" rx="2" />
<circle cx="8.5" cy="8.5" r="1.5" /> <circle cx="8.5" cy="8.5" r="1.5" />
<polyline points="21 15 16 10 5 21" /> <polyline points="21 15 16 10 5 21" />
</svg> </svg>
</div> </div>
<!-- Overlay com ações que aparecem no hover -->
<div class="card__overlay"> <div class="card__overlay">
<div class="card__overlay-top"> <div class="card__overlay-top">
<button class="btn-salvar">Salvar</button> <span class="card__tempo">{{ receita.tempo }}</span>
</div> </div>
<div class="card__overlay-bottom"> <div class="card__overlay-bottom">
<a class="btn-editar" href="/editar/{{ receita.id }}">Editar</a> <a class="btn-editar" href="{{ url_for('editar', id=receita.id) }}" onclick="event.stopPropagation()">Editar</a>
</div> </div>
</div> </div>
<!-- Nome da receita -->
<div class="card__info"> <div class="card__info">
<p class="card__title">{{ receita.nome }}</p> <p class="card__title">{{ receita.nome }}</p>
<p class="card__meta">{{ receita.porcoes }}</p>
</div> </div>
</a>
</article> </article>
{% endfor %} {% endfor %}
</main> {% else %}
<div class="empty-state">
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#ccc" stroke-width="1.5" aria-hidden="true">
<path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"/>
<line x1="3" y1="6" x2="21" y2="6"/>
<path d="M16 10a4 4 0 0 1-8 0"/>
</svg>
<h2>Nenhuma receita encontrada</h2>
<p>
{% if busca or categoria_ativa != 'Todos' %}
Tente outra busca ou categoria.
{% else %}
Comece cadastrando sua primeira receita!
{% endif %}
</p>
<a class="btn-principal btn-principal--inline" href="{{ url_for('cadastro') }}">Nova receita</a>
</div>
{% endif %}
</main>
<!-- Botão flutuante para cadastrar nova receita --> <a class="fab" href="{{ url_for('cadastro') }}" title="Nova receita" aria-label="Nova receita">
<a class="fab" href="/cadastro" title="Nova receita"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="12" y1="5" x2="12" y2="19" /> <line x1="12" y1="5" x2="12" y2="19" />
<line x1="5" y1="12" x2="19" y2="12" /> <line x1="5" y1="12" x2="19" y2="12" />
</svg> </svg>
</a> </a>
<footer> {% endblock %}
<p>&copy; 2026 Dishly. Todos os direitos reservados.</p>
</footer>
</body>
</html>
<!DOCTYPE html> {% extends "base.html" %}
<html lang="pt-BR">
<head> {% block title %}Perfil — Dishly{% endblock %}
<meta charset="UTF-8"> {% block body_class %}profile-page{% endblock %}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Perfil</title> {% block search %}{% endblock %}
</head>
<body> {% block content %}
<main class="profile">
</body> <div class="profile__header">
</html> <div class="profile__avatar">
\ No newline at end of file <svg width="48" height="48" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M12 12c2.7 0 4.8-2.1 4.8-4.8S14.7 2.4 12 2.4 7.2 4.5 7.2 7.2 9.3 12 12 12zm0 2.4c-3.2 0-9.6 1.6-9.6 4.8v2.4h19.2v-2.4c0-3.2-6.4-4.8-9.6-4.8z"/>
</svg>
</div>
<div>
<h1>Meu perfil</h1>
<p>Suas receitas no Dishly</p>
</div>
</div>
<div class="profile__stats">
<article class="stat-card">
<strong>{{ total }}</strong>
<span>Receitas cadastradas</span>
</article>
{% for cat, qtd in por_categoria %}
<article class="stat-card">
<strong>{{ qtd }}</strong>
<span>{{ cat }}</span>
</article>
{% endfor %}
</div>
<section class="profile__recent">
<h2>Receitas recentes</h2>
{% if recentes %}
<ul class="profile__list">
{% for receita in recentes %}
<li>
<a href="{{ url_for('receita', id=receita.id) }}">
<span class="profile__list-name">{{ receita.nome }}</span>
<span class="profile__list-meta">{{ receita.categoria }} · {{ receita.tempo }}</span>
</a>
</li>
{% endfor %}
</ul>
{% else %}
<p class="profile__empty">Você ainda não cadastrou nenhuma receita.</p>
<a class="btn-principal btn-principal--inline" href="{{ url_for('cadastro') }}">Cadastrar receita</a>
{% endif %}
</section>
</main>
{% endblock %}
{% extends "base.html" %}
{% block title %}{{ receita.nome }} — Dishly{% endblock %}
{% block body_class %}detail-page{% endblock %}
{% block search %}{% endblock %}
{% block content %}
<main class="detail">
<div class="detail__hero">
<div class="detail__hero-img">
<svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="1.2" aria-hidden="true">
<rect x="3" y="3" width="18" height="18" rx="2" />
<circle cx="8.5" cy="8.5" r="1.5" />
<polyline points="21 15 16 10 5 21" />
</svg>
</div>
</div>
<div class="detail__content">
<div class="detail__header">
<span class="detail__badge">{{ receita.categoria or 'Salgados' }}</span>
<h1>{{ receita.nome }}</h1>
<p class="detail__desc">{{ receita.descricao }}</p>
<div class="detail__meta">
<span>{{ receita.porcoes }}</span>
<span>{{ receita.tempo }}</span>
</div>
<div class="detail__actions">
<a class="btn-principal btn-principal--inline" href="{{ url_for('editar', id=receita.id) }}">Editar</a>
<a class="btn-secundario btn-secundario--inline" href="{{ url_for('index') }}">Voltar ao feed</a>
</div>
</div>
<section class="detail__section">
<h2>Ingredientes</h2>
<ul class="detail__list">
{% for linha in receita.ingredientes.splitlines() if linha.strip() %}
<li>{{ linha.strip() }}</li>
{% endfor %}
</ul>
</section>
<section class="detail__section">
<h2>Modo de preparo</h2>
<ol class="detail__steps">
{% for passo in receita.preparo.splitlines() if passo.strip() %}
<li>{{ passo.strip() }}</li>
{% endfor %}
</ol>
</section>
</div>
</main>
{% endblock %}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment