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
+26
View File
@@ -0,0 +1,26 @@
[package]
name = "nutriapp-frontend"
version = "0.1.0"
edition = "2024"
[dependencies]
# --- Dioxus ---
dioxus = { version = "0.6", features = ["web"] }
# --- Shared ---
shared = { path = "../shared" }
serde = { workspace = true }
serde_json = { workspace = true }
uuid = { workspace = true, features = ["v4"] }
chrono = { workspace = true }
# --- HTTP calls al backend ---
reqwest = { version = "0.12", features = ["json"] }
# --- WASM bindings ---
wasm-bindgen = "0.2"
web-sys = { version = "0.3", features = ["console"] }
console_error_panic_hook = "0.1"
# --- Logging ---
log = "0.4"
+25
View File
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NutriApp</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: system-ui, -apple-system, sans-serif;
background: #0f172a;
color: #e2e8f0;
min-height: 100vh;
}
#main { min-height: 100vh; }
</style>
</head>
<body>
<div id="main"></div>
<script type="module">
import init from './assets/dioxus/nutriapp-frontend.js';
init('./assets/dioxus/nutriapp-frontend_bg.wasm');
</script>
</body>
</html>
+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