diff --git a/src/components/ai-monitoring/AIErrorBadge.tsx b/src/components/ai-monitoring/AIErrorBadge.tsx index d063d8b..dfe8b31 100644 --- a/src/components/ai-monitoring/AIErrorBadge.tsx +++ b/src/components/ai-monitoring/AIErrorBadge.tsx @@ -1,4 +1,4 @@ -import { Chip, Tooltip } from '@mui/material' +import { GenericBadge } from '../shared/GenericBadge' import type { AIOutputError } from '../../domain/aiOutput' const ERROR_CONFIG: Record = { @@ -11,13 +11,5 @@ const ERROR_CONFIG: Record = { export function AIErrorBadge({ error }: { error: AIOutputError }) { const { label, color } = ERROR_CONFIG[error.type] ?? { label: error.type, color: '#c0392b' } - return ( - - - - ) + return } diff --git a/src/components/ai-monitoring/AIOutputStatusBadge.tsx b/src/components/ai-monitoring/AIOutputStatusBadge.tsx index 409d3c0..e88d25a 100644 --- a/src/components/ai-monitoring/AIOutputStatusBadge.tsx +++ b/src/components/ai-monitoring/AIOutputStatusBadge.tsx @@ -1,21 +1,15 @@ -import { Chip } from '@mui/material' +import { GenericBadge } from '../shared/GenericBadge' import type { ReviewStatus } from '../../domain/enums' const CONFIG: Record = { - UNREVIEWED: { label: 'Ungeprüft', color: '#94a3b8' }, + UNREVIEWED: { label: 'Ungeprüft', color: '#94a3b8' }, IN_REVIEW: { label: 'In Prüfung', color: '#d97706' }, - APPROVED: { label: 'Genehmigt', color: '#1a7a4a' }, - REJECTED: { label: 'Abgelehnt', color: '#c0392b' }, - FLAGGED: { label: 'Markiert', color: '#ea580c' }, + APPROVED: { label: 'Genehmigt', color: '#1a7a4a' }, + REJECTED: { label: 'Abgelehnt', color: '#c0392b' }, + FLAGGED: { label: 'Markiert', color: '#ea580c' }, } export function AIOutputStatusBadge({ status }: { status: ReviewStatus }) { const { label, color } = CONFIG[status] ?? { label: status, color: '#64748b' } - return ( - - ) + return } diff --git a/src/components/match-center/MatchStatusBadge.tsx b/src/components/match-center/MatchStatusBadge.tsx index 2e5a2c2..f2afbc6 100644 --- a/src/components/match-center/MatchStatusBadge.tsx +++ b/src/components/match-center/MatchStatusBadge.tsx @@ -1,4 +1,4 @@ -import { Chip } from '@mui/material' +import { GenericBadge } from '../shared/GenericBadge' import type { MatchStatus } from '../../domain/enums' const STATUS_META: Record = { @@ -10,9 +10,6 @@ const STATUS_META: Record = { export function MatchStatusBadge({ status }: { status?: MatchStatus }) { if (!status) return null - const meta = STATUS_META[status] ?? { label: status, color: '#64748b' } - return ( - - ) + const { label, color } = STATUS_META[status] ?? { label: status, color: '#64748b' } + return } diff --git a/src/components/review/ReviewEntityTypeBadge.tsx b/src/components/review/ReviewEntityTypeBadge.tsx index 8b320d5..918d64f 100644 --- a/src/components/review/ReviewEntityTypeBadge.tsx +++ b/src/components/review/ReviewEntityTypeBadge.tsx @@ -1,11 +1,6 @@ -import { Chip } from '@mui/material' +import { GenericBadge } from '../shared/GenericBadge' import type { ReviewEntityType } from '../../domain/review' -interface ReviewEntityTypeBadgeProps { - entityType: ReviewEntityType - size?: 'small' | 'medium' -} - const CONFIG: Record = { FUTURE_SIGNAL: { label: 'Zukunftssignal', color: '#7c3aed' }, MATCH_EXPLANATION: { label: 'Match-Begründung', color: '#1e3a5f' }, @@ -15,18 +10,12 @@ const CONFIG: Record = { PROPERTY_DATA_ISSUE: { label: 'Datenfehler', color: '#c0392b' }, } -export function ReviewEntityTypeBadge({ entityType, size = 'small' }: ReviewEntityTypeBadgeProps) { - const { label, color } = CONFIG[entityType] ?? { label: entityType, color: '#64748b' } - return ( - - ) +interface Props { + entityType: ReviewEntityType + size?: 'small' | 'medium' +} + +export function ReviewEntityTypeBadge({ entityType, size = 'small' }: Props) { + const { label, color } = CONFIG[entityType] ?? { label: entityType, color: '#64748b' } + return } diff --git a/src/components/review/ReviewPriorityBadge.tsx b/src/components/review/ReviewPriorityBadge.tsx index 6732c33..b349472 100644 --- a/src/components/review/ReviewPriorityBadge.tsx +++ b/src/components/review/ReviewPriorityBadge.tsx @@ -1,11 +1,6 @@ -import { Chip } from '@mui/material' +import { GenericBadge } from '../shared/GenericBadge' import type { ReviewPriority } from '../../domain/review' -interface ReviewPriorityBadgeProps { - priority: ReviewPriority - size?: 'small' | 'medium' -} - const CONFIG: Record = { LOW: { label: 'Niedrig', color: '#64748b' }, MEDIUM: { label: 'Mittel', color: '#d97706' }, @@ -13,19 +8,12 @@ const CONFIG: Record = { CRITICAL: { label: 'Kritisch', color: '#c0392b' }, } -export function ReviewPriorityBadge({ priority, size = 'small' }: ReviewPriorityBadgeProps) { - const { label, color } = CONFIG[priority] ?? CONFIG.MEDIUM - return ( - - ) +interface Props { + priority: ReviewPriority + size?: 'small' | 'medium' +} + +export function ReviewPriorityBadge({ priority, size = 'small' }: Props) { + const { label, color } = CONFIG[priority] ?? CONFIG.MEDIUM + return } diff --git a/src/components/review/ReviewStatusBadge.tsx b/src/components/review/ReviewStatusBadge.tsx index 3f35414..84fb96e 100644 --- a/src/components/review/ReviewStatusBadge.tsx +++ b/src/components/review/ReviewStatusBadge.tsx @@ -1,33 +1,21 @@ -import { Chip } from '@mui/material' +import { GenericBadge } from '../shared/GenericBadge' import type { ReviewTaskStatus } from '../../domain/review' -interface ReviewStatusBadgeProps { +const CONFIG: Record = { + PENDING: { label: 'Ausstehend', color: '#d97706' }, + IN_REVIEW: { label: 'In Prüfung', color: '#2563eb' }, + APPROVED: { label: 'Genehmigt', color: '#1a7a4a' }, + REJECTED: { label: 'Abgelehnt', color: '#c0392b' }, + NEEDS_MORE_DATA: { label: 'Mehr Daten nötig', color: '#7c3aed' }, + ESCALATED: { label: 'Eskaliert', color: '#ea580c' }, +} + +interface Props { status: ReviewTaskStatus size?: 'small' | 'medium' } -const CONFIG: Record = { - PENDING: { label: 'Ausstehend', color: '#d97706' }, - IN_REVIEW: { label: 'In Prüfung', color: '#2563eb' }, - APPROVED: { label: 'Genehmigt', color: '#1a7a4a' }, - REJECTED: { label: 'Abgelehnt', color: '#c0392b' }, - NEEDS_MORE_DATA: { label: 'Mehr Daten nötig', color: '#7c3aed' }, - ESCALATED: { label: 'Eskaliert', color: '#ea580c' }, -} - -export function ReviewStatusBadge({ status, size = 'small' }: ReviewStatusBadgeProps) { +export function ReviewStatusBadge({ status, size = 'small' }: Props) { const { label, color } = CONFIG[status] ?? CONFIG.PENDING - return ( - - ) + return } diff --git a/src/components/shared/GenericBadge.tsx b/src/components/shared/GenericBadge.tsx new file mode 100644 index 0000000..fdc4a3a --- /dev/null +++ b/src/components/shared/GenericBadge.tsx @@ -0,0 +1,50 @@ +import { Chip, Tooltip } from '@mui/material' +import type { ReactElement } from 'react' + +export interface GenericBadgeProps { + label: string + color: string + /** transparent: semi-opaque bg (color + 18% opacity) | solid: filled bg, white text */ + variant?: 'transparent' | 'solid' + /** Adds a 1px border at color 25% opacity (transparent variant only) */ + showBorder?: boolean + /** fontWeight 700 instead of 600 */ + bold?: boolean + /** Optional lucide / MUI icon element — sized by the caller */ + icon?: ReactElement + size?: 'small' | 'medium' + /** Wraps the badge in a Tooltip */ + tooltip?: string + ariaLabel?: string +} + +export function GenericBadge({ + label, + color, + variant = 'transparent', + showBorder = false, + bold = false, + icon, + size = 'small', + tooltip, + ariaLabel, +}: GenericBadgeProps) { + const chip = ( + + ) + + return tooltip ? {chip} : chip +} diff --git a/src/components/shared/index.ts b/src/components/shared/index.ts index 7fc6bf8..eeac11e 100644 --- a/src/components/shared/index.ts +++ b/src/components/shared/index.ts @@ -1,3 +1,5 @@ +export { GenericBadge } from './GenericBadge' +export type { GenericBadgeProps } from './GenericBadge' export { ViewToggle } from './ViewToggle' export { HeatBadge } from './HeatBadge' export { LocationPreview } from './LocationPreview' diff --git a/src/components/shortlist/ShortlistStatusBadge.tsx b/src/components/shortlist/ShortlistStatusBadge.tsx index e7025dc..5ef6ab7 100644 --- a/src/components/shortlist/ShortlistStatusBadge.tsx +++ b/src/components/shortlist/ShortlistStatusBadge.tsx @@ -1,4 +1,4 @@ -import { Chip } from '@mui/material' +import { GenericBadge } from '../shared/GenericBadge' import type { ShortlistStatus } from '../../domain/enums' const STATUS_META: Record = { @@ -12,12 +12,6 @@ const STATUS_META: Record = { } export function ShortlistStatusBadge({ status }: { status: ShortlistStatus }) { - const meta = STATUS_META[status] ?? { label: status, color: '#64748b' } - return ( - - ) + const { label, color } = STATUS_META[status] ?? { label: status, color: '#64748b' } + return } diff --git a/src/mock-data/propertyStore.ts b/src/mock-data/propertyStore.ts new file mode 100644 index 0000000..eeeb834 --- /dev/null +++ b/src/mock-data/propertyStore.ts @@ -0,0 +1,11 @@ +import type { Property } from '../domain/property' +import { mockProperties } from './properties' + +/** + * Shared mutable store for mock Property data. + * + * Imported by MockupPropertyProvider and MockupUnitProvider. + * Real providers (REST, Supabase, …) replace the entire provider file + * and never touch this module. + */ +export const propertyStore: Property[] = [...mockProperties] diff --git a/src/provider/MockupPropertyProvider.ts b/src/provider/MockupPropertyProvider.ts index a613acc..9e616ae 100644 --- a/src/provider/MockupPropertyProvider.ts +++ b/src/provider/MockupPropertyProvider.ts @@ -1,8 +1,7 @@ import type { IPropertyProvider, PropertyFilters } from './IPropertyProvider' import type { Property, CreatePropertyInput, UpdatePropertyInput } from '../domain/property' -import { mockProperties } from '../mock-data/properties' +import { propertyStore } from '../mock-data/propertyStore' -export const propertyStore: Property[] = [...mockProperties] const store = propertyStore export const MockupPropertyProvider: IPropertyProvider = { diff --git a/src/provider/MockupUnitProvider.ts b/src/provider/MockupUnitProvider.ts index 4e29792..994e8cd 100644 --- a/src/provider/MockupUnitProvider.ts +++ b/src/provider/MockupUnitProvider.ts @@ -1,6 +1,6 @@ import type { IUnitProvider } from './IUnitProvider' import type { PropertyUnit } from '../domain/property' -import { propertyStore } from './MockupPropertyProvider' +import { propertyStore } from '../mock-data/propertyStore' function getAllUnits(): PropertyUnit[] { return propertyStore.flatMap(p => diff --git a/src/services/matchSyncService.ts b/src/services/matchSyncService.ts index b15d761..b3fa011 100644 --- a/src/services/matchSyncService.ts +++ b/src/services/matchSyncService.ts @@ -4,7 +4,7 @@ * another provider directly. */ import { matchStore } from '../provider/MockupMatchProvider' -import { propertyStore } from '../provider/MockupPropertyProvider' +import { propertyStore } from '../mock-data/propertyStore' import { MatchStrength, MatchStatus, RiskLevel, ResultType } from '../domain/enums' import type { Match } from '../domain/match' import type { MatchEngineOutput } from '../domain/scoring'