Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: "9f455d2486bcb28cad87b062475f42edc959f636"
channel: "stable"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 9f455d2486bcb28cad87b062475f42edc959f636
base_revision: 9f455d2486bcb28cad87b062475f42edc959f636
- platform: android
create_revision: 9f455d2486bcb28cad87b062475f42edc959f636
base_revision: 9f455d2486bcb28cad87b062475f42edc959f636
- platform: ios
create_revision: 9f455d2486bcb28cad87b062475f42edc959f636
base_revision: 9f455d2486bcb28cad87b062475f42edc959f636
- platform: linux
create_revision: 9f455d2486bcb28cad87b062475f42edc959f636
base_revision: 9f455d2486bcb28cad87b062475f42edc959f636
- platform: macos
create_revision: 9f455d2486bcb28cad87b062475f42edc959f636
base_revision: 9f455d2486bcb28cad87b062475f42edc959f636
- platform: web
create_revision: 9f455d2486bcb28cad87b062475f42edc959f636
base_revision: 9f455d2486bcb28cad87b062475f42edc959f636
- platform: windows
create_revision: 9f455d2486bcb28cad87b062475f42edc959f636
base_revision: 9f455d2486bcb28cad87b062475f42edc959f636

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
211 changes: 179 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,189 @@
# Bienvenido al coding-interview-frontend
# 💱 Crypto Calculator Challenge

## Descripción
Acá tienes todos los assets que necesitas para llevar a cabo una pequeña prueba técnica. El objetivo es que puedas demostrar tus habilidades de programación y de UI. El proyecto consiste de una pequeña calculadora que te muestra cuanto vas a recibir si quieres cambiar una determinada cantidad de una moneda a otra.
<div align="center">

