mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-10-05 12:28:22 +00:00
Fix UI formatting for CI
This commit is contained in:
@@ -78,25 +78,35 @@ export function CostCalculator({ model }: CostCalculatorProps) {
|
||||
<div className='space-y-2 text-sm'>
|
||||
<div className='flex justify-between'>
|
||||
<span>Input Cost ({inputTokens.toLocaleString()} tokens):</span>
|
||||
<span className='font-mono'>{formatDisplayCost(costCalculation.inputCost)}</span>
|
||||
<span className='font-mono'>
|
||||
{formatDisplayCost(costCalculation.inputCost)}
|
||||
</span>
|
||||
</div>
|
||||
<div className='flex justify-between'>
|
||||
<span>Output Cost ({outputTokens.toLocaleString()} tokens):</span>
|
||||
<span className='font-mono'>{formatDisplayCost(costCalculation.outputCost)}</span>
|
||||
<span className='font-mono'>
|
||||
{formatDisplayCost(costCalculation.outputCost)}
|
||||
</span>
|
||||
</div>
|
||||
<hr className='my-2' />
|
||||
<div className='flex justify-between'>
|
||||
<span>Base Cost:</span>
|
||||
<span className='font-mono'>{formatDisplayCost(costCalculation.baseCost)}</span>
|
||||
<span className='font-mono'>
|
||||
{formatDisplayCost(costCalculation.baseCost)}
|
||||
</span>
|
||||
</div>
|
||||
<div className='flex justify-between'>
|
||||
<span>Minimum Cost per Request:</span>
|
||||
<span className='font-mono'>{formatDisplayCost(costCalculation.minCostPerRequest)}</span>
|
||||
<span className='font-mono'>
|
||||
{formatDisplayCost(costCalculation.minCostPerRequest)}
|
||||
</span>
|
||||
</div>
|
||||
<hr className='my-2' />
|
||||
<div className='flex justify-between font-medium'>
|
||||
<span>Final Cost:</span>
|
||||
<span className='font-mono text-lg'>{formatDisplayCost(costCalculation.finalCost)}</span>
|
||||
<span className='font-mono text-lg'>
|
||||
{formatDisplayCost(costCalculation.finalCost)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -197,15 +207,21 @@ export function CostCalculator({ model }: CostCalculatorProps) {
|
||||
<div className='space-y-2 text-sm'>
|
||||
<div className='flex justify-between'>
|
||||
<span>Input cost per 1M tokens:</span>
|
||||
<span className='font-mono'>{formatDisplayCost(model.input_cost)}</span>
|
||||
<span className='font-mono'>
|
||||
{formatDisplayCost(model.input_cost)}
|
||||
</span>
|
||||
</div>
|
||||
<div className='flex justify-between'>
|
||||
<span>Output cost per 1M tokens:</span>
|
||||
<span className='font-mono'>{formatDisplayCost(model.output_cost)}</span>
|
||||
<span className='font-mono'>
|
||||
{formatDisplayCost(model.output_cost)}
|
||||
</span>
|
||||
</div>
|
||||
<div className='flex justify-between'>
|
||||
<span>Minimum cost per request:</span>
|
||||
<span className='font-mono'>{formatDisplayCost(model.min_cost_per_request)}</span>
|
||||
<span className='font-mono'>
|
||||
{formatDisplayCost(model.min_cost_per_request)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { type JSX, useState, useCallback, useEffect } from 'react';
|
||||
import {
|
||||
Copy,
|
||||
RefreshCcw,
|
||||
RotateCcw,
|
||||
} from 'lucide-react';
|
||||
import { Copy, RefreshCcw, RotateCcw } from 'lucide-react';
|
||||
import { toast } from 'sonner';
|
||||
import {
|
||||
Card,
|
||||
|
||||
@@ -77,7 +77,9 @@ function getModelTypeParts(modelType: string): {
|
||||
inputs: ModelModality[];
|
||||
outputs: ModelModality[];
|
||||
} {
|
||||
const [inputPart, outputPart] = modelType.split('->').map((part) => part.trim());
|
||||
const [inputPart, outputPart] = modelType
|
||||
.split('->')
|
||||
.map((part) => part.trim());
|
||||
|
||||
return {
|
||||
inputs: extractModalities(inputPart || modelType),
|
||||
@@ -115,7 +117,7 @@ function ModelTypeIcons({ modelType }: { modelType: string }) {
|
||||
|
||||
return (
|
||||
<span
|
||||
className='inline-flex max-w-full min-w-0 items-center gap-0.5 overflow-hidden text-muted-foreground'
|
||||
className='text-muted-foreground inline-flex max-w-full min-w-0 items-center gap-0.5 overflow-hidden'
|
||||
title={modelType}
|
||||
aria-label={modelType}
|
||||
>
|
||||
@@ -254,7 +256,7 @@ export function ModelItemCard({
|
||||
return (
|
||||
<Card
|
||||
className={cn(
|
||||
"relative overflow-hidden rounded-none border-0 bg-transparent py-0 shadow-none ring-0 transition-colors duration-150 after:absolute after:right-3 after:bottom-0 after:left-3 after:h-px after:bg-border/80 after:content-[''] last:after:hidden md:after:hidden",
|
||||
"after:bg-border/80 relative overflow-hidden rounded-none border-0 bg-transparent py-0 shadow-none ring-0 transition-colors duration-150 after:absolute after:right-3 after:bottom-0 after:left-3 after:h-px after:content-[''] last:after:hidden md:after:hidden",
|
||||
'hover:bg-muted/25',
|
||||
isSelected && 'bg-primary/12',
|
||||
model.soft_deleted && 'bg-muted/20 opacity-80'
|
||||
@@ -339,7 +341,7 @@ export function ModelItemCard({
|
||||
<span className={statusDotClass} />
|
||||
<h3
|
||||
className={cn(
|
||||
'line-clamp-2 min-w-0 flex-1 text-[15px] font-medium leading-5',
|
||||
'line-clamp-2 min-w-0 flex-1 text-[15px] leading-5 font-medium',
|
||||
model.soft_deleted && 'text-muted-foreground'
|
||||
)}
|
||||
title={model.name}
|
||||
@@ -382,13 +384,13 @@ export function ModelItemCard({
|
||||
|
||||
<div aria-hidden />
|
||||
{isFreeModel ? (
|
||||
<div className='text-muted-foreground text-sm font-medium'>Free</div>
|
||||
<div className='text-muted-foreground text-sm font-medium'>
|
||||
Free
|
||||
</div>
|
||||
) : (
|
||||
<div className='border-border/45 bg-background/20 grid grid-cols-2 overflow-hidden rounded-lg border'>
|
||||
<div className='px-3 py-2.5'>
|
||||
<div className='text-muted-foreground text-[11px]'>
|
||||
Input
|
||||
</div>
|
||||
<div className='text-muted-foreground text-[11px]'>Input</div>
|
||||
<div className='pt-0.5 text-[15px] font-medium tabular-nums'>
|
||||
{inputPriceLabel}
|
||||
</div>
|
||||
|
||||
@@ -83,7 +83,7 @@ export function ModelProviderSection({
|
||||
|
||||
if (filterProvider) {
|
||||
return (
|
||||
<div className='bg-card/35 border-border/70 overflow-hidden rounded-lg border md:divide-y md:divide-border/75'>
|
||||
<div className='bg-card/35 border-border/70 md:divide-border/75 overflow-hidden rounded-lg border md:divide-y'>
|
||||
{providerModels.map((model) => (
|
||||
<ModelItemCard
|
||||
key={model.id}
|
||||
@@ -194,7 +194,7 @@ export function ModelProviderSection({
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className='px-3 pt-0 pb-3 sm:px-6 sm:pb-6'>
|
||||
<div className='bg-card/35 border-border/70 overflow-hidden rounded-lg border md:divide-y md:divide-border/75'>
|
||||
<div className='bg-card/35 border-border/70 md:divide-border/75 overflow-hidden rounded-lg border md:divide-y'>
|
||||
{providerModels.map((model) => (
|
||||
<ModelItemCard
|
||||
key={model.id}
|
||||
|
||||
@@ -59,7 +59,9 @@ export function ProviderCard({
|
||||
<div className='flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between'>
|
||||
<div className='min-w-0 flex-1'>
|
||||
<div className='flex flex-col gap-2 sm:flex-row sm:items-center'>
|
||||
<CardTitle className='truncate'>{provider.provider_type}</CardTitle>
|
||||
<CardTitle className='truncate'>
|
||||
{provider.provider_type}
|
||||
</CardTitle>
|
||||
<Badge
|
||||
variant={provider.enabled ? 'default' : 'secondary'}
|
||||
className='w-fit'
|
||||
|
||||
@@ -120,7 +120,9 @@ export function UsageSummaryCards({ summary }: UsageSummaryCardsProps) {
|
||||
{card.title}
|
||||
</CardTitle>
|
||||
<span className='inline-flex size-6 items-center justify-center sm:size-7'>
|
||||
<card.icon className={`size-3.5 sm:size-4 ${card.iconClassName}`} />
|
||||
<card.icon
|
||||
className={`size-3.5 sm:size-4 ${card.iconClassName}`}
|
||||
/>
|
||||
</span>
|
||||
</CardHeader>
|
||||
<CardContent className='pt-0'>
|
||||
|
||||
Reference in New Issue
Block a user