Ir al contenido

Estructura del proyecto

com.omar.act4racingcards
├── MainActivity.kt # única Activity: instala el splash y monta Compose
├── RacingCardsApp.kt # composable raíz: Scaffold + bottom nav + estado de navegación
├── model/
│ ├── RacingCard.kt # RacingCard, CardStats, CardOptions
│ └── PerformanceRoller.kt # rifa de estadísticas + cálculo de rareza
├── navigation/
│ └── Destination.kt # enum de las 3 tabs (Gallery, Create, Details)
├── ui/
│ ├── theme/ # Color.kt, Type.kt, Theme.kt, Dimens.kt — el sistema de diseño
│ ├── components/ # composables reutilizables entre pantallas
│ │ ├── CardComponents.kt # carta, chips, empty state, pickers…
│ │ ├── Buttons.kt # PrimaryButton / SecondaryButton / TertiaryButton
│ │ └── Inputs.kt # estilos compartidos de OutlinedTextField
│ ├── loading/LoadingScreen.kt
│ ├── gallery/GalleryScreen.kt
│ ├── edit/
│ │ ├── EditScreen.kt # formulario de Create/Edit
│ │ └── PerformanceRollOverlay.kt # animación de rifa de estadísticas
│ └── details/DetailsScreen.kt

No hay capa de datos ni ViewModel: model/ son data classes + un objeto de lógica pura (PerformanceRoller), y todo el estado de UI vive directamente en los composables.

A diferencia de una app Compose “de manual”, este proyecto no usa androidx.navigation ni ViewModel. La navegación es un when sobre un enum guardado con rememberSaveable, y el estado (la lista de cartas, la carta seleccionada) vive en el composable raíz RacingCardsApp y se pasa hacia abajo por parámetros — el patrón de state hoisting puro de Compose.

Es una decisión razonable dado el tamaño actual de la app: 4 pantallas, sin persistencia, sin llamadas de red. Si el proyecto creciera (persistencia real, múltiples pantallas por flujo, deep links), sería el primer punto a revisar.

Capas del proyecto

graph TD
  subgraph entry["Entrada"]
      MainActivity["MainActivity"]
  end
  subgraph app["Estado de navegación"]
      RacingCardsApp["RacingCardsApp"]
      Destination["navigation.Destination"]
  end
  subgraph screens["Pantallas"]
      Loading["ui.loading.LoadingScreen"]
      Gallery["ui.gallery.GalleryScreen"]
      Edit["ui.edit.EditScreen"]
      Roll["ui.edit.PerformanceRollOverlay"]
      Details["ui.details.DetailsScreen"]
  end
  subgraph shared["Compartido"]
      Components["ui.components.*"]
      Theme["ui.theme.*"]
  end
  subgraph domain["Modelo"]
      RacingCard["model.RacingCard / CardStats / CardOptions"]
      Roller["model.PerformanceRoller"]
  end

  MainActivity --> Loading
  MainActivity --> RacingCardsApp
  RacingCardsApp --> Destination
  RacingCardsApp --> Gallery
  RacingCardsApp --> Edit
  RacingCardsApp --> Details
  Edit --> Roll
  Gallery --> Components
  Edit --> Components
  Details --> Components
  Roll --> Components
  Components --> Theme
  Loading --> Theme
  Gallery --> RacingCard
  Edit --> RacingCard
  Edit --> Roller
  Roll --> Roller
  Details --> RacingCard