Initial commit: NutriApp - Rust + Axum + Dioxus - CI/CD con Gitea Runner

This commit is contained in:
2026-06-24 08:35:09 +01:00
commit bede2018a6
35 changed files with 829 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
// Cliente HTTP para la API del backend (Axum en :3100)
// TODO: reemplazar con llamadas reales a /api/v1/*
use reqwest::Client;
use shared::{RecetaDto, SlotComidaDto, ItemCompraDto, ListaCompraRequest};
const API_BASE: &str = "http://localhost:3100/api/v1";
pub async fn listar_recetas() -> Result<Vec<RecetaDto>, String> {
let client = Client::new();
let resp = client
.get(format!("{API_BASE}/recetas"))
.send()
.await
.map_err(|e| e.to_string())?;
resp.json::<Vec<RecetaDto>>()
.await
.map_err(|e| e.to_string())
}
pub async fn listar_slots(
familia_id: &str,
desde: &str,
hasta: &str,
) -> Result<Vec<SlotComidaDto>, String> {
let client = Client::new();
let resp = client
.get(format!(
"{API_BASE}/calendario?familia_id={familia_id}&desde={desde}&hasta={hasta}"
))
.send()
.await
.map_err(|e| e.to_string())?;
resp.json::<Vec<SlotComidaDto>>()
.await
.map_err(|e| e.to_string())
}
pub async fn generar_lista_compras(
req: &ListaCompraRequest,
) -> Result<Vec<ItemCompraDto>, String> {
let client = Client::new();
let resp = client
.post(format!("{API_BASE}/lista-compras"))
.json(req)
.send()
.await
.map_err(|e| e.to_string())?;
resp.json::<Vec<ItemCompraDto>>()
.await
.map_err(|e| e.to_string())
}
+2
View File
@@ -0,0 +1,2 @@
// API client para llamadas al backend (Axum en :3100)
pub mod client;
+3
View File
@@ -0,0 +1,3 @@
pub mod receta_card;
pub mod slot_calendario;
pub mod nav;
+1
View File
@@ -0,0 +1 @@
// Barra de navegación reutilizable
+22
View File
@@ -0,0 +1,22 @@
// Componente tarjeta de receta — nombre, porciones, tiempo, ingredientes
use dioxus::prelude::*;
use shared::RecetaDto;
#[component]
pub fn RecetaCard(receta: RecetaDto, on_click: Option<EventHandler<()>>) -> Element {
rsx! {
div {
class: "receta-card",
onclick: move |_| {
if let Some(ref handler) = on_click {
handler.call(());
}
},
h3 { "{receta.nombre}" }
span { "🍽️ {receta.porciones} porciones" }
if let Some(tiempo) = receta.tiempo_preparacion_min {
span { "⏱️ {tiempo} min" }
}
}
}
}
@@ -0,0 +1 @@
// Slot de comida en el calendario (desayuno/comida/cena de un día)
+34
View File
@@ -0,0 +1,34 @@
#![allow(non_snake_case)]
use dioxus::prelude::*;
mod pages;
mod components;
mod api;
fn main() {
console_error_panic_hook::set_once();
dioxus::launch(App);
}
#[component]
fn App() -> Element {
rsx! {
div { class: "app-container",
header { class: "header",
h1 { "🍽️ NutriApp" }
nav {
a { href: "/", "Calendario" }
a { href: "/recetas", "Recetas" }
a { href: "/lista", "Lista de Compras" }
a { href: "/inventario", "Inventario" }
}
}
main { class: "main-content",
// Placeholder — routing se agrega después
h2 { "Bienvenido a NutriApp" }
p { "Planifica tus comidas semanales en familia." }
}
}
}
}
+3
View File
@@ -0,0 +1,3 @@
// Página de calendario semanal
// Grid 7 columnas (días) × 3 filas (desayuno, comida, cena)
// Drag & drop de recetas a slots
+2
View File
@@ -0,0 +1,2 @@
// Página de inventario — productos disponibles en casa
// Se descuenta de la lista de compras
+1
View File
@@ -0,0 +1 @@
// Página de lista de compras generada automáticamente desde el menú semanal
+4
View File
@@ -0,0 +1,4 @@
pub mod calendario;
pub mod recetas;
pub mod lista_compras;
pub mod inventario;
+2
View File
@@ -0,0 +1,2 @@
// Página de recetas
// Lista, búsqueda, crear/editar receta con ingredientes dinámicos