import React from 'react'; import { View, Text, StyleSheet, Image, TouchableOpacity } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { Card } from '../ui/Card'; import { colors, spacing, typography, borderRadius } from '../../theme'; import { Issue } from '../../types'; interface IssueCardProps { issue: Issue; onPress?: () => void; } const priorityColors: Record = { 1: colors.priority.critical, 2: colors.priority.high, 3: colors.priority.medium, 4: colors.priority.low, }; const priorityLabels: Record = { 1: 'CRITICAL', 2: 'HIGH', 3: 'MEDIUM', 4: 'LOW', }; const stateColors: Record = { reported: colors.status.info, validated: colors.accent.purple, assigned: colors.accent.cyan, in_progress: colors.status.warning, resolved: colors.status.success, closed: colors.text.tertiary, rejected: colors.status.error, }; export function IssueCard({ issue, onPress }: IssueCardProps) { const priorityColor = issue.priority ? priorityColors[issue.priority] : colors.text.tertiary; const priorityLabel = issue.priority ? priorityLabels[issue.priority] : 'N/A'; const stateColor = stateColors[issue.state] || colors.text.tertiary; const formatDate = (dateStr: string) => { const date = new Date(dateStr); return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', }); }; return ( {issue.annotated_urls[0] ? ( ) : issue.image_urls[0] ? ( ) : ( )} {priorityLabel} {issue.state.toUpperCase().replace('_', ' ')} {issue.category ? ( {issue.category} ) : null} {issue.confidence !== undefined && issue.confidence !== null ? ( Confidence: {(issue.confidence * 100).toFixed(0)}% ) : null} {issue.description ? ( {issue.description} ) : null} {formatDate(issue.created_at)} {issue.is_duplicate ? ( DUPLICATE ) : null} ); } const styles = StyleSheet.create({ container: { marginBottom: spacing.md, }, header: { flexDirection: 'row', }, thumbnail: { width: 80, height: 80, borderRadius: borderRadius.md, }, placeholderImage: { backgroundColor: colors.background.tertiary, alignItems: 'center', justifyContent: 'center', }, info: { flex: 1, marginLeft: spacing.md, }, badges: { flexDirection: 'row', flexWrap: 'wrap', gap: spacing.xs, }, badge: { paddingHorizontal: spacing.sm, paddingVertical: spacing.xs, borderRadius: borderRadius.sm, }, stateBadge: { backgroundColor: 'transparent', borderWidth: 1, }, badgeText: { color: colors.text.primary, fontSize: 10, fontWeight: '600', }, category: { color: colors.text.primary, fontSize: typography.body.fontSize, fontWeight: '600', marginTop: spacing.sm, }, confidence: { color: colors.text.secondary, fontSize: typography.caption.fontSize, marginTop: spacing.xs, }, description: { color: colors.text.secondary, fontSize: typography.bodySmall.fontSize, marginTop: spacing.md, }, footer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginTop: spacing.md, paddingTop: spacing.md, borderTopWidth: 1, borderTopColor: colors.border.light, }, date: { color: colors.text.tertiary, fontSize: typography.caption.fontSize, }, duplicateBadge: { backgroundColor: colors.status.warning, paddingHorizontal: spacing.sm, paddingVertical: spacing.xs, borderRadius: borderRadius.sm, }, duplicateText: { color: colors.text.inverse, fontSize: 10, fontWeight: '600', }, });