turash/bugulma/frontend/components/ui/PriceDisplay.tsx
2025-12-15 10:06:41 +01:00

93 lines
2.7 KiB
TypeScript

import { useTranslation } from '@/hooks/useI18n.tsx';
import React from 'react';
import Badge from './Badge';
import { Price, Text } from './Typography';
import { Flex } from './layout';
export type PriceType = 'unit' | 'hourly' | 'fixed' | 'free' | 'on-request';
export interface PriceDisplayProps {
value?: number | null;
priceType?: PriceType;
/** Translation key for unit label (e.g., 'common.currency.perUnit') */
unitTKey?: string;
/** Direct unit text (alternative to unitTKey) */
unit?: string;
/** Translation key for "free" label */
freeTKey?: string;
/** Translation key for "price on request" label */
onRequestTKey?: string;
currency?: string;
variant?: 'large' | 'medium' | 'small';
showUnitLabel?: boolean;
additionalInfo?: React.ReactNode;
className?: string;
}
/**
* PriceDisplay component for displaying prices with different types and formatting
* Supports localization via translation keys
*
* @example
* <PriceDisplay value={99.99} priceType="unit" unitTKey="common.currency.perUnit" />
* <PriceDisplay value={null} priceType="free" freeTKey="common.free" />
*/
export const PriceDisplay: React.FC<PriceDisplayProps> = ({
value,
priceType = 'fixed',
unitTKey,
unit,
freeTKey = 'common.free',
onRequestTKey = 'common.priceOnRequest',
currency = 'EUR',
variant = 'large',
showUnitLabel = true,
additionalInfo,
className,
}) => {
const { t } = useTranslation();
// If no value or value is 0, show appropriate fallback
if (value == null || value === 0) {
if (priceType === 'free') {
return (
<Badge variant="outline" className="text-sm">
{t(freeTKey)}
</Badge>
);
}
return (
<Badge variant="outline" className="text-sm">
{t(onRequestTKey)}
</Badge>
);
}
// Map price types to unit translation keys (can be overridden with unitTKey)
const unitTKeyMap: Record<PriceType, string | undefined> = {
unit: 'common.currency.perUnit',
hourly: 'common.currency.perHour',
fixed: undefined,
free: undefined,
'on-request': undefined,
};
// Use provided unitTKey, or fallback to type-based key, or direct unit
const displayUnitTKey = unitTKey || unitTKeyMap[priceType];
const displayUnit = showUnitLabel ? (displayUnitTKey ? undefined : unit) : undefined;
return (
<Flex align="baseline" gap="md" wrap="wrap" className={className}>
<Price
value={value}
currency={currency}
variant={variant}
showUnit={!!(displayUnitTKey || displayUnit)}
unitTKey={displayUnitTKey}
unit={displayUnit}
/>
{additionalInfo && <Text variant="muted">{additionalInfo}</Text>}
</Flex>
);
};