## Características
1. Hay dos tipos de monedas: "FIAT" y "CRYPTO".
2. La tasa de cambio la podrás obtener de nuestro API público.
3. La moneda del input
![Flutter](https://img.shields.io/badge/Flutter-3.8.0+-02569B?style=for-the-badge&logo=flutter&logoColor=white)
![Dart](https://img.shields.io/badge/Dart-3.8.0+-0175C2?style=for-the-badge&logo=dart&logoColor=white)
![Riverpod](https://img.shields.io/badge/Riverpod-3.0.3-5ECCAA?style=for-the-badge)
![Tests](https://img.shields.io/badge/Tests-Passing-success?style=for-the-badge)

## API
- URL: https://74j6q7lg6a.execute-api.eu-west-1.amazonaws.com/stage/orderbook/public/recommendations
- Query Params:
- `type`: 0 -> Cambio de CRYPTO a FIAT, 1 -> Cambio de FIAT a CRYPTO
- `cryptoCurrencyId`: La moneda crypto (el ID está en el nombre del asset)
- `fiatCurrencyId`: La moneda fiat (el ID está en el nombre del asset)
- `amount`: Cantidad a cambiar
- `amountCurrencyId`: La moneda en la que está del input
**Una calculadora de criptomonedas moderna, escalable y pixel-perfect construida con Flutter**

Del response, simplemente obtener el `data.byPrice.fiatToCryptoExchangeRate` y multiplicarlo/dividirlo para mostrar toda la data necesaria.
[Características](#-características) • [Arquitectura](#-arquitectura) • [Instalación](#-instalación) • [Testing](#-testing)

### Que puedes hacer:
- ✅ Preferiblemente, usa Flutter :)
- ✅ Cuantas mejoras de UX como veas necesarias/quieras
- ✅ No todo tiene que estar funcionando a la perfección, lo que más vamos a tomar en cuenta es el parecido con el diseño y la calidad del código.
- ✅ Desarrolla la app con la arquitecura de una app que va a escalar, no hagas un código que no puedas mantener en el futuro.
</div>

---

### Que **no** puedes hacer:
- ❌ Estresarte 🤗
## 🎥 Video Demo

<div align="center">

## Pasos para comenzar
1. Haz un fork usando este repositorio como template
2. Clona el repositorio en tu máquina
3. Desarrolla la mini-app
4. Sube tus cambios a tu repositorio
5. Avísanos que has terminado
6. ???
7. PROFIT
### Android

### Cualquier duda contactarme a https://www.linkedin.com/in/carlosfontest/
https://github.com/user-attachments/assets/a6854466-b527-4db8-a559-f64a38a883f9

### iOS

https://github.com/user-attachments/assets/32faa560-6e04-4a00-a03f-ca6e2c438074

</div>

---

## ✨ Características

### 🎨 UI/UX Excellence
- **Pixel Perfect Implementation** - Diseño implementado con precisión absoluta
- **Animaciones Suaves** - Chevron animados y transiciones fluidas
- **Mejoras de UX** - Tasa de conversión mostrada (1 FIAT = X USDT) para mayor claridad
- **Tema Moderno** - Paleta de colores vibrante con modo oscuro nativo
- **Responsive Design** - Adaptable a diferentes tamaños de pantalla

### 🏗️ Arquitectura Robusta
- **Clean Architecture** - Separación clara en capas: Data, Domain, Presentation
- **Escalabilidad** - Preparado para crecer con nuevas features
- **SOLID Principles** - Código mantenible y de alta calidad
- **Gestión de Estado** - Riverpod 3.0 con code generation
- **Navegación Declarativa** - GoRouter para routing type-safe y deep linking

### 🛡️ Manejo de Errores Profesional
- **Validaciones Robustas** - Límites de monto, validaciones de entrada
- **Mensajes Amigables** - Errores claros y comprensibles para el usuario
- **Recuperación Elegante** - Manejo de errores de red y API
- **Estados Consistentes** - Loading, Error y Success states bien definidos

### ⚡ Optimizaciones Técnicas
- **Use Cases** - Lógica de negocio encapsulada y testeable
- **Providers Optimizados** - Mínimos rebuilds, máximo rendimiento
- **Code Generation** - Riverpod Generator y Freezed para código type-safe
- **Últimas Versiones** - Flutter 3.8+, Riverpod 3.0, Dio 5.9

### 🧪 Testing & Calidad
- **11 Unit Tests** - Cobertura completa de lógica crítica
- **100% de Éxito** - Todos los tests pasan correctamente
- **Validaciones Testeadas** - ValidateExchangeAmountUseCase
- **Cálculos Testeados** - CalculateCryptoExchangeUseCase

---

## 🏛️ Arquitectura

El proyecto sigue **Clean Architecture** con tres capas bien definidas:

```
lib/
├── src/
│ ├── core/ # Recursos compartidos
│ │ ├── constants/ # Strings, validaciones, colores
│ │ ├── theme/ # Temas y estilos
│ │ ├── utils/ # Utilidades y helpers
│ │ └── widgets/ # Widgets reutilizables
│ │
│ └── features/
│ └── calculator/
│ ├── data/ # Capa de Datos
│ │ ├── datasources/ # API & Local data
│ │ └── repositories/ # Implementaciones
│ │
│ ├── domain/ # Capa de Dominio
│ │ ├── entities/ # Modelos de negocio
│ │ ├── repositories/ # Contratos
│ │ └── usecases/ # Lógica de negocio
│ │
│ └── presentation/ # Capa de Presentación
│ ├── providers/ # Riverpod providers
│ ├── screens/ # Pantallas
│ ├── states/ # Estados
│ └── widgets/ # UI components
```

### 📦 Paquetes Principales

| Paquete | Versión | Propósito |
|---------|---------|-----------|
| `flutter_riverpod` | 3.0.3 | Gestión de estado reactiva |
| `riverpod_annotation` | 3.0.3 | Code generation para providers |
| `dio` | 5.9.0 | Cliente HTTP robusto |
| `freezed` | 3.2.3 | Modelos inmutables |
| `flutter_svg` | 2.2.1 | Renderizado de SVG |
| `go_router` | 16.3.0 | Navegación declarativa y deep linking |

---

## 🚀 Instalación

### Prerequisitos

- Flutter SDK: `>= 3.8.0`
- Dart SDK: `>= 3.8.0`

### Pasos

1. **Clonar el repositorio**
```bash
git clone https://github.com/cuambyte/crypto-calculator.git
cd crypto-calculator
```

2. **Instalar dependencias**
```bash
flutter pub get
```

3. **Generar código**
```bash
dart run build_runner build -d
```

4. **Ejecutar la app**
```bash
flutter run
```

### Ejecutar Tests

```bash
flutter test
```

---

## 🎯 Decisiones Técnicas

### ¿Por qué Clean Architecture?
- ✅ Facilita el testing
- ✅ Código desacoplado y mantenible
- ✅ Preparado para escalar
- ✅ Independencia de frameworks

### ¿Por qué Riverpod?
- ✅ Type-safe y compile-time
- ✅ Sin context necesario
- ✅ Code generation
- ✅ Performance optimizado

### ¿Por qué Unit Testing?
- ✅ Valida lógica crítica del negocio
- ✅ Rápido de ejecutar
- ✅ Detecta regresiones temprano
- ✅ Documenta comportamiento esperado

---

## 🔮 Mejoras Futuras

- [ ] Tests de integración E2E
- [ ] Persistencia local con Hive/SQLite
- [ ] Soporte multi-idioma (i18n)
- [ ] Más criptomonedas y fiat
- [ ] Historial de conversiones
- [ ] Modo offline con cache

---

<div align="center">

⭐ Si te gustó este proyecto, dale una estrella

</div>
28 changes: 28 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
14 changes: 14 additions & 0 deletions android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
.cxx/

# Remember to never publicly share your keystore.
# See https://flutter.dev/to/reference-keystore
key.properties
**/*.keystore
**/*.jks
44 changes: 44 additions & 0 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
plugins {
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}

android {
namespace = "com.crypto.calculator.crypto_calculator"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion

compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.crypto.calculator.crypto_calculator"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
}
}
}

flutter {
source = "../.."
}
7 changes: 7 additions & 0 deletions android/app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
Loading