Ejemplos del Sistema de Monedas
📚 Casos de Uso Reales
1. Tabla de Órdenes
// apps/app/app/[lang]/dashboard/(project)/project/[projectSlug]/orders/view.tsx
<CurrencyDisplay
value={row.original.totalPrice}
sourceCurrency={row.original.currency as Currency}
targetCurrency={projectCurrency as Currency}
size="sm"
/>
Escenarios:
- Orden USD ($2.57) en app COP → $10,794 COP
- Orden COP (10,800) en app USD → $2.57 USD
- Orden COP (10,800) en app COP → $10,800 COP (sin conversión)
2. Detalle de Pago
// apps/app/app/[lang]/dashboard/(project)/project/[projectSlug]/orders/[orderId]/sections/payments.tsx
<CurrencyDisplay
value={subtotalPrice}
sourceCurrency={currency as Currency}
targetCurrency={projectCurrency as Currency}
size="sm"
/>
3. Productos y Variantes
// apps/app/app/[lang]/dashboard/(project)/project/[projectSlug]/products/view.tsx
<CurrencyDisplay
value={variant.price}
sourceCurrency={variant.currency as Currency}
targetCurrency={projectCurrency as Currency}
size="sm"
/>
4. Planes de Billing
// apps/app/app/[lang]/dashboard/(config)/org/[orgId]/(billing)/plans/view.tsx
<CurrencyDisplay
value={planData.price / 100} // Convertir centavos a dólares
sourceCurrency={Currency.Usd} // Los planes siempre están en USD
targetCurrency={currency as Currency}
size="xl"
showDecimals={currency === "USD"} // Decimales solo para USD
/>
🎯 Configuraciones Especiales
Mostrar Sin Símbolo de Moneda
<CurrencyDisplay
value={price}
sourceCurrency={sourceCurrency}
targetCurrency={targetCurrency}
showCurrencySymbol={false}
/>
// Resultado: "2.57" en lugar de "$2.57"
Forzar Decimales
<CurrencyDisplay
value={price}
sourceCurrency={sourceCurrency}
targetCurrency={targetCurrency}
showDecimals={true}
/>
// Resultado: COP muestra "10,800.00" en lugar de "10,800"
Tasa de Cambio Personalizada
<CurrencyDisplay
value={price}
sourceCurrency={Currency.Usd}
targetCurrency={Currency.Cop}
exchangeRate={4500} // 1 USD = 4,500 COP (tasa especial)
/>
// Resultado: Usa la tasa personalizada en lugar de la por defecto (4,200)
Tamaños de Texto
// Extra pequeño
<CurrencyDisplay size="xs" value={price} sourceCurrency={src} targetCurrency={tgt} />
// Pequeño
<CurrencyDisplay size="sm" value={price} sourceCurrency={src} targetCurrency={tgt} />
// Mediano (por defecto)
<CurrencyDisplay size="md" value={price} sourceCurrency={src} targetCurrency={tgt} />
// Grande
<CurrencyDisplay size="lg" value={price} sourceCurrency={src} targetCurrency={tgt} />
// Extra grande
<CurrencyDisplay size="xl" value={price} sourceCurrency={src} targetCurrency={tgt} />
🔧 Configuración de Páginas
Obtener Moneda del Proyecto (Server Component)
// apps/app/app/[lang]/dashboard/(project)/project/[projectSlug]/orders/page.tsx
export default async function OrdersPage(props: OrdersPageProps) {
const [params] = await Promise.all([props.params]);
// Obtener currency del proyecto
const { data: projectData } = await ApolloServerSupabase.query({
query: graphql(/* GraphQL */ `
query GetProjectCurrency {
getProject {
currency
}
}
`),
context: {
headers: {
"x-project-slug": params.projectSlug, // IMPORTANTE
},
},
});
return (
<OrdersView
projectSlug={params.projectSlug}
projectCurrency={projectData?.getProject?.currency || "USD"}
/>
);
}
Pasar a Componentes Hijos
// En el componente padre
interface OrdersViewProps {
projectSlug: string;
projectCurrency: string;
}
export function OrdersView({ projectSlug, projectCurrency }: OrdersViewProps) {
return (
<div>
{/* Pasar projectCurrency a componentes que muestran precios */}
<OrderTable projectCurrency={projectCurrency} />
<OrderSummary projectCurrency={projectCurrency} />
</div>
);
}
🚨 Errores y Soluciones
Error: "Cannot find name 'Currency'"
// Solución: Importar el enum
import { Currency } from "@packages/apollo/src/__generated__/graphql";
Error: "Property 'currency' does not exist"
// Solución: Agregar campo currency a la query GraphQL
query GetOrders {
getTenantOrders {
id
totalPrice
currency # ← Agregar este campo
}
}
Error: "Type 'string' is not assignable to type 'Currency'"
// Solución: Cast explícito
<CurrencyDisplay
sourceCurrency={order.currency as Currency}
targetCurrency={projectCurrency as Currency}
/>
Los precios no se convierten
// Verificar que se esté pasando el contexto del proyecto
const { data } = await ApolloServerSupabase.query({
query: graphql(`query GetProject { getProject { currency } }`),
context: {
headers: {
"x-project-slug": params.projectSlug, // ← No olvidar esto
},
},
});
🧪 Testing Manual
Probar Conversiones
- Crear orden en USD con precio $2.57
- Cambiar proyecto a COP en configuración
- Verificar que se muestre como ~$10,794 COP
- Cambiar proyecto a USD
- Verificar que se muestre como $2.57 USD
Probar Sin Conversión
- Crear orden en COP con precio 10,800 COP
- Mantener proyecto en COP
- Verificar que se muestre como $10,800 COP (sin conversión)
Probar Planes de Billing
- Ir a configuración de organización
- Cambiar moneda entre USD y COP
- Verificar que los precios de planes se conviertan correctamente
- Verificar que USD muestre decimales y COP no
📊 Datos de Prueba
Órdenes de Prueba
{
"orders": [
{
"id": "order-1",
"totalPrice": 257, // $2.57 USD (en centavos)
"currency": "USD"
},
{
"id": "order-2",
"totalPrice": 10800, // 10,800 COP
"currency": "COP"
}
]
}
Resultados Esperados
| Orden | Moneda Original | Proyecto USD | Proyecto COP |
|---|---|---|---|
| order-1 | USD ($2.57) | $2.57 USD | $10,794 COP |
| order-2 | COP (10,800) | $2.57 USD | $10,800 COP |
Planes de Billing
{
"plans": [
{
"name": "Basic",
"price": 2999, // $29.99 USD (en centavos)
"currency": "USD"
}
]
}
Resultados Esperados
| Plan | Proyecto USD | Proyecto COP |
|---|---|---|
| Basic | $29.99 USD | $125,980 COP |
🔍 Debugging
Agregar Logs Temporales
// En CurrencyDisplay component
console.log('Currency conversion:', {
value,
sourceCurrency,
targetCurrency,
finalValue,
formattedPrice
});
Verificar Props
// En componentes que usan CurrencyDisplay
console.log('CurrencyDisplay props:', {
value: price,
sourceCurrency: order.currency,
targetCurrency: projectCurrency
});
Verificar Query GraphQL
// En páginas
console.log('Project data:', projectData);
console.log('Currency:', projectData?.getProject?.currency);
Última actualización Diciembre 2024
Para más información Ver CURRENCY_SYSTEM.md