PageSourceSearch

https://sistur.lovable.app/assets/IssueCard-CJW_RD_G.js

js sistur.lovable.app collected 2026-10-03 03:47:40 UTC 4,915 bytes, 133 lines download raw bytes

1const e=`import { tx } from '@/i18n/t';
2import { cn } from '@/lib/utils';
3import { AlertTriangle, ChevronRight, Building2, Users, Truck } from 'lucide-react';
4import type { Issue, TerritorialInterpretation } from '@/types/sistur';
5import { PILLAR_INFO, SEVERITY_INFO, INTERPRETATION_INFO } from '@/types/sistur';
6import { Badge } from '@/components/ui/badge';
7import { Button } from '@/components/ui/button';
8import {
9  Tooltip,
10  TooltipContent,
11  TooltipTrigger,
12} from '@/components/ui/tooltip';
13
14interface IssueCardProps {
15  issue: Issue;
16  onViewRecommendations?: () => void;
17}
18
19const InterpretationIcon = ({ interpretation }: { interpretation: TerritorialInterpretation }) => {
20  switch (interpretation) {
21    case 'ESTRUTURAL':
22      return <Building2 className="h-3.5 w-3.5" />;
23    case 'GESTAO':
24      return <Users className="h-3.5 w-3.5" />;
25    case 'ENTREGA':
26      return <Truck className="h-3.5 w-3.5" />;
27    default:
28      return null;
29  }
30};
31
32export function IssueCard({ issue, onViewRecommendations }: IssueCardProps) {
33  // NOTE: Some views (e.g. Enterprise dashboard) may pass a simplified issue shape.
34  // Keep this component defensive to avoid hard crashes (white screen).
35  const pillarInfo = (PILLAR_INFO as any)[issue.pillar] ?? { name: issue.pillar };
36  const severityInfo = (SEVERITY_INFO as any)[issue.severity] ?? { label: issue.severity };
37  const interpretationInfo = issue.interpretation ? (INTERPRETATION_INFO as any)[issue.interpretation] : null;
38
39  const themeLabel = (issue as any)?.theme;
40  const evidenceIndicators = ((issue as any)?.evidence?.indicators ?? []) as Array<{ name: string; score: number }>;
41
42  const pillarVariant = issue.pillar.toLowerCase() as 'ra' | 'oe' | 'ao';
43  const severityVariant = issue.severity === 'CRITICO' 
44    ? 'critical' 
45    : issue.severity === 'MODERADO' 
46    ? 'moderate' 
47    : 'good';
48
49  return (
50    <div className="p-4 rounded-lg border bg-card hover:shadow-md transition-all duration-200">
51      <div className="flex items-start gap-3">
52        <div
53          className={cn(
54            'p-2 rounded-lg',
55            issue.severity === 'CRITICO'
56              ? 'bg-severity-critical/10'
57              : issue.severity === 'MODERADO'
58              ? 'bg-severity-moderate/10'
59              : 'bg-severity-good/10'
60          )}
61        >
62          <AlertTriangle
63            className={cn(
64              'h-5 w-5',
65              issue.severity === 'CRITICO'
66                ? 'text-severity-critical'
67                : issue.severity === 'MODERADO'
68                ? 'text-severity-moderate'
69                : 'text-severity-good'
70            )}
71          />
72        </div>
73
74        <div className="flex-1 min-w-0">
75          <div className="flex items-center gap-2 flex-wrap">
76            <Badge variant={pillarVariant}>{pillarInfo.name}</Badge>
77            <Badge variant={severityVariant}>{tx(severityInfo.label)}</Badge>
78            {themeLabel ? (
79              <Badge variant="outline" className="text-xs">
80                {tx(String(themeLabel ?? ""))}
81              </Badge>
82            ) : null}
83            {/* Territorial Interpretation Badge */}
84            {interpretationInfo && (
85              <Tooltip>
86                <TooltipTrigger>
87                  <Badge 
88                    variant="secondary" 
89                    className={cn("text-xs gap-1", interpretationInfo.color)}
90                  >
91                    <InterpretationIcon interpretation={issue.interpretation!} />
92                    {tx(interpretationInfo.label)}
93                  </Badge>
94                </TooltipTrigger>
95                <TooltipContent className="max-w-xs">
96                  <p className="font-medium">{tx(interpretationInfo.label)}</p>
97                  <p className="text-xs text-muted-foreground">{tx(interpretationInfo.description)}</p>
98                </TooltipContent>
99              </Tooltip>
100            )}
101          </div>
102
103          <h4 className="mt-2 font-medium text-foreground">{tx(issue.title)}</h4>
104
105          {evidenceIndicators.length > 0 && (
106            <div className="mt-2 text-sm text-muted-foreground">
107              <span className="font-medium">{tx('Evidências:')} </span>
108              {evidenceIndicators.map((ind, i) => (
109                <span key={i}>
110                  {ind.name} ({Math.round(ind.score * 100)}%)
111                  {i < evidenceIndicators.length - 1 && ', '}
112                </span>
113              ))}
114            </div>
115          )}
116
117          {onViewRecommendations && (
118            <Button
119              variant="ghost"
120              size="sm"
121              className="mt-2 -ml-2 text-primary hover:text-primary"
122              onClick={onViewRecommendations}
123            >
124              {tx('Ver recomendações')}
125              <ChevronRight className="ml-1 h-4 w-4" />
126            </Button>
127          )}
128        </div>
129      </div>
130    </div>
131  );
132}
133`;export{e as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